Click here to Skip to main content
15,895,084 members
Articles / Web Development / ASP.NET

Web User Forms for ASP.NET

Rate me:
Please Sign up or sign in to vote.
4.90/5 (52 votes)
18 Sep 2012CPOL12 min read 135.6K   4.5K   187  
User driven runtime dynamic ASP.NET Web Forms
// -- FILE ------------------------------------------------------------------
// name       : IVariableSet.cs
// project    : Itenso Web User Forms
// created    : Jani Giannoudis - 2008.10.30
// language   : c#
// environment: .NET 2.0
// copyright  : (c) 2008-2012 by Itenso GmbH, Switzerland
// --------------------------------------------------------------------------
using System;
using System.Text;
using System.Reflection;
using System.Globalization;
using System.Collections.Generic;

namespace Itenso.WebUserForms.Data.Variable
{

	// ------------------------------------------------------------------------
	public enum ObjectMappingMode
	{
		AnyValue,
		DefinedValue,
	} // enum ObjectMappingMode

	// ------------------------------------------------------------------------
	public sealed class VariableSet : IVariableSet
	{

		// ----------------------------------------------------------------------
		public int Count
		{
			get { return contentMap.Count; }
		} // Count

		// ----------------------------------------------------------------------
		public IEnumerable<string> VariableNames
		{
			get { return contentMap.Keys; }
		} // VariableNames

		// ----------------------------------------------------------------------
		public string this[ string variableName ]
		{
			get { return contentMap[ variableName ]; }
		} // this[]

		// ----------------------------------------------------------------------
		public string GetVariableContent( string variableName )
		{
			return contentMap.ContainsKey( variableName ) ? contentMap[ variableName ] : null;
		} // GetVariableContent

		// ----------------------------------------------------------------------
		public void MapContentToVariable( string variableName, string content )
		{
			if ( string.IsNullOrEmpty( variableName ) )
			{
				throw new ArgumentNullException( "variableName" );
			}
			if ( content == null )
			{
				throw new ArgumentNullException( "content" );
			}

			if ( contentMap.ContainsKey( variableName ) )
			{
				contentMap[ variableName ] = content;
			}
			else
			{
				contentMap.Add( variableName, content );
			}
		} // MapContentToVariable

		// ----------------------------------------------------------------------
		public void MapObjectPropertiesToVariables( object variableObject )
		{
			MapObjectPropertiesToVariables( variableObject, ObjectMappingMode.AnyValue );
		} // MapObjectPropertiesToVariables

		// ----------------------------------------------------------------------
		public void MapObjectPropertiesToVariables( object variableObject, ObjectMappingMode objectMappingMode )
		{
			if ( variableObject == null )
			{
				throw new ArgumentNullException( "variableObject" );
			}

			PropertyInfo[] propertyInfos = variableObject.GetType().GetProperties(
				BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic );
			foreach ( PropertyInfo propertyInfo in propertyInfos )
			{
				if ( propertyInfo.PropertyType.BaseType == null )
				{
					continue; // do not allow classes and interfaces
				}

				object variableValue = propertyInfo.GetValue( variableObject, null );
				if ( objectMappingMode == ObjectMappingMode.DefinedValue && variableValue == null )
				{
					continue;
				}

				if ( variableValue == null )
				{
					variableValue = string.Empty;
				}
				MapContentToVariable( propertyInfo.Name, variableValue.ToString() );
			}
		} // MapObjectPropertiesToVariables

		// ----------------------------------------------------------------------
		public void RemoveVariable( string variableName )
		{
			if ( string.IsNullOrEmpty( variableName ) )
			{
				throw new ArgumentNullException( "variableName" );
			}
			contentMap.Remove( variableName );
		} // RemoveVariable

		// ----------------------------------------------------------------------
		public string Expand( string textToExpand )
		{
			StringBuilder output = new StringBuilder();
			ExpandVariablesRecursive( textToExpand, startDelimiter, endDelimiter, new Stack<string>(), output );
			return output.ToString();
		} // Expand

		// ----------------------------------------------------------------------
		public void Clear()
		{
			contentMap.Clear();
		} // Clear

		// ----------------------------------------------------------------------
		public void CopyTo( IVariableSet destination )
		{
			CopyTo( destination, null );
		} // CopyTo

		// ----------------------------------------------------------------------
		public void CopyTo( IVariableSet destination, string nameFormat )
		{
			if ( destination == null )
			{
				throw new ArgumentNullException( "destination" );
			}

			foreach ( string variableName in VariableNames )
			{
				string destinationVariableName = variableName;
				if ( !string.IsNullOrEmpty( nameFormat ) )
				{
					destinationVariableName = string.Format(
						CultureInfo.InvariantCulture,
						nameFormat,
						destinationVariableName );
				}
				destination.MapContentToVariable( destinationVariableName, this[ variableName ] );
			}
		} // CopyTo

		// ----------------------------------------------------------------------
		private void ExpandVariablesRecursive(
			string textToExpand,
			string variablePrefix,
			string variablePostfix,
			Stack<string> replacementStack,
			StringBuilder output
		)
		{
			if ( !string.IsNullOrEmpty( textToExpand ) )
			{
				int remainderBegin = 0;
				int totalLen = textToExpand.Length;
				int varPrefixLen = variablePrefix.Length;
				int varStartPos = textToExpand.IndexOf( variablePrefix, StringComparison.Ordinal );
				while ( varStartPos >= remainderBegin )
				{
					if ( remainderBegin < varStartPos )
					{
						output.Append( textToExpand.Substring( remainderBegin, varStartPos - remainderBegin ) );
						remainderBegin = varStartPos;
					}
					int varNameBegin = varStartPos + varPrefixLen;
					int varEndPos = textToExpand.IndexOf( variablePostfix, varNameBegin, StringComparison.Ordinal );
					int nextSearchBegin = varEndPos + variablePostfix.Length;
					if ( varEndPos >= varNameBegin )
					{
						int varNameLen = varEndPos - varNameBegin;
						string variableName = textToExpand.Substring( varNameBegin, varNameLen );
						string replacement = GetVariableContent( variableName );
						if ( replacement != null )
						{
							if ( replacementStack.Contains( variableName ) )
							{
							}
							else
							{
								replacementStack.Push( variableName );
								ExpandVariablesRecursive( replacement, variablePrefix, variablePostfix, replacementStack, output );
								replacementStack.Pop();
								remainderBegin = nextSearchBegin;
							}
						}
						else
						{
							nextSearchBegin = varStartPos + 1;
						}
					}
					else
					{
						break;
					}
					varStartPos = textToExpand.IndexOf( variablePrefix, nextSearchBegin, StringComparison.Ordinal );
				}
				if ( remainderBegin < totalLen )
				{
					output.Append( textToExpand.Substring( remainderBegin ) );
				}
			}
		} // ExpandVariablesRecursive

		// ----------------------------------------------------------------------
		// members
		private readonly SortedDictionary<string, string> contentMap = new SortedDictionary<string, string>();

		private const string startDelimiter = "${";
		private const string endDelimiter = "}";

	} // class VariableSet

} // namespace Itenso.WebUserForms.Data.Variable
// -- EOF -------------------------------------------------------------------

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior)
Switzerland Switzerland
👨 Senior .NET Software Engineer

🚀 My Open Source Projects
- Time Period Library 👉 GitHub
- Payroll Engine 👉 GitHub

Feedback and contributions are welcome.



Comments and Discussions