Files
linux-packaging-mono/external/aspnetwebstack/src/Microsoft.Web.Helpers/Themes.cs
Jo Shields a575963da9 Imported Upstream version 3.6.0
Former-commit-id: da6be194a6b1221998fc28233f2503bd61dd9d14
2014-08-13 10:39:27 +01:00

286 lines
9.4 KiB
C#

// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Web.Hosting;
using System.Web.WebPages.Scope;
using Microsoft.Internal.Web.Utils;
using Resources;
namespace Microsoft.Web.Helpers
{
public static class Themes
{
public static string ThemeDirectory
{
get { return Implementation.ThemeDirectory; }
}
public static string CurrentTheme
{
get { return Implementation.CurrentTheme; }
set { Implementation.CurrentTheme = value; }
}
public static string DefaultTheme
{
get { return Implementation.DefaultTheme; }
}
public static ReadOnlyCollection<string> AvailableThemes
{
get { return Implementation.AvailableThemes; }
}
private static ThemesImplementation Implementation
{
get { return new ThemesImplementation(HostingEnvironment.VirtualPathProvider, ScopeStorage.CurrentScope); }
}
public static void Initialize(string themeDirectory, string defaultTheme)
{
Implementation.Initialize(themeDirectory, defaultTheme);
}
/// <summary>
/// Get a file that lives directly inside the theme directory
/// </summary>
/// <param name="fileName">The filename to look for</param>
/// <returns>The full path to the file that matches the requested file</returns>
public static string GetResourcePath(string fileName)
{
return Implementation.GetResourcePath(fileName);
}
public static string GetResourcePath(string folder, string fileName)
{
return Implementation.GetResourcePath(folder, fileName);
}
}
internal class ThemesImplementation
{
internal static readonly object CurrentThemeKey = new object();
internal static readonly object ThemeDirectoryKey = new object();
internal static readonly object DefaultThemeKey = new object();
internal static readonly object ThemesInitializedKey = new object();
private readonly VirtualPathProvider _vpp;
private readonly IDictionary<object, object> _currentScope;
public ThemesImplementation(VirtualPathProvider vpp, IDictionary<object, object> scopeStorage)
{
_vpp = vpp;
_currentScope = scopeStorage;
}
public string ThemeDirectory
{
get
{
EnsureInitialized();
return (string)_currentScope[ThemeDirectoryKey];
}
private set
{
Debug.Assert(value != null);
_currentScope[ThemeDirectoryKey] = value;
}
}
/// <summary>
/// This should live throughout the application life cycle
/// and be set in _appstart.cshtml
/// </summary>
public string DefaultTheme
{
get
{
EnsureInitialized();
return (string)_currentScope[DefaultThemeKey];
}
private set
{
Debug.Assert(value != null);
_currentScope[DefaultThemeKey] = value;
}
}
/// <summary>
/// The current theme to use. When this is set,
/// all GetResource checks will check if the CurrentTheme
/// contains the file, and if it doesn't it will fall back to
/// the DefaultTheme
/// </summary>
public string CurrentTheme
{
get
{
EnsureInitialized();
return (string)_currentScope[CurrentThemeKey] ?? DefaultTheme;
}
set
{
if (String.IsNullOrEmpty(value))
{
throw new ArgumentException(CommonResources.Argument_Cannot_Be_Null_Or_Empty, "value");
}
// EnsureValidTheme would verify if themes have been correctly initialized and that the value specified is a valid theme.
if (!IsValidTheme(AvailableThemes, value))
{
throw new ArgumentException(String.Format(CultureInfo.CurrentCulture, HelpersToolkitResources.Themes_InvalidTheme, value), "value");
}
_currentScope[CurrentThemeKey] = value;
}
}
public ReadOnlyCollection<string> AvailableThemes
{
get
{
EnsureInitialized();
return GetAvailableThemes(ThemeDirectory);
}
}
private string CurrentThemePath
{
get { return Path.Combine(ThemeDirectory, CurrentTheme); }
}
private string DefaultThemePath
{
get { return Path.Combine(ThemeDirectory, DefaultTheme); }
}
private bool ThemesInitialized
{
get
{
bool? value = (bool?)_currentScope[ThemesInitializedKey];
return value != null && value.Value;
}
set { _currentScope[ThemesInitializedKey] = value; }
}
public void Initialize(string themeDirectory, string defaultTheme)
{
if (String.IsNullOrEmpty(themeDirectory))
{
throw new ArgumentException(CommonResources.Argument_Cannot_Be_Null_Or_Empty, "themeDirectory");
}
if (String.IsNullOrEmpty(defaultTheme))
{
throw new ArgumentException(CommonResources.Argument_Cannot_Be_Null_Or_Empty, "defaultTheme");
}
var availableThemes = GetAvailableThemes(themeDirectory);
if (!IsValidTheme(availableThemes, defaultTheme))
{
throw new ArgumentException(String.Format(CultureInfo.CurrentCulture, HelpersToolkitResources.Themes_InvalidTheme, defaultTheme), "defaultTheme");
}
ThemeDirectory = themeDirectory;
DefaultTheme = defaultTheme;
ThemesInitialized = true;
}
/// <summary>
/// Get a file that lives directly inside the theme directory
/// </summary>
/// <param name="fileName">The filename to look for</param>
/// <returns>The full path to the file that matches the requested file</returns>
public string GetResourcePath(string fileName)
{
return GetResourcePath(String.Empty, fileName);
}
public string GetResourcePath(string folder, string fileName)
{
EnsureInitialized();
if (folder == null)
{
throw new ArgumentNullException("folder", HelpersToolkitResources.Themes_FolderCannotBeNull);
}
if (String.IsNullOrEmpty(fileName))
{
throw new ArgumentException(CommonResources.Argument_Cannot_Be_Null_Or_Empty, "fileName");
}
return FindMatchingFile(Path.Combine(CurrentThemePath, folder), fileName) ??
FindMatchingFile(Path.Combine(DefaultThemePath, folder), fileName);
}
/// <summary>
/// Try and find a file in the specified folder that matches name.
/// </summary>
/// <returns>The full path to the file that matches the requested file
/// or null if no matching file is found</returns>
internal string FindMatchingFile(string folder, string name)
{
Debug.Assert(!String.IsNullOrEmpty(folder));
Debug.Assert(!String.IsNullOrEmpty(name));
// Get the virtual path information
VirtualDirectory directory = _vpp.GetDirectory(folder);
// If the folder specified doesn't exist
// or it doesn't contain any files
if (directory == null || directory.Files == null)
{
return null;
}
// Go through every file in the directory
foreach (VirtualFile file in directory.Files)
{
string path = file.VirtualPath;
// Compare the filename to the filename that we passed
if (Path.GetFileName(path).Equals(name, StringComparison.OrdinalIgnoreCase))
{
return path;
}
}
// If no matching files, return null
return null;
}
private ReadOnlyCollection<string> GetAvailableThemes(string themesRoot)
{
VirtualDirectory directory = _vpp.GetDirectory(themesRoot);
var themes = new List<string>();
// Go through every file in the directory
foreach (VirtualDirectory dir in directory.Directories)
{
themes.Add(dir.Name);
}
return themes.AsReadOnly();
}
private void EnsureInitialized()
{
if (!ThemesInitialized)
{
throw new InvalidOperationException(HelpersToolkitResources.Themes_NotInitialized);
}
}
private static bool IsValidTheme(IEnumerable<string> availableThemes, string theme)
{
return availableThemes.Contains(theme, StringComparer.OrdinalIgnoreCase);
}
}
}