/// <summary> /// Converts <paramref name="results"/> to a list of anonymous objects. /// </summary> /// <param name="results">The validation results to convert.</param> /// <param name="controlList">The control metadata list.</param> /// <param name="firstError">When the method returns, will contain the earliest control that has an error.</param> /// <returns>A new list of anonymous objects.</returns> public static Dictionary<string, List<string>> ConvertValidationResultsToErrorMessages(ValidationResults results, ControlList controlList, out Control firstError) { int minPos = int.MaxValue; firstError = null; Dictionary<string, List<string>> errors = new Dictionary<string, List<string>>(); foreach (ValidationResult result in results) { string errorKey = Regex.Replace(result.Key, "[" + Regex.Escape(".[") + "\\]]+", "-"); if (!errors.ContainsKey(errorKey)) { errors.Add(errorKey, new List<string>()); } errors[errorKey].Add(result.Message); string controlName = Regex.Match(errorKey, "[a-z0-9_]+$", RegexOptions.IgnoreCase).Value; Control control = controlList.FindRecursive(controlName); if (control == null) { controlName = Regex.Match(errorKey, "[a-z0-9_]+(?=-" + controlName + "$)", RegexOptions.IgnoreCase).Value; control = controlList.FindRecursive(controlName); } if (control.Position < minPos) { minPos = control.Position; firstError = control; } } return errors; }
/// <summary> /// Renders <paramref name="control"/> to the <paramref name="document"/>. /// </summary> /// <param name="document">The PDF document.</param> /// <param name="control">The control to be rendered.</param> /// <param name="level">The depth down the control tree being rendered (affects indenting).</param> /// <param name="controlList">The complete control list.</param> protected override void DoRender(Document document, Control control, int level, ControlList controlList) { IControlWithOptions controlWithOptions = control as IControlWithOptions; string suffix = string.Format(" {0}", controlWithOptions.AllowMultipleSelect ? PdfResources.IndicateAll : PdfResources.IndicateOne); FormattedText formattedSuffix = new FormattedText { Style = StyleNames.Normal, Italic = true }; formattedSuffix.AddText(suffix); this.Label.Add(formattedSuffix); RepeaterOptionSource optionSource = controlWithOptions.OptionSource as RepeaterOptionSource; RepeaterControl repeater = controlList.FindRecursive<RepeaterControl>(optionSource.RepeaterName); ControlList valueList = new ControlList(); valueList.AddRange(optionSource.ValueFields.Select(valueField => repeater.Controls.FindRecursive<Control>(valueField))); for (int i = 1; i <= (repeater.MaximumCount ?? PdfConstants.DefaultRepeaterLength); i++) { this.ListRenderer.Render(valueList, this.Factory, level, controlList); } }
/// <summary> /// Gets the replacement string for a token. /// </summary> /// <param name="token">The token being replaced.</param> /// <param name="format">A format string.</param> /// <param name="application">The application to source data from.</param> /// <param name="controls">The controls.</param> /// <param name="path">Specifies the path to the token.</param> /// <param name="defaultReplaceValue">The default replace value.</param> /// <returns> /// The replacement string. /// </returns> /// <remarks> /// Order of precedence: (1) Timestamp; (2) <paramref name="application" /> object; (3) application data. /// </remarks> private string GetReplacementString(string token, string format, Application application, ControlList controls, ApplicationDataPath path, string defaultReplaceValue) { Control control = controls.FindRecursive(c => c.Name == token); object value = this.GetTokenValue(token, application, control, path); if (value == null) { return defaultReplaceValue; } if (value is Array) { object[] valueArray = value as object[]; StringBuilder builder = new StringBuilder(); if (valueArray.Length == 0) { return defaultReplaceValue; } string appendFormat = valueArray[0] is string ? "'{0}'" : "{0}"; builder.AppendFormat(appendFormat, valueArray[0]); for (var i = 1; i < valueArray.Length; i++) { builder.Append(","); builder.AppendFormat(appendFormat, valueArray[i]); } return builder.ToString(); } string formatString = string.IsNullOrEmpty(format) ? "{0}" : string.Format("{{0:{0}}}", format.Substring(1, format.Length - 2)); return string.Format(CultureInfo.CurrentCulture, formatString, value); }
/// <summary> /// Validates an application. /// </summary> /// <param name="application">The application to validate.</param> /// <param name="pagesToValidate">The pagesToValidate to validate.</param> /// <param name="controls">A list of all controls.</param> /// <param name="controlsAccess">The control access list for the current user.</param> /// <param name="subpageControlId">The id of the control acting as the current subpage. If <see langword="null" />, then all controls are validated.</param> /// <param name="product">The product object.</param> /// <returns> /// The <see cref="ValidationResults" />. /// </returns> private ValidationResults ValidateApplication(Application application, PageList pagesToValidate, ControlList controls, List<ControlAccess> controlsAccess, int? subpageControlId = null, ProductDefinition product = null) { List<ControlWithOptions> controlsWithOptions = controls.FindAllRecursive<ControlWithOptions>(); if (controlsWithOptions.Any()) { this.RegisterOptionControls(application.FormOrganisationId, true, controlsWithOptions, application.ApplicationData); } var controlList = pagesToValidate.AllControls; var ruleList = pagesToValidate.AllRules; if (subpageControlId != null) { var subpageControl = controlList.FindRecursive<GroupControl>(x => x.Id == subpageControlId); if (subpageControl != null) { controlList = new ControlList { subpageControl }; TruthConditionList validRules = new TruthConditionList(); validRules.AddRange(ruleList.Where(rule => controlList.FindRecursive(x => x.Id.ToString().Equals(((ValidateTruthCondition)rule).Error.Position)) != null)); ruleList = validRules; } } ServiceEndpointList endpointList = pagesToValidate.AllExternalRuleHandlers.Count > 0 ? this.DataAccess.GetServiceEndpointList() : new ServiceEndpointList(); RegexValidatorList regexValidators = this.DataAccess.GetValidatorList(); if (product != null) { this.FillControlReferences(pagesToValidate, product.FormDefinition.Pages.AllControls); foreach (var referencedControls in pagesToValidate.Select(p => p.ReferencedControls)) { foreach (var control in referencedControls) { var exists = controls.FindRecursive(control.Name) != null; if (exists) { continue; } controls.AddRange(referencedControls); } } } ApplicationValidator validator = new ApplicationValidator(controls, controlList, controlsAccess, ruleList, pagesToValidate.AllExternalRuleHandlers, endpointList, this.endpointCommunicator, regexValidators); return validator.Validate(application); }