/SoftwareRockstar.Texticize/SubstitutionProcessors/VocabularySubstitutionProcessor.cs

http://texticize.codeplex.com · C# · 173 lines · 118 code · 22 blank · 33 comment · 13 complexity · fc45b34f8dfbe184261ed16bf2c8d2b9 MD5 · raw file

  1. //-----------------------------------------------------------------------
  2. // <copyright author="Muhammad Haroon">
  3. // Texticize
  4. // Codeplex Project: http://texticize.codeplex.com/
  5. // Copyright (c) Muhammad Haroon, http://www.softwarerockstar.com/
  6. // Released under Apache License Version 2.0, http://www.apache.org/licenses/
  7. // </copyright>
  8. //-----------------------------------------------------------------------
  9. using System;
  10. using System.Collections.Generic;
  11. using System.ComponentModel.Composition;
  12. using System.Linq;
  13. using System.Text.RegularExpressions;
  14. using SoftwareRockstar.ComponentModel.Extensibility;
  15. using System.Collections;
  16. namespace SoftwareRockstar.Texticize.SubstitutionProcessors
  17. {
  18. [Export(typeof(ISubstitutionProcessor))]
  19. [ExportMetadata(UniquenessEvidenceFields.UniqueName, SystemSubstitutionProcessorNames.Vocabulary)]
  20. class VocabularySubstitutionProcessor : ISubstitutionProcessor
  21. {
  22. public ProcessorOutput Process(ProcessorInput input)
  23. {
  24. Logger.LogMethodStartup();
  25. ProcessorOutput output = new ProcessorOutput();
  26. if (input != null)
  27. {
  28. try
  29. {
  30. // Process regular vocabulary with provided maps
  31. Logger.LogInfo("Processing Maps");
  32. output.Combine(ProcessMaps(input));
  33. // If no mpas specified but a default variable is specified then see if default variable is a
  34. // dictionary and then perform dictionary subsitutions
  35. if (input.Maps.Count == 0 && input.Variables.ContainsKey(input.Configuration.DefaultVariableKey))
  36. {
  37. if (output.IsSuccess || input.Configuration.ContinueOnError)
  38. {
  39. input.Target = output.Result;
  40. Logger.LogInfo("Processing Default Variables");
  41. output.Combine(ProcessDefaultVariableDictionary(input));
  42. }
  43. }
  44. }
  45. catch (ApplicationException ex)
  46. {
  47. Logger.LogError(ex);
  48. output.Exceptions.Add(ex);
  49. }
  50. }
  51. Logger.LogMethodEnd();
  52. return output;
  53. }
  54. /// <summary>
  55. /// If default variable is an IDictionary performs subsitutions based on it's keys and values.
  56. /// </summary>
  57. /// <param name="input">The input.</param>
  58. /// <returns></returns>
  59. protected ProcessorOutput ProcessDefaultVariableDictionary(ProcessorInput input)
  60. {
  61. ProcessorOutput output = new ProcessorOutput();
  62. try
  63. {
  64. output.Result = input.Target;
  65. var dictionary = input.Variables[input.Configuration.DefaultVariableKey] as IDictionary;
  66. if (dictionary != null)
  67. foreach (DictionaryEntry item in dictionary)
  68. output.Result = output.Result.Replace(
  69. input.Configuration.PlaceHolderBegin + item.Key.ToString() + input.Configuration.PlaceHolderEnd,
  70. item.Value.ToString());
  71. }
  72. catch (ApplicationException ex)
  73. {
  74. output.Exceptions.Add(ex);
  75. }
  76. return output;
  77. }
  78. /// <summary>
  79. /// Iterates through provided maps and processes the template performing substitutions specified by maps.
  80. /// </summary>
  81. /// <returns>String result.</returns>
  82. protected ProcessorOutput ProcessMaps(ProcessorInput input)
  83. {
  84. ProcessorOutput output = new ProcessorOutput();
  85. output.Result = input.Target;
  86. try
  87. {
  88. foreach (var map in input.Maps)
  89. {
  90. // Escape begin and end tokens
  91. string placeHolderBegin = Regex.Escape(input.Configuration.PlaceHolderBegin);
  92. string placeHolderEnd = Regex.Escape(input.Configuration.PlaceHolderEnd);
  93. // Generate pattern based on mapy's key and begin and end tokens
  94. string originalPattern = placeHolderBegin + Regex.Escape(map.Key) + placeHolderEnd;
  95. // Insert parameters pattern into generated pattern
  96. string parameterPattern = input.Configuration.TemplateRegexPatternFormatted;
  97. string pattern = originalPattern.Insert(originalPattern.Length - placeHolderEnd.Length, parameterPattern);
  98. Regex regex = new Regex(pattern, input.Configuration.TemplateRegexOptions);
  99. // Get all regex matches in template
  100. var matches = regex.Matches(output.Result);
  101. // Process each match...
  102. for (int j = 0; j < matches.Count; j++)
  103. {
  104. var match = matches[j];
  105. // Process each group in the match...
  106. if (match.Success && match.Groups.Count > 0 && match.Groups.Count > 1)
  107. {
  108. // Determine variable name
  109. string varName = (map.Key.Contains(input.Configuration.PropertySeperator)) ?
  110. map.Key.Substring(0, map.Key.IndexOf(input.Configuration.PropertySeperator)) :
  111. input.Variables.ContainsKey(input.Configuration.DefaultVariableKey) ?
  112. input.Configuration.DefaultVariableKey :
  113. input.Configuration.NoVariableName;
  114. // Determine expression found in template to be replaced
  115. string expression = (map.Key.Contains(input.Configuration.PropertySeperator)) ?
  116. expression = String.Format("{0}{1}",
  117. map.Key.Substring(0, 1),
  118. map.Key.Substring(map.Key.IndexOf(input.Configuration.PropertySeperator) + 1)) :
  119. match.Value;
  120. // Determine parameters within expression
  121. Dictionary<string, string> parameterDictionary =
  122. (match.Groups.Count > 1) ?
  123. match.Groups[input.Configuration.TemplateRegexParamInternalGroupName]
  124. .ToParameterDictionary(input.Configuration.ParameterSeperatorChar) :
  125. new Dictionary<string, string>();
  126. // Determine target variable
  127. object target = (input.Variables.ContainsKey(varName)) ?
  128. input.Variables[varName] :
  129. new System.Object();
  130. // Create context to be sent to delegate that will provide replacement value
  131. IContext context = CachedContext.GetContext(
  132. variable: target,
  133. variableName: varName,
  134. expression: expression,
  135. parameters: parameterDictionary);
  136. // Get substitute value
  137. var substitute = map.Value.DynamicInvoke(context).ToString();
  138. // Make replacement in template
  139. output.Result = output.Result.Replace(match.Value, substitute);
  140. }
  141. }
  142. }
  143. }
  144. catch (ApplicationException ex)
  145. {
  146. output.Exceptions.Add(ex);
  147. }
  148. return output;
  149. }
  150. }
  151. }