/// <summary> /// Extracts for each properties. /// </summary> /// <param name="compoundValueNames">The compound value names.</param> /// <param name="context">The context.</param> /// <param name="maxCount">The max count.</param> /// <returns></returns> private Dictionary <string, string[]> ExtractForEachProperties(string compoundValueNames, PreprocessingContext context, out int maxCount) { maxCount = 0; Dictionary <string, string[]> compoundValues = new Dictionary <string, string[]>(); string[] compoundValueNamesArray = compoundValueNames.Split(','); foreach (string compoundValueName in compoundValueNamesArray) { string compoundValueNameTrimmed = compoundValueName.Trim(); if (!string.IsNullOrEmpty(compoundValueNameTrimmed)) { string compoundValue = ""; PreprocessingProperty compoundProperty = context.Properties[compoundValueNameTrimmed]; if (null != compoundProperty) { compoundValue = ResolveProperties(compoundProperty.Value, context, null); } string[] compoundValuesArray = null; if (!string.IsNullOrEmpty(compoundValue)) { compoundValuesArray = compoundValue.Split(';'); if (compoundValuesArray.Length > maxCount) { maxCount = compoundValuesArray.Length; } } compoundValues.Add(compoundValueNameTrimmed, compoundValuesArray); } } return(compoundValues); }
/// <summary> /// Removes the specified key. /// </summary> /// <param name="key">The key.</param> /// <returns></returns> public bool Remove(string key) { PreprocessingProperty property = this[key]; if (null != property) { return(_properties.Remove(property)); } return(false); }
/// <summary> /// Resolves content that could possibly contain macros /// </summary> /// <param name="context">The preprocessing context.</param> /// <param name="content">The content that could contain macros.</param> /// <exception cref="UndefinedSettingException">Throws this exception if it encounters an undefined setting</exception> /// <returns>the resolved content</returns> public string ResolveContent(PreprocessingContext context, string content) { if (!string.IsNullOrEmpty(content)) { bool isSameTokenUsedForStartAndEnd = context.TokenStart.Equals(context.TokenEnd, StringComparison.OrdinalIgnoreCase); // Look for start of tokens, order depends on type of token used int macroPosition = -1; // Evaluate from back to front if tokens are not equal // this enables nested tokens such as this: ${PROPERTY_${MACHINE}} // Evaluate from front to back if start and end tokens are equal...nested properties with // custom tokens that match is not supported. You can't do this: #PROPERTY_#MACHINE## if (!isSameTokenUsedForStartAndEnd) { macroPosition = content.LastIndexOf(context.TokenStart); } else { macroPosition = content.IndexOf(context.TokenStart); } while (macroPosition > -1) { int endMacroPosition = content.IndexOf(context.TokenEnd, macroPosition + context.TokenStart.Length); string macro = content.Substring(macroPosition, endMacroPosition - macroPosition + 1); string key = macro.Substring(context.TokenStart.Length, macro.Length - (context.TokenStart.Length + context.TokenEnd.Length)).Trim(); PreprocessingProperty property = this[key]; if (null == property) { throw new UndefinedSettingException(string.Format("{0} was not defined", key), key); } string val = property.Value; content = content.Replace(macro, val); if (!isSameTokenUsedForStartAndEnd) { macroPosition = content.LastIndexOf(context.TokenStart); } else { macroPosition = content.IndexOf(context.TokenStart); } } } return(content); }
/// <summary> /// Dumps the environment names from the data source to the console. /// </summary> /// <param name="context">The preprocessing context.</param> /// <returns></returns> private static int DumpEnvironments(PreprocessingContext context) { int exitCode = 0; try { DataSource firstDataSource = context.DataSources[0]; SettingsLoader loader = new SettingsLoader(context); DataTable settingsTable = loader.LoadDataTableFromDataSource(firstDataSource); List <string> environments = loader.GetEnvironmentsFromDataTable(settingsTable); foreach (string environment in environments) { if (!string.IsNullOrEmpty(context.PropertyToExtract)) { PreprocessingProperties properties = new PreprocessingProperties(context.FixFalse); loader.LoadSettingsFromDataTable(settingsTable, context.Properties, environment); PreprocessingProperty property = context.Properties[context.PropertyToExtract]; if (null != property) { string resolvedPropertyValue = context.ResolveContent(property.Value); if (!string.IsNullOrEmpty(resolvedPropertyValue)) { Console.WriteLine(resolvedPropertyValue); } } } else { Console.WriteLine(environment); } } } catch (Exception e) { ConsoleUtils.WriteLine(ConsoleColor.Red, e.Message); exitCode = 1; } return(exitCode); }
/// <summary> /// Dumps an individual property from the data source to the console. /// </summary> /// <param name="context">The preprocessing context.</param> /// <returns></returns> private static int DumpProperty(PreprocessingContext context) { int exitCode = 0; try { PreprocessingProperty property = context.Properties[context.PropertyToExtract]; if (null != property) { string resolvedValue = context.ResolveContent(property.Value); if (!string.IsNullOrEmpty(resolvedValue)) { if (!string.IsNullOrEmpty(context.Delimiters)) { foreach (string s in resolvedValue.Split(context.Delimiters.ToCharArray())) { Console.WriteLine(s.Trim()); } } else { Console.WriteLine(resolvedValue); } } } } catch (Exception e) { ConsoleUtils.WriteLine(ConsoleColor.Red, e.Message); exitCode = 1; } return(exitCode); }
/// <summary> /// Replace any macros with their property value. /// </summary> /// <param name="content">Content in which to replace all macros.</param> /// <param name="context">The preprocessing context.</param> /// <param name="overriddenValues">The value to insert.</param> /// <returns>The content with macros replaced with corresponding property values.</returns> private string ResolveProperties(string content, PreprocessingContext context, IDictionary <string, string> overriddenValues) { bool containedEscapedMacros = false; const string startEscapedMacro = "{6496D0A7-21B9-4603-A2E5-43C64FCD435E{"; const string endEscapedMacro = "}6496D0A7-21B9-4603-A2E5-43C64FCD435E}"; bool isSameTokenUsedForStartAndEnd = context.TokenStart.Equals(context.TokenEnd, StringComparison.OrdinalIgnoreCase); if (null != content && null != context.Properties) { // Look for start of tokens, order depends on type of token used int macroPosition = -1; // Evaluate from back to front if tokens are not equal // this enables nested tokens such as this: ${PROPERTY_${MACHINE}} // Evaluate from front to back if start and end tokens are equal...nested properties with // custom tokens that match is not supported. You can't do this: #PROPERTY_#MACHINE## if (!isSameTokenUsedForStartAndEnd) { macroPosition = content.LastIndexOf(context.TokenStart); } else { macroPosition = content.IndexOf(context.TokenStart); } while (macroPosition > -1) { int endMacroPosition = content.IndexOf(context.TokenEnd, macroPosition + context.TokenStart.Length); string macro = content.Substring(macroPosition, endMacroPosition - macroPosition + 1); string key = macro.Substring(context.TokenStart.Length, macro.Length - (context.TokenStart.Length + context.TokenEnd.Length)).Trim(); string val = null; // if the key starts out with "script=" treat it as an expression if (key.Length > 6 && key.StartsWith("script", StringComparison.OrdinalIgnoreCase) && key.Substring(6).Trim().StartsWith("=")) { key = key.Substring(6).Trim().Substring(1).Trim(); if (!string.IsNullOrEmpty(key)) { val = ResolveExpression(key, context); } } else if (key.Length > 8 && key.StartsWith("registry", StringComparison.OrdinalIgnoreCase) && key.Substring(8).Trim().StartsWith("=")) { key = key.Substring(8).Trim().Substring(1).Trim(); if (!string.IsNullOrEmpty(key)) { val = RegistryEvaluator.GetValue(key); } } else { if (null != overriddenValues && overriddenValues.ContainsKey(key)) { val = overriddenValues[key]; } else { PreprocessingProperty property = null; // Implementation of fallback properties. // Go through the semicolon delimited list // of properties looking for the first one that exists // ex: ${PROPERTY_ABC;PROPERTY_DEF;PROPERTY} // useful for machine-specific configuration // when coupled with nested properties like this: // ${PROPERTY_${_machine_name};PROPERTY} string[] keys = key.Split(';'); foreach (string keyPart in keys) { string keyPartTrimmed = keyPart.Trim(); if (!string.IsNullOrEmpty(keyPartTrimmed)) { property = context.Properties[keyPartTrimmed]; if (null != property) { break; } } } if (null != property) { val = property.Value; if (context.CountUsage) { int useCount = CountOccurrences(content, macro); property.UseCount = property.UseCount + useCount; } } else { //Pavan added code here.. val = "$${{" + key + "}}"; ConsoleUtils.WriteLine(ConsoleColor.Yellow, string.Format("The setting named '{0}' was not defined.", key)); //Instead of erroring out, keep macro as value and write to warning. /* * val = "<!-- " + key + " not defined -->"; * * if (context.ValidateSettingsExist) * { * ErrorInfo errorInfo = new ErrorInfo(ErrorCode.ErrorMissingToken, context.SourceFile); * errorInfo.Message = string.Format("The setting named '{0}' was not defined.", key); * context.Errors.Add(errorInfo); * }*/ } } } // Enable Escaping if (!string.IsNullOrEmpty(val)) { int escapedMacroStartPos = val.IndexOf(context.TokenStartEscaped); int escapedMacroEndPos = val.IndexOf(context.TokenEndEscaped); if (escapedMacroStartPos > -1 && escapedMacroEndPos > escapedMacroStartPos) { val = val.Replace(context.TokenStartEscaped, startEscapedMacro).Replace(context.TokenEndEscaped, endEscapedMacro); containedEscapedMacros = true; } } content = content.Replace(macro, val); if (!isSameTokenUsedForStartAndEnd) { macroPosition = content.LastIndexOf(context.TokenStart); } else { macroPosition = content.IndexOf(context.TokenStart); } } } if (containedEscapedMacros) { content = content.Replace(startEscapedMacro, context.TokenStart).Replace(endEscapedMacro, context.TokenEnd); } return(content); }