/// <summary> /// Evaluate the specified expression, for the given element and model. /// </summary> /// <param name="expression">The expression to evaluate.</param> /// <param name="context">The rendering context for the expression being evaluated.</param> /// <param name="model">The ZPT model, providing the context for evaluation.</param> public override ExpressionResult Evaluate(Expression expression, IRenderingContext context, ITalesModel model) { object result; try { result = _host.Evaluate(expression.Content, model.GetAllDefinitions()); } catch(Exception ex) { string message = String.Format(Resources.ExceptionMessages.EvaluationFailureFormat, expression.Content); throw new ModelEvaluationException(message, ex); } return new ExpressionResult(result); }
/// <summary> /// Evaluate the specified expression, for the given element and model. /// </summary> /// <param name="expression">The expression to evaluate.</param> /// <param name="context">The rendering context for the expression being evaluated.</param> /// <param name="model">The ZPT model, providing the context for evaluation.</param> public override ExpressionResult Evaluate(Expression expression, IRenderingContext context, ITalesModel model) { if(expression == null) { throw new ArgumentNullException(nameof(expression)); } if(context == null) { throw new ArgumentNullException(nameof(context)); } if(model == null) { throw new ArgumentNullException(nameof(model)); } var trimmedContent = expression.Content.TrimStart(); var result = model.Evaluate(ExpressionCreator.Create(trimmedContent), context); bool booleanResult = this.CoerceToBoolean(result); return new ExpressionResult(!booleanResult); }
/// <summary> /// Evaluate the specified expression, for the given element and model. /// </summary> /// <param name="expression">The expression to evaluate.</param> /// <param name="context">The rendering context for the expression being evaluated.</param> /// <param name="model">The ZPT model, providing the context for evaluation.</param> public override ExpressionResult Evaluate(Expression expression, IRenderingContext context, ITalesModel model) { if(expression == null) { throw new ArgumentNullException(nameof(expression)); } if(context == null) { throw new ArgumentNullException(nameof(context)); } if(model == null) { throw new ArgumentNullException(nameof(model)); } string source = expression.Content, output; var escapeSequenceIndices = this.FindAndUnescapePlaceholders(source, out output); output = this.ApplyPlaceholderReplacements(output, escapeSequenceIndices, context, model); return new ExpressionResult(output); }
/// <summary> /// Evaluate the specified expression, for the given element and model. /// </summary> /// <param name="expression">The expression to evaluate.</param> /// <param name="context">The rendering context for the expression being evaluated.</param> /// <param name="model">The ZPT model, providing the context for evaluation.</param> public override ExpressionResult Evaluate(Expression expression, IRenderingContext context, ITalesModel model) { if(expression == null) { throw new ArgumentNullException(nameof(expression)); } if(context == null) { throw new ArgumentNullException(nameof(context)); } if(model == null) { throw new ArgumentNullException(nameof(model)); } var expressionText = expression.Content; var allDefinitions = model.GetAllDefinitions(); var csharpExpression = _expressionService.GetExpression(expressionText, allDefinitions.Keys); return new ExpressionResult(csharpExpression.Evaluate(allDefinitions)); }
/// <summary> /// Evaluate the specified expression, for the given element and model. /// </summary> /// <param name="expression">The expression to evaluate.</param> /// <param name="context">The rendering context for the expression being evaluated.</param> /// <param name="model">The ZPT model, providing the context for evaluation.</param> public override ExpressionResult Evaluate(Expression expression, IRenderingContext context, ITalesModel model) { if(expression == null) { throw new ArgumentNullException(nameof(expression)); } if(context == null) { throw new ArgumentNullException(nameof(context)); } if(model == null) { throw new ArgumentNullException(nameof(model)); } var expressionText = expression.Content; var path = Path.Create(expressionText); var walker = new PathWalker(path); object output; try { output = this.WalkPath(walker, context, model); } catch(TraversalException ex) { string message = String.Format(Resources.ExceptionMessages.CouldNotWalkAnyPathsWithExpression, expressionText, context?.Element?.Name); throw new ModelEvaluationException(message, ex) { ExpressionText = expressionText, ElementName = context?.Element?.Name }; } return new ExpressionResult(output); }
/// <summary> /// Walks and evaluates a TALES path. /// </summary> /// <returns>The evaluated value of the path.</returns> /// <param name="walker">A TALES path walker, containing a path.</param> /// <param name="context">The rendering context for the expression being evaluated.</param> /// <param name="model">The ZPT model, providing the context for evaluation.</param> private object WalkPath(PathWalker walker, IRenderingContext context, ITalesModel model) { object output = null; bool success = false; while(walker.NextComponent() && !success) { success = this.WalkComponent(walker, context, model, out output); } if(!success) { throw new TraversalException(Resources.ExceptionMessages.CouldNotWalkAnyPaths); } return output; }
/// <summary> /// Walks and evaluates a single TALES path component. /// </summary> /// <returns> /// <c>true</c>, if the path component was successfully evaluated, <c>false</c> otherwise. /// </returns> /// <param name="walker">A TALES path walker, containing a path.</param> /// <param name="context">The rendering context for the expression being evaluated.</param> /// <param name="model">The ZPT model, providing the context for evaluation.</param> /// <param name="result">Exposes the result of the evaluation.</param> private bool WalkComponent(PathWalker walker, IRenderingContext context, ITalesModel model, out object result) { bool output; if(this.TryGetTraversalRoot(walker, context, model, out result)) { object traversalChild; output = true; while(walker.NextPart()) { string partName; if(this.TryGetPartName(walker.CurrentPart, context, model, out partName) && ObjectTraverser.Default.Traverse(result, partName, out traversalChild, context)) { result = traversalChild; } else { output = false; result = null; break; } } } else { output = false; result = null; } return output; }
/// <summary> /// Attempts to get a part-name for traversal, expanding interpolated part-names if appropriate. /// </summary> /// <returns><c>true</c>, if a part name was resolved, <c>false</c> otherwise.</returns> /// <param name="part">A TALES path part.</param> /// <param name="context">The rendering context.</param> /// <param name="model">The TALES model.</param> /// <param name="result">Exposes the result of this operation.</param> private bool TryGetPartName(PathPart part, IRenderingContext context, ITalesModel model, out string result) { result = part.Value; bool output = true; if(part.IsInterpolated) { object interpolatedValue; if(model.TryGetRootObject(result, context, out interpolatedValue) && interpolatedValue != null) { output = true; result = interpolatedValue.ToString(); } else { output = false; result = null; } } return output; }
/// <summary> /// Attempts to get a root object, from which to begin traversal of the path. /// </summary> /// <returns><c>true</c>, if the root object was retrieved, <c>false</c> otherwise.</returns> /// <param name="walker">A TALES path walker.</param> /// <param name="context">The rendering context.</param> /// <param name="model">The TALES model.</param> /// <param name="result">Exposes the result of this operation.</param> protected virtual bool TryGetTraversalRoot(PathWalker walker, IRenderingContext context, ITalesModel model, out object result) { bool output; if(walker.NextPart() && model.TryGetRootObject(walker.CurrentPart.Value, context, out result)) { output = true; } else { output = false; result = null; } return output; }
/// <summary> /// Applies placeholder replacements to the input string. /// </summary> /// <returns>The result of the application of placeholders.</returns> /// <param name="input">The input string.</param> /// <param name="escapedPlaceholderIndices">A collection containing the indices of escaped placeholder sequences.</param> /// <param name="context">The rendering context.</param> /// <param name="model">The TALES model.</param> private string ApplyPlaceholderReplacements(string input, ISet<int> escapedPlaceholderIndices, IRenderingContext context, ITalesModel model) { var pathEvaluator = EvaluatorSelector.GetEvaluator<PathExpressionEvaluator>(); return ReplacementFinder.Replace(input, match => { string output; if(escapedPlaceholderIndices.Contains(match.Index)) { output = match.Value; } else { string val = match.Groups[1].Success? match.Groups[1].Value : match.Groups[2].Value; var pathResult = pathEvaluator.Evaluate(ExpressionCreator.Create(val), context, model); if(pathResult.Value == null) { output = String.Empty; } else { output = pathResult.Value.ToString(); } } return output; }); }
/// <summary> /// Evaluate the specified expression, for the given element and model. /// </summary> /// <param name="expression">The expression to evaluate.</param> /// <param name="context">The rendering context for the expression being evaluated.</param> /// <param name="model">The ZPT model, providing the context for evaluation.</param> public abstract ExpressionResult Evaluate(Expression expression, IRenderingContext context, ITalesModel model);