X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fclass%2FSystem.Web%2FSystem.Web%2FHttpApplicationFactory.cs;h=597379a9bad1bf9fd94c6a0ead55e9c87673080f;hb=3bc22b19614835c73c42101eaf58de6f666ef81a;hp=8ad77289b6cef9c90e4cf9addb6cc899fb21df35;hpb=6b2b2a1f2ceb55082031e2d1a69f481c3202a5a3;p=mono.git diff --git a/mcs/class/System.Web/System.Web/HttpApplicationFactory.cs b/mcs/class/System.Web/System.Web/HttpApplicationFactory.cs index 8ad77289b6c..597379a9bad 100644 --- a/mcs/class/System.Web/System.Web/HttpApplicationFactory.cs +++ b/mcs/class/System.Web/System.Web/HttpApplicationFactory.cs @@ -5,7 +5,7 @@ // Gonzalo Paniagua Javier (gonzalo@ximian.com) // // (c) 2002,2003 Ximian, Inc. (http://www.ximian.com) -// (c) Copyright 2004 Novell, Inc. (http://www.novell.com) +// (c) Copyright 2004-2009 Novell, Inc. (http://www.novell.com) // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the @@ -28,6 +28,7 @@ // using System; using System.Collections; +using System.Globalization; using System.IO; using System.Reflection; using System.Web.UI; @@ -37,40 +38,16 @@ using System.Threading; using System.Web.Util; using System.Web.Compilation; -#if TARGET_J2EE -using vmw.common; -#endif - -#if NET_2_0 && !TARGET_J2EE using System.CodeDom.Compiler; -#endif -namespace System.Web { - class HttpApplicationFactory { +namespace System.Web +{ + sealed class HttpApplicationFactory + { object this_lock = new object (); // Initialized in InitType -#if TARGET_J2EE - static HttpApplicationFactory theFactory { - get - { - HttpApplicationFactory factory = (HttpApplicationFactory)AppDomain.CurrentDomain.GetData("HttpApplicationFactory"); - if (factory == null) { - lock(typeof(HttpApplicationFactory)) { - factory = (HttpApplicationFactory)AppDomain.CurrentDomain.GetData("HttpApplicationFactory"); - if (factory == null) { - factory = new HttpApplicationFactory(); - System.Threading.Thread.Sleep(1); - AppDomain.CurrentDomain.SetData("HttpApplicationFactory", factory); - } - } - } - return factory; - } - } -#else static HttpApplicationFactory theFactory = new HttpApplicationFactory(); -#endif object session_end; // This is a MethodInfo bool needs_init = true; bool app_start_needed = true; @@ -81,12 +58,10 @@ namespace System.Web { static ArrayList watchers = new ArrayList(); static object watchers_lock = new object(); static bool app_shutdown = false; -#if NET_2_0 static bool app_disabled = false; static string[] app_browsers_files = new string[0]; static string[] default_machine_browsers_files = new string[0]; static string[] app_mono_machine_browsers_files = new string[0]; -#endif Stack available = new Stack (); object next_free; Stack available_for_end = new Stack (); @@ -109,7 +84,7 @@ namespace System.Web { return false; if (pi [0].ParameterType != typeof (object) || - pi [1].ParameterType != typeof (EventArgs)) + !typeof (EventArgs).IsAssignableFrom (pi [1].ParameterType)) return false; return true; @@ -316,12 +291,7 @@ namespace System.Web { } else { evt.AddEventHandler (target, Delegate.CreateDelegate ( evt.EventHandlerType, app, -#if NET_2_0 - method -#else - method.Name -#endif - )); + method)); } } @@ -368,14 +338,6 @@ namespace System.Web { } internal static HttpApplicationState ApplicationState { -#if TARGET_J2EE - get { - HttpApplicationFactory factory = theFactory; - if (factory.app_state == null) - factory.app_state = new HttpApplicationState (null, null); - return factory.app_state; - } -#else get { if (theFactory.app_state == null) { HttpStaticObjectsCollection app = MakeStaticCollection (GlobalAsaxCompiler.ApplicationObjects); @@ -385,7 +347,6 @@ namespace System.Web { } return theFactory.app_state; } -#endif } internal static Type AppType { @@ -400,9 +361,7 @@ namespace System.Web { if (!needs_init) return; -#if NET_2_0 try { -#endif string physical_app_path = HttpRuntime.AppDomainAppPath; string app_file = null; @@ -412,12 +371,8 @@ namespace System.Web { if (!File.Exists (app_file)) app_file = null; } - -#if !NET_2_0 - WebConfigurationSettings.Init (context); -#endif - -#if NET_2_0 && !TARGET_J2EE + BuildManager.CallPreStartMethods (); + BuildManager.CompilingTopLevelAssemblies = true; AppResourcesCompiler ac = new AppResourcesCompiler (context); ac.Compile (); @@ -425,12 +380,13 @@ namespace System.Web { AppWebReferencesCompiler awrc = new AppWebReferencesCompiler (); awrc.Compile (); #endif - // Todo: Generate profile properties assembly from Web.config here AppCodeCompiler acc = new AppCodeCompiler (); acc.Compile (); + BuildManager.AllowReferencedAssembliesCaching = true; + // Get the default machine *.browser files. string default_machine_browsers_path = Path.Combine (HttpRuntime.MachineConfigurationDirectory, "Browsers"); default_machine_browsers_files = new string[0]; @@ -455,22 +411,10 @@ namespace System.Web { if (Directory.Exists (app_browsers_path)) { app_browsers_files = Directory.GetFiles (app_browsers_path, "*.browser"); } -#endif - -#if NET_2_0 + BuildManager.CompilingTopLevelAssemblies = false; app_type = BuildManager.GetPrecompiledApplicationType (); -#endif if (app_type == null && app_file != null) { -#if TARGET_J2EE - app_file = System.Web.Util.UrlUtils.ResolveVirtualPathFromAppAbsolute("~/" + Path.GetFileName(app_file)); - app_type = System.Web.J2EE.PageMapper.GetObjectType(context, app_file); -#else -#if NET_2_0 app_type = BuildManager.GetCompiledType ("~/" + Path.GetFileName (app_file)); -#else - app_type = ApplicationFileParser.GetCompiledApplicationType (app_file, context); -#endif -#endif if (app_type == null) { string msg = String.Format ("Error compiling application file ({0}).", app_file); throw new ApplicationException (msg); @@ -492,11 +436,15 @@ namespace System.Web { // recursively for all subdirectories and adds them to the // watch set. This can take a lot of time for deep directory // trees (see bug #490497) - ThreadPool.QueueUserWorkItem (new WaitCallback (SetUpWebConfigWatchers), null); + ThreadPool.QueueUserWorkItem (delegate { + try { + WatchLocationForRestart (String.Empty, "?eb.?onfig", true); + } catch (Exception e) { + Console.Error.WriteLine (e); + } }, null); #endif needs_init = false; -#if NET_2_0 } catch (Exception) { if (BuildManager.CodeAssemblies != null) BuildManager.CodeAssemblies.Clear (); @@ -506,19 +454,8 @@ namespace System.Web { WebConfigurationManager.ExtraAssemblies.Clear (); throw; } -#endif - - // - // Now init the settings - // - } } - - static void SetUpWebConfigWatchers (object state) - { - WatchLocationForRestart (String.Empty, "?eb.?onfig", true); - } // // Multiple-threads might hit this one on startup, and we have @@ -526,10 +463,6 @@ namespace System.Web { // internal static HttpApplication GetApplication (HttpContext context) { -#if TARGET_J2EE - if (context.ApplicationInstance!=null) - return context.ApplicationInstance; -#endif HttpApplicationFactory factory = theFactory; HttpApplication app = null; if (factory.app_start_needed){ @@ -541,8 +474,7 @@ namespace System.Web { if (factory.app_start_needed) { foreach (string dir in HttpApplication.BinDirs) WatchLocationForRestart (dir, "*.dll"); -#if NET_2_0 - // Restart if the App_* directories are created... + // Restart if the App_* directories are created... WatchLocationForRestart (".", "App_Code"); WatchLocationForRestart (".", "App_Browsers"); WatchLocationForRestart (".", "App_GlobalResources"); @@ -550,7 +482,6 @@ namespace System.Web { WatchLocationForRestart ("App_Code", "*", true); WatchLocationForRestart ("App_Browsers", "*"); WatchLocationForRestart ("App_GlobalResources", "*"); -#endif app = factory.FireOnAppStart (context); factory.app_start_needed = false; return app; @@ -659,7 +590,6 @@ namespace System.Web { } } -#if NET_2_0 internal static bool ApplicationDisabled { get { return app_disabled; } set { app_disabled = value; } @@ -691,7 +621,6 @@ namespace System.Web { return capabilities_processor; } } -#endif internal static void DisableWatchers () { @@ -701,6 +630,28 @@ namespace System.Web { } } + internal static void DisableWatcher (string virtualPath, string filter) + { + EnableWatcherEvents (virtualPath, filter, false); + } + + internal static void EnableWatcher (string virtualPath, string filter) + { + EnableWatcherEvents (virtualPath, filter, true); + } + + static void EnableWatcherEvents (string virtualPath, string filter, bool enable) + { + lock (watchers_lock) { + foreach (FileSystemWatcher watcher in watchers) { + if (String.Compare (watcher.Path, virtualPath, StringComparison.Ordinal) != 0 || String.Compare (watcher.Filter, filter, StringComparison.Ordinal) != 0) + continue; + + watcher.EnableRaisingEvents = enable; + } + } + } + internal static void EnableWatchers () { lock (watchers_lock) { @@ -716,20 +667,36 @@ namespace System.Web { static void OnFileChanged(object sender, FileSystemEventArgs args) { + if (HttpRuntime.DomainUnloading) + return; string name = args.Name; + bool isConfig = false; - if (StrUtils.EndsWith (name, "onfig", true) && String.Compare (name, "web.config", true) != 0) - return; - if (StrUtils.EndsWith (name, "lobal.asax", true) && String.Compare (name, "global.asax", true) != 0) + if (StrUtils.EndsWith (name, "onfig", true)) { + if (String.Compare (Path.GetFileName (name), "web.config", true, Helpers.InvariantCulture) != 0) + return; + isConfig = true; + } else if (StrUtils.EndsWith (name, "lobal.asax", true) && String.Compare (name, "global.asax", true, Helpers.InvariantCulture) != 0) return; + Console.WriteLine ("Change: " + name); + // {Inotify,FAM}Watcher will notify about events for a directory regardless // of the filter pattern. This might be a bug in the watchers code, but // since I couldn't find any rationale for the code in there I'd opted for // not removing it and instead working around the issue here. Fix for bug // #495011 FileSystemWatcher watcher = sender as FileSystemWatcher; - if (watcher != null && String.Compare (watcher.Filter, "?eb.?onfig", true) == 0) + if (watcher != null && String.Compare (watcher.Filter, "?eb.?onfig", true, Helpers.InvariantCulture) == 0 && Directory.Exists (name)) + return; + + // We re-enable suppression here since WebConfigurationManager will disable + // it after save is done. WebConfigurationManager is called twice by + // Configuration - just after opening the target file and just after closing + // it. For that reason we will receive two change notifications and if we + // disabled suppression here, it would reload the application on the second + // change notification. + if (isConfig && WebConfigurationManager.SuppressAppReload (true)) return; lock (watchers_lock) {