Пример #1
0
        /// <summary>
        /// Processes the supplied ApplyWhen element.
        /// </summary>
        public override ProcessNodeResults ProcessNode(
            [NotNull] XElement element,
            [NotNull] IConfiguration configuration)
        {
            if (element == null)
            {
                throw new ArgumentNullException(nameof(element));
            }
            if (configuration == null)
            {
                throw new ArgumentNullException(nameof(configuration));
            }

            if (element.Name.LocalName != "Apply" ||
                element.Name.Namespace != XmlTemplate.ConfigGenXmlNamespace)
            {
                throw new ArgumentException("Supplied element should have name 'Apply' in the configgen namespace.", nameof(element));
            }

            IResult <ApplyElement, string> result = _applyElementCreator.Create(element);

            if (!result.Success)
            {
                element.Remove();
                return(ProcessNodeResults.CreateErrorResult(XmlTemplateErrorCodes.ApplyWhenElseFormatError, result.Error));
            }

            bool trueConditionAlreadyEvaluated = false;

            ApplyElement applyElement = result.Value;

            while (applyElement.PredicateSubNodes.Count > 0)
            {
                var subNode = applyElement.PredicateSubNodes.Dequeue();

                // if we've already evalutated a true, don't bother evaluating sub node conditions, just return a fail result
                ExpressionEvaluationResults evaluationResults = trueConditionAlreadyEvaluated
                    ? new ExpressionEvaluationResults(false, null, null, null)
                    : EvaluateCondition(subNode.Element, configuration, _configurationExpressionEvaluator);

                if (evaluationResults.ErrorCode != null)
                {
                    element.Remove();
                    return(ProcessNodeResults.CreateErrorResult(evaluationResults.ErrorCode, evaluationResults.ErrorMessage));
                }

                ProcessElement(subNode, evaluationResults.Result && !trueConditionAlreadyEvaluated);

                trueConditionAlreadyEvaluated |= evaluationResults.Result;
            }

            if (applyElement.FinalElseSubNode != null)
            {
                ProcessElement(applyElement.FinalElseSubNode, !trueConditionAlreadyEvaluated);
            }

            element.Remove();

            return(ProcessNodeResults.CreateSuccessResult());
        }
Пример #2
0
        public virtual IResult <ApplyElement, string> Create(XElement applyElement)
        {
            if (applyElement == null)
            {
                throw new ArgumentNullException();
            }

            var returnValue       = new ApplyElement();
            var xname             = XName.Get("When", XmlTemplate.ConfigGenXmlNamespace);
            var predicateElements = applyElement.Elements();
            var primaryPredicate  = predicateElements.FirstOrDefault();

            if (primaryPredicate == null ||
                primaryPredicate.Name != xname)
            {
                return(Result <ApplyElement, string> .CreateFailureResult("The first element in the 'Apply' container must be a 'When' element in the ConfigGen namespace."));
            }

            var onNotAppliedAttribute = applyElement.GetOnNotAppliedAttribute(OnNotAppliedAction.Remove);
            var result = _applyElementSubNodeCreator.Create(primaryPredicate, onNotAppliedAttribute);

            if (!result.Success)
            {
                return(Result <ApplyElement, string> .CreateFailureResult(result.Error));
            }

            returnValue.PredicateSubNodes.Enqueue(result.Value);

            foreach (var currentElement in primaryPredicate.ElementsAfterSelf())
            {
                if (currentElement != null)
                {
                    if (returnValue.FinalElseSubNode != null)
                    {
                        return(Result <ApplyElement, string> .CreateFailureResult("The 'else' element must be the final element in the 'Apply' container."));
                    }

                    if (currentElement.Name == XName.Get("ElseWhen", XmlTemplate.ConfigGenXmlNamespace))
                    {
                        result = _applyElementSubNodeCreator.Create(currentElement, onNotAppliedAttribute);
                        if (!result.Success)
                        {
                            return(Result <ApplyElement, string> .CreateFailureResult(result.Error));
                        }
                        returnValue.PredicateSubNodes.Enqueue(result.Value);
                    }
                    else if (currentElement.Name == XName.Get("Else", XmlTemplate.ConfigGenXmlNamespace))
                    {
                        result = _applyElementSubNodeCreator.Create(currentElement, onNotAppliedAttribute);
                        if (!result.Success)
                        {
                            return(Result <ApplyElement, string> .CreateFailureResult(result.Error));
                        }
                        returnValue.FinalElseSubNode = result.Value;
                    }
                    else
                    {
                        return(Result <ApplyElement, string> .CreateFailureResult("Unexpected node appeared in 'Apply' container: " + currentElement.Name));
                    }
                }
            }

            return(Result <ApplyElement, string> .CreateSuccessResult(returnValue));
        }