/// <summary>
        /// Установить содержимое блока.
        /// </summary>
        /// <param name="element">Xml-элемент.</param>
        /// <param name="configSettingsParser">Настройки конфига.</param>
        /// <param name="nodesToRemove">Узлы для последующего удаления.</param>
        private void SetBlockContent(XElement element, ConfigSettingsParser configSettingsParser, List <XNode> nodesToRemove)
        {
            string blockContent = null;

            foreach (var node in element.Nodes())
            {
                if (node is XComment commentNode)
                {
                    var comment = commentNode.Value.Trim();
                    if (comment.Length > 3 && comment.StartsWith("{~", StringComparison.Ordinal) && comment.EndsWith("}", StringComparison.Ordinal))
                    {
                        var blockName = comment.Substring(2, comment.Length - 3);
                        blockContent = configSettingsParser.GetBlockContent(blockName);
                    }
                    else
                    {
                        blockContent = null;
                    }
                }
                else if (node is XElement elementNode)
                {
                    if (!string.IsNullOrEmpty(blockContent))
                    {
                        nodesToRemove.AddRange(elementNode.Nodes());
                        foreach (var subNode in this.ParseElement(blockContent, elementNode).Nodes())
                        {
                            elementNode.Add(subNode);
                        }
                        blockContent = null;
                    }
                    this.SetBlockContent(elementNode, configSettingsParser, nodesToRemove);
                }
            }
        }
Exemple #2
0
        /// <summary>
        /// Применить настройки к элементу.
        /// </summary>
        /// <param name="element">XML элемент.</param>
        /// <param name="configSettingsParser">Парсер настроек.</param>
        /// <param name="isAncestorSetter">Установлено в предке.</param>
        public override void Apply(XElement element, ConfigSettingsParser configSettingsParser, bool isAncestorSetter)
        {
            if (isAncestorSetter)
            {
                return;
            }
            var textNode =
                element.Nodes().OfType <XText>().FirstOrDefault(node => !string.IsNullOrWhiteSpace(node.Value)) ??
                element.Nodes().OfType <XText>().FirstOrDefault();

            if (textNode == null)
            {
                textNode = new XText(string.Empty);
                element.Add(textNode);
            }

            var textValue = textNode.Value;
            var result    = this.EvaluateValue(textValue, configSettingsParser);

            if (result != null)
            {
                var leftWhitespace  = textValue.Substring(0, textValue.Length - textValue.TrimStart().Length);
                var rightWhitespace = textValue.Substring(textValue.TrimEnd().Length);
                textNode.Value = leftWhitespace + result + rightWhitespace;
            }
        }
Exemple #3
0
        /// <summary>
        /// Применить настройки доступности блоков.
        /// </summary>
        /// <param name="configSettingsParser">Настройки конфига.</param>
        public void ApplyAccess(ConfigSettingsParser configSettingsParser)
        {
            this.Apply(this.EnableBlocks, configSettingsParser);
            this.Apply(this.DisableBlocks, configSettingsParser);

            if (configSettingsParser.HasContentBlocks)
            {
                this.Apply(this.SetBlockContent, configSettingsParser);
            }
        }
Exemple #4
0
 /// <summary>
 /// Получить фактическое значение аргумента.
 /// </summary>
 /// <param name="argumentExpression">Строка с выражением-аргументом.</param>
 /// <param name="configSettingsParser">Настройки конфига.</param>
 /// <returns>Фактическое значение аргумента.</returns>
 private string GetActualArgumentValue(string argumentExpression, ConfigSettingsParser configSettingsParser)
 {
     if (argumentExpression.StartsWith(FunctionPrefix, StringComparison.Ordinal))
     {
         return(new ExpressionEvaluator(argumentExpression).EvaluateValue(string.Empty, configSettingsParser));
     }
     if (argumentExpression.Length >= 2 && argumentExpression[0] == '"' && argumentExpression[argumentExpression.Length - 1] == '"')
     {
         return(argumentExpression.Substring(1, argumentExpression.Length - 2));
     }
     return(configSettingsParser.HasVariable(argumentExpression) ? configSettingsParser.GetVariableValue(argumentExpression) : null);
 }
Exemple #5
0
        /// <inheritdoc />
        public override void Apply(XElement element, ConfigSettingsParser configSettingsParser, bool isAncestorSetter)
        {
            if (!this.IsElelementSuitable(element, isAncestorSetter))
            {
                return;
            }
            var isExistingAttribute = element.Attribute(this.AttributeName) != null;
            var attributeValue      = isExistingAttribute ? element.Attribute(this.AttributeName).Value : string.Empty;
            var result = this.EvaluateValue(attributeValue, configSettingsParser);

            if (result != null)
            {
                element.SetAttributeValue(this.AttributeName, result != "_REMOVE_" ? result : null);
            }
        }
Exemple #6
0
        /// <summary>
        /// Получить фактическое значение для установки.
        /// </summary>
        /// <param name="currentValue">Текущее значение.</param>
        /// <param name="configSettingsParser">Настройки конфига.</param>
        /// <returns>Фактическое (новое) значение.</returns>
        public string EvaluateValue(string currentValue, ConfigSettingsParser configSettingsParser)
        {
            if (string.IsNullOrEmpty(this.FunctionName))
            {
                return(null);
            }
            var actualArgumentsValues = this.FunctionArguments.Select(arg => this.GetActualArgumentValue(arg, configSettingsParser)).ToArray();

            if (actualArgumentsValues.Any(v => v == null))
            {
                return(null);
            }
            if (this.FunctionName == IdentityFunctionName)
            {
                return(actualArgumentsValues[0]);
            }
            if (this.FunctionName == "if-not-empty" && actualArgumentsValues.Length == 1)
            {
                return(string.IsNullOrWhiteSpace(actualArgumentsValues[0]) ? null : actualArgumentsValues[0]);
            }
            if (this.FunctionName == "replace" && actualArgumentsValues.Length == 2)
            {
                return(currentValue.Replace(actualArgumentsValues[0], actualArgumentsValues[1]));
            }
            if (this.FunctionName == "replace-if" && actualArgumentsValues.Length == 3 && actualArgumentsValues[0].ToUpperInvariant() == "TRUE")
            {
                return(currentValue.Replace(actualArgumentsValues[1], actualArgumentsValues[2]));
            }
            if (this.FunctionName == "replace-if-not" && actualArgumentsValues.Length == 3 && actualArgumentsValues[0].ToUpperInvariant() != "TRUE")
            {
                return(currentValue.Replace(actualArgumentsValues[1], actualArgumentsValues[2]));
            }
            if (this.FunctionName == "concat")
            {
                return(string.Join(string.Empty, actualArgumentsValues));
            }
            if (this.FunctionName == "equals" && actualArgumentsValues.Length == 2)
            {
                return(string.Equals(actualArgumentsValues[0], actualArgumentsValues[1], StringComparison.OrdinalIgnoreCase) ? "true" : "false");
            }
            if (this.FunctionName == "not" && actualArgumentsValues.Length == 1)
            {
                return(string.Equals(actualArgumentsValues[0], "false", StringComparison.OrdinalIgnoreCase) ? "true" : "false");
            }
            return(null);
        }
Exemple #7
0
        /// <summary>
        /// Сделать блоки xml-элемента доступными (раскомментировать элементы).
        /// </summary>
        /// <param name="element">Xml-элемент.</param>
        /// <param name="configSettingsParser">Настройки конфига.</param>
        /// <param name="nodesToRemove">Узлы для последующего удаления.</param>
        private void EnableBlocks(XElement element, ConfigSettingsParser configSettingsParser, List <XNode> nodesToRemove)
        {
            var needEnableBlock = false;

            foreach (var node in element.Nodes())
            {
                var commentNode = node as XComment;
                var elementNode = node as XElement;
                if (commentNode != null)
                {
                    var comment = commentNode.Value.Trim();
                    if (comment.Length > 3 && comment.StartsWith("{~", StringComparison.Ordinal) && comment.EndsWith("}", StringComparison.Ordinal))
                    {
                        var blockName     = comment.Substring(2, comment.Length - 3);
                        var negateEnabled = this.IsNegatedBlockName(ref blockName);
                        var blockEnabled  = configSettingsParser.IsBlockEnabled(blockName);
                        if (negateEnabled)
                        {
                            blockEnabled = !blockEnabled;
                        }

                        if (blockEnabled)
                        {
                            needEnableBlock = true;
                        }
                    }
                    else
                    {
                        if (needEnableBlock)
                        {
                            var newBlock = this.ParseElement(comment, element);
                            node.AddAfterSelf(newBlock);
                            nodesToRemove.Add(node);
                            needEnableBlock = false;
                        }
                    }
                }
                else if (elementNode != null)
                {
                    needEnableBlock = false;
                    this.EnableBlocks(elementNode, configSettingsParser, nodesToRemove);
                }
            }
        }
 /// <summary>
 /// Конструктор.
 /// </summary>
 /// <param name="config">Xml-конфиг.</param>
 /// <param name="configSettingsParser">Настройки конфига.</param>
 public ConfigPatch(XDocument config, ConfigSettingsParser configSettingsParser)
 {
     this.config = config;
     this.configSettingsParser = configSettingsParser;
 }
Exemple #9
0
        /// <summary>
        /// Применить настройки доступности блоков.
        /// </summary>
        /// <param name="action">Действие для управления доступностью.</param>
        /// <param name="configSettingsParser">Настройки конфига.</param>
        private void Apply(Action <XElement, ConfigSettingsParser, List <XNode> > action, ConfigSettingsParser configSettingsParser)
        {
            var nodesToRemove = new List <XNode>();

            action(this.config.Root, configSettingsParser, nodesToRemove);
            foreach (var node in nodesToRemove)
            {
                node.Remove();
            }
        }
Exemple #10
0
 /// <summary>
 /// Применить установку значения к переданному xml-элементу.
 /// </summary>
 /// <param name="element">Xml-элемент.</param>
 /// <param name="configSettingsParser">Настройки конфига.</param>
 /// <param name="isAncestorSetter">Признак, что правило установки является унаследованным (с предыдущих уровней xml-документа).</param>
 public abstract void Apply(XElement element, ConfigSettingsParser configSettingsParser, bool isAncestorSetter);
Exemple #11
0
 /// <summary>
 /// Получить фактическое значение для установки.
 /// </summary>
 /// <param name="currentValue">Текущее значение.</param>
 /// <param name="configSettingsParser">Настройки конфига.</param>
 /// <returns>Фактическое (новое) значение.</returns>
 public string EvaluateValue(string currentValue, ConfigSettingsParser configSettingsParser)
 {
     return(this.expressionEvaluator.EvaluateValue(currentValue, configSettingsParser));
 }