/// <summary>The restore sprited images from cache.</summary>
        /// <param name="mapXmlFile">The map xml file.</param>
        /// <param name="cacheSection">The cache section.</param>
        /// <param name="results">The results.</param>
        /// <param name="destinationDirectory">The destination Directory.</param>
        /// <param name="imageAssembleScanDestinationFile">The image Assemble Scan Destination File.</param>
        /// <returns>The <see cref="bool"/>.</returns>
        private static ImageLog RestoreSpritedImagesFromCache(string mapXmlFile, ICacheSection cacheSection, BlockingCollection <ContentItem> results, string destinationDirectory, string imageAssembleScanDestinationFile)
        {
            // restore log file, is required by next step in applying sprites to the css.
            var spriteLogFileContentItem = cacheSection.GetCachedContentItems(CacheFileCategories.SpriteLogFile).FirstOrDefault();

            if (spriteLogFileContentItem == null)
            {
                return(null);
            }

            if (!string.IsNullOrWhiteSpace(imageAssembleScanDestinationFile))
            {
                var spriteLogFileXmlContentItem = cacheSection.GetCachedContentItems(CacheFileCategories.SpriteLogFileXml).FirstOrDefault();
                if (spriteLogFileXmlContentItem != null)
                {
                    spriteLogFileXmlContentItem.WriteTo(mapXmlFile);
                }
            }

            var imageLog = spriteLogFileContentItem.Content.FromJson <ImageLog>(true);

            // Restore images
            var spritedImageContentItems = cacheSection.GetCachedContentItems(CacheFileCategories.HashedSpriteImage);

            spritedImageContentItems.ForEach(sici => sici.WriteToContentPath(destinationDirectory));
            results.AddRange(spritedImageContentItems);

            return(imageLog);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Parse out the @imports and replace with all files in directory @import.
        /// </summary>
        /// <param name="fileContent">The content</param>
        /// <param name="workingFolder">The workingFolder</param>
        /// <param name="cacheSection">The cache section</param>
        /// <param name="minimalOutput">Is the goal to have the most minimal output (true skips lots of comments)</param>
        /// <returns>The parses less content.</returns>
        private static string ParseImports(string fileContent, string workingFolder, ICacheSection cacheSection, bool minimalOutput)
        {
            var withImports = ImportsPattern.Replace(fileContent, match => ReplaceImports(match, workingFolder.EnsureEndSeparator(), cacheSection, minimalOutput));

            SetImportSourceDependencies(withImports, workingFolder, cacheSection);
            return(withImports);
        }
Ejemplo n.º 3
0
        /// <summary>The restore bundle from cache.</summary>
        /// <param name="cacheSection">The cache section.</param>
        /// <returns>The <see cref="bool"/>.</returns>
        private bool RestoreBundleFromCache(ICacheSection cacheSection)
        {
            var endResults = cacheSection.GetCachedContentItems(CacheFileCategories.AssemblerResult, true);

            endResults.ForEach(er => er.WriteToContentPath(this.context.Configuration.DestinationDirectory));
            return(true);
        }
Ejemplo n.º 4
0
        /// <summary>The method called from the regex replace to replace the matched wgInclude() statements.</summary>
        /// <param name="match">The regex match</param>
        /// <param name="workingFolder">The working folder from which to determine relative path's in the include.</param>
        /// <param name="cacheSection">The cache Section.</param>
        /// <param name="minimalOutput">Is the goal to have the most minimal output (true skips lots of comments)</param>
        /// <returns>The contents of the file to replace, with a /* WGINCLUDE [fullFilePath] */ header on top.</returns>
        private static string ReplaceInputs(Match match, string workingFolder, ICacheSection cacheSection, bool minimalOutput)
        {
            var fileOrPath = Path.Combine(workingFolder, match.Groups["fileOrPath"].Value.Trim());
            var inputSpec  = new InputSpec {
                IsOptional = true, Path = fileOrPath
            };

            if (Directory.Exists(fileOrPath))
            {
                inputSpec.SearchPattern = match.Groups["searchPattern"].Value.Trim();
            }

            cacheSection.AddSourceDependency(inputSpec);

            var result = string.Empty;

            foreach (var file in inputSpec.GetFiles())
            {
                if (!minimalOutput)
                {
                    result += "/* WGINCLUDE: {0} */\r\n".InvariantFormat(file);
                }

                result += File.ReadAllText(file) + "\r\n";
            }

            return(result);
        }
Ejemplo n.º 5
0
 /// <summary>Begins a new cache section.</summary>
 /// <param name="webGreaseSectionKey">The web Grease Section Key.</param>
 /// <param name="autoLoad">The auto Load.</param>
 /// <returns>The <see cref="ICacheSection"/>.</returns>
 public ICacheSection BeginSection(WebGreaseSectionKey webGreaseSectionKey, bool autoLoad = true)
 {
     return(this.currentCacheSection = CacheSection.Begin(
                this.context,
                webGreaseSectionKey.Category,
                webGreaseSectionKey.Value,
                this.CurrentCacheSection,
                autoLoad));
 }
Ejemplo n.º 6
0
        public static IEnumerable <ICacheResult> GetAllEntriesUntyped([NotNull] this ICacheSection cacheSection)
        {
            cacheSection.AssertArgumentNotNull(nameof(cacheSection));

            var values = cacheSection
                         .Keys
                         .Select(key => cacheSection.GetCacheEntryUntyped(key))
                         .Where(cacheResult => cacheResult != null);

            return(values);
        }
Ejemplo n.º 7
0
        public async Task Test1()
        {
            MemoryCache memoryCache  = new MemoryCache(new MemoryCacheOptions());
            var         cacheManager = new CacheManager(memoryCache);

            double d1 = await cacheManager.GetOrCreateAsync(Cache.Section1, "Value1", context => Task.FromResult(1.0));

            double d2 = await cacheManager.GetOrCreateAsync(Cache.Section1, "Value2", context => Task.FromResult(2.0));

            ICacheSection <double> cacheSection = cacheManager.GetOrCreateSection(Cache.Section1);
        }
Ejemplo n.º 8
0
        public static IEnumerable <CacheResult <T> > GetAllEntries <T>([NotNull] this ICacheSection <T> cacheSection)
        {
            cacheSection.AssertArgumentNotNull(nameof(cacheSection));

            var values = cacheSection
                         .Keys
                         .Select(key => cacheSection.GetCacheEntry(key))
                         .Where(cacheResult => !cacheResult.IsEmpty());

            return(values);
        }
Ejemplo n.º 9
0
        public static IEnumerable <T> GetAllValues <T>([NotNull] this ICacheSection <T> cacheSection)
        {
            cacheSection.AssertArgumentNotNull(nameof(cacheSection));

            var values = cacheSection
                         .Keys
                         .Select(key => cacheSection.Get(key))
                         .Where(option => option.IsSome)
                         .Select(option => option.GetValueOrDefault());

            return(values);
        }
Ejemplo n.º 10
0
 /// <summary>The handle other content type cache sections.</summary>
 /// <param name="context">The context.</param>
 /// <param name="parentCacheSection">The session cache section.</param>
 /// <param name="sessionCacheData">The session cache data.</param>
 /// <param name="contentTypeSectionId">The content type section id.</param>
 private void HandleOtherContentTypeCacheSections(IWebGreaseContext context, ICacheSection parentCacheSection, SessionCacheData sessionCacheData, string[] contentTypeSectionId)
 {
     if (sessionCacheData != null)
     {
         foreach (var configType in sessionCacheData.ConfigTypes.Keys.Where(ct => !ct.Equals(this.ConfigType, StringComparison.OrdinalIgnoreCase)))
         {
             // TODO: Do a better job at touching all the files used by the last build from another config type.
             var otherContentTypeCacheSection = CacheSection.Begin(context, WebGreaseContext.ToStringId(contentTypeSectionId), sessionCacheData.GetConfigTypeUniqueKey(configType), parentCacheSection);
             otherContentTypeCacheSection.Save();
         }
     }
 }
        /// <summary>
        /// Initializes a new instance of the <see cref="MemoryCacheStorage{TSessionState, TOperationState}"/> class.
        /// </summary>
        /// <param name="memoryCache">Memory cache.</param>
        /// <param name="cacheSectionName">Optional cache section name.</param>
        /// <param name="configureCacheEntry">Optional cache configure method for all sections.</param>
        public MemoryCacheStorage(
            IMemoryCache memoryCache,
            string?cacheSectionName = null,
            Action <ICacheEntryContext>?configureCacheEntry = null)
        {
            memoryCache.AssertArgumentNotNull(nameof(memoryCache));

            string sectionName = cacheSectionName ?? $"OperationManager<{nameof(TSessionState)}, {nameof(TOperationState)}>";

            _sessionsCache = new CacheManager(memoryCache, configureCacheEntry)
                             .GetOrCreateSection(sectionName, CacheSettings <IOperationManager <TSessionState, TOperationState> > .Default);
        }
Ejemplo n.º 12
0
        /// <summary>Ends the cache section.</summary>
        /// <param name="cacheSection">The cache section.</param>
        public void EndSection(ICacheSection cacheSection)
        {
#if DEBUG
            if (this.CurrentCacheSection != cacheSection)
            {
                throw new BuildWorkflowException("Something unexpected went wrong with the caching logic.");
            }
#endif
            if (this.CurrentCacheSection == cacheSection)
            {
                this.currentCacheSection = cacheSection.Parent;
            }
        }
Ejemplo n.º 13
0
        /// <summary>The create sprited images.</summary>
        /// <param name="mapXmlFile">The map xml file.</param>
        /// <param name="imageAssemblyAnalysisLog">The image assembly analysis log.</param>
        /// <param name="imageReferencesToAssemble">The image references to assemble.</param>
        /// <param name="cacheSection">The cache section.</param>
        /// <param name="results">The results.</param>
        /// <param name="threadContext">The thread Context.</param>
        /// <returns>The <see cref="bool"/>.</returns>
        private ImageLog CreateSpritedImages(
            string mapXmlFile,
            ImageAssemblyAnalysisLog imageAssemblyAnalysisLog,
            IEnumerable <InputImage> imageReferencesToAssemble,
            ICacheSection cacheSection,
            BlockingCollection <ContentItem> results,
            IWebGreaseContext threadContext)
        {
            if (!Directory.Exists(this.ImagesOutputDirectory))
            {
                Directory.CreateDirectory(this.ImagesOutputDirectory);
            }

            var imageMap = ImageAssembleGenerator.AssembleImages(
                imageReferencesToAssemble.ToSafeReadOnlyCollection(),
                SpritePackingType.Vertical,
                this.ImagesOutputDirectory,
                string.Empty,
                true,
                threadContext,
                this.ImageAssemblyPadding,
                imageAssemblyAnalysisLog,
                this.ForcedSpritingImageType);

            if (imageMap == null || imageMap.Document == null)
            {
                return(null);
            }

            var destinationDirectory = threadContext.Configuration.DestinationDirectory;

            if (!string.IsNullOrWhiteSpace(this.ImageAssembleScanDestinationFile))
            {
                var scanXml = imageMap.Document.ToString();
                FileHelper.WriteFile(mapXmlFile, scanXml);
                cacheSection.AddResult(ContentItem.FromFile(mapXmlFile), CacheFileCategories.SpriteLogFileXml);
            }

            var imageLog = new ImageLog(imageMap.Document);

            cacheSection.AddResult(ContentItem.FromContent(imageLog.ToJson(true)), CacheFileCategories.SpriteLogFile);

            foreach (var spritedFile in imageLog.InputImages.Select(il => il.OutputFilePath).Distinct())
            {
                var spritedImageContentItem = ContentItem.FromFile(spritedFile, spritedFile.MakeRelativeToDirectory(destinationDirectory));
                results.Add(spritedImageContentItem);
                cacheSection.AddResult(spritedImageContentItem, CacheFileCategories.HashedSpriteImage);
            }

            return(imageLog);
        }
Ejemplo n.º 14
0
        /// <summary>Initializes a new instance of the <see cref="CacheManager"/> class.</summary>
        /// <param name="configuration">The configuration.</param>
        /// <param name="logManager">The log manager.</param>
        /// <param name="parentCacheSection">The parent Cache Section.</param>
        public CacheManager(WebGreaseConfiguration configuration, LogManager logManager, ICacheSection parentCacheSection)
        {
            this.currentCacheSection = parentCacheSection;

            if (configuration == null)
            {
                throw new ArgumentNullException("configuration");
            }

            if (logManager == null)
            {
                throw new ArgumentNullException("logManager");
            }

            var cacheRoot = configuration.CacheRootPath.AsNullIfWhiteSpace() ?? "_webgrease.cache";

            if (!Path.IsPathRooted(cacheRoot))
            {
                cacheRoot = Path.Combine(configuration.SourceDirectory, cacheRoot);
            }

            this.cacheRootPath = GetCacheUniquePath(cacheRoot, configuration.CacheUniqueKey);

            if (!Directory.Exists(this.cacheRootPath))
            {
                Directory.CreateDirectory(this.cacheRootPath);
            }

            Safe.Lock(
                First,
                () =>
            {
                // Only log this once when multi threading.
                if (First.Contains(this.cacheRootPath))
                {
                    First.Add(this.cacheRootPath);
                    logManager.Information("Cache enabled using cache path: {0}".InvariantFormat(this.cacheRootPath));
                }
            });
        }
Ejemplo n.º 15
0
        /// <summary>The replace imports.</summary>
        /// <param name="match">The match.</param>
        /// <param name="workingFolder">The working folder.</param>
        /// <param name="cacheSection">The cache Section.</param>
        /// <param name="minimalOutput">Is the goal to have the most minimal output (true skips lots of comments)</param>
        /// <returns>The replaced imports.</returns>
        private static string ReplaceImports(Match match, string workingFolder, ICacheSection cacheSection, bool minimalOutput)
        {
            var    path            = match.Groups["path"].Value;
            string pattern         = null;
            var    pathParts       = path.Split(new[] { '/', '\\' }, StringSplitOptions.RemoveEmptyEntries).ToList();
            var    possiblePattern = pathParts.LastOrDefault();

            if (!string.IsNullOrEmpty(possiblePattern) && possiblePattern.Contains("*"))
            {
                pattern = possiblePattern;
                pathParts.RemoveAt(pathParts.Count - 1);
            }

            var pathInfo = new DirectoryInfo(Path.Combine(workingFolder, string.Join("\\", pathParts)));

            cacheSection.AddSourceDependency(new InputSpec {
                IsOptional = true, Path = pathInfo.FullName, SearchOption = SearchOption.TopDirectoryOnly, SearchPattern = pattern
            });

            if (!pathInfo.Exists)
            {
                return(string.Empty);
            }

            var files = !string.IsNullOrWhiteSpace(pattern)
                            ? Directory.GetFiles(pathInfo.FullName, pattern)
                            : Directory.GetFiles(pathInfo.FullName);

            return
                ((minimalOutput ? string.Empty : GetImportsComment(path, string.Empty))
                 + string.Join(
                     " ",
                     files
                     .Select(file => MakeRelativePath(workingFolder, file))
                     .Select(relativeFile => "{0}\r\n@import \"{1}\";".InvariantFormat(
                                 minimalOutput ? string.Empty : "\r\n" + GetImportsComment(path, Path.GetFileName(relativeFile)),
                                 relativeFile.Replace("\\", "/")))));
        }
 public void EndSection(ICacheSection cacheSection)
 {
     throw new NotImplementedException();
 }
Ejemplo n.º 17
0
        /// <summary>Hash the images.</summary>
        /// <param name="cssContent">The css content.</param>
        /// <param name="imageHasher">The image Hasher.</param>
        /// <param name="cacheSection">The cache section.</param>
        /// <param name="threadContext">The context.</param>
        /// <param name="sourceImages">The source Images.</param>
        /// <param name="missingImage">The missing Image.</param>
        /// <returns>The css with hashed images.</returns>
        private static Tuple <string, IEnumerable <ContentItem> > HashImages(string cssContent, FileHasherActivity imageHasher, ICacheSection cacheSection, IWebGreaseContext threadContext, IDictionary <string, string> sourceImages, string missingImage)
        {
            return(threadContext.SectionedAction(SectionIdParts.MinifyCssActivity, SectionIdParts.ImageHash).Execute(() =>
            {
                var contentImagesToHash = new HashSet <string>();
                var hashedContentItems = new List <ContentItem>();
                var hashedImages = new Dictionary <string, string>();
                cssContent = UrlHashRegexPattern.Replace(
                    cssContent,
                    match =>
                {
                    var urlToHash = match.Groups["url"].Value;
                    var extraInfo = match.Groups["extra"].Value;

                    if (ResourcesResolver.LocalizationResourceKeyRegex.IsMatch(urlToHash))
                    {
                        return match.Value;
                    }

                    var normalizedHashUrl = urlToHash.NormalizeUrl();

                    var imageContentFile = sourceImages.TryGetValue(normalizedHashUrl);
                    if (imageContentFile == null && !string.IsNullOrWhiteSpace(missingImage))
                    {
                        imageContentFile = sourceImages.TryGetValue(missingImage);
                    }

                    if (imageContentFile == null)
                    {
                        throw new BuildWorkflowException("Could not find a matching source image for url: {0}".InvariantFormat(urlToHash));
                    }

                    if (contentImagesToHash.Add(normalizedHashUrl))
                    {
                        // Add the image as end result
                        var imageContentItem = ContentItem.FromFile(imageContentFile, normalizedHashUrl);
                        imageContentItem = imageHasher.Hash(imageContentItem);
                        cacheSection.AddSourceDependency(imageContentFile);
                        hashedContentItems.Add(imageContentItem);

                        imageContentFile =
                            Path.Combine(
                                imageHasher.BasePrefixToAddToOutputPath ?? Path.AltDirectorySeparatorChar.ToString(CultureInfo.InvariantCulture),
                                imageContentItem.RelativeHashedContentPath.Replace(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar));

                        hashedImages.Add(normalizedHashUrl, imageContentFile);
                    }
                    else
                    {
                        imageContentFile = hashedImages[normalizedHashUrl];
                    }

                    return "url(" + imageContentFile + extraInfo + ")";
                });

                return Tuple.Create(cssContent, (IEnumerable <ContentItem>)hashedContentItems);
            }));
        }
        /// <summary>
        /// Gets or creates value according default cache behavior <see cref="CacheSettings{TValue}.Default"/>.
        /// </summary>
        /// <typeparam name="TValue">Value type.</typeparam>
        /// <param name="sectionName">Section name.</param>
        /// <param name="key">Cache key.</param>
        /// <param name="factory">Factory method to create and customize cache item.</param>
        /// <returns><see cref="CacheResult{TValue}"/>.</returns>
        public async Task <CacheResult <TValue> > GetOrCreateAsync <TValue>(string sectionName, string key, Func <ICacheEntryContext, Task <TValue> > factory)
        {
            ICacheSection <TValue> cacheSection = GetOrCreateSection(sectionName, CacheSettings <TValue> .Default);

            return(await cacheSection.GetOrCreateAsync(key, factory));
        }
        /// <summary>
        /// Gets or creates cache section by provided settings.
        /// </summary>
        /// <typeparam name="TValue">Value type.</typeparam>
        /// <param name="sectionDescriptor">CacheSectionDescriptor.</param>
        /// <returns>Cache section.</returns>
        public ICacheSection <TValue> GetOrCreateSection <TValue>(ICacheSectionDescriptor <TValue> sectionDescriptor)
        {
            ICacheSection cacheSection = _sections.GetOrAdd(sectionDescriptor.SectionName, sectionName => CreateCacheSection(sectionName, sectionDescriptor.CacheSettings));

            return((ICacheSection <TValue>)cacheSection);
        }
Ejemplo n.º 20
0
        /// <summary>Begins the section, create a new section and returns it.</summary>
        /// <param name="context">The context.</param>
        /// <param name="cacheCategory">The cache category.</param>
        /// <param name="uniqueKey">The unique Key.</param>
        /// <param name="parentCacheSection">The parent cache section.</param>
        /// <param name="autoLoad">The auto Load.</param>
        /// <returns>The <see cref="CacheSection"/>.</returns>
        public static CacheSection Begin(IWebGreaseContext context, string cacheCategory, string uniqueKey, ICacheSection parentCacheSection = null, bool autoLoad = true)
        {
            var cacheSection = new CacheSection
            {
                parent        = parentCacheSection as CacheSection,
                cacheCategory = cacheCategory,
                context       = context,
                UniqueKey     = uniqueKey
            };

            cacheSection.absolutePath = context.Cache.GetAbsoluteCacheFilePath(cacheSection.cacheCategory, context.GetValueHash(cacheSection.UniqueKey) + ".cache.json");

            if (cacheSection.parent != null)
            {
                cacheSection.parent.AddChildCacheSection(cacheSection);
            }

            EnsureCachePath(context, cacheCategory);

            if (autoLoad)
            {
                cacheSection.Load();
            }

            return(cacheSection);
        }
Ejemplo n.º 21
0
        /// <summary>Sets the import source dependencies.</summary>
        /// <param name="fileContent">The file content.</param>
        /// <param name="workingFolder">The working folder.</param>
        /// <param name="cacheSection">The cache section.</param>
        private static void SetImportSourceDependencies(string fileContent, string workingFolder, ICacheSection cacheSection)
        {
            var matches = ImportPattern.Matches(fileContent);

            foreach (Match match in matches)
            {
                var path = Path.Combine(workingFolder, match.Groups["path"].Value);
                var fi   = new FileInfo(path);
                cacheSection.AddSourceDependency(path);
                if (fi.Exists)
                {
                    SetImportSourceDependencies(File.ReadAllText(fi.FullName), fi.DirectoryName, cacheSection);
                }
            }
        }
        /// <summary>
        /// Gets or creates cache section by provided settings.
        /// </summary>
        /// <typeparam name="TValue">Value type.</typeparam>
        /// <param name="sectionName">Section name.</param>
        /// <param name="cacheSettings">Cache settings.</param>
        /// <returns>Cache section.</returns>
        public ICacheSection <TValue> GetOrCreateSection <TValue>(string sectionName, ICacheSettings <TValue> cacheSettings)
        {
            ICacheSection cacheSection = _sections.GetOrAdd(sectionName, name => CreateCacheSection(name, cacheSettings));

            return((ICacheSection <TValue>)cacheSection);
        }
Ejemplo n.º 23
0
        /// <summary>Initializes a new instance of the <see cref="WebGreaseContext"/> class. The web grease context.</summary>
        /// <param name="configuration">The configuration</param>
        /// <param name="logManager">The log Manager.</param>
        /// <param name="parentCacheSection">The parent Cache Section.</param>
        /// <param name="preprocessingManager">The preprocessing Manager.</param>
        public WebGreaseContext(WebGreaseConfiguration configuration, LogManager logManager, ICacheSection parentCacheSection = null, PreprocessingManager preprocessingManager = null)
        {
            var runStartTime = DateTimeOffset.Now;

            configuration.Validate();
            var timeMeasure  = configuration.Measure ? new TimeMeasure() as ITimeMeasure : new NullTimeMeasure();
            var cacheManager = configuration.CacheEnabled ? new CacheManager(configuration, logManager, parentCacheSection) as ICacheManager : new NullCacheManager();

            this.Initialize(
                configuration,
                logManager,
                cacheManager,
                preprocessingManager != null ? new PreprocessingManager(preprocessingManager) : new PreprocessingManager(configuration, logManager, timeMeasure),
                runStartTime,
                timeMeasure);
        }
Ejemplo n.º 24
0
 /// <summary>Ends the cache section.</summary>
 /// <param name="cacheSection">The cache section.</param>
 public void EndSection(ICacheSection cacheSection)
 {
 }