// -- 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 -------------------------------------------------------------------