Making simple web app work with Grasshopper.
[mono.git] / mcs / class / System.Web / System.Web.UI / TemplateControl.jvm.cs
1 //
2 // (C) 2005 Mainsoft Corporation (http://www.mainsoft.com)
3 //
4
5 //
6 // Permission is hereby granted, free of charge, to any person obtaining
7 // a copy of this software and associated documentation files (the
8 // "Software"), to deal in the Software without restriction, including
9 // without limitation the rights to use, copy, modify, merge, publish,
10 // distribute, sublicense, and/or sell copies of the Software, and to
11 // permit persons to whom the Software is furnished to do so, subject to
12 // the following conditions:
13 //
14 // The above copyright notice and this permission notice shall be
15 // included in all copies or substantial portions of the Software.
16 //
17 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
21 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
22 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
23 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 //
25
26 using System;
27 using System.Collections;
28 using System.ComponentModel;
29 using System.Reflection;
30 using System.Web;
31 using System.IO;
32 using System.Web.J2EE;
33 using vmw.common;
34 using System.Web.Util;
35
36 namespace System.Web.UI {
37
38         public abstract class TemplateControl : Control, INamingContainer
39         {
40                 static object abortTransaction = new object ();
41                 static object commitTransaction = new object ();
42                 static object error = new object ();
43                 static string [] methodNames = { "Page_Init",
44                                                  "Page_Load",
45                                                  "Page_DataBind",
46                                                  "Page_PreRender",
47                                                  "Page_Disposed",
48                                                  "Page_Error",
49                                                  "Page_Unload",
50                                                  "Page_AbortTransaction",
51                                                  "Page_CommitTransaction" };
52
53                 const BindingFlags bflags = BindingFlags.Public |
54                                             BindingFlags.NonPublic |
55                                             BindingFlags.Instance;
56
57                 private string _templateSourceDir;
58                 private static string hashTableMutex = "lock"; //used to sync access ResourceHash property
59                 private byte[] GetResourceBytes(Type type) {
60                         Hashtable table = (Hashtable)AppDomain.CurrentDomain.GetData("TemplateControl.RES_BYTES");
61                         if (table == null) {
62                                 return null;
63                         }
64                         return (byte[])table[type];
65                 }
66                 private void SetResourceBytes(Type type, byte[] bytes) {
67                         Hashtable table = (Hashtable)AppDomain.CurrentDomain.GetData("TemplateControl.RES_BYTES");
68                         if (table == null) {
69                                 table = new Hashtable();
70                                 AppDomain.CurrentDomain.SetData("TemplateControl.RES_BYTES" , table);
71                         }
72                         table[type] = bytes;
73                         return;
74                 }
75
76                 private Hashtable ResourceHash {
77                         get {
78                                 Hashtable table = (Hashtable)AppDomain.CurrentDomain.GetData("TemplateControl.RES_STRING");
79                                 if (table == null) {
80                                         table = new Hashtable();
81                                         AppDomain.CurrentDomain.SetData("TemplateControl.RES_STRING" , table);
82                                 }
83                                 return table;
84                         }
85                 }
86
87                 private string CachedString(string filename , int offset, int size)
88                 {
89                         string key = filename + offset + size;
90                         lock (hashTableMutex)
91                         {
92                                 string strObj = (string)ResourceHash[key];
93                                 if (strObj == null) 
94                                 {
95                                         
96                                         char[] tmp = System.Text.Encoding.UTF8.GetChars(GetResourceBytes(this.GetType()) , offset , size);
97                                         strObj = new string(tmp);
98                                         ResourceHash.Add(key, strObj);
99                                 }
100                         
101                                 return strObj;
102                         }
103                         
104                 }
105                 public virtual string TemplateSourceDirectory_Private 
106                 {
107                         get { return null; }
108                 }
109
110                 public override string TemplateSourceDirectory 
111                 {
112                         get {
113                                 int location = 0;
114                                 if (_templateSourceDir == null)
115                                 {
116                                         string tempSrcDir = TemplateSourceDirectory_Private;
117                                         if (tempSrcDir == null && Parent != null)
118                                                 tempSrcDir = Parent.TemplateSourceDirectory;
119                                         if (tempSrcDir != null && tempSrcDir.Length > 1)
120                                         {
121                                                 location = tempSrcDir.IndexOf('/',1);
122                                                 if (location!= -1)
123                                                         tempSrcDir = tempSrcDir.Substring(location+1);
124                                                 else
125                                                         tempSrcDir = string.Empty;
126                                         }
127                                         string answer =  HttpRuntime.AppDomainAppVirtualPath;
128                                         if(tempSrcDir == null)
129                                                 tempSrcDir = "";
130                                         if (tempSrcDir.StartsWith("/") || tempSrcDir.Length == 0)
131                                                 _templateSourceDir =  answer + tempSrcDir;
132                                         else
133                                                 _templateSourceDir = answer + "/"+ tempSrcDir;
134                                 }
135                                 return _templateSourceDir;
136                         }
137                 }
138
139
140                 #region Constructor
141                 protected TemplateControl ()
142                 {
143                         Construct ();
144                 }
145
146                 #endregion
147
148                 #region Properties
149                 [EditorBrowsable (EditorBrowsableState.Never)]
150                 protected virtual int AutoHandlers {
151                         get { return 0; }
152                         set { }
153                 }
154
155                 [EditorBrowsable (EditorBrowsableState.Never)]
156                 protected virtual bool SupportAutoEvents {
157                         get { return true; }
158                 }
159
160                 #endregion
161
162                 #region Methods
163
164                 protected virtual void Construct ()
165                 {
166                 }
167
168                 [MonoTODO]
169                 protected LiteralControl CreateResourceBasedLiteralControl (int offset,
170                                                                                     int size,
171                                                                                     bool fAsciiOnly)
172                 {
173                         string str = CachedString(this.GetType().FullName, offset, size);
174                         return new LiteralControl(str);
175                 }
176
177                 internal void WireupAutomaticEvents ()
178                 {
179                         if (!SupportAutoEvents || !AutoEventWireup)
180                                 return;
181
182                         Type type = GetType ();
183                         foreach (string methodName in methodNames) {
184                                 MethodInfo method = type.GetMethod (methodName, bflags);
185                                 if (method == null)
186                                         continue;
187
188                                 if (method.DeclaringType != type) {
189                                         if (!method.IsPublic && !method.IsFamilyOrAssembly &&
190                                             !method.IsFamilyAndAssembly && !method.IsFamily)
191                                                 continue;
192                                 }
193
194                                 if (method.ReturnType != typeof (void))
195                                         continue;
196
197                                 ParameterInfo [] parms = method.GetParameters ();
198                                 int length = parms.Length;
199                                 bool noParams = (length == 0);
200                                 if (!noParams && (length != 2 ||
201                                     parms [0].ParameterType != typeof (object) ||
202                                     parms [1].ParameterType != typeof (EventArgs)))
203                                         continue;
204
205                                 int pos = methodName.IndexOf ("_");
206                                 string eventName = methodName.Substring (pos + 1);
207                                 EventInfo evt = type.GetEvent (eventName);
208                                 if (evt == null) {
209                                         /* This should never happen */
210                                         continue;
211                                 }
212
213                                 if (noParams) {
214                                         NoParamsInvoker npi = new NoParamsInvoker (this, methodName);
215                                         evt.AddEventHandler (this, npi.FakeDelegate);
216                                 } else {
217                                         evt.AddEventHandler (this, Delegate.CreateDelegate (
218                                                         typeof (EventHandler), this, methodName));
219                                 }
220                         }
221                 }
222
223                 [EditorBrowsable (EditorBrowsableState.Never)]
224                 protected virtual void FrameworkInitialize ()
225                 {
226                 }
227
228                 Type GetTypeFromControlPath (string virtualPath)
229                 {
230                         if (virtualPath == null)
231                                 throw new ArgumentNullException ("virtualPath");
232
233                         string vpath = UrlUtils.Combine (TemplateSourceDirectory, virtualPath);
234                         if (!vpath.StartsWith(IAppDomainConfig.WAR_ROOT_SYMBOL)) 
235                                 vpath = Context.Request.MapPath(vpath);
236                         return PageMapper.GetObjectType(vpath);
237                 }
238
239                 public Control LoadControl (string virtualPath)
240                 {
241                         object control = Activator.CreateInstance (GetTypeFromControlPath (virtualPath));
242                         if (control is UserControl)
243                                 ((UserControl) control).InitializeAsUserControl (Page);
244
245                         return (Control) control;
246                 }
247
248                 public ITemplate LoadTemplate (string virtualPath)
249                 {
250                         Type t = GetTypeFromControlPath (virtualPath);
251                         return new SimpleTemplate (t);
252                 }
253
254                 protected virtual void OnAbortTransaction (EventArgs e)
255                 {
256                         EventHandler eh = Events [abortTransaction] as EventHandler;
257                         if (eh != null)
258                                 eh (this, e);
259                 }
260
261                 protected virtual void OnCommitTransaction (EventArgs e)
262                 {
263                         EventHandler eh = Events [commitTransaction] as EventHandler;
264                         if (eh != null)
265                                 eh (this, e);
266                 }
267
268                 protected virtual void OnError (EventArgs e)
269                 {
270                         EventHandler eh = Events [error] as EventHandler;
271                         if (eh != null)
272                                 eh (this, e);
273                 }
274
275                 [MonoTODO]
276                 public Control ParseControl (string content)
277                 {
278                         return null;
279                 }
280
281                 [MonoTODO]
282                 [EditorBrowsable (EditorBrowsableState.Never)]
283                 public static object ReadStringResource (Type t)
284                 {
285                         return t;
286                 }
287
288                 [MonoTODO]
289                 [EditorBrowsable (EditorBrowsableState.Never)]
290                 protected void SetStringResourcePointer (object stringResourcePointer,
291                                                          int maxResourceOffset)
292                 {
293                         if ( GetResourceBytes(this.GetType()) != null)
294                                 return;
295
296                         java.lang.Class c = vmw.common.TypeUtils.ToClass(stringResourcePointer);
297                         java.lang.ClassLoader  contextClassLoader = c.getClassLoader();
298                         string assemblyName = "dll.ghres";
299                         
300                         java.io.InputStream inputStream = contextClassLoader.getResourceAsStream(assemblyName);
301                         System.IO.Stream strim = null;
302                         if (inputStream == null) {
303                                 string descPath = String.Join("/", new string[]{"assemblies", this.GetType().Assembly.GetName().Name, assemblyName});
304                                 try 
305                                 {
306                                         strim = new StreamReader(HttpContext.Current.Request.MapPath("/" + descPath)).BaseStream;
307                                 }
308                                 catch (Exception ex)
309                                 {
310                                         throw new System.IO.IOException("couldn't open resource file:" + assemblyName, ex);
311                                 }
312                                 if (strim == null)
313                                         throw new System.IO.IOException("couldn't open resource file:" + assemblyName);
314                         }
315
316                         try
317                         {
318                                 if (strim == null)
319                                         strim = (System.IO.Stream)vmw.common.IOUtils.getStream(inputStream);
320                                 int capacity = (int)strim.Length;
321                                 byte[] resourceBytes = new byte[capacity];
322                                 strim.Read(resourceBytes,0,capacity);
323                                 SetResourceBytes(this.GetType(), resourceBytes);
324                         }
325                         catch(Exception e)
326                         {
327                                 throw new HttpException("problem with dll.ghres file", e);
328                         }
329                         finally
330                         {
331                                 if(strim != null)
332                                         strim.Close();
333                                 if (inputStream != null )
334                                         inputStream.close();
335                         }
336                 }
337
338                 [MonoTODO]
339                 [EditorBrowsable (EditorBrowsableState.Never)]
340                 protected void WriteUTF8ResourceString (HtmlTextWriter output, int offset,
341                                                         int size, bool fAsciiOnly)
342                 {
343                         string str = CachedString(this.GetType().FullName, offset, size);
344                         output.Write(str);
345                 }
346
347                 #endregion
348
349                 #region Events
350
351                 [WebSysDescription ("Raised when the user aborts a transaction.")]
352                 public event EventHandler AbortTransaction {
353                         add { Events.AddHandler (abortTransaction, value); }
354                         remove { Events.RemoveHandler (abortTransaction, value); }
355                 }
356
357                 [WebSysDescription ("Raised when the user initiates a transaction.")]
358                 public event EventHandler CommitTransaction {
359                         add { Events.AddHandler (commitTransaction, value); }
360                         remove { Events.RemoveHandler (commitTransaction, value); }
361                 }
362
363                 [WebSysDescription ("Raised when an exception occurs that cannot be handled.")]
364                 public event EventHandler Error {
365                         add { Events.AddHandler (error, value); }
366                         remove { Events.RemoveHandler (error, value); }
367                 }
368
369                 #endregion
370
371                 class SimpleTemplate : ITemplate
372                 {
373                         Type type;
374
375                         public SimpleTemplate (Type type)
376                         {
377                                 this.type = type;
378                         }
379
380                         public void InstantiateIn (Control control)
381                         {
382                                 Control template = Activator.CreateInstance (type) as Control;
383                                 template.SetBindingContainer (false);
384                                 control.Controls.Add (template);
385                         }
386                 }
387
388 #if NET_2_0
389
390         Stack dataItemCtx;
391         
392         internal void PushDataItemContext (object o)
393         {
394                 if (dataItemCtx == null)
395                         dataItemCtx = new Stack ();
396                 
397                 dataItemCtx.Push (o);
398         }
399         
400         internal void PopDataItemContext ()
401         {
402                 if (dataItemCtx == null)
403                         throw new InvalidOperationException ();
404                 
405                 dataItemCtx.Pop ();
406         }
407         
408         internal object CurrentDataItem {
409                 get {
410                         if (dataItemCtx == null || dataItemCtx.Count == 0)
411                                 throw new InvalidOperationException ("No data item");
412                         
413                         return dataItemCtx.Peek ();
414                 }
415         }
416         
417         protected object Eval (string expression)
418         {
419                 return DataBinder.Eval (CurrentDataItem, expression);
420         }
421         
422         protected object Eval (string expression, string format)
423         {
424                 return DataBinder.Eval (CurrentDataItem, expression, format);
425         }
426         
427         protected object XPath (string xpathexpression)
428         {
429                 return XPathBinder.Eval (CurrentDataItem, xpathexpression);
430         }
431         
432         protected object XPath (string xpathexpression, string format)
433         {
434                 return XPathBinder.Eval (CurrentDataItem, xpathexpression, format);
435         }
436         
437         protected IEnumerable XPathSelect (string xpathexpression)
438         {
439                 return XPathBinder.Select (CurrentDataItem, xpathexpression);
440         }
441 #endif
442
443         }
444 }