Updates referencesource to .NET 4.7
[mono-project.git] / mcs / class / referencesource / System.Workflow.Activities / Common / ValidationHelpers.cs
blob65a9025900758416ebca9e97a187314c72a6dab0
1 // Copyright (c) Microsoft Corporation. All rights reserved.
2 //
3 // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
4 // WHETHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
5 // WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
6 // THE ENTIRE RISK OF USE OR RESULTS IN CONNECTION WITH THE USE OF THIS CODE
7 // AND INFORMATION REMAINS WITH THE USER.
8 //
10 /*********************************************************************
11 * NOTE: A copy of this file exists at: WF\Common\Shared
12 * The two files must be kept in sync. Any change made here must also
13 * be made to WF\Common\Shared\ValidationHelpers.cs
14 *********************************************************************/
15 namespace System.Workflow.Activities.Common
17 #region Imports
19 using System;
20 using System.Diagnostics;
21 using System.Collections;
22 using System.Collections.Generic;
23 using System.Reflection;
24 using System.CodeDom.Compiler;
25 using System.Workflow.ComponentModel.Design;
26 using System.Workflow.ComponentModel.Compiler;
27 using System.Collections.Specialized;
28 using System.ComponentModel.Design.Serialization;
29 using System.Workflow.ComponentModel;
30 #endregion
32 internal static class ValidationHelpers
34 #region Validation & helpers for ID and Type
36 internal static void ValidateIdentifier(IServiceProvider serviceProvider, string identifier)
38 if (serviceProvider == null)
39 throw new ArgumentNullException("serviceProvider");
41 SupportedLanguages language = CompilerHelpers.GetSupportedLanguage(serviceProvider);
42 CodeDomProvider provider = CompilerHelpers.GetCodeDomProvider(language);
43 if (language == SupportedLanguages.CSharp && identifier.StartsWith("@", StringComparison.Ordinal) ||
44 language == SupportedLanguages.VB && identifier.StartsWith("[", StringComparison.Ordinal) && identifier.EndsWith("]", StringComparison.Ordinal) ||
45 !provider.IsValidIdentifier(identifier))
47 throw new Exception(SR.GetString(SR.Error_InvalidLanguageIdentifier, identifier));
51 internal static ValidationError ValidateIdentifier(string propName, IServiceProvider context, string identifier)
53 if (context == null)
54 throw new ArgumentNullException("context");
56 ValidationError error = null;
57 if (identifier == null || identifier.Length == 0)
58 error = new ValidationError(SR.GetString(SR.Error_PropertyNotSet, propName), ErrorNumbers.Error_PropertyNotSet);
59 else
61 try
63 ValidationHelpers.ValidateIdentifier(context, identifier);
65 catch (Exception e)
67 error = new ValidationError(SR.GetString(SR.Error_InvalidIdentifier, propName, e.Message), ErrorNumbers.Error_InvalidIdentifier);
70 if (error != null)
71 error.PropertyName = propName;
72 return error;
75 internal static ValidationError ValidateNameProperty(string propName, IServiceProvider context, string identifier)
77 if (context == null)
78 throw new ArgumentNullException("context");
80 ValidationError error = null;
81 if (identifier == null || identifier.Length == 0)
82 error = new ValidationError(SR.GetString(SR.Error_PropertyNotSet, propName), ErrorNumbers.Error_PropertyNotSet);
83 else
85 SupportedLanguages language = CompilerHelpers.GetSupportedLanguage(context);
86 CodeDomProvider provider = CompilerHelpers.GetCodeDomProvider(language);
88 if (language == SupportedLanguages.CSharp && identifier.StartsWith("@", StringComparison.Ordinal) ||
89 language == SupportedLanguages.VB && identifier.StartsWith("[", StringComparison.Ordinal) && identifier.EndsWith("]", StringComparison.Ordinal) ||
90 !provider.IsValidIdentifier(provider.CreateEscapedIdentifier(identifier)))
92 error = new ValidationError(SR.GetString(SR.Error_InvalidIdentifier, propName, SR.GetString(SR.Error_InvalidLanguageIdentifier, identifier)), ErrorNumbers.Error_InvalidIdentifier);
95 if (error != null)
96 error.PropertyName = propName;
97 return error;
100 internal static ValidationErrorCollection ValidateUniqueIdentifiers(Activity rootActivity)
102 if (rootActivity == null)
103 throw new ArgumentNullException("rootActivity");
105 Hashtable identifiers = new Hashtable();
106 ValidationErrorCollection validationErrors = new ValidationErrorCollection();
107 Queue activities = new Queue();
108 activities.Enqueue(rootActivity);
109 while (activities.Count > 0)
111 Activity activity = (Activity)activities.Dequeue();
112 if (activity.Enabled)
114 if (identifiers.ContainsKey(activity.QualifiedName))
116 ValidationError duplicateError = new ValidationError(SR.GetString(SR.Error_DuplicatedActivityID, activity.QualifiedName), ErrorNumbers.Error_DuplicatedActivityID);
117 duplicateError.PropertyName = "Name";
118 duplicateError.UserData[typeof(Activity)] = activity;
119 validationErrors.Add(duplicateError);
121 else
122 identifiers.Add(activity.QualifiedName, activity);
124 if (activity is CompositeActivity && ((activity.Parent == null) || !Helpers.IsCustomActivity(activity as CompositeActivity)))
126 foreach (Activity child in Helpers.GetAllEnabledActivities((CompositeActivity)activity))
127 activities.Enqueue(child);
132 return validationErrors;
135 #endregion
137 #region Validation for Activity Ref order
139 internal static bool IsActivitySourceInOrder(Activity request, Activity response)
141 if (request.Parent == null)
142 return true;
143 List<Activity> responsePath = new List<Activity>();
144 responsePath.Add(response);
145 Activity responseParent = response is CompositeActivity ? (CompositeActivity)response : response.Parent;
146 while (responseParent != null)
148 responsePath.Add(responseParent);
149 responseParent = responseParent.Parent;
152 Activity requestChild = request;
153 CompositeActivity requestParent = request is CompositeActivity ? (CompositeActivity)request : request.Parent;
154 while (requestParent != null && !responsePath.Contains(requestParent))
156 requestChild = requestParent;
157 requestParent = requestParent.Parent;
160 if (requestParent == requestChild)
161 return true;
163 bool incorrectOrder = false;
164 int index = (responsePath.IndexOf(requestParent) - 1);
165 index = (index < 0) ? 0 : index; //sometimes parent gets added to the collection twice which causes index to be -1
166 Activity responseChild = responsePath[index];
168 if (requestParent == null || Helpers.IsAlternateFlowActivity(requestChild) || Helpers.IsAlternateFlowActivity(responseChild))
169 incorrectOrder = true;
170 else
172 for (int i = 0; i < requestParent.EnabledActivities.Count; i++)
174 if (requestParent.EnabledActivities[i] == requestChild)
175 break;
176 else if (requestParent.EnabledActivities[i] == responseChild)
178 incorrectOrder = true;
179 break;
183 return !incorrectOrder;
186 #endregion
188 internal static ValidationErrorCollection ValidateObject(ValidationManager manager, object obj)
190 ValidationErrorCollection errors = new ValidationErrorCollection();
191 if (obj == null)
192 return errors;
194 Type objType = obj.GetType();
195 if (!objType.IsPrimitive && (objType != typeof(string)))
197 bool removeValidatedObjectCollection = false;
198 Dictionary<int, object> validatedObjects = manager.Context[typeof(Dictionary<int, object>)] as Dictionary<int, object>;
199 if (validatedObjects == null)
201 validatedObjects = new Dictionary<int, object>();
202 manager.Context.Push(validatedObjects);
203 removeValidatedObjectCollection = true;
208 if (!validatedObjects.ContainsKey(obj.GetHashCode()))
210 validatedObjects.Add(obj.GetHashCode(), obj);
213 Validator[] validators = manager.GetValidators(objType);
214 foreach (Validator validator in validators)
215 errors.AddRange(validator.Validate(manager, obj));
217 finally
219 validatedObjects.Remove(obj.GetHashCode());
223 finally
225 if (removeValidatedObjectCollection)
226 manager.Context.Pop();
230 return errors;
233 internal static ValidationErrorCollection ValidateActivity(ValidationManager manager, Activity activity)
235 ValidationErrorCollection errors = ValidationHelpers.ValidateObject(manager, activity);
237 foreach (ValidationError error in errors)
239 if (!error.UserData.Contains(typeof(Activity)))
240 error.UserData[typeof(Activity)] = activity;
242 return errors;
245 internal static ValidationErrorCollection ValidateProperty(ValidationManager manager, Activity activity, object obj, PropertyValidationContext propertyValidationContext)
247 return ValidateProperty(manager, activity, obj, propertyValidationContext, null);
250 internal static ValidationErrorCollection ValidateProperty(ValidationManager manager, Activity activity, object obj, PropertyValidationContext propertyValidationContext, object extendedPropertyContext)
252 if (manager == null)
253 throw new ArgumentNullException("manager");
254 if (obj == null)
255 throw new ArgumentNullException("obj");
256 if (propertyValidationContext == null)
257 throw new ArgumentNullException("propertyValidationContext");
259 ValidationErrorCollection errors = new ValidationErrorCollection();
261 manager.Context.Push(activity);
262 manager.Context.Push(propertyValidationContext);
263 if (extendedPropertyContext != null)
264 manager.Context.Push(extendedPropertyContext);
267 errors.AddRange(ValidationHelpers.ValidateObject(manager, obj));
269 finally
271 manager.Context.Pop();
272 manager.Context.Pop();
273 if (extendedPropertyContext != null)
274 manager.Context.Pop();
277 return errors;