// -------------------------------------------------------------------------------------------------------------------- // // Copyright (c) James South. // Licensed under the Apache License, Version 2.0. // // // Encapsulates methods to allow the retrieval of ImageProcessor settings. // // // -------------------------------------------------------------------------------------------------------------------- namespace ImageProcessor.Web.Config { #region Using using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Web.Compilation; using ImageProcessor.Processors; #endregion /// /// Encapsulates methods to allow the retrieval of ImageProcessor settings. /// /// public sealed class ImageProcessorConfig { #region Fields /// /// A new instance Initializes a new instance of the class. /// with lazy initialization. /// private static readonly Lazy Lazy = new Lazy(() => new ImageProcessorConfig()); /// /// A collection of the elements /// for available plugins. /// private static readonly Dictionary> PluginSettings = new Dictionary>(); /// /// A collection of the processing presets defined in the configuration. /// for available plugins. /// private static readonly Dictionary PresetSettings = new Dictionary(); /// /// The processing configuration section from the current application configuration. /// private static ImageProcessingSection imageProcessingSection; /// /// The cache configuration section from the current application configuration. /// private static ImageCacheSection imageCacheSection; /// /// The security configuration section from the current application configuration. /// private static ImageSecuritySection imageSecuritySection; #endregion #region Constructors /// /// Prevents a default instance of the class from being created. /// private ImageProcessorConfig() { this.LoadGraphicsProcessors(); } #endregion #region Properties /// /// Gets the current instance of the class. /// public static ImageProcessorConfig Instance { get { return Lazy.Value; } } /// /// Gets the list of available GraphicsProcessors. /// public IList GraphicsProcessors { get; private set; } #region Caching /// /// Gets the maximum number of days to store images in the cache. /// public int MaxCacheDays { get { return GetImageCacheSection().MaxDays; } } /// /// Gets or the virtual path of the cache folder. /// /// The virtual path of the cache folder. public string VirtualCachePath { get { return GetImageCacheSection().VirtualPath; } } #endregion #region Security /// /// Gets a list of white listed url[s] that images can be downloaded from. /// public Uri[] RemoteFileWhiteList { get { return GetImageSecuritySection().WhiteList.Cast().Select(x => x.Url).ToArray(); } } /// /// Gets a list of image extensions for url[s] with no extension. /// public ImageSecuritySection.SafeUrl[] RemoteFileWhiteListExtensions { get { return GetImageSecuritySection().WhiteList.Cast().ToArray(); } } /// /// Gets a value indicating whether the current application is allowed to download remote files. /// public bool AllowRemoteDownloads { get { return GetImageSecuritySection().AllowRemoteDownloads; } } /// /// Gets the maximum length to wait in milliseconds before throwing an error requesting a remote file. /// public int Timeout { get { return GetImageSecuritySection().Timeout; } } /// /// Gets the maximum allowable size in bytes of e remote file to process. /// public int MaxBytes { get { return GetImageSecuritySection().MaxBytes; } } /// /// Gets the remote prefix for external files for the application. /// public string RemotePrefix { get { return GetImageSecuritySection().RemotePrefix; } } #endregion #endregion #region Methods /// /// Returns the collection of the processing presets defined in the configuration. /// /// /// The name of the plugin to get the settings for. /// /// /// The containing the processing presets defined in the configuration. /// public string GetPresetSettings(string name) { if (!PresetSettings.ContainsKey(name)) { var presetElement = GetImageProcessingSection().Presets .Cast() .FirstOrDefault(x => x.Name == name); if (presetElement != null) { PresetSettings.Add(presetElement.Name, presetElement.Value); } } string preset; PresetSettings.TryGetValue(name, out preset); return preset; } /// /// Returns the for the given plugin. /// /// /// The name of the plugin to get the settings for. /// /// /// The for the given plugin. /// public Dictionary GetPluginSettings(string name) { if (!PluginSettings.ContainsKey(name)) { var pluginElement = GetImageProcessingSection().Plugins .Cast() .FirstOrDefault(x => x.Name == name); Dictionary settings; if (pluginElement != null) { settings = pluginElement.Settings .Cast() .ToDictionary(setting => setting.Key, setting => setting.Value); } else { settings = new Dictionary(); } PluginSettings.Add(name, settings); return settings; } return PluginSettings[name]; } /// /// Retrieves the processing configuration section from the current application configuration. /// /// The processing configuration section from the current application configuration. private static ImageProcessingSection GetImageProcessingSection() { return imageProcessingSection ?? (imageProcessingSection = ImageProcessingSection.GetConfiguration()); } /// /// Retrieves the caching configuration section from the current application configuration. /// /// The caching configuration section from the current application configuration. private static ImageCacheSection GetImageCacheSection() { return imageCacheSection ?? (imageCacheSection = ImageCacheSection.GetConfiguration()); } /// /// Retrieves the security configuration section from the current application configuration. /// /// The security configuration section from the current application configuration. private static ImageSecuritySection GetImageSecuritySection() { return imageSecuritySection ?? (imageSecuritySection = ImageSecuritySection.GetConfiguration()); } /// /// Gets the list of available GraphicsProcessors. /// private void LoadGraphicsProcessors() { if (this.GraphicsProcessors == null) { if (GetImageProcessingSection().Plugins.AutoLoadPlugins) { Type type = typeof(IGraphicsProcessor); try { // Build a list of native IGraphicsProcessor instances. List availableTypes = BuildManager.GetReferencedAssemblies() .Cast() .SelectMany(s => s.GetTypes()) .Where(t => t != null && type.IsAssignableFrom(t) && t.IsClass && !t.IsAbstract) .ToList(); // Create them and add. this.GraphicsProcessors = availableTypes.Select(x => (Activator.CreateInstance(x) as IGraphicsProcessor)).ToList(); // Add the available settings. foreach (IGraphicsProcessor processor in this.GraphicsProcessors) { processor.Settings = this.GetPluginSettings(processor.GetType().Name); } } catch (ReflectionTypeLoadException) { this.LoadGraphicsProcessorsFromConfiguration(); } } else { this.LoadGraphicsProcessorsFromConfiguration(); } } } /// /// Loads graphics processors from configuration. /// /// /// Thrown when an cannot be loaded. /// private void LoadGraphicsProcessorsFromConfiguration() { ImageProcessingSection.PluginElementCollection pluginConfigs = imageProcessingSection.Plugins; this.GraphicsProcessors = new List(); foreach (ImageProcessingSection.PluginElement pluginConfig in pluginConfigs) { Type type = Type.GetType(pluginConfig.Type); if (type == null) { throw new TypeLoadException("Couldn't load IGraphicsProcessor: " + pluginConfig.Type); } this.GraphicsProcessors.Add(Activator.CreateInstance(type) as IGraphicsProcessor); } // Add the available settings. foreach (IGraphicsProcessor processor in this.GraphicsProcessors) { processor.Settings = this.GetPluginSettings(processor.GetType().Name); } } #endregion } }