namespace Caliburn.Micro.Core { using System; using System.Collections.Generic; using System.Linq; using System.Text.RegularExpressions; /// /// Class for managing the list of rules for doing name transformation. /// public class NameTransformer : BindableCollection { #if NET private const RegexOptions options = RegexOptions.Compiled; #else private const RegexOptions options = RegexOptions.None; #endif bool useEagerRuleSelection = true; /// /// Flag to indicate if transformations from all matched rules are returned. Otherwise, transformations from only the first matched rule are returned. /// public bool UseEagerRuleSelection { get { return useEagerRuleSelection; } set { useEagerRuleSelection = value; } } /// /// Adds a transform using a single replacement value and a global filter pattern. /// /// Regular expression pattern for replacing text /// The replacement value. /// Regular expression pattern for global filtering public void AddRule(string replacePattern, string replaceValue, string globalFilterPattern = null) { AddRule(replacePattern, new[] { replaceValue }, globalFilterPattern); } /// /// Adds a transform using a list of replacement values and a global filter pattern. /// /// Regular expression pattern for replacing text /// The list of replacement values /// Regular expression pattern for global filtering public void AddRule(string replacePattern, IEnumerable replaceValueList, string globalFilterPattern = null) { Add(new Rule { ReplacePattern = replacePattern, ReplacementValues = replaceValueList, GlobalFilterPattern = globalFilterPattern }); } /// /// Gets the list of transformations for a given name. /// /// The name to transform into the resolved name list /// The transformed names. public IEnumerable Transform(string source) { return Transform(source, r => r); } /// /// Gets the list of transformations for a given name. /// /// The name to transform into the resolved name list /// A function to do a transform on each item in the ReplaceValueList prior to applying the regular expression transform /// The transformed names. public IEnumerable Transform(string source, Func getReplaceString) { var nameList = new List(); var rules = this.Reverse(); foreach(var rule in rules) { if(!string.IsNullOrEmpty(rule.GlobalFilterPattern) && !rule.GlobalFilterPatternRegex.IsMatch(source)) { continue; } if(!rule.ReplacePatternRegex.IsMatch(source)) { continue; } nameList.AddRange( rule.ReplacementValues .Select(getReplaceString) .Select(repString => rule.ReplacePatternRegex.Replace(source, repString)) ); if (!useEagerRuleSelection) { break; } } return nameList; } /// /// A rule that describes a name transform. /// public class Rule { private Regex replacePatternRegex; private Regex globalFilterPatternRegex; /// /// Regular expression pattern for global filtering /// public string GlobalFilterPattern; /// /// Regular expression pattern for replacing text /// public string ReplacePattern; /// /// The list of replacement values /// public IEnumerable ReplacementValues; /// /// Regular expression for global filtering /// public Regex GlobalFilterPatternRegex { get { return globalFilterPatternRegex ?? (globalFilterPatternRegex = new Regex(GlobalFilterPattern, options)); } } /// /// Regular expression for replacing text /// public Regex ReplacePatternRegex { get { return replacePatternRegex ?? (replacePatternRegex = new Regex(ReplacePattern, options)); } } } } }