1 // Copyright (c) Microsoft Corporation. All rights reserved.
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.
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
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
;
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
)
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
);
63 ValidationHelpers
.ValidateIdentifier(context
, identifier
);
67 error
= new ValidationError(SR
.GetString(SR
.Error_InvalidIdentifier
, propName
, e
.Message
), ErrorNumbers
.Error_InvalidIdentifier
);
71 error
.PropertyName
= propName
;
75 internal static ValidationError
ValidateNameProperty(string propName
, IServiceProvider context
, string identifier
)
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
);
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
);
96 error
.PropertyName
= propName
;
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
);
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
;
137 #region Validation for Activity Ref order
139 internal static bool IsActivitySourceInOrder(Activity request
, Activity response
)
141 if (request
.Parent
== null)
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
)
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;
172 for (int i
= 0; i
< requestParent
.EnabledActivities
.Count
; i
++)
174 if (requestParent
.EnabledActivities
[i
] == requestChild
)
176 else if (requestParent
.EnabledActivities
[i
] == responseChild
)
178 incorrectOrder
= true;
183 return !incorrectOrder
;
188 internal static ValidationErrorCollection
ValidateObject(ValidationManager manager
, object obj
)
190 ValidationErrorCollection errors
= new ValidationErrorCollection();
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
));
219 validatedObjects
.Remove(obj
.GetHashCode());
225 if (removeValidatedObjectCollection
)
226 manager
.Context
.Pop();
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
;
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
)
253 throw new ArgumentNullException("manager");
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
));
271 manager
.Context
.Pop();
272 manager
.Context
.Pop();
273 if (extendedPropertyContext
!= null)
274 manager
.Context
.Pop();