WebApplicationContext.cs :  » Inversion-of-Control-Dependency-Injection » Spring.net » Spring » Context » Support » C# / CSharp Open Source

Home
C# / CSharp Open Source
1.2.6.4 mono .net core
2.2.6.4 mono core
3.Aspect Oriented Frameworks
4.Bloggers
5.Build Systems
6.Business Application
7.Charting Reporting Tools
8.Chat Servers
9.Code Coverage Tools
10.Content Management Systems CMS
11.CRM ERP
12.Database
13.Development
14.Email
15.Forum
16.Game
17.GIS
18.GUI
19.IDEs
20.Installers Generators
21.Inversion of Control Dependency Injection
22.Issue Tracking
23.Logging Tools
24.Message
25.Mobile
26.Network Clients
27.Network Servers
28.Office
29.PDF
30.Persistence Frameworks
31.Portals
32.Profilers
33.Project Management
34.RSS RDF
35.Rule Engines
36.Script
37.Search Engines
38.Sound Audio
39.Source Control
40.SQL Clients
41.Template Engines
42.Testing
43.UML
44.Web Frameworks
45.Web Service
46.Web Testing
47.Wiki Engines
48.Windows Presentation Foundation
49.Workflows
50.XML Parsers
C# / C Sharp
C# / C Sharp by API
C# / CSharp Tutorial
C# / CSharp Open Source » Inversion of Control Dependency Injection » Spring.net 
Spring.net » Spring » Context » Support » WebApplicationContext.cs
#region License

/*
 * Copyright 2002-2004 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#endregion

using System;
using System.Collections;
using System.Collections.Specialized;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Web;
using System.Web.Hosting;
using System.Xml;
using Common.Logging;
using Spring.Collections;
using Spring.Objects;
using Spring.Objects.Factory.Config;
using Spring.Objects.Factory.Support;
using Spring.Objects.Factory.Xml;
using Spring.Objects.Support;
using Spring.Reflection.Dynamic;
using Spring.Util;

namespace Spring.Context.Support{
    /// <summary>
    /// Web application context, taking the context definition files
    /// from the file system or from URLs.
    ///
    /// Treats resource paths as web resources, when using
    /// IApplicationContext.GetResource. Resource paths are considered relative
    /// to the virtual directory.
    ///
    /// Note: In case of multiple config locations, later object definitions will
    /// override ones defined in earlier loaded files. This can be leveraged to
    /// deliberately override certain object definitions via an extra XML file.
    /// </summary>
    /// <author>Aleksandar Seovic</author>
    public class WebApplicationContext : AbstractXmlApplicationContext
    {
        // holds construction info for debugging output
        private DateTime _constructionTimeStamp;
        private string _constructionUrl;

        private readonly string[] _configurationLocations;

        /// <summary>
        /// Create a new WebApplicationContext, loading the definitions
        /// from the given XML resource.
        /// </summary>
        /// <param name="configurationLocations">Names of configuration resources.</param>
        public WebApplicationContext(params string[] configurationLocations)
            : this(null, false, null, configurationLocations)
        {
        }

        /// <summary>
        /// Create a new WebApplicationContext, loading the definitions
        /// from the given XML resource.
        /// </summary>
        /// <param name="name">The application context name.</param>
        /// <param name="caseSensitive">Flag specifying whether to make this context case sensitive or not.</param>
        /// <param name="configurationLocations">Names of configuration resources.</param>
        public WebApplicationContext(string name, bool caseSensitive, params string[] configurationLocations)
            : this(name, caseSensitive, null, configurationLocations)
        {
        }

        /// <summary>
        /// Create a new WebApplicationContext with the given parent,
        /// loading the definitions from the given XML resources.
        /// </summary>
        /// <param name="name">The application context name.</param>
        /// <param name="caseSensitive">Flag specifying whether to make this context case sensitive or not.</param>
        /// <param name="parentContext">The parent context.</param>
        /// <param name="configurationLocations">Names of configuration resources.</param>
        public WebApplicationContext(string name, bool caseSensitive, IApplicationContext parentContext,
                                     params string[] configurationLocations) : base(name, caseSensitive, parentContext)
        {
            _configurationLocations = configurationLocations;
            DefaultResourceProtocol = WebUtils.DEFAULT_RESOURCE_PROTOCOL;
            Refresh();

            // remember creation info for debug output
            this._constructionTimeStamp = DateTime.Now;
            this._constructionUrl = VirtualEnvironment.CurrentVirtualPathAndQuery;
            if (log.IsDebugEnabled)
            {
                log.Debug("created instance " + this.ToString());
            }
        }

        /// <summary>
        /// returns detailed instance information for debugging
        /// </summary>
        /// <returns></returns>
        public override string ToString()
        {
            //return base.ToString() + " - created on " + _constructionTimeStamp + "\n\ncreated by:" + _constructionUrl + "\n" + _constructionStackTrace.ToString();
            return string.Format("[{0}]:{1}({2})", this.Name, this.GetType().Name, base.GetHashCode().ToString());
        }


        /// <summary>
        /// Since the HttpRuntime discards it's configurationsection cache, we maintain our own context cache.
        /// Despite it really speeds up context-lookup, since we don't have to go through the whole HttpConfigurationSystem
        /// </summary>
        private static readonly Hashtable s_webContextCache = new CaseInsensitiveHashtable();

        static WebApplicationContext()
        {
            ILog s_weblog = LogManager.GetLogger(typeof(WebApplicationContext));

            // register for ContextRegistry.Cleared event - we need to discard our cache in this case
            ContextRegistry.Cleared += new EventHandler(OnContextRegistryCleared);

#if NET_2_0 && !MONO_2_0
            if (HttpRuntime.AppDomainAppVirtualPath != null) // check if we're within an ASP.NET AppDomain!
            {
                // ensure HttpRuntime has been fully initialized!
                // this is a problem,.if ASP.NET Web Administration Application is used. This app does not fully set up the AppDomain...
                HttpRuntime runtime =
                    (HttpRuntime)
                    typeof(HttpRuntime).GetField("_theRuntime", BindingFlags.Static | BindingFlags.NonPublic).GetValue(null);

                bool beforeFirstRequest = false;
                lock (runtime)
                {
                    beforeFirstRequest =
                        (bool)
                        typeof(HttpRuntime).GetField("_beforeFirstRequest", BindingFlags.Instance | BindingFlags.NonPublic).
                            GetValue(runtime);
                }
                s_weblog.Debug("BeforeFirstRequest:" + beforeFirstRequest);
                if (beforeFirstRequest)
                {
                    try
                    {
                        string firstRequestPath = HttpRuntime.AppDomainAppVirtualPath.TrimEnd('/') + "/dummy.context";
                        s_weblog.Info("Forcing first request " + firstRequestPath);
                        SafeMethod fnProcessRequestNow = new SafeMethod(typeof(HttpRuntime).GetMethod("ProcessRequestNow", BindingFlags.Static|BindingFlags.NonPublic));
                        SimpleWorkerRequest wr = new SimpleWorkerRequest(firstRequestPath, string.Empty, new StringWriter());
                        fnProcessRequestNow.Invoke(null, new object[] { wr });
//                        HttpRuntime.ProcessRequest(
//                            wr);
                        s_weblog.Info("Successfully processed first request!");
                    }
                    catch (Exception ex)
                    {
                        s_weblog.Error("Failed processing first request", ex);
                        throw;
                    }
                }
            }
#endif
        }

        /// <summary>
        /// EventHandler for ContextRegistry.Cleared event. Discards webContextCache.
        /// </summary>
        private static void OnContextRegistryCleared(object sender, EventArgs ev)
        {
            lock (s_webContextCache)
            {
                ILog s_weblog = LogManager.GetLogger(typeof(WebApplicationContext));
                if (s_weblog.IsDebugEnabled)
                {
                    s_weblog.Debug("received ContextRegistry.Cleared event - clearing webContextCache");
                }
                s_webContextCache.Clear();
            }
        }

        /// <summary>
        /// Returns the root context of this web application
        /// </summary>
        public static IApplicationContext GetRootContext()
        {
            return GetContextInternal( ("" + HttpRuntime.AppDomainAppVirtualPath).TrimEnd('/') + "/dummy.context");
        }

        /// <summary>
        /// Returns the web application context for the given (absolute!) virtual path
        /// </summary>
        public static IApplicationContext GetContext(string virtualPath)
        {
            return GetContextInternal(virtualPath);
        }

        /// <summary>
        /// Returns the web application context for the current request's filepath
        /// </summary>
        public static IApplicationContext Current
        {
            get
            {
                string requestUrl = VirtualEnvironment.CurrentVirtualFilePath;
                return GetContextInternal(requestUrl);
            }
        }

        private static IApplicationContext GetContextInternal(string virtualPath)
        {
            string virtualDirectory = WebUtils.GetVirtualDirectory(virtualPath);
            string contextName = virtualDirectory;
            if ( 0 == string.Compare( contextName , ("" + HttpRuntime.AppDomainAppVirtualPath).TrimEnd('/') + "/", true) )
            {
                contextName = DefaultRootContextName;
            }

            ILog s_weblog = LogManager.GetLogger(typeof(WebApplicationContext));
            bool isLogDebugEnabled = s_weblog.IsDebugEnabled;

            lock (s_webContextCache)
            {
                if (isLogDebugEnabled)
                {
                    s_weblog.Debug(string.Format("looking up web context '{0}' in WebContextCache", contextName));
                }
                // first lookup in our own cache
                IApplicationContext context = (IApplicationContext) s_webContextCache[contextName];
                if (context != null)
                {
                    // found - nothing to do anymore
                    if (isLogDebugEnabled)
                    {
                        s_weblog.Debug(
                            string.Format("returning WebContextCache hit '{0}' for vpath '{1}' ", context, contextName));
                    }
                    return context;
                }

                // lookup ContextRegistry
                lock (ContextRegistry.SyncRoot)
                {
                    if (isLogDebugEnabled)
                    {
                        s_weblog.Debug(string.Format("looking up web context '{0}' in ContextRegistry", contextName));
                    }

                    if (ContextRegistry.IsContextRegistered(contextName))
                    {
                        context = ContextRegistry.GetContext(contextName);
                    }

                    if (context == null)
                    {
                        // finally ask HttpConfigurationSystem for the requested context
                        try
                        {
                            if (isLogDebugEnabled)
                            {
                                s_weblog.Debug(
                                    string.Format(
                                        "web context for vpath '{0}' not found. Force creation using filepath '{1}'",
                                        contextName, virtualPath));
                            }

                            // assure context is resolved to the given virtualDirectory
                            using (new HttpContextSwitch(virtualDirectory))
                            {
                                context = (IApplicationContext)ConfigurationUtils.GetSection(ContextSectionName);
                            }

                            if (context != null)
                            {
                                if (isLogDebugEnabled)
                                    s_weblog.Debug(string.Format("got context '{0}' for vpath '{1}'", context, contextName));
                            }
                            else
                            {
                                if (isLogDebugEnabled)
                                    s_weblog.Debug(string.Format("no context defined for vpath '{0}'", contextName));
                            }
                        }
                        catch (Exception ex)
                        {
                            if (s_weblog.IsErrorEnabled)
                            {
                                s_weblog.Error(string.Format("failed creating context '{0}', Stacktrace:\n{1}", contextName, new StackTrace()), ex);
                            }
#if NET_1_1
                            if (ConfigurationUtils.IsConfigurationException(ex))
                            {
                                if (ex.InnerException != null)
                                {
                                    throw ex.InnerException;
                                }
                            }
#endif
                            throw;
                        }
                    }
                }

                // add it to the cache
                // Note: use 'contextName' not 'context.Name' here - the same context may be used for different paths!
                s_webContextCache.Add(contextName, context);
                if (isLogDebugEnabled)
                {
                    s_weblog.Debug(
                        string.Format("added context '{0}' to WebContextCache for vpath '{1}'", context, contextName));
                }

                if (context != null)
                {
                    // register this context and all ParentContexts by their name - parent contexts may be additionally created by the HttpRuntime
                    IApplicationContext parentContext = context;
                    while (parentContext != null)
                    {
                        if (!s_webContextCache.ContainsKey(parentContext.Name))
                        {
                            s_webContextCache.Add(parentContext.Name, parentContext);
                            if (isLogDebugEnabled)
                            {
                                s_weblog.Debug(
                                    string.Format("added parent context '{0}' to WebContextCache for vpath '{1}'",
                                                  parentContext, parentContext.Name));
                            }
                        }
                        parentContext = parentContext.ParentContext;
                    }
                }
                return context;
            } // lock(s_webContextCache)
        }

        /// <summary>
        /// Initializes object definition reader.
        /// </summary>
        /// <param name="objectDefinitionReader">Reader to initialize.</param>
        protected override void InitObjectDefinitionReader(XmlObjectDefinitionReader objectDefinitionReader)
        {
//            NamespaceParserRegistry.RegisterParser(typeof(WebObjectsNamespaceParser));
        }

        /// <summary>
        /// Return an array of resource locations, referring to the XML object
        /// definition files that this context should be built with.
        /// </summary>
        /// <returns>an array of resource locations, or null if none</returns>
        protected override string[] ConfigurationLocations
        {
            get { return _configurationLocations; }
        }

        /// <summary>
        /// Creates web object factory for this context using parent context's factory as a parent.
        /// </summary>
        /// <returns>Web object factory to use.</returns>
        protected override DefaultListableObjectFactory CreateObjectFactory()
        {
            string contextPath = GetContextPathWithTrailingSlash();
            return new WebObjectFactory(contextPath, this.IsCaseSensitive, GetInternalParentObjectFactory());
        }

        /// <summary>
        /// Returns the application-relative virtual path of this context (without leading '~'!).
        /// </summary>
        /// <returns></returns>
        private string GetContextPathWithTrailingSlash()
        {
            string contextPath = this.Name;
            if (contextPath == DefaultRootContextName)
            {
                contextPath = "/";
            }
            else
            {
                contextPath = contextPath + "/";
            }
            return contextPath;
        }

        /// <summary>
        /// Create a reader instance capable of handling web objects (Pages,Controls) for importing o
        /// bject definitions into the specified <paramref name="objectFactory"/>.
        /// </summary>
        protected override XmlObjectDefinitionReader CreateXmlObjectDefinitionReader(DefaultListableObjectFactory objectFactory)
        {
            return new WebObjectDefinitionReader(GetContextPathWithTrailingSlash(), objectFactory, new XmlUrlResolver());
        }
    }
}
www.java2v.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.