2 // (C) 2005 Mainsoft Corporation (http://www.mainsoft.com)
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:
14 // The above copyright notice and this permission notice shall be
15 // included in all copies or substantial portions of the Software.
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.
27 using System.Collections;
28 using System.ComponentModel;
29 using System.Reflection;
32 using System.Web.J2EE;
34 using System.Web.Util;
36 namespace System.Web.UI {
38 public abstract class TemplateControl : Control, INamingContainer
40 static object abortTransaction = new object ();
41 static object commitTransaction = new object ();
42 static object error = new object ();
43 static string [] methodNames = { "Page_Init",
50 "Page_AbortTransaction",
51 "Page_CommitTransaction" };
53 const BindingFlags bflags = BindingFlags.Public |
54 BindingFlags.NonPublic |
55 BindingFlags.Instance;
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");
64 return (byte[])table[type];
66 private void SetResourceBytes(Type type, byte[] bytes) {
67 Hashtable table = (Hashtable)AppDomain.CurrentDomain.GetData("TemplateControl.RES_BYTES");
69 table = new Hashtable();
70 AppDomain.CurrentDomain.SetData("TemplateControl.RES_BYTES" , table);
76 private Hashtable ResourceHash {
78 Hashtable table = (Hashtable)AppDomain.CurrentDomain.GetData("TemplateControl.RES_STRING");
80 table = new Hashtable();
81 AppDomain.CurrentDomain.SetData("TemplateControl.RES_STRING" , table);
87 private string CachedString(string filename , int offset, int size)
89 string key = filename + offset + size;
92 string strObj = (string)ResourceHash[key];
96 char[] tmp = System.Text.Encoding.UTF8.GetChars(GetResourceBytes(this.GetType()) , offset , size);
97 strObj = new string(tmp);
98 ResourceHash.Add(key, strObj);
105 public virtual string TemplateSourceDirectory_Private
111 // This shouldnt be there, Page.TemplateSourceDirectory must know to get
112 // the right directory of the control.
113 public override string TemplateSourceDirectory
117 if (this is MasterPage)
118 // because MasterPage also has implementation of this property,
119 // but not always gets the right directory, in case where master page
120 // is in the root of webapp and the page that uses it is in sub folder.
121 return base.TemplateSourceDirectory;
124 if (_templateSourceDir == null)
126 string tempSrcDir = AppRelativeTemplateSourceDirectory;
127 if (tempSrcDir == null && Parent != null)
128 tempSrcDir = Parent.TemplateSourceDirectory;
129 if (tempSrcDir != null && tempSrcDir.Length > 1)
131 location = tempSrcDir.IndexOf('/',1);
133 tempSrcDir = tempSrcDir.Substring(location+1);
135 tempSrcDir = string.Empty;
137 string answer = HttpRuntime.AppDomainAppVirtualPath;
138 if(tempSrcDir == null)
141 if (tempSrcDir.Length > 0 && tempSrcDir [tempSrcDir.Length - 1] == '/')
142 tempSrcDir = tempSrcDir.Substring (0, tempSrcDir.Length - 1);
144 if (tempSrcDir.StartsWith("/") || tempSrcDir.Length == 0)
145 _templateSourceDir = answer + tempSrcDir;
147 _templateSourceDir = answer + "/"+ tempSrcDir;
149 return _templateSourceDir;
155 protected TemplateControl ()
163 [EditorBrowsable (EditorBrowsableState.Never)]
164 protected virtual int AutoHandlers {
169 [EditorBrowsable (EditorBrowsableState.Never)]
170 protected virtual bool SupportAutoEvents {
178 protected virtual void Construct ()
183 protected LiteralControl CreateResourceBasedLiteralControl (int offset,
187 string str = CachedString(this.GetType().FullName, offset, size);
188 return new LiteralControl(str);
191 internal void WireupAutomaticEvents ()
193 if (!SupportAutoEvents || !AutoEventWireup)
196 Type type = GetType ();
197 foreach (string methodName in methodNames) {
198 MethodInfo method = type.GetMethod (methodName, bflags);
203 if (method.DeclaringType != type) {
204 if (!method.IsPublic && !method.IsFamilyOrAssembly &&
205 !method.IsFamilyAndAssembly && !method.IsFamily)
210 if (method.ReturnType != typeof (void))
213 ParameterInfo [] parms = method.GetParameters ();
214 int length = parms.Length;
215 bool noParams = (length == 0);
216 if (!noParams && (length != 2 ||
217 parms [0].ParameterType != typeof (object) ||
218 parms [1].ParameterType != typeof (EventArgs)))
221 int pos = methodName.IndexOf ("_");
222 string eventName = methodName.Substring (pos + 1);
223 EventInfo evt = type.GetEvent (eventName);
225 /* This should never happen */
230 NoParamsInvoker npi = new NoParamsInvoker (this, methodName);
231 evt.AddEventHandler (this, npi.FakeDelegate);
233 evt.AddEventHandler (this, Delegate.CreateDelegate (
234 typeof (EventHandler), this, methodName));
239 [EditorBrowsable (EditorBrowsableState.Never)]
240 protected virtual void FrameworkInitialize ()
244 Type GetTypeFromControlPath (string virtualPath)
246 if (virtualPath == null)
247 throw new ArgumentNullException ("virtualPath");
249 string vpath = UrlUtils.Combine (TemplateSourceDirectory, virtualPath);
250 return PageMapper.GetObjectType(vpath);
253 public Control LoadControl (string virtualPath)
255 object control = Activator.CreateInstance (GetTypeFromControlPath (virtualPath));
256 if (control is UserControl)
257 ((UserControl) control).InitializeAsUserControl (Page);
259 return (Control) control;
262 public ITemplate LoadTemplate (string virtualPath)
264 Type t = GetTypeFromControlPath (virtualPath);
265 return new SimpleTemplate (t);
268 protected virtual void OnAbortTransaction (EventArgs e)
270 EventHandler eh = Events [abortTransaction] as EventHandler;
275 protected virtual void OnCommitTransaction (EventArgs e)
277 EventHandler eh = Events [commitTransaction] as EventHandler;
282 protected virtual void OnError (EventArgs e)
284 EventHandler eh = Events [error] as EventHandler;
290 public Control ParseControl (string content)
296 [EditorBrowsable (EditorBrowsableState.Never)]
297 public static object ReadStringResource (Type t)
302 [MonoTODO ("is this correct?")]
303 public Object ReadStringResource ()
305 return this.GetType();
309 [EditorBrowsable (EditorBrowsableState.Never)]
310 protected void SetStringResourcePointer (object stringResourcePointer,
311 int maxResourceOffset)
313 if ( GetResourceBytes(this.GetType()) != null)
316 java.lang.Class c = vmw.common.TypeUtils.ToClass(stringResourcePointer);
317 java.lang.ClassLoader contextClassLoader = c.getClassLoader();
319 //TODO:move this code to page mapper
320 string assemblyName = PageMapper.GetAssemblyResource(this.AppRelativeVirtualPath);
322 java.io.InputStream inputStream = contextClassLoader.getResourceAsStream(assemblyName);
324 System.IO.Stream strim = null;
325 if (inputStream == null) {
326 string descPath = String.Join("/", new string[]{"assemblies", this.GetType().Assembly.GetName().Name, assemblyName});
329 strim = new StreamReader(HttpContext.Current.Request.MapPath("/" + descPath)).BaseStream;
333 throw new System.IO.IOException("couldn't open resource file:" + assemblyName, ex);
336 throw new System.IO.IOException("couldn't open resource file:" + assemblyName);
342 strim = (System.IO.Stream)vmw.common.IOUtils.getStream(inputStream);
343 int capacity = (int)strim.Length;
344 byte[] resourceBytes = new byte[capacity];
345 strim.Read(resourceBytes,0,capacity);
346 SetResourceBytes(this.GetType(), resourceBytes);
350 throw new HttpException("problem with dll.ghres file", e);
356 if (inputStream != null )
362 [EditorBrowsable (EditorBrowsableState.Never)]
363 protected void WriteUTF8ResourceString (HtmlTextWriter output, int offset,
364 int size, bool fAsciiOnly)
366 string str = CachedString(this.GetType().FullName, offset, size);
374 [WebSysDescription ("Raised when the user aborts a transaction.")]
375 public event EventHandler AbortTransaction {
376 add { Events.AddHandler (abortTransaction, value); }
377 remove { Events.RemoveHandler (abortTransaction, value); }
380 [WebSysDescription ("Raised when the user initiates a transaction.")]
381 public event EventHandler CommitTransaction {
382 add { Events.AddHandler (commitTransaction, value); }
383 remove { Events.RemoveHandler (commitTransaction, value); }
386 [WebSysDescription ("Raised when an exception occurs that cannot be handled.")]
387 public event EventHandler Error {
388 add { Events.AddHandler (error, value); }
389 remove { Events.RemoveHandler (error, value); }
394 class SimpleTemplate : ITemplate
398 public SimpleTemplate (Type type)
403 public void InstantiateIn (Control control)
405 Control template = Activator.CreateInstance (type) as Control;
406 template.SetBindingContainer (false);
407 control.Controls.Add (template);
413 string _appRelativeVirtualPath = null;
415 public string AppRelativeVirtualPath
417 get { return _appRelativeVirtualPath; }
421 throw new ArgumentNullException ("value");
422 if (!UrlUtils.IsRooted (value) && !(value.Length > 0 && value[0] == '~'))
423 throw new ArgumentException ("The path that is set is not rooted");
424 _appRelativeVirtualPath = value;
426 int lastSlash = _appRelativeVirtualPath.LastIndexOf ('/');
427 AppRelativeTemplateSourceDirectory = (lastSlash > 0) ? _appRelativeVirtualPath.Substring (0, lastSlash + 1) : "~/";
431 protected object Eval (string expression)
433 return DataBinder.Eval (Page.GetDataItem (), expression);
436 protected string Eval (string expression, string format)
438 return DataBinder.Eval (Page.GetDataItem (), expression, format);
441 protected object XPath (string xpathexpression)
443 return XPathBinder.Eval (Page.GetDataItem (), xpathexpression);
446 protected string XPath (string xpathexpression, string format)
448 return XPathBinder.Eval (Page.GetDataItem (), xpathexpression, format);
451 protected IEnumerable XPathSelect (string xpathexpression)
453 return XPathBinder.Select (Page.GetDataItem (), xpathexpression);