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
110 public override string TemplateSourceDirectory
114 if (_templateSourceDir == null)
116 string tempSrcDir = TemplateSourceDirectory_Private;
117 if (tempSrcDir == null && Parent != null)
118 tempSrcDir = Parent.TemplateSourceDirectory;
119 if (tempSrcDir != null && tempSrcDir.Length > 1)
121 location = tempSrcDir.IndexOf('/',1);
123 tempSrcDir = tempSrcDir.Substring(location+1);
125 tempSrcDir = string.Empty;
127 string answer = HttpRuntime.AppDomainAppVirtualPath;
128 if(tempSrcDir == null)
130 if (tempSrcDir.StartsWith("/") || tempSrcDir.Length == 0)
131 _templateSourceDir = answer + tempSrcDir;
133 _templateSourceDir = answer + "/"+ tempSrcDir;
135 return _templateSourceDir;
141 protected TemplateControl ()
149 [EditorBrowsable (EditorBrowsableState.Never)]
150 protected virtual int AutoHandlers {
155 [EditorBrowsable (EditorBrowsableState.Never)]
156 protected virtual bool SupportAutoEvents {
164 protected virtual void Construct ()
169 protected LiteralControl CreateResourceBasedLiteralControl (int offset,
173 string str = CachedString(this.GetType().FullName, offset, size);
174 return new LiteralControl(str);
177 internal void WireupAutomaticEvents ()
179 if (!SupportAutoEvents || !AutoEventWireup)
182 Type type = GetType ();
183 foreach (string methodName in methodNames) {
184 MethodInfo method = type.GetMethod (methodName, bflags);
188 if (method.DeclaringType != type) {
189 if (!method.IsPublic && !method.IsFamilyOrAssembly &&
190 !method.IsFamilyAndAssembly && !method.IsFamily)
194 if (method.ReturnType != typeof (void))
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)))
205 int pos = methodName.IndexOf ("_");
206 string eventName = methodName.Substring (pos + 1);
207 EventInfo evt = type.GetEvent (eventName);
209 /* This should never happen */
214 NoParamsInvoker npi = new NoParamsInvoker (this, methodName);
215 evt.AddEventHandler (this, npi.FakeDelegate);
217 evt.AddEventHandler (this, Delegate.CreateDelegate (
218 typeof (EventHandler), this, methodName));
223 [EditorBrowsable (EditorBrowsableState.Never)]
224 protected virtual void FrameworkInitialize ()
228 Type GetTypeFromControlPath (string virtualPath)
230 if (virtualPath == null)
231 throw new ArgumentNullException ("virtualPath");
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);
239 public Control LoadControl (string virtualPath)
241 object control = Activator.CreateInstance (GetTypeFromControlPath (virtualPath));
242 if (control is UserControl)
243 ((UserControl) control).InitializeAsUserControl (Page);
245 return (Control) control;
248 public ITemplate LoadTemplate (string virtualPath)
250 Type t = GetTypeFromControlPath (virtualPath);
251 return new SimpleTemplate (t);
254 protected virtual void OnAbortTransaction (EventArgs e)
256 EventHandler eh = Events [abortTransaction] as EventHandler;
261 protected virtual void OnCommitTransaction (EventArgs e)
263 EventHandler eh = Events [commitTransaction] as EventHandler;
268 protected virtual void OnError (EventArgs e)
270 EventHandler eh = Events [error] as EventHandler;
276 public Control ParseControl (string content)
282 [EditorBrowsable (EditorBrowsableState.Never)]
283 public static object ReadStringResource (Type t)
289 [EditorBrowsable (EditorBrowsableState.Never)]
290 protected void SetStringResourcePointer (object stringResourcePointer,
291 int maxResourceOffset)
293 if ( GetResourceBytes(this.GetType()) != null)
296 java.lang.Class c = vmw.common.TypeUtils.ToClass(stringResourcePointer);
297 java.lang.ClassLoader contextClassLoader = c.getClassLoader();
298 string assemblyName = "dll.ghres";
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});
306 strim = new StreamReader(HttpContext.Current.Request.MapPath("/" + descPath)).BaseStream;
310 throw new System.IO.IOException("couldn't open resource file:" + assemblyName, ex);
313 throw new System.IO.IOException("couldn't open resource file:" + assemblyName);
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);
327 throw new HttpException("problem with dll.ghres file", e);
333 if (inputStream != null )
339 [EditorBrowsable (EditorBrowsableState.Never)]
340 protected void WriteUTF8ResourceString (HtmlTextWriter output, int offset,
341 int size, bool fAsciiOnly)
343 string str = CachedString(this.GetType().FullName, offset, size);
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); }
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); }
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); }
371 class SimpleTemplate : ITemplate
375 public SimpleTemplate (Type type)
380 public void InstantiateIn (Control control)
382 Control template = Activator.CreateInstance (type) as Control;
383 template.SetBindingContainer (false);
384 control.Controls.Add (template);
392 internal void PushDataItemContext (object o)
394 if (dataItemCtx == null)
395 dataItemCtx = new Stack ();
397 dataItemCtx.Push (o);
400 internal void PopDataItemContext ()
402 if (dataItemCtx == null)
403 throw new InvalidOperationException ();
408 internal object CurrentDataItem {
410 if (dataItemCtx == null || dataItemCtx.Count == 0)
411 throw new InvalidOperationException ("No data item");
413 return dataItemCtx.Peek ();
417 protected object Eval (string expression)
419 return DataBinder.Eval (CurrentDataItem, expression);
422 protected object Eval (string expression, string format)
424 return DataBinder.Eval (CurrentDataItem, expression, format);
427 protected object XPath (string xpathexpression)
429 return XPathBinder.Eval (CurrentDataItem, xpathexpression);
432 protected object XPath (string xpathexpression, string format)
434 return XPathBinder.Eval (CurrentDataItem, xpathexpression, format);
437 protected IEnumerable XPathSelect (string xpathexpression)
439 return XPathBinder.Select (CurrentDataItem, xpathexpression);