2008-09-04 Jb Evain <jbevain@novell.com>
[mono.git] / mcs / class / System.Web / System.Web.UI / PageParser.cs
index e43f3bbab86483eea14c50799619eeed90416dd2..e2ea3a0ae141c50921d8b1a7f405d078265ab6d6 100644 (file)
@@ -1,4 +1,4 @@
-//
+//     
 // System.Web.UI.PageParser
 //
 // Authors:
@@ -43,12 +43,13 @@ namespace System.Web.UI
        [AspNetHostingPermission (SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
        public sealed class PageParser : TemplateControlParser
        {
-               bool enableSessionState = true;
+               PagesEnableSessionState enableSessionState = PagesEnableSessionState.True;
+               bool enableViewStateMac = true;
+               bool smartNavigation;
                bool haveTrace;
                bool trace;
                bool notBuffer;
-               TraceMode tracemode;
-               bool readonlySessionState;
+               TraceMode tracemode = TraceMode.Default;
                string responseEncoding;
                string contentType;
                int codepage = -1;
@@ -58,19 +59,25 @@ namespace System.Web.UI
                string errorPage;
                bool validateRequest;
                string clientTarget;
-               Type baseType = typeof (Page);
 
 #if NET_2_0
+               bool async;
+               int asyncTimeout = -1;
                string masterPage;
                Type masterType;
                string title;
                string theme;
                string styleSheetTheme;
                bool enable_event_validation;
+               bool maintainScrollPositionOnPostBack;
+               int maxPageStateFieldLength = -1;
+               string pageParserFilter = String.Empty;
+               Type previousPageType;
 #endif
 
                public PageParser ()
                {
+                       LoadConfigDefaults ();
                }
                
                internal PageParser (string virtualPath, string inputFile, HttpContext context)
@@ -78,55 +85,107 @@ namespace System.Web.UI
                        Context = context;
                        BaseVirtualDir = UrlUtils.GetDirectory (virtualPath);
                        InputFile = inputFile;
-                       SetBaseType (PagesConfig.PageBaseType);
+                       SetBaseType (null);
                        AddApplicationAssembly ();
+                       LoadConfigDefaults ();
+#if NET_2_0
+                       this.VirtualPath = new VirtualPath (virtualPath);
+#endif
                }
 
 #if NET_2_0
                internal PageParser (string virtualPath, TextReader reader, HttpContext context)
+                       : this (virtualPath, null, reader, context)
+               {
+               }
+               
+               internal PageParser (string virtualPath, string inputFile, TextReader reader, HttpContext context)
                {
                        Context = context;
                        BaseVirtualDir = UrlUtils.GetDirectory (virtualPath);
                        Reader = reader;
-                       SetBaseType (PagesConfig.PageBaseType);
+                       if (String.IsNullOrEmpty (inputFile)) {
+                               HttpRequest req = context != null ? context.Request : null;
+                               if (req != null)
+                                       InputFile = req.MapPath (virtualPath);
+                       } else
+                               InputFile = inputFile;
+                       SetBaseType (null);
                        AddApplicationAssembly ();
+                       LoadConfigDefaults ();
+#if NET_2_0
+                       this.VirtualPath = new VirtualPath (virtualPath);
+#endif
                }
 #endif
 
+               internal override void LoadConfigDefaults ()
+               {
+                       base.LoadConfigDefaults ();
+#if NET_2_0
+                       PagesSection ps = PagesConfig;
+#else
+                       PagesConfiguration ps = PagesConfig;
+#endif                 
+
+                       notBuffer = !ps.Buffer;
+                       enableSessionState = ps.EnableSessionState;
+                       enableViewStateMac = ps.EnableViewStateMac;
+                       smartNavigation = ps.SmartNavigation;
+                       validateRequest = ps.ValidateRequest;
+#if NET_2_0
+                       masterPage = ps.MasterPageFile;
+                       if (masterPage.Length == 0)
+                               masterPage = null;
+                       
+                       enable_event_validation = ps.EnableEventValidation;
+                       maxPageStateFieldLength = ps.MaxPageStateFieldLength;
+                       pageParserFilter = ps.PageParserFilterType;
+                       theme = ps.Theme;
+                       if (theme.Length == 0)
+                               theme = null;
+                       styleSheetTheme = ps.StyleSheetTheme;
+                       if (styleSheetTheme.Length == 0)
+                               styleSheetTheme = null;
+                       maintainScrollPositionOnPostBack = ps.MaintainScrollPositionOnPostBack;
+#endif
+               }
+               
                public static IHttpHandler GetCompiledPageInstance (string virtualPath,
                                                                    string inputFile, 
                                                                    HttpContext context)
                {
+#if NET_2_0
+                       return BuildManager.CreateInstanceFromVirtualPath (virtualPath, typeof (IHttpHandler)) as IHttpHandler;
+#else
                        PageParser pp = new PageParser (virtualPath, inputFile, context);
                        IHttpHandler h = (IHttpHandler) pp.GetCompiledInstance ();
                        return h;
+#endif
                }
-
+               
                internal override void ProcessMainAttributes (Hashtable atts)
                {
-                       string enabless = GetString (atts, "EnableSessionState",
-#if NET_2_0
-                                                    PagesConfig.EnableSessionState.ToString()
-#else
-                                                    PagesConfig.EnableSessionState
-#endif
-                                                    );
+                       // note: the 'enableSessionState' configuration property is
+                       // processed in a case-sensitive manner while the page-level
+                       // attribute is processed case-insensitive
+                       string enabless = GetString (atts, "EnableSessionState", null);
                        if (enabless != null) {
-                               readonlySessionState = (String.Compare (enabless, "readonly", true) == 0);
-                               if (readonlySessionState == true || String.Compare (enabless, "true", true) == 0) {
-                                       enableSessionState = true;
-                               } else if (String.Compare (enabless, "false", true) == 0) {
-                                       enableSessionState = false;
-                               } else {
-                                       ThrowParseException ("Invalid value for EnableSessionState: " + enabless);
-                               }
+                               if (String.Compare (enabless, "readonly", true) == 0)
+                                       enableSessionState = PagesEnableSessionState.ReadOnly;
+                               else if (String.Compare (enabless, "true", true) == 0)
+                                       enableSessionState = PagesEnableSessionState.True;
+                               else if (String.Compare (enabless, "false", true) == 0)
+                                       enableSessionState = PagesEnableSessionState.False;
+                               else
+                                       ThrowParseException ("Invalid value for enableSessionState: " + enabless);
                        }
 
                        string cp = GetString (atts, "CodePage", null);
                        if (cp != null) {
                                if (responseEncoding != null)
                                        ThrowParseException ("CodePage and ResponseEncoding are " +
-                                                            "mutually exclusive.");
+                                               "mutually exclusive.");
 
                                int codepage = 0;
                                try {
@@ -191,12 +250,15 @@ namespace System.Web.UI
                                
                                CultureInfo ci = null;
                                try {
-                                       ci = new CultureInfo (culture);                                 
+#if NET_2_0
+                                       if (!culture.StartsWith ("auto"))
+#endif
+                                               ci = new CultureInfo (culture);
                                } catch {
                                        ThrowParseException ("Unsupported Culture: " + culture);
                                }
 
-                               if (ci.IsNeutralCulture) {
+                               if (ci != null && ci.IsNeutralCulture) {
                                        string suggestedCulture = SuggestCulture (culture);
                                        string fmt = "Culture attribute must be set to a non-neutral Culture.";
                                        if (suggestedCulture != null)
@@ -211,12 +273,15 @@ namespace System.Web.UI
                        if (uiculture != null) {
                                CultureInfo ci = null;
                                try {
-                                       ci = new CultureInfo (uiculture);                                       
+#if NET_2_0
+                                       if (!uiculture.StartsWith ("auto"))
+#endif
+                                               ci = new CultureInfo (uiculture);
                                } catch {
                                        ThrowParseException ("Unsupported Culture: " + uiculture);
                                }
 
-                               if (ci.IsNeutralCulture) {
+                               if (ci != null && ci.IsNeutralCulture) {
                                        string suggestedCulture = SuggestCulture (uiculture);
                                        string fmt = "UICulture attribute must be set to a non-neutral Culture.";
                                        if (suggestedCulture != null)
@@ -249,45 +314,72 @@ namespace System.Web.UI
                        }
 
                        errorPage = GetString (atts, "ErrorPage", null);
-                       validateRequest = GetBool (atts, "ValidateRequest", PagesConfig.ValidateRequest);
+                       validateRequest = GetBool (atts, "ValidateRequest", validateRequest);
                        clientTarget = GetString (atts, "ClientTarget", null);
                        if (clientTarget != null) {
+                               clientTarget = clientTarget.Trim ();
 #if NET_2_0
                                ClientTargetSection sec = (ClientTargetSection)WebConfigurationManager.GetSection ("system.web/clientTarget");
-                               if (sec.ClientTargets[clientTarget] == null) {
+                               ClientTarget ct = null;
+                               
+                               if ((ct = sec.ClientTargets [clientTarget]) == null)
+                                       clientTarget = clientTarget.ToLower (CultureInfo.InvariantCulture);
+                               
+                               if (ct == null && (ct = sec.ClientTargets [clientTarget]) == null) {
                                        ThrowParseException (String.Format (
                                                        "ClientTarget '{0}' is an invalid alias. See the " +
                                                        "documentation for <clientTarget> config. section.",
                                                        clientTarget));
                                }
-                               clientTarget = sec.ClientTargets[clientTarget].UserAgent;
+                               clientTarget = ct.UserAgent;
 #else
                                NameValueCollection coll;
                                coll = (NameValueCollection) Context.GetConfig ("system.web/clientTarget");
-                               if (coll == null || coll [clientTarget] == null) {
+                               object ct = null;
+                               
+                               if (coll != null) {
+                                       ct = coll [clientTarget];
+                                       if (ct == null)
+                                               ct = coll [clientTarget.ToLower ()];
+                               }
+                               
+                               if (ct == null) {
                                        ThrowParseException (String.Format (
                                                        "ClientTarget '{0}' is an invalid alias. See the " +
                                                        "documentation for <clientTarget> config. section.",
                                                        clientTarget));
                                }
-                               clientTarget = (string) coll [clientTarget];
+                               clientTarget = (string) ct;
 #endif
                        }
 
                        notBuffer = !GetBool (atts, "Buffer", true);
                        
 #if NET_2_0
-                       masterPage = GetString (atts, "MasterPageFile", null);
+                       async = GetBool (atts, "Async", false);
+                       string asyncTimeoutVal = GetString (atts, "AsyncTimeout", null);
+                       if (asyncTimeoutVal != null) {
+                               try {
+                                       asyncTimeout = Int32.Parse (asyncTimeoutVal);
+                               } catch (Exception) {
+                                       ThrowParseException ("AsyncTimeout must be an integer value");
+                               }
+                       }
+                       
+                       masterPage = GetString (atts, "MasterPageFile", masterPage);
                        
                        // Make sure the page exists
-                       if (masterPage != null)
-                               MasterPageParser.GetCompiledMasterType (masterPage, MapPath (masterPage), HttpContext.Current);
-
+                       if (!String.IsNullOrEmpty (masterPage)) {
+                               BuildManager.GetCompiledType (masterPage);
+                               AddDependency (masterPage);
+                       }
+                       
                        title = GetString(atts, "Title", null);
 
-                       theme = GetString (atts, "Theme", null);
-                       styleSheetTheme = GetString (atts, "StyleSheetTheme", null);
-                       enable_event_validation = GetBool (atts, "EnableEventValidation", true);
+                       theme = GetString (atts, "Theme", theme);
+                       styleSheetTheme = GetString (atts, "StyleSheetTheme", styleSheetTheme);
+                       enable_event_validation = GetBool (atts, "EnableEventValidation", enable_event_validation);
+                       maintainScrollPositionOnPostBack = GetBool (atts, "MaintainScrollPositionOnPostBack", maintainScrollPositionOnPostBack);
 #endif
                        // Ignored by now
                        GetString (atts, "EnableViewStateMac", null);
@@ -298,23 +390,39 @@ namespace System.Web.UI
                
 #if NET_2_0
                internal override void AddDirective (string directive, Hashtable atts)
-               {
-                       if (String.Compare ("MasterType", directive, true) == 0) {
-                               string type = GetString (atts, "TypeName", null);
-                               if (type != null) {
-                                       masterType = LoadType (type);
-                                       if (masterType == null)
-                                               ThrowParseException ("Could not load type '" + type + "'.");
-                               } else {
-                                       string path = GetString (atts, "VirtualPath", null);
-                                       if (path != null)
-                                               masterType = MasterPageParser.GetCompiledMasterType (path, MapPath (path), HttpContext.Current);
+               {                       
+                       bool isMasterType = String.Compare ("MasterType", directive, StringComparison.OrdinalIgnoreCase) == 0;
+                       bool isPreviousPageType = isMasterType ? false : String.Compare ("PreviousPageType", directive,
+                                                                                        StringComparison.OrdinalIgnoreCase) == 0;
+                       
+                       string typeName = null;
+                       string virtualPath = null;
+                       Type type = null;
+                       
+                       if (isMasterType || isPreviousPageType) {
+                               typeName = GetString (atts, "TypeName", null);
+                               virtualPath = GetString (atts, "VirtualPath", null);
+
+                               if (typeName != null && virtualPath != null)
+                                       ThrowParseException (
+                                               String.Format ("The '{0}' directive must have exactly one attribute: TypeName or VirtualPath", directive));
+                               if (typeName != null) {
+                                       type = LoadType (typeName);
+                                       if (type == null)
+                                               ThrowParseException (String.Format ("Could not load type '{0}'.", typeName));
+                               } else if (virtualPath != null) {
+                                       string mappedPath = MapPath (virtualPath);
+                                       if (isMasterType)
+                                               type = masterType = BuildManager.GetCompiledType (virtualPath);
                                        else
-                                               ThrowParseException ("The MasterType directive must have either a TypeName or a VirtualPath attribute.");
-                               }
-                               AddAssembly (masterType.Assembly, true);
-                       }
-                       else
+                                               type = previousPageType = GetCompiledPageType (virtualPath, mappedPath,
+                                                                                              HttpContext.Current);
+                               } else
+                                       ThrowParseException (
+                                               String.Format ("The {0} directive must have either a TypeName or a VirtualPath attribute.", directive));
+
+                               AddAssembly (type.Assembly, true);
+                       } else
                                base.AddDirective (directive, atts);
                }
 #endif
@@ -329,6 +437,16 @@ namespace System.Web.UI
                        return retval;
                }
 
+               public static Type GetCompiledPageType (string virtualPath, string inputFile, HttpContext context)
+               {
+#if NET_2_0
+                       return BuildManager.GetCompiledType (virtualPath);
+#else
+                       PageParser pp = new PageParser (virtualPath, inputFile, context);
+                       return pp.CompileIntoType ();
+#endif
+               }
+               
                protected override Type CompileIntoType ()
                {
                        AspGenerator generator = new AspGenerator (this);
@@ -336,11 +454,24 @@ namespace System.Web.UI
                }
 
                internal bool EnableSessionState {
-                       get { return enableSessionState; }
+                       get {
+                               return enableSessionState == PagesEnableSessionState.True ||
+                                       ReadOnlySessionState;
+                       }
+               }
+
+               internal bool EnableViewStateMac {
+                       get { return enableViewStateMac; }
+               }
+               
+               internal bool SmartNavigation {
+                       get { return smartNavigation; }
                }
                
                internal bool ReadOnlySessionState {
-                       get { return readonlySessionState; }
+                       get {
+                               return enableSessionState == PagesEnableSessionState.ReadOnly;
+                       }
                }
 
                internal bool HaveTrace {
@@ -353,16 +484,18 @@ namespace System.Web.UI
 
                internal TraceMode TraceMode {
                        get { return tracemode; }
-               }
-               
-               internal override Type DefaultBaseType {
-                       get { return baseType; }
-               }
+               }               
 
+#if NET_2_0
+               internal override string DefaultBaseTypeName {
+                       get { return PagesConfig.PageBaseType; }
+               }
+#else
                internal override string DefaultBaseTypeName {
                        get { return "System.Web.UI.Page"; }
                }
-
+#endif
+               
                internal override string DefaultDirectiveName {
                        get { return "page"; }
                }
@@ -408,6 +541,14 @@ namespace System.Web.UI
                }
 
 #if NET_2_0
+               internal bool Async {
+                       get { return async; }
+               }
+
+               internal int AsyncTimeout {
+                       get { return asyncTimeout; }
+               }
+               
                internal string Theme {
                        get { return theme; }
                }
@@ -431,6 +572,22 @@ namespace System.Web.UI
                internal bool EnableEventValidation {
                        get { return enable_event_validation; }
                }
+
+               internal bool MaintainScrollPositionOnPostBack {
+                       get { return maintainScrollPositionOnPostBack; }
+               }
+
+               internal int MaxPageStateFieldLength {
+                       get { return maxPageStateFieldLength; }
+               }
+
+               internal string PageParserFilterType {
+                       get { return pageParserFilter; }
+               }
+
+               internal Type PreviousPageType {
+                       get { return previousPageType; }
+               }
 #endif
        }
 }