/// <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()); }
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)); }