// 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
//
using System;
using System.Collections;
+using System.Globalization;
using System.IO;
using System.Reflection;
using System.Web.UI;
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;
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 ();
return false;
if (pi [0].ParameterType != typeof (object) ||
- pi [1].ParameterType != typeof (EventArgs))
+ !typeof (EventArgs).IsAssignableFrom (pi [1].ParameterType))
return false;
return true;
} else {
evt.AddEventHandler (target, Delegate.CreateDelegate (
evt.EventHandlerType, app,
-#if NET_2_0
- method
-#else
- method.Name
-#endif
- ));
+ method));
}
}
}
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);
}
return theFactory.app_state;
}
-#endif
}
internal static Type AppType {
if (!needs_init)
return;
-#if NET_2_0
try {
-#endif
string physical_app_path = HttpRuntime.AppDomainAppPath;
string app_file = null;
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 ();
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];
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);
// 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 ();
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
//
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){
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");
WatchLocationForRestart ("App_Code", "*", true);
WatchLocationForRestart ("App_Browsers", "*");
WatchLocationForRestart ("App_GlobalResources", "*");
-#endif
app = factory.FireOnAppStart (context);
factory.app_start_needed = false;
return app;
}
}
-#if NET_2_0
internal static bool ApplicationDisabled {
get { return app_disabled; }
set { app_disabled = value; }
return capabilities_processor;
}
}
-#endif
internal static void DisableWatchers ()
{
}
}
+ 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) {
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) {