Example #1
0
        private void AddThemeManifestInternal(ThemeManifest manifest, bool isInit)
        {
            Guard.ArgumentNotNull(() => manifest);

            if (!isInit)
            {
                TryRemoveManifest(manifest.ThemeName);
            }

            ThemeManifest baseManifest = null;

            if (manifest.BaseThemeName != null)
            {
                if (!_themes.TryGetValue(manifest.BaseThemeName, out baseManifest))
                {
                    manifest.State = ThemeManifestState.MissingBaseTheme;
                }
            }

            manifest.BaseTheme = baseManifest;
            var added = _themes.TryAdd(manifest.ThemeName, manifest);

            if (added && !isInit)
            {
                // post process
                var children = GetChildrenOf(manifest.ThemeName, false);
                foreach (var child in children)
                {
                    child.BaseTheme = manifest;
                    child.State     = ThemeManifestState.Active;
                }
            }
        }
Example #2
0
 protected override void OnDispose(bool disposing)
 {
     if (disposing)
     {
         this.Manifest = null;
     }
 }
Example #3
0
        public void ReloadThemes()
        {
            _themes.Clear();

            var folder      = EngineContext.Current.Resolve <IWebSiteFolder>();
            var folderDatas = new List <ThemeFolderData>();
            var dirs        = folder.ListDirectories(_themesBasePath);

            // create folder (meta)datas first
            foreach (var path in dirs)
            {
                try
                {
                    var folderData = ThemeManifest.CreateThemeFolderData(CommonHelper.MapPath(path), _themesBasePath);
                    if (folderData != null)
                    {
                        folderDatas.Add(folderData);
                    }
                }
                catch (Exception ex)
                {
                    Debug.WriteLine("ERR - unable to create folder data for folder '{0}': {1}".FormatCurrent(path, ex.Message));
                }
            }

            // perform topological sort (BaseThemes first...)
            IEnumerable <ThemeFolderData> sortedThemeFolders;

            try
            {
                sortedThemeFolders = folderDatas.ToArray().SortTopological(StringComparer.OrdinalIgnoreCase).Cast <ThemeFolderData>();
            }
            catch (CyclicDependencyException)
            {
                throw new CyclicDependencyException("Cyclic theme dependencies detected. Please check the 'baseTheme' attribute of your themes and ensure that they do not reference themselves (in)directly.");
            }
            catch
            {
                throw;
            }

            // create theme manifests
            foreach (var themeFolder in sortedThemeFolders)
            {
                try
                {
                    var manifest = ThemeManifest.Create(themeFolder);
                    if (manifest != null)
                    {
                        AddThemeManifestInternal(manifest, true);
                    }
                }
                catch (Exception ex)
                {
                    Debug.WriteLine("ERR - unable to create manifest for theme '{0}': {1}".FormatCurrent(themeFolder.FolderName, ex.Message));
                }
            }
        }
Example #4
0
        public ThemeManifestMaterializer(ThemeFolderData folderData)
        {
            Guard.ArgumentNotNull(() => folderData);

            _manifest = new ThemeManifest();

            _manifest.ThemeName         = folderData.FolderName;
            _manifest.BaseThemeName     = folderData.BaseTheme;
            _manifest.Location          = folderData.VirtualBasePath;
            _manifest.Path              = folderData.FullPath;
            _manifest.ConfigurationNode = folderData.Configuration.DocumentElement;
        }
Example #5
0
        private void OnThemeFileChanged(string name, string fullPath, ThemeFileChangeType changeType)
        {
            // Enable event throttling by allowing the very same event to be published only all 500 ms.
            var throttleKey = new EventThrottleKey(name, changeType);

            if (ShouldThrottleEvent(throttleKey))
            {
                return;
            }

            if (!_fileFilterPattern.IsMatch(Path.GetExtension(name)))
            {
                return;
            }

            var idx = name.IndexOf('\\');

            if (idx < 0)
            {
                // must be a subfolder of "~/Themes/"
                return;
            }

            var themeName    = name.Substring(0, idx);
            var relativePath = name.Substring(themeName.Length + 1).Replace('\\', '/');
            var isConfigFile = relativePath.IsCaseInsensitiveEqual("theme.config");

            if (changeType == ThemeFileChangeType.Modified && !isConfigFile)
            {
                // Monitor changes only for root theme.config
                return;
            }

            BaseThemeChangedEventArgs baseThemeChangedArgs = null;

            if (isConfigFile)
            {
                // config file changes always result in refreshing the corresponding theme manifest
                var di = new DirectoryInfo(Path.GetDirectoryName(fullPath));

                string oldBaseThemeName = null;
                var    oldManifest      = this.GetThemeManifest(di.Name);
                if (oldManifest != null)
                {
                    oldBaseThemeName = oldManifest.BaseThemeName;
                }

                try
                {
                    // FS watcher in conjunction with some text editors fires change events twice and locks the file.
                    // Let's wait max. 250 ms till the lock is gone (hopefully).
                    WaitForUnlock(fullPath);

                    var newManifest = ThemeManifest.Create(di.FullName, _themesBasePath);
                    if (newManifest != null)
                    {
                        this.AddThemeManifestInternal(newManifest, false);

                        if (!oldBaseThemeName.IsCaseInsensitiveEqual(newManifest.BaseThemeName))
                        {
                            baseThemeChangedArgs = new BaseThemeChangedEventArgs
                            {
                                ThemeName    = newManifest.ThemeName,
                                BaseTheme    = newManifest.BaseTheme != null ? newManifest.BaseTheme.ThemeName : null,
                                OldBaseTheme = oldBaseThemeName
                            };
                        }

                        Debug.WriteLine("Changed theme manifest for '{0}'".FormatCurrent(name));
                    }
                    else
                    {
                        // something went wrong (most probably no 'theme.config'): remove the manifest
                        TryRemoveManifest(di.Name);
                    }
                }
                catch (Exception ex)
                {
                    TryRemoveManifest(di.Name);
                    Debug.WriteLine("ERR - Could not touch theme manifest '{0}': {1}".FormatCurrent(name, ex.Message));
                }
            }

            if (baseThemeChangedArgs != null)
            {
                RaiseBaseThemeChanged(baseThemeChangedArgs);
            }

            RaiseThemeFileChanged(new ThemeFileChangedEventArgs {
                ChangeType          = changeType,
                FullPath            = fullPath,
                ThemeName           = themeName,
                RelativePath        = relativePath,
                IsConfigurationFile = isConfigFile
            });
        }
Example #6
0
 public void AddThemeManifest(ThemeManifest manifest)
 {
     AddThemeManifestInternal(manifest, false);
 }