internal static SageContext InitializeConfiguration(SageContext context) { string projectConfigPathBinDir = Path.Combine(Project.AssemblyCodeBaseDirectory, ProjectConfiguration.ProjectConfigName); string projectConfigPathProjDir = Path.Combine(Project.AssemblyCodeBaseDirectory, "..\\" + ProjectConfiguration.ProjectConfigName); string projectConfigPath = projectConfigPathBinDir; if (File.Exists(projectConfigPathProjDir)) { projectConfigPath = projectConfigPathProjDir; } var projectConfig = ProjectConfiguration.Create(); if (!File.Exists(projectConfigPath)) { log.Warn("Project configuration file not found; configuration initialized with default values"); return new SageContext(context); } installOrder = new List<string>(); extensions = new OrderedDictionary<string, ExtensionInfo>(); if (File.Exists(projectConfigPath)) projectConfig.Parse(projectConfigPath); if (projectConfig.Locales.Count == 0) { var defaultLocale = new LocaleInfo(); projectConfig.Locales.Add(defaultLocale.Name, defaultLocale); } var result = projectConfig.ValidationResult; if (!result.Success) { initializationError = result.Exception; initializationProblemInfo = new ProblemInfo(ProblemType.ProjectSchemaValidationError, result.SourceFile); } else { configuration = projectConfig; // this will ensure the new context uses the just // created configuration immediately context = new SageContext(context); var extensionManager = new ExtensionManager(); try { extensionManager.Initialize(context); } catch (ProjectInitializationException ex) { initializationError = ex; initializationProblemInfo = new ProblemInfo(ex.Reason, ex.SourceFile); if (ex.Reason == ProblemType.MissingExtensionDependency) { initializationProblemInfo.InfoBlocks .Add("Dependencies", ex.Dependencies.ToDictionary(name => name)); } } if (initializationError == null) { var missingDependencies = projectConfig.Dependencies .Where(name => extensionManager.Count(ex => ex.Name.Equals(name, StringComparison.InvariantCultureIgnoreCase)) == 0) .ToList(); var extraDependencies = extensionManager .Where(extension => projectConfig.Dependencies.Count(name => name.Equals(extension.Name, StringComparison.InvariantCultureIgnoreCase)) == 0) .ToList(); if (missingDependencies.Count != 0) { string errorMessage = string.Format("Project is missing one or more dependencies ({0}) - installation cancelled.", string.Join(", ", missingDependencies)); initializationError = new ProjectInitializationException(errorMessage); initializationProblemInfo = new ProblemInfo(ProblemType.MissingDependency); initializationProblemInfo.InfoBlocks .Add("Dependencies", missingDependencies.ToDictionary(name => name)); } if (extraDependencies.Count != 0) { log.WarnFormat("There are additional, unreferenced extensions in the extensions directory: {0}", string.Join(",", extraDependencies)); } foreach (var name in projectConfig.Dependencies) { var extension = extensionManager.First(ex => ex.Name.Equals(name, StringComparison.InvariantCultureIgnoreCase)); installOrder.Add(extension.Config.Id); Project.RelevantAssemblies.AddRange(extension.Assemblies); projectConfig.RegisterExtension(extension.Config); extensions.Add(extension.Config.Id, extension); } // fire this event at the end rather than once for each extension var totalAssemblies = extensionManager.Sum(info => info.Assemblies.Count); if (totalAssemblies != 0) { if (Project.AssembliesUpdated != null) { log.DebugFormat("{0} extension assemblies loaded, triggering AssembliesUpdated event", totalAssemblies); Project.AssembliesUpdated(null, EventArgs.Empty); } } installOrder.Add(projectConfig.Id); projectConfig.RegisterRoutes(); context.LmCache.Put(ConfigWatchName, DateTime.Now, projectConfig.Files); } } return context; }
internal static SageContext CreateSageContext(string url, ProjectConfiguration config) { return Program.CreateSageContext(url, config, Program.MapPath); }
internal static SageContext CreateSageContext(string url, ProjectConfiguration config, Func<string, string> pathMapper) { HttpContextBase httpContext = Program.CreateHttpContext(url, "default.aspx"); SageContext context = new SageContext(httpContext, pathMapper, config); return context; }
/// <summary> /// Initializes a new instance of the <see cref="SageContext"/> class, using an existing context instance. /// </summary> /// <param name="context">An existing <see cref="SageContext"/> to use to initialize this instance.</param> /// <param name="pathMapper">The function to use for resolving relative paths.</param> /// <param name="config">The project configuration to use with this context instance.</param> public SageContext(SageContext context, ProjectConfiguration config = null, Func<string, string> pathMapper = null) : this(context, context.Category, config) { if (pathMapper != null) this.pathMapper = pathMapper; }
/// <summary> /// Initializes a new instance of the <see cref="SageContext"/> class, using an existing context instance. /// </summary> /// <param name="context">An existing <see cref="SageContext"/> to use to initialize this instance.</param> /// <param name="categoryName">The name of the category to set on the new context.</param> /// <param name="config">The project configuration to use with this context instance.</param> public SageContext(SageContext context, string categoryName, ProjectConfiguration config = null) : this(context.HttpContext, config) { this.Category = categoryName; pathMapper = context.MapPath; }
/// <summary> /// Initializes a new instance of the <see cref="SageContext"/> class, using the specified <paramref name="httpContext"/>, /// <paramref name="categoryName"/> and <paramref name="pathMapper"/>. /// </summary> /// <param name="httpContext">The current HTTP context.</param> /// <param name="categoryName">The category to set for this instance.</param> /// <param name="pathMapper">The function to use to map relative paths to absolute.</param> /// <param name="config">The project configuration to use with this context instance.</param> public SageContext(HttpContextBase httpContext, string categoryName, Func<string, string> pathMapper, ProjectConfiguration config = null) : this(httpContext, config) { this.Category = categoryName; this.pathMapper = pathMapper; }
/// <summary> /// Initializes a new instance of the <see cref="SageContext"/> class, using the specified <see cref="HttpContextBase"/> and /// <paramref name="pathMapper"/>. /// </summary> /// <param name="httpContext">The current <see cref="HttpContextBase"/> to use to initialize this instance.</param> /// <param name="pathMapper">The function to use for resolving relative paths.</param> /// <param name="config">The project configuration to use with this context instance.</param> public SageContext(HttpContextBase httpContext, Func<string, string> pathMapper, ProjectConfiguration config = null) { Contract.Requires<ArgumentNullException>(httpContext != null); Contract.Requires<ArgumentNullException>(pathMapper != null); //// In certain cases, an instance of Sage context is needed while the request //// may not be available (when creating it from Application_Start event for instance) //// This variable checks for that scenario, so that we can then initialize this instance //// with less features. bool requestAvailable = false; string queryString = string.Empty; try { requestAvailable = httpContext.Request != null; queryString = httpContext.Request.Url.Query; } catch (HttpException ex) { // request unavailable if (ex.ErrorCode != -2147467259) throw; } this.ProjectConfiguration = config ?? Sage.Project.Configuration; this.pathMapper = pathMapper; textEvaluator = new TextEvaluator(this); nodeEvaluator = new NodeEvaluator(this); this.ViewCache = new ViewCache(this); this.Query = new QueryString(queryString); this.Cache = new CacheWrapper(httpContext); this.LmCache = new LastModifiedCache(this); this.Data = new QueryString(); this.HttpContext = httpContext; this.Locale = this.Query.GetString(LocaleVariableName, this.ProjectConfiguration.DefaultLocale); this.Category = this.Query.GetString(CategoryVariableName); if (string.IsNullOrEmpty(this.Category) || !this.ProjectConfiguration.Categories.ContainsKey(this.Category)) this.Category = this.ProjectConfiguration.DefaultCategory; if (string.IsNullOrEmpty(this.Locale)) this.Locale = this.ProjectConfiguration.DefaultLocale; this.Query.Remove(LocaleVariableName); this.Query.Remove(CategoryVariableName); this.Query.Remove(RefreshVariableName); this.Url = new UrlGenerator(this); this.Path = new PathResolver(this); this.Resources = new ResourceManager(this); if (requestAvailable) { bool isNoCacheRequest = httpContext.Request.Headers["Cache-Control"] == "no-cache"; this.Query = new QueryString(httpContext.Request.QueryString); this.ForceRefresh = isNoCacheRequest || (this.IsDeveloperRequest && this.Query.GetString(RefreshVariableName).EqualsAnyOf("1", "true", "yes")); if (httpContext.Request.UrlReferrer != null) this.ReferrerUrl = httpContext.Request.UrlReferrer.ToString(); this.ApplicationPath = httpContext.Request.ApplicationPath.TrimEnd('/') + "/"; this.PhysicalApplicationPath = httpContext.Request.PhysicalApplicationPath; this.UserAgentID = httpContext.Request.Browser.Type.ToLower(); this.UserAgentType = httpContext.Request.Browser.Crawler ? UserAgentType.Crawler : UserAgentType.Browser; if (Project.IsReady) this.SubstituteExtensionPath(); } else { this.ApplicationPath = (HostingEnvironment.ApplicationVirtualPath ?? "/").TrimEnd('/') + "/"; this.PhysicalApplicationPath = HostingEnvironment.ApplicationPhysicalPath ?? @"c:\inetpub\wwwroot"; } }
/// <summary> /// Initializes a new instance of the <see cref="SageContext"/> class, using the specified <see cref="HttpContext"/>. /// </summary> /// <param name="httpContext">The current <see cref="HttpContext"/> to use to initialize this instance.</param> /// <param name="config">The project configuration to use with this context instance.</param> public SageContext(HttpContext httpContext, ProjectConfiguration config = null) : this(new HttpContextWrapper(httpContext), config) { }
/// <summary> /// Initializes a new instance of the <see cref="SageContext"/> class, using the specified <paramref name="httpContext"/> and /// <paramref name="categoryName"/>. /// </summary> /// <param name="httpContext">The current HTTP context.</param> /// <param name="categoryName">The category to set for this instance.</param> /// <param name="localeName">The locale to set for this instance.</param> /// <param name="config">The project configuration to use with this context instance.</param> public SageContext(HttpContextBase httpContext, string categoryName, string localeName, ProjectConfiguration config = null) : this(httpContext, config) { this.Category = categoryName; this.Locale = localeName; pathMapper = httpContext.Server.MapPath; }
/// <summary> /// Initializes a new instance of the <see cref="SageContext"/> class, using the specified <see cref="ControllerContext"/>. /// </summary> /// <param name="controllerContext">The current <see cref="ControllerContext"/> to use to initialize this instance.</param> /// <param name="config">The project configuration to use with this context instance.</param> public SageContext(ControllerContext controllerContext, ProjectConfiguration config = null) : this(controllerContext.HttpContext, config) { this.Route = controllerContext.RouteData.Route; this.RouteValues = new NameValueCollection(); foreach (string key in controllerContext.RouteData.Values.Keys) { this.RouteValues[key] = controllerContext.RouteData.Values[key] as string; } }
/// <summary> /// Initializes a new instance of the <see cref="SageContext"/> class, using the specified <see cref="HttpContextBase"/>. /// </summary> /// <param name="httpContext">The current <see cref="HttpContextBase"/> to use to initialize this instance.</param> /// <param name="config">The project configuration to use with this context instance.</param> public SageContext(HttpContextBase httpContext, ProjectConfiguration config = null) : this(httpContext, httpContext.Server.MapPath, config) { }
/// <summary> /// Initializes a new instance of the <see cref="PathResolver"/> class using the specified <see cref="SageContext"/> /// to retrieve current category and locale information. /// </summary> /// <param name="context">The current <see cref="SageContext"/>.</param> public PathResolver(SageContext context) { this.context = context; config = context.ProjectConfiguration; }
private void MergeExtension(ProjectConfiguration extensionConfig) { string extensionName = extensionConfig.Name; foreach (string name in extensionConfig.Routing.Keys) { if (this.Routing.ContainsKey(name)) { log.WarnFormat("Skipped registering route '{0}' from extension '{1}' because a route with the same name already exists.", name, extensionName); continue; } extensionConfig.Routing[name].Extension = extensionName; this.Routing.Add(name, extensionConfig.Routing[name]); } foreach (KeyValuePair<string, ExtensionString> pair in extensionConfig.Linking.Links) { if (this.Linking.Links.ContainsKey(pair.Key)) { log.WarnFormat("Skipped registering link '{0}' from extension '{1}' because a link with the same name already exists.", pair.Key, extensionName); continue; } var newLink = this.Linking.AddLink(pair.Key, pair.Value.Value); newLink.Extension = extensionName; } foreach (KeyValuePair<string, ExtensionString> pair in extensionConfig.Linking.Formats) { if (this.Linking.Formats.ContainsKey(pair.Key)) { log.WarnFormat("Skipped registering format '{0}' from extension '{1}' because a link with the same name already exists.", pair.Key, extensionName); continue; } var newFormat = this.Linking.AddFormat(pair.Key, pair.Value.Value); newFormat.Extension = extensionName; } foreach (string name in extensionConfig.ResourceLibraries.Keys) { if (this.ResourceLibraries.ContainsKey(name)) { log.WarnFormat("Skipped registering script library '{0}' from extension '{1}' because a script library with the same name already exists.", name, extensionName); continue; } ResourceLibraryInfo library = extensionConfig.ResourceLibraries[name]; library.Resources.Each(r => r.Extension = extensionName); library.Extension = extensionName; this.ResourceLibraries.Add(name, library); } foreach (string name in extensionConfig.MetaViews.Keys) { if (this.MetaViews.ContainsKey(name)) { log.WarnFormat("Skipped registering meta view '{0}' from extension '{1}' because a meta view with the same name already exists.", name, extensionName); continue; } MetaViewInfo info = extensionConfig.MetaViews[name]; info.Extension = extensionName; this.MetaViews.Add(name, info); } foreach (string number in extensionConfig.ErrorViews.Keys) { if (this.ErrorViews.ContainsKey(number)) { log.WarnFormat("Skipped registering error view '{0}' from extension '{1}' because an error view with the same number already exists.", number, extensionName); continue; } ErrorViewInfo info = extensionConfig.ErrorViews[number]; info.Extension = extensionName; this.ErrorViews.Add(number, info); } foreach (string name in extensionConfig.Modules.Keys) { if (this.Modules.ContainsKey(name)) { log.WarnFormat("Skipped registering module '{0}' from extension '{1}' because a module with the same name already exists.", name, extensionName); continue; } ModuleConfiguration module = extensionConfig.Modules[name]; module.Resources.Each(r => r.Extension = extensionName); module.Extension = extensionName; this.Modules.Add(name, module); } }
internal void RegisterExtension(ProjectConfiguration extensionConfig) { Contract.Requires<ArgumentNullException>(extensionConfig != null); Contract.Requires<ArgumentException>(!string.IsNullOrWhiteSpace(extensionConfig.Name)); string extensionName = extensionConfig.Name; extensions[extensionName] = extensionConfig; this.MergeExtension(extensionConfig); }
private ProjectConfiguration(ProjectConfiguration initConfiguration = null) { this.AssetPath = initConfiguration != null ? initConfiguration.AssetPath : "~/assets"; this.Modules = initConfiguration != null ? new Dictionary<string, ModuleConfiguration>(initConfiguration.Modules) : new Dictionary<string, ModuleConfiguration>(); this.MetaViews = initConfiguration != null ? new MetaViewDictionary(initConfiguration.MetaViews) : new MetaViewDictionary(); this.ErrorViews = initConfiguration != null ? new Dictionary<string, ErrorViewInfo>(initConfiguration.ErrorViews) : new Dictionary<string, ErrorViewInfo>(); this.Environment = initConfiguration != null ? new EnvironmentConfiguration(initConfiguration.Environment) : new EnvironmentConfiguration(); this.Linking = initConfiguration != null ? new LinkingConfiguration(initConfiguration.Linking) : new LinkingConfiguration(); this.Routing = initConfiguration != null ? new RoutingConfiguration(initConfiguration.Routing) : new RoutingConfiguration(); this.PathTemplates = initConfiguration != null ? new PathTemplates(initConfiguration.PathTemplates) : new PathTemplates(); this.ResourceLibraries = initConfiguration != null ? new Dictionary<string, ResourceLibraryInfo>(initConfiguration.ResourceLibraries) : new Dictionary<string, ResourceLibraryInfo>(); this.ViewCaching = initConfiguration != null ? initConfiguration.ViewCaching : new CachingConfiguration(); this.Type = initConfiguration != null ? initConfiguration.Type : ProjectType.Project; this.SharedCategory = initConfiguration != null ? initConfiguration.SharedCategory : "shared"; this.DefaultLocale = initConfiguration != null ? initConfiguration.DefaultLocale : "us"; this.DefaultCategory = initConfiguration != null ? initConfiguration.DefaultCategory : "default"; this.AutoInternationalize = initConfiguration == null || initConfiguration.AutoInternationalize; this.ValidationResult = initConfiguration != null ? new ValidationResult(initConfiguration.ValidationResult) : new ValidationResult(); this.Files = initConfiguration != null ? new List<string>(initConfiguration.Files) : new List<string>(); this.Dependencies = initConfiguration != null ? new List<string>(initConfiguration.Dependencies) : new List<string>(); this.Locales = initConfiguration != null ? new Dictionary<string, LocaleInfo>(initConfiguration.Locales) : new Dictionary<string, LocaleInfo> { { "us", new LocaleInfo { Name = "us", DictionaryNames = new List<string> { "us", "en" }, ResourceNames = new List<string> { "us", "en", "default" }, }}}; this.Categories = initConfiguration != null ? new Dictionary<string, CategoryInfo>(initConfiguration.Categories) : new Dictionary<string, CategoryInfo>(); this.Categories[this.DefaultCategory] = new CategoryInfo(this.DefaultCategory) { Locales = this.Locales.Keys.ToList() }; customElements = initConfiguration != null ? new List<XmlElement>(initConfiguration.customElements) : new List<XmlElement>(); this.Variables = new Dictionary<string, NameValueCollection>(); }
static ProjectConfiguration() { defaultConfiguration = new ProjectConfiguration(); if (File.Exists(ProjectConfiguration.SystemConfigurationPath)) defaultConfiguration.Parse(ProjectConfiguration.SystemConfigurationPath); }