fbdegroot
7/6/2011 - 3:25 PM

SqlResourceProvider

SqlResourceProvider

using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Globalization;
using System.Resources;
using System.Web;
using System.Web.Compilation;
using System.Linq;
using System.Web.Mvc;

namespace MvcApplication1
{
	public static class Helpers
	{
		public static string Resource(this HtmlHelper htmlhelper, string expression, params object[] args)
		{
			string virtualPath = GetVirtualPath(htmlhelper);
			return GetResourceString(htmlhelper.ViewContext.HttpContext, expression, virtualPath, args);
		}

		public static string Resource(this Controller controller, string expression, params object[] args)
		{
			return GetResourceString(controller.HttpContext, expression, "~/", args);
		}

		private static string GetResourceString(HttpContextBase httpContext, string expression, string virtualPath, object[] args)
		{
			var identity = SqlResourceProvider.GetClassKey(expression);
			if (identity.ClassKey != null)
				return string.Format((string)httpContext.GetGlobalResourceObject(identity.ClassKey, identity.ResourceKey, CultureInfo.CurrentUICulture), args);

			return string.Format((string)httpContext.GetLocalResourceObject(virtualPath, identity.ResourceKey, CultureInfo.CurrentUICulture), args);
		}

		private static string GetVirtualPath(HtmlHelper htmlhelper)
		{
			RazorView view = htmlhelper.ViewContext.View as RazorView;

			if (view != null)
				return view.ViewPath;

			return null;
		}
	}

	public class SqlResourceProviderFactory : ResourceProviderFactory
	{
		public override IResourceProvider CreateGlobalResourceProvider(string className)
		{
			return new SqlResourceProvider(className);
		}

		public override IResourceProvider CreateLocalResourceProvider(string virtualPath)
		{
			return new SqlResourceProvider(virtualPath);
		}
	}

	internal class SqlResourceProvider : IResourceProvider
	{
		string nameSpace;

		public SqlResourceProvider(string nameSpace)
		{
			this.nameSpace = nameSpace;

			System.Web.HttpContext.Current.Cache["nl"] = new Dictionary<string, string> {
				{ "Something", "NL" }
			};

			System.Web.HttpContext.Current.Cache["en"] = new Dictionary<string, string> {
				{ "Something", "EN" }
			};

			System.Web.HttpContext.Current.Cache["en-US"] = new Dictionary<string, string> {
				{ "Something", "EN-US" }
			};
		}

		private IDictionary GetResourceCache(string cultureName)
		{
			return (IDictionary)System.Web.HttpContext.Current.Cache[cultureName];
		}

		object IResourceProvider.GetObject(string resourceKey, CultureInfo culture)
		{
			var resource = GetResourceCache(CultureInfo.CurrentUICulture.Name);
			return resource[resourceKey];
		}

		IResourceReader IResourceProvider.ResourceReader
		{
			get
			{
				string cultureName = null;
				CultureInfo currentUICulture = CultureInfo.CurrentUICulture;
				if (!String.Equals(currentUICulture.Name,
					CultureInfo.InstalledUICulture.Name)) {
					cultureName = currentUICulture.Name;
				}

				return new SqlResourceReader(GetResourceCache(cultureName));
			}
		}

		public static SqlResourceIdentity GetClassKey(string expression)
		{
		    if (expression == null)
		        throw new ArgumentNullException("expression");

		    var parts = expression.Split(new[] { ',', ' ' }, StringSplitOptions.RemoveEmptyEntries);
			switch(parts.Count())
			{
				case 1:
					return new SqlResourceIdentity {
						ResourceKey = parts[0]
					};
				case 2:
					return new SqlResourceIdentity {
						ClassKey = parts[0],
						ResourceKey = parts[1]
					};
				default:
					throw new InvalidExpressionException(string.Format("\"{0}\" is not a valid SqlResourceExpression", expression));
			}
		}
	}

	public class SqlResourceIdentity
	{
		public string ClassKey { get; set; }
		public string ResourceKey { get; set; }
	}

	internal sealed class SqlResourceReader : IResourceReader
	{
		private IDictionary _resources;

		public SqlResourceReader(IDictionary resources)
		{
			_resources = resources;
		}

		IDictionaryEnumerator IResourceReader.GetEnumerator()
		{
			return _resources.GetEnumerator();
		}

		void IResourceReader.Close() { }

		IEnumerator IEnumerable.GetEnumerator()
		{
			return _resources.GetEnumerator();
		}

		void IDisposable.Dispose() { return; }
	}
}