2005-09-27 Gonzalo Paniagua Javier <gonzalo@ximian.com>
[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                 protected virtual int AutoHandlers {
77                         get { return 0; }
78                         set { }
79                 }
80
81                 [EditorBrowsable (EditorBrowsableState.Never)]
82                 protected virtual bool SupportAutoEvents {
83                         get { return true; }
84                 }
85
86                 #endregion
87
88                 #region Methods
89
90                 protected virtual void Construct ()
91                 {
92                 }
93
94                 [MonoTODO]
95                 protected LiteralControl CreateResourceBasedLiteralControl (int offset,
96                                                                                     int size,
97                                                                                     bool fAsciiOnly)
98                 {
99                         return null;
100                 }
101
102                 internal void WireupAutomaticEvents ()
103                 {
104                         if (!SupportAutoEvents || !AutoEventWireup)
105                                 return;
106
107                         Type type = GetType ();
108                         foreach (string methodName in methodNames) {
109                                 MethodInfo method = type.GetMethod (methodName, bflags);
110                                 if (method == null)
111                                         continue;
112
113                                 if (method.DeclaringType != type) {
114                                         if (!method.IsPublic && !method.IsFamilyOrAssembly &&
115                                             !method.IsFamilyAndAssembly && !method.IsFamily)
116                                                 continue;
117                                 }
118
119                                 if (method.ReturnType != typeof (void))
120                                         continue;
121
122                                 ParameterInfo [] parms = method.GetParameters ();
123                                 int length = parms.Length;
124                                 bool noParams = (length == 0);
125                                 if (!noParams && (length != 2 ||
126                                     parms [0].ParameterType != typeof (object) ||
127                                     parms [1].ParameterType != typeof (EventArgs)))
128                                     continue;
129
130                                 int pos = methodName.IndexOf ("_");
131                                 string eventName = methodName.Substring (pos + 1);
132                                 EventInfo evt = type.GetEvent (eventName);
133                                 if (evt == null) {
134                                         /* This should never happen */
135                                         continue;
136                                 }
137
138                                 if (noParams) {
139                                         NoParamsInvoker npi = new NoParamsInvoker (this, methodName);
140                                         evt.AddEventHandler (this, npi.FakeDelegate);
141                                 } else {
142                                         evt.AddEventHandler (this, Delegate.CreateDelegate (
143                                                         typeof (EventHandler), this, methodName));
144                                 }
145                         }
146                 }
147
148                 [EditorBrowsable (EditorBrowsableState.Never)]
149                 protected virtual void FrameworkInitialize ()
150                 {
151                 }
152
153                 Type GetTypeFromControlPath (string virtualPath)
154                 {
155                         if (virtualPath == null)
156                                 throw new ArgumentNullException ("virtualPath");
157
158                         string vpath = UrlUtils.Combine (TemplateSourceDirectory, virtualPath);
159                         string realpath = Context.Request.MapPath (vpath);
160                         return UserControlParser.GetCompiledType (vpath, realpath, Context);
161                 }
162
163                 public Control LoadControl (string virtualPath)
164                 {
165 #if NET_2_0
166                         if (virtualPath == null)
167                                 throw new ArgumentNullException ("virtualPath");
168 #else
169                         if (virtualPath == null)
170                                 throw new HttpException ("virtualPath is null");
171 #endif
172                         object control = Activator.CreateInstance (GetTypeFromControlPath (virtualPath));
173                         if (control is UserControl)
174                                 ((UserControl) control).InitializeAsUserControl (Page);
175
176                         return (Control) control;
177                 }
178
179                 public ITemplate LoadTemplate (string virtualPath)
180                 {
181 #if NET_2_0
182                         if (virtualPath == null)
183                                 throw new ArgumentNullException ("virtualPath");
184 #else
185                         if (virtualPath == null)
186                                 throw new HttpException ("virtualPath is null");
187 #endif
188                         Type t = GetTypeFromControlPath (virtualPath);
189                         return new SimpleTemplate (t);
190                 }
191
192                 protected virtual void OnAbortTransaction (EventArgs e)
193                 {
194                         EventHandler eh = Events [abortTransaction] as EventHandler;
195                         if (eh != null)
196                                 eh (this, e);
197                 }
198
199                 protected virtual void OnCommitTransaction (EventArgs e)
200                 {
201                         EventHandler eh = Events [commitTransaction] as EventHandler;
202                         if (eh != null)
203                                 eh (this, e);
204                 }
205
206                 protected virtual void OnError (EventArgs e)
207                 {
208                         EventHandler eh = Events [error] as EventHandler;
209                         if (eh != null)
210                                 eh (this, e);
211                 }
212
213                 [MonoTODO]
214                 public Control ParseControl (string content)
215                 {
216                         if (content == null)
217                                 throw new ArgumentNullException ("content");
218
219                         return null;
220                 }
221
222                 [MonoTODO]
223                 [EditorBrowsable (EditorBrowsableState.Never)]
224                 public static object ReadStringResource (Type t)
225                 {
226                         if (t == null)
227                                 throw new ArgumentNullException ("t");
228
229                         return null;
230                 }
231
232                 [MonoTODO]
233                 [EditorBrowsable (EditorBrowsableState.Never)]
234                 protected void SetStringResourcePointer (object stringResourcePointer,
235                                                          int maxResourceOffset)
236                 {
237                 }
238
239                 [MonoTODO]
240                 [EditorBrowsable (EditorBrowsableState.Never)]
241                 protected void WriteUTF8ResourceString (HtmlTextWriter output, int offset,
242                                                         int size, bool fAsciiOnly)
243                 {
244                 }
245
246                 #endregion
247
248                 #region Events
249
250                 [WebSysDescription ("Raised when the user aborts a transaction.")]
251                 public event EventHandler AbortTransaction {
252                         add { Events.AddHandler (abortTransaction, value); }
253                         remove { Events.RemoveHandler (abortTransaction, value); }
254                 }
255
256                 [WebSysDescription ("Raised when the user initiates a transaction.")]
257                 public event EventHandler CommitTransaction {
258                         add { Events.AddHandler (commitTransaction, value); }
259                         remove { Events.RemoveHandler (commitTransaction, value); }
260                 }
261
262                 [WebSysDescription ("Raised when an exception occurs that cannot be handled.")]
263                 public event EventHandler Error {
264                         add { Events.AddHandler (error, value); }
265                         remove { Events.RemoveHandler (error, value); }
266                 }
267
268                 #endregion
269
270                 class SimpleTemplate : ITemplate
271                 {
272                         Type type;
273
274                         public SimpleTemplate (Type type)
275                         {
276                                 this.type = type;
277                         }
278
279                         public void InstantiateIn (Control control)
280                         {
281                                 Control template = Activator.CreateInstance (type) as Control;
282                                 template.SetBindingContainer (false);
283                                 control.Controls.Add (template);
284                         }
285                 }
286
287 #if NET_2_0
288
289         Stack dataItemCtx;
290         
291         internal void PushDataItemContext (object o)
292         {
293                 if (dataItemCtx == null)
294                         dataItemCtx = new Stack ();
295                 
296                 dataItemCtx.Push (o);
297         }
298         
299         internal void PopDataItemContext ()
300         {
301                 if (dataItemCtx == null)
302                         throw new InvalidOperationException ();
303                 
304                 dataItemCtx.Pop ();
305         }
306         
307         internal object CurrentDataItem {
308                 get {
309                         if (dataItemCtx == null || dataItemCtx.Count == 0)
310                                 throw new InvalidOperationException ("No data item");
311                         
312                         return dataItemCtx.Peek ();
313                 }
314         }
315         
316         protected object Eval (string expression)
317         {
318                 return DataBinder.Eval (CurrentDataItem, expression);
319         }
320         
321         protected object Eval (string expression, string format)
322         {
323                 return DataBinder.Eval (CurrentDataItem, expression, format);
324         }
325         
326         protected object XPath (string xpathexpression)
327         {
328                 return XPathBinder.Eval (CurrentDataItem, xpathexpression);
329         }
330         
331         protected object XPath (string xpathexpression, string format)
332         {
333                 return XPathBinder.Eval (CurrentDataItem, xpathexpression, format);
334         }
335         
336         protected IEnumerable XPathSelect (string xpathexpression)
337         {
338                 return XPathBinder.Select (CurrentDataItem, xpathexpression);
339         }
340
341                 // IFilterResolutionService
342
343                 [MonoTODO]
344                 int IFilterResolutionService.CompareFilters (string filter1, string filter2)
345                 {
346                         throw new NotImplementedException ();
347                 }
348
349                 [MonoTODO]
350                 bool IFilterResolutionService.EvaluateFilter (string filterName)
351                 {
352                         throw new NotImplementedException ();
353                 }
354 #endif
355         }
356 }