svn path=/branches/mono-1-1-9/mcs/; revision=50439
[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 //
11
12 //
13 // Permission is hereby granted, free of charge, to any person obtaining
14 // a copy of this software and associated documentation files (the
15 // "Software"), to deal in the Software without restriction, including
16 // without limitation the rights to use, copy, modify, merge, publish,
17 // distribute, sublicense, and/or sell copies of the Software, and to
18 // permit persons to whom the Software is furnished to do so, subject to
19 // the following conditions:
20 // 
21 // The above copyright notice and this permission notice shall be
22 // included in all copies or substantial portions of the Software.
23 // 
24 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
28 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
29 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
30 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
31 //
32
33 using System;
34 using System.Collections;
35 using System.ComponentModel;
36 using System.Reflection;
37 using System.Web;
38 using System.Web.Compilation;
39 using System.Web.Util;
40
41 namespace System.Web.UI {
42
43         public abstract class TemplateControl : Control, INamingContainer
44         {
45                 static object abortTransaction = new object ();
46                 static object commitTransaction = new object ();
47                 static object error = new object ();
48                 static string [] methodNames = { "Page_Init",
49                                                  "Page_Load",
50                                                  "Page_DataBind",
51                                                  "Page_PreRender",
52                                                  "Page_Disposed",
53                                                  "Page_Error",
54                                                  "Page_Unload",
55                                                  "Page_AbortTransaction",
56                                                  "Page_CommitTransaction" };
57
58                 const BindingFlags bflags = BindingFlags.Public |
59                                             BindingFlags.NonPublic |
60                                             BindingFlags.Instance;
61
62                 #region Constructor
63                 protected TemplateControl ()
64                 {
65                         Construct ();
66                 }
67
68                 #endregion
69
70                 #region Properties
71                 [EditorBrowsable (EditorBrowsableState.Never)]
72                 protected virtual int AutoHandlers {
73                         get { return 0; }
74                         set { }
75                 }
76
77                 [EditorBrowsable (EditorBrowsableState.Never)]
78                 protected virtual bool SupportAutoEvents {
79                         get { return true; }
80                 }
81
82                 #endregion
83
84                 #region Methods
85
86                 protected virtual void Construct ()
87                 {
88                 }
89
90                 [MonoTODO]
91                 protected LiteralControl CreateResourceBasedLiteralControl (int offset,
92                                                                                     int size,
93                                                                                     bool fAsciiOnly)
94                 {
95                         return null;
96                 }
97
98                 internal void WireupAutomaticEvents ()
99                 {
100                         if (!SupportAutoEvents || !AutoEventWireup)
101                                 return;
102
103                         Type type = GetType ();
104                         foreach (string methodName in methodNames) {
105                                 MethodInfo method = type.GetMethod (methodName, bflags);
106                                 if (method == null)
107                                         continue;
108
109                                 if (method.DeclaringType != type) {
110                                         if (!method.IsPublic && !method.IsFamilyOrAssembly &&
111                                             !method.IsFamilyAndAssembly && !method.IsFamily)
112                                                 continue;
113                                 }
114
115                                 if (method.ReturnType != typeof (void))
116                                         continue;
117
118                                 ParameterInfo [] parms = method.GetParameters ();
119                                 int length = parms.Length;
120                                 bool noParams = (length == 0);
121                                 if (!noParams && (length != 2 ||
122                                     parms [0].ParameterType != typeof (object) ||
123                                     parms [1].ParameterType != typeof (EventArgs)))
124                                     continue;
125
126                                 int pos = methodName.IndexOf ("_");
127                                 string eventName = methodName.Substring (pos + 1);
128                                 EventInfo evt = type.GetEvent (eventName);
129                                 if (evt == null) {
130                                         /* This should never happen */
131                                         continue;
132                                 }
133
134                                 if (noParams) {
135                                         NoParamsInvoker npi = new NoParamsInvoker (this, methodName);
136                                         evt.AddEventHandler (this, npi.FakeDelegate);
137                                 } else {
138                                         evt.AddEventHandler (this, Delegate.CreateDelegate (
139                                                         typeof (EventHandler), this, methodName));
140                                 }
141                         }
142                 }
143
144                 [EditorBrowsable (EditorBrowsableState.Never)]
145                 protected virtual void FrameworkInitialize ()
146                 {
147                 }
148
149                 Type GetTypeFromControlPath (string virtualPath)
150                 {
151                         if (virtualPath == null)
152                                 throw new ArgumentNullException ("virtualPath");
153
154                         string vpath = UrlUtils.Combine (TemplateSourceDirectory, virtualPath);
155                         string realpath = Context.Request.MapPath (vpath);
156                         return UserControlParser.GetCompiledType (vpath, realpath, Context);
157                 }
158
159                 public Control LoadControl (string virtualPath)
160                 {
161                         object control = Activator.CreateInstance (GetTypeFromControlPath (virtualPath));
162                         if (control is UserControl)
163                                 ((UserControl) control).InitializeAsUserControl (Page);
164
165                         return (Control) control;
166                 }
167
168                 public ITemplate LoadTemplate (string virtualPath)
169                 {
170                         Type t = GetTypeFromControlPath (virtualPath);
171                         return new SimpleTemplate (t);
172                 }
173
174                 protected virtual void OnAbortTransaction (EventArgs e)
175                 {
176                         EventHandler eh = Events [abortTransaction] as EventHandler;
177                         if (eh != null)
178                                 eh (this, e);
179                 }
180
181                 protected virtual void OnCommitTransaction (EventArgs e)
182                 {
183                         EventHandler eh = Events [commitTransaction] as EventHandler;
184                         if (eh != null)
185                                 eh (this, e);
186                 }
187
188                 protected virtual void OnError (EventArgs e)
189                 {
190                         EventHandler eh = Events [error] as EventHandler;
191                         if (eh != null)
192                                 eh (this, e);
193                 }
194
195                 [MonoTODO]
196                 public Control ParseControl (string content)
197                 {
198                         return null;
199                 }
200
201                 [MonoTODO]
202                 [EditorBrowsable (EditorBrowsableState.Never)]
203                 public static object ReadStringResource (Type t)
204                 {
205                         return null;
206                 }
207
208                 [MonoTODO]
209                 [EditorBrowsable (EditorBrowsableState.Never)]
210                 protected void SetStringResourcePointer (object stringResourcePointer,
211                                                          int maxResourceOffset)
212                 {
213                 }
214
215                 [MonoTODO]
216                 [EditorBrowsable (EditorBrowsableState.Never)]
217                 protected void WriteUTF8ResourceString (HtmlTextWriter output, int offset,
218                                                         int size, bool fAsciiOnly)
219                 {
220                 }
221
222                 #endregion
223
224                 #region Events
225
226                 [WebSysDescription ("Raised when the user aborts a transaction.")]
227                 public event EventHandler AbortTransaction {
228                         add { Events.AddHandler (abortTransaction, value); }
229                         remove { Events.RemoveHandler (abortTransaction, value); }
230                 }
231
232                 [WebSysDescription ("Raised when the user initiates a transaction.")]
233                 public event EventHandler CommitTransaction {
234                         add { Events.AddHandler (commitTransaction, value); }
235                         remove { Events.RemoveHandler (commitTransaction, value); }
236                 }
237
238                 [WebSysDescription ("Raised when an exception occurs that cannot be handled.")]
239                 public event EventHandler Error {
240                         add { Events.AddHandler (error, value); }
241                         remove { Events.RemoveHandler (error, value); }
242                 }
243
244                 #endregion
245
246                 class SimpleTemplate : ITemplate
247                 {
248                         Type type;
249
250                         public SimpleTemplate (Type type)
251                         {
252                                 this.type = type;
253                         }
254
255                         public void InstantiateIn (Control control)
256                         {
257                                 Control template = Activator.CreateInstance (type) as Control;
258                                 template.SetBindingContainer (false);
259                                 control.Controls.Add (template);
260                         }
261                 }
262
263 #if NET_2_0
264
265         Stack dataItemCtx;
266         
267         internal void PushDataItemContext (object o)
268         {
269                 if (dataItemCtx == null)
270                         dataItemCtx = new Stack ();
271                 
272                 dataItemCtx.Push (o);
273         }
274         
275         internal void PopDataItemContext ()
276         {
277                 if (dataItemCtx == null)
278                         throw new InvalidOperationException ();
279                 
280                 dataItemCtx.Pop ();
281         }
282         
283         internal object CurrentDataItem {
284                 get {
285                         if (dataItemCtx == null || dataItemCtx.Count == 0)
286                                 throw new InvalidOperationException ("No data item");
287                         
288                         return dataItemCtx.Peek ();
289                 }
290         }
291         
292         protected object Eval (string expression)
293         {
294                 return DataBinder.Eval (CurrentDataItem, expression);
295         }
296         
297         protected object Eval (string expression, string format)
298         {
299                 return DataBinder.Eval (CurrentDataItem, expression, format);
300         }
301         
302         protected object XPath (string xpathexpression)
303         {
304                 return XPathBinder.Eval (CurrentDataItem, xpathexpression);
305         }
306         
307         protected object XPath (string xpathexpression, string format)
308         {
309                 return XPathBinder.Eval (CurrentDataItem, xpathexpression, format);
310         }
311         
312         protected IEnumerable XPathSelect (string xpathexpression)
313         {
314                 return XPathBinder.Select (CurrentDataItem, xpathexpression);
315         }
316 #endif
317
318         }
319 }