diff --git a/src/SoundInTheory.DynamicImage/Caching/DynamicImageCacheManager.cs b/src/SoundInTheory.DynamicImage/Caching/DynamicImageCacheManager.cs index 305ad4a..d179d07 100644 --- a/src/SoundInTheory.DynamicImage/Caching/DynamicImageCacheManager.cs +++ b/src/SoundInTheory.DynamicImage/Caching/DynamicImageCacheManager.cs @@ -118,6 +118,7 @@ public static void Remove(ImageSource source) dependencies.ForEach(RemoveByDependency); } + public static void RemoveAll() { Provider.RemoveAllFromCache(); diff --git a/src/SoundInTheory.DynamicImage/Caching/DynamicImageCacheProvider.cs b/src/SoundInTheory.DynamicImage/Caching/DynamicImageCacheProvider.cs index 6fa5989..be9a7ce 100644 --- a/src/SoundInTheory.DynamicImage/Caching/DynamicImageCacheProvider.cs +++ b/src/SoundInTheory.DynamicImage/Caching/DynamicImageCacheProvider.cs @@ -14,5 +14,6 @@ public abstract class DynamicImageCacheProvider : ProviderBase public abstract DateTime GetImageLastModifiedDate(HttpContext context, string cacheKey, string fileExtension); public abstract void SendImageToHttpResponse(HttpContext context, string cacheKey, string fileExtension); - } + + } } diff --git a/src/SoundInTheory.DynamicImage/Caching/ImageUrlGenerator.cs b/src/SoundInTheory.DynamicImage/Caching/ImageUrlGenerator.cs index 1fb415c..29cc48e 100644 --- a/src/SoundInTheory.DynamicImage/Caching/ImageUrlGenerator.cs +++ b/src/SoundInTheory.DynamicImage/Caching/ImageUrlGenerator.cs @@ -1,4 +1,6 @@ -using System.Linq; +using SoundInTheory.DynamicImage.Configuration; +using System.Configuration; +using System.Linq; using System.Web; namespace SoundInTheory.DynamicImage.Caching @@ -23,9 +25,11 @@ public static string GetImageUrl(Composition composition) private static string GetUrl(string cacheKey, ImageProperties imageProperties) { - const string path = "~/Assets/Images/DynamicImages/"; + var config = ((DynamicImageSection)ConfigurationManager.GetSection("soundInTheory/dynamicImage")) ?? new DynamicImageSection(); + string path = config.BaseVirtualPath; string fileName = string.Format("{0}.{1}", cacheKey, imageProperties.FileExtension); return VirtualPathUtility.ToAbsolute(path) + fileName; } - } + + } } \ No newline at end of file diff --git a/src/SoundInTheory.DynamicImage/Caching/XmlCacheProvider.cs b/src/SoundInTheory.DynamicImage/Caching/XmlCacheProvider.cs index c4c49c9..6ce5229 100644 --- a/src/SoundInTheory.DynamicImage/Caching/XmlCacheProvider.cs +++ b/src/SoundInTheory.DynamicImage/Caching/XmlCacheProvider.cs @@ -6,175 +6,176 @@ namespace SoundInTheory.DynamicImage.Caching { - public class XmlCacheProvider : DiskCacheProviderBase, IDisposable - { - private string _docPath; - private FileSystemWatcher _watcher; - private XDocument _doc; - - public override void Initialize(string name, System.Collections.Specialized.NameValueCollection config) - { - base.Initialize(name, config); - - _docPath = HttpContext.Current.Server.MapPath(string.Format("{0}/DynamicImageCache.xml", CachePath)); - EnsureDocument(); - - _watcher = new FileSystemWatcher(Path.GetDirectoryName(_docPath), "DynamicImageCache.xml"); - _watcher.Deleted += (sender, e) => _doc = null; - } - - void IDisposable.Dispose() - { - if (_watcher != null) - _watcher.Dispose(); - } - - private void EnsureDocument() - { - lock (this) - { - string imageCacheFolder = HttpContext.Current.Server.MapPath(CachePath); - if (!Directory.Exists(imageCacheFolder)) - Directory.CreateDirectory(imageCacheFolder); - - if (!File.Exists(_docPath)) - { - string xml = new XElement("cache").ToString(); - using (var stream = File.CreateText(_docPath)) - stream.Write(xml); - } - - if (_doc == null) - _doc = XDocument.Load(_docPath); - } - } - - public override bool ExistsInCache(string cacheKey) - { - EnsureDocument(); - return _doc.Root.Elements().Any(e => e.Attribute("id").Value == cacheKey); - } - - public override void AddToCache(string cacheKey, GeneratedImage generatedImage, Dependency[] dependencies) - { - EnsureDocument(); - - // Save image to disk. - SaveImageToDiskCache(cacheKey, generatedImage); - - lock (_doc) - { - // Double-check that item hasn't been added to cache since we checked. - if (ExistsInCache(cacheKey)) - return; - - var itemElement = new XElement("item", - new XAttribute("id", cacheKey), - new XAttribute("isImagePresent", generatedImage.Properties.IsImagePresent), - new XAttribute("format", generatedImage.Properties.Format), - new XAttribute("colorDepth", generatedImage.Properties.ColorDepth)); - if (generatedImage.Properties.Width != null) - itemElement.Add(new XAttribute("width", generatedImage.Properties.Width.Value)); - if (generatedImage.Properties.Height != null) - itemElement.Add(new XAttribute("height", generatedImage.Properties.Height.Value)); - if (generatedImage.Properties.JpegCompressionLevel != null) - itemElement.Add(new XAttribute("jpegCompressionLevel", generatedImage.Properties.JpegCompressionLevel.Value)); - - XElement dependenciesElement = new XElement("dependencies"); - itemElement.Add(dependenciesElement); - - foreach (var dependency in dependencies) - dependenciesElement.Add(new XElement("dependency", - new XAttribute("text1", dependency.Text1 ?? string.Empty), - new XAttribute("text2", dependency.Text2 ?? string.Empty), - new XAttribute("text3", dependency.Text3 ?? string.Empty), - new XAttribute("text4", dependency.Text4 ?? string.Empty))); - - _doc.Root.Add(itemElement); - _doc.Save(_docPath); - } - } - - public override ImageProperties GetPropertiesFromCache(string cacheKey) - { - EnsureDocument(); - - lock (_doc) - { - ImageProperties result = null; - - XElement itemElement = _doc.Root.Elements().SingleOrDefault(e => e.Attribute("id").Value == cacheKey); - if (itemElement != null) - result = GetImageProperties(itemElement); - - return result; - } - } - - private static ImageProperties GetImageProperties(XElement itemElement) - { - string cacheKey; - ImageProperties result; - GetImageProperties(itemElement, out cacheKey, out result); - return result; - } - - private static void GetImageProperties(XElement itemElement, out string cacheKey, out ImageProperties imageProperties) - { - imageProperties = new ImageProperties(); - imageProperties.IsImagePresent = Convert.ToBoolean(itemElement.Attribute("isImagePresent").Value); - imageProperties.Format = (DynamicImageFormat)Enum.Parse(typeof(DynamicImageFormat), itemElement.Attribute("format").Value); - if (itemElement.Attribute("width") != null) - imageProperties.Width = Convert.ToInt32(itemElement.Attribute("width").Value); - if (itemElement.Attribute("height") != null) - imageProperties.Height = Convert.ToInt32(itemElement.Attribute("height").Value); - imageProperties.ColorDepth = Convert.ToInt32(itemElement.Attribute("colorDepth").Value); - if (itemElement.Attribute("jpegCompressionLevel") != null) - imageProperties.JpegCompressionLevel = Convert.ToInt32(itemElement.Attribute("jpegCompressionLevel").Value); - cacheKey = itemElement.Attribute("id").Value; - } - - public override void RemoveAllFromCache() - { - EnsureDocument(); - - lock (_doc) - { - foreach (XElement itemElement in _doc.Root.Elements()) - { - string cacheKey; - ImageProperties imageProperties; - GetImageProperties(itemElement, out cacheKey, out imageProperties); - DeleteImageFromDiskCache(cacheKey, imageProperties , HttpContext.Current); - itemElement.Remove(); - } - _doc.Save(_docPath); - } - } - - public override void RemoveFromCache(Dependency dependency) - { - EnsureDocument(); - - lock (_doc) - { - Func attributeMatcher = d => d.Attribute("text1").Value == dependency.Text1 - && d.Attribute("text2").Value == dependency.Text2 - && d.Attribute("text3").Value == dependency.Text3 - && d.Attribute("text4").Value == dependency.Text4; - - var items = _doc.Root.Elements().Where(e => e.Element("dependencies").Elements().Any(attributeMatcher)).ToList(); - foreach (XElement itemElement in items) - { - string cacheKey; - ImageProperties imageProperties; - GetImageProperties(itemElement, out cacheKey, out imageProperties); - DeleteImageFromDiskCache(cacheKey, imageProperties, HttpContext.Current); - itemElement.Remove(); - } - - _doc.Save(_docPath); - } - } - } + public class XmlCacheProvider : DiskCacheProviderBase, IDisposable + { + private string _docPath; + private FileSystemWatcher _watcher; + private XDocument _doc; + + public override void Initialize(string name, System.Collections.Specialized.NameValueCollection config) + { + base.Initialize(name, config); + + _docPath = HttpContext.Current.Server.MapPath(string.Format("{0}/DynamicImageCache.xml", CachePath)); + EnsureDocument(); + + _watcher = new FileSystemWatcher(Path.GetDirectoryName(_docPath), "DynamicImageCache.xml"); + _watcher.Deleted += (sender, e) => _doc = null; + } + + void IDisposable.Dispose() + { + if (_watcher != null) + _watcher.Dispose(); + } + + private void EnsureDocument() + { + lock (this) + { + string imageCacheFolder = HttpContext.Current.Server.MapPath(CachePath); + if (!Directory.Exists(imageCacheFolder)) + Directory.CreateDirectory(imageCacheFolder); + + if (!File.Exists(_docPath)) + { + string xml = new XElement("cache").ToString(); + using (var stream = File.CreateText(_docPath)) + stream.Write(xml); + } + + if (_doc == null) + _doc = XDocument.Load(_docPath); + } + } + + public override bool ExistsInCache(string cacheKey) + { + EnsureDocument(); + return _doc.Root.Elements().Any(e => e.Attribute("id").Value == cacheKey); + } + + public override void AddToCache(string cacheKey, GeneratedImage generatedImage, Dependency[] dependencies) + { + EnsureDocument(); + + // Save image to disk. + SaveImageToDiskCache(cacheKey, generatedImage); + + lock (_doc) + { + // Double-check that item hasn't been added to cache since we checked. + if (ExistsInCache(cacheKey)) + return; + + var itemElement = new XElement("item", + new XAttribute("id", cacheKey), + new XAttribute("isImagePresent", generatedImage.Properties.IsImagePresent), + new XAttribute("format", generatedImage.Properties.Format), + new XAttribute("colorDepth", generatedImage.Properties.ColorDepth)); + if (generatedImage.Properties.Width != null) + itemElement.Add(new XAttribute("width", generatedImage.Properties.Width.Value)); + if (generatedImage.Properties.Height != null) + itemElement.Add(new XAttribute("height", generatedImage.Properties.Height.Value)); + if (generatedImage.Properties.JpegCompressionLevel != null) + itemElement.Add(new XAttribute("jpegCompressionLevel", generatedImage.Properties.JpegCompressionLevel.Value)); + + XElement dependenciesElement = new XElement("dependencies"); + itemElement.Add(dependenciesElement); + + foreach (var dependency in dependencies) + dependenciesElement.Add(new XElement("dependency", + new XAttribute("text1", dependency.Text1 ?? string.Empty), + new XAttribute("text2", dependency.Text2 ?? string.Empty), + new XAttribute("text3", dependency.Text3 ?? string.Empty), + new XAttribute("text4", dependency.Text4 ?? string.Empty))); + + _doc.Root.Add(itemElement); + _doc.Save(_docPath); + } + } + + public override ImageProperties GetPropertiesFromCache(string cacheKey) + { + EnsureDocument(); + + lock (_doc) + { + ImageProperties result = null; + + XElement itemElement = _doc.Root.Elements().SingleOrDefault(e => e.Attribute("id").Value == cacheKey); + if (itemElement != null) + result = GetImageProperties(itemElement); + + return result; + } + } + + private static ImageProperties GetImageProperties(XElement itemElement) + { + string cacheKey; + ImageProperties result; + GetImageProperties(itemElement, out cacheKey, out result); + return result; + } + + private static void GetImageProperties(XElement itemElement, out string cacheKey, out ImageProperties imageProperties) + { + imageProperties = new ImageProperties(); + imageProperties.IsImagePresent = Convert.ToBoolean(itemElement.Attribute("isImagePresent").Value); + imageProperties.Format = (DynamicImageFormat)Enum.Parse(typeof(DynamicImageFormat), itemElement.Attribute("format").Value); + if (itemElement.Attribute("width") != null) + imageProperties.Width = Convert.ToInt32(itemElement.Attribute("width").Value); + if (itemElement.Attribute("height") != null) + imageProperties.Height = Convert.ToInt32(itemElement.Attribute("height").Value); + imageProperties.ColorDepth = Convert.ToInt32(itemElement.Attribute("colorDepth").Value); + if (itemElement.Attribute("jpegCompressionLevel") != null) + imageProperties.JpegCompressionLevel = Convert.ToInt32(itemElement.Attribute("jpegCompressionLevel").Value); + cacheKey = itemElement.Attribute("id").Value; + } + + public override void RemoveAllFromCache() + { + EnsureDocument(); + + lock (_doc) + { + foreach (XElement itemElement in _doc.Root.Elements()) + { + string cacheKey; + ImageProperties imageProperties; + GetImageProperties(itemElement, out cacheKey, out imageProperties); + DeleteImageFromDiskCache(cacheKey, imageProperties, HttpContext.Current); + itemElement.Remove(); + } + _doc.Save(_docPath); + } + } + + public override void RemoveFromCache(Dependency dependency) + { + EnsureDocument(); + + lock (_doc) + { + var items = _doc.Root.Elements().Where(e => e.Element("dependencies").Elements().Any(m => + m.Attribute("text1").Value == (dependency.Text1) && + m.Attribute("text2").Value == (dependency.Text2 ?? "") && + m.Attribute("text3").Value == (dependency.Text3 ?? "") && + m.Attribute("text4").Value == (dependency.Text4 ?? "") + )).ToList(); + foreach (XElement itemElement in items) + { + string cacheKey; + ImageProperties imageProperties; + GetImageProperties(itemElement, out cacheKey, out imageProperties); + DeleteImageFromDiskCache(cacheKey, imageProperties, HttpContext.Current); + itemElement.Remove(); + } + + _doc.Save(_docPath); + } + } + + } } \ No newline at end of file diff --git a/src/SoundInTheory.DynamicImage/Configuration/DynamicImageSection.cs b/src/SoundInTheory.DynamicImage/Configuration/DynamicImageSection.cs index 3d83594..c1f2478 100644 --- a/src/SoundInTheory.DynamicImage/Configuration/DynamicImageSection.cs +++ b/src/SoundInTheory.DynamicImage/Configuration/DynamicImageSection.cs @@ -22,5 +22,14 @@ public DynamicImageFormat DefaultImageFormat get { return (DynamicImageFormat)this["defaultImageFormat"]; } set { this["defaultImageFormat"] = value; } } + + + [ConfigurationProperty("baseVirtualPath", DefaultValue = "~/assets/images/dynamicimages/")] + public string BaseVirtualPath + { + get { return (string)base["baseVirtualPath"]; } + set { this["baseVirtualPath"] = value; } + } + } } diff --git a/src/SoundInTheory.DynamicImage/DynamicImageModule.cs b/src/SoundInTheory.DynamicImage/DynamicImageModule.cs index 0f79a16..481eccb 100644 --- a/src/SoundInTheory.DynamicImage/DynamicImageModule.cs +++ b/src/SoundInTheory.DynamicImage/DynamicImageModule.cs @@ -12,6 +12,8 @@ namespace SoundInTheory.DynamicImage /// public class DynamicImageModule : IHttpModule { + + public void Init(HttpApplication context) { context.PostAuthorizeRequest += OnContextPostAuthorizeRequest; @@ -63,7 +65,9 @@ private static void OnContextPostAuthorizeRequest(object sender, EventArgs e) HttpApplication app = sender as HttpApplication; if (app == null || app.Context == null || app.Context.Request == null) return; - if (!string.IsNullOrEmpty(app.Context.Request.Path) && VirtualPathUtility.ToAppRelative(app.Context.Request.Path).StartsWith("~/Assets/Images/DynamicImages/", StringComparison.InvariantCultureIgnoreCase)) + + DynamicImageSection config = ((DynamicImageSection)ConfigurationManager.GetSection("soundInTheory/dynamicImage")) ?? new DynamicImageSection(); + if (!string.IsNullOrEmpty(app.Context.Request.Path) && VirtualPathUtility.ToAppRelative(app.Context.Request.Path).StartsWith(config.BaseVirtualPath, StringComparison.InvariantCultureIgnoreCase)) HandleRequest(app.Context); } diff --git a/src/SoundInTheory.DynamicImage/Sources/BytesImageSource.cs b/src/SoundInTheory.DynamicImage/Sources/BytesImageSource.cs index 68600a4..be1c15b 100644 --- a/src/SoundInTheory.DynamicImage/Sources/BytesImageSource.cs +++ b/src/SoundInTheory.DynamicImage/Sources/BytesImageSource.cs @@ -1,4 +1,6 @@ -using SoundInTheory.DynamicImage.Util; +using SoundInTheory.DynamicImage.Caching; +using SoundInTheory.DynamicImage.Util; +using System.Collections.Generic; namespace SoundInTheory.DynamicImage.Sources { @@ -17,5 +19,13 @@ public override FastBitmap GetBitmap(ImageGenerationContext context) return new FastBitmap(bytes); return null; } + + public override void PopulateDependencies(List dependencies) + { + // TO-DO: GERAR UM HASH DO BYTEARRAY E COLOCAR COMO DEPENDÊNCIA + // Dependency dependency = new Dependency(); + // dependency.Text1 = Hash(Bytes); + // dependencies.Add(dependency); + } } } diff --git a/src/SoundInTheory.DynamicImage/Sources/FileImageSource.cs b/src/SoundInTheory.DynamicImage/Sources/FileImageSource.cs index 21aed2e..5cdabba 100644 --- a/src/SoundInTheory.DynamicImage/Sources/FileImageSource.cs +++ b/src/SoundInTheory.DynamicImage/Sources/FileImageSource.cs @@ -2,6 +2,8 @@ using System.IO; using System.Web.UI; using SoundInTheory.DynamicImage.Util; +using SoundInTheory.DynamicImage.Caching; +using System.Collections.Generic; namespace SoundInTheory.DynamicImage.Sources { @@ -21,5 +23,13 @@ public override FastBitmap GetBitmap(ImageGenerationContext context) return new FastBitmap(resolvedFileName); return null; } + + public override void PopulateDependencies(List dependencies) + { + Dependency dependency = new Dependency(); + dependency.Text1 = FileName; + dependencies.Add(dependency); + } + } } diff --git a/src/SoundInTheory.DynamicImage/Sources/RemoteImageSource.cs b/src/SoundInTheory.DynamicImage/Sources/RemoteImageSource.cs index 6f1923f..4a27994 100644 --- a/src/SoundInTheory.DynamicImage/Sources/RemoteImageSource.cs +++ b/src/SoundInTheory.DynamicImage/Sources/RemoteImageSource.cs @@ -3,6 +3,8 @@ using System.Net; using System.Web.UI; using SoundInTheory.DynamicImage.Util; +using SoundInTheory.DynamicImage.Caching; +using System.Collections.Generic; namespace SoundInTheory.DynamicImage.Sources { @@ -30,6 +32,13 @@ public override FastBitmap GetBitmap(ImageGenerationContext context) } } + public override void PopulateDependencies(List dependencies) + { + Dependency dependency = new Dependency(); + dependency.Text1 = Url; + dependencies.Add(dependency); + } + private class ImpatientWebClient : WebClient { private readonly int _timeout;