protected override void CacheMetadata(NativeActivityMetadata metadata) { RuntimeArgument argument = new RuntimeArgument("Handle", typeof(THandle), ArgumentDirection.In); metadata.Bind(this.Handle, argument); metadata.SetArgumentsCollection(new Collection <RuntimeArgument> { argument }); if (this.Body != null) { metadata.SetChildrenCollection(new Collection <Activity> { this.Body }); } Collection <Variable> collection = null; if ((this.Handle == null) || this.Handle.IsEmpty) { if (this.declaredHandle == null) { this.declaredHandle = new Variable <THandle>(); } } else { this.declaredHandle = null; } if (this.declaredHandle != null) { ActivityUtilities.Add <Variable>(ref collection, this.declaredHandle); } metadata.SetImplementationVariablesCollection(collection); }
internal static void ValidateRootInputs(Activity rootActivity, IDictionary <string, object> inputs) { IList <ValidationError> validationErrors = null; ValidationHelper.ValidateArguments(rootActivity, rootActivity.EquivalenceInfo, rootActivity.OverloadGroups, rootActivity.RequiredArgumentsNotInOverloadGroups, inputs, ref validationErrors); if (inputs != null) { List <string> c = null; IEnumerable <RuntimeArgument> enumerable = from a in rootActivity.RuntimeArguments where ArgumentDirectionHelper.IsIn(a.Direction) select a; foreach (string str in inputs.Keys) { bool flag = false; foreach (RuntimeArgument argument in enumerable) { if (argument.Name == str) { flag = true; object obj2 = null; if (inputs.TryGetValue(str, out obj2) && !TypeHelper.AreTypesCompatible(obj2, argument.Type)) { ActivityUtilities.Add <ValidationError>(ref validationErrors, new ValidationError(System.Activities.SR.InputParametersTypeMismatch(argument.Type, argument.Name), rootActivity)); } break; } } if (!flag) { if (c == null) { c = new List <string>(); } c.Add(str); } } if (c != null) { ActivityUtilities.Add <ValidationError>(ref validationErrors, new ValidationError(System.Activities.SR.UnusedInputArguments(c.AsCommaSeparatedValues()), rootActivity)); } } if ((validationErrors != null) && (validationErrors.Count > 0)) { string paramName = "rootArgumentValues"; ExceptionReason invalidNonNullInputs = ExceptionReason.InvalidNonNullInputs; if (inputs == null) { paramName = "program"; invalidNonNullInputs = ExceptionReason.InvalidNullInputs; } string message = GenerateExceptionString(validationErrors, invalidNonNullInputs); if (message != null) { throw FxTrace.Exception.Argument(paramName, message); } } }
// This method checks if any of the overload groups are equivalent and/or are a subset/superset of another // overload group. Returns true if there are not any errors. static bool ValidateOverloadGroupDefinitions(Activity activity, OverloadGroupEquivalenceInfo equivalenceInfo, Dictionary <string, List <RuntimeArgument> > overloadGroups, ref IList <ValidationError> validationErrors) { Fx.Assert(equivalenceInfo != null, "equivalenceInfo should have been setup before calling this method"); bool noErrors = true; if (!equivalenceInfo.EquivalentGroupsDictionary.IsNullOrEmpty()) { Hashtable keysVisited = new Hashtable(equivalenceInfo.EquivalentGroupsDictionary.Count); foreach (KeyValuePair <string, List <string> > entry in equivalenceInfo.EquivalentGroupsDictionary) { if (!keysVisited.Contains(entry.Key)) { string[] equivalentGroups = new string[entry.Value.Count + 1]; equivalentGroups[0] = entry.Key; entry.Value.CopyTo(equivalentGroups, 1); IEnumerable <string> sortedList = equivalentGroups.OrderBy((s) => s, StringComparer.Ordinal); ActivityUtilities.Add(ref validationErrors, new ValidationError(SR.OverloadGroupsAreEquivalent(sortedList.AsCommaSeparatedValues()), false, activity)); noErrors = false; for (int i = 0; i < equivalentGroups.Length; i++) { keysVisited.Add(equivalentGroups[i], null); } } } } else if (!equivalenceInfo.SupersetOfGroupsDictionary.IsNullOrEmpty()) { foreach (KeyValuePair <string, List <string> > entry in equivalenceInfo.SupersetOfGroupsDictionary) { IList <string> sortedList = entry.Value.OrderBy((s) => s, StringComparer.Ordinal).ToList(); string[] subsetGroups = new string[sortedList.Count]; int index = 0; // Select only subsets that have atleast one required argument in them. // We ignore the subsets that have no required arguments in them. foreach (string subsetGroup in sortedList) { if (overloadGroups[subsetGroup].Any <RuntimeArgument>((a) => a.IsRequired)) { subsetGroups[index++] = subsetGroup; } } // If there were any subsets with required arguments generate an error. if (index > 0) { ActivityUtilities.Add(ref validationErrors, new ValidationError(SR.OverloadGroupHasSubsets(entry.Key, subsetGroups.AsCommaSeparatedValues()), false, activity)); noErrors = false; } } } return(noErrors); }
private void ValidateExpressionSubtree(ActivityUtilities.ChildActivity childActivity, ActivityUtilities.ActivityCallStack parentChain) { if (childActivity.Activity.InternalCanInduceIdle) { Activity activity = childActivity.Activity; Activity expressionRoot = this.expressionRoot; RuntimeArgument boundRuntimeArgument = ActivityValidationServices.GetBoundRuntimeArgument(expressionRoot); ValidationError data = new ValidationError(System.Activities.SR.CanInduceIdleActivityInArgumentExpression(boundRuntimeArgument.Name, expressionRoot.Parent.DisplayName, activity.DisplayName), true, boundRuntimeArgument.Name, expressionRoot.Parent); ActivityUtilities.Add <ValidationError>(ref this.errors, data); } }
internal static void ValidateEvaluationOrder(IList <RuntimeArgument> runtimeArguments, Activity referenceActivity, ref IList <ValidationError> validationErrors) { for (int i = 0; i < (runtimeArguments.Count - 1); i++) { RuntimeArgument argument = runtimeArguments[i]; RuntimeArgument argument2 = runtimeArguments[i + 1]; if ((argument.IsEvaluationOrderSpecified && argument2.IsEvaluationOrderSpecified) && (argument.BoundArgument.EvaluationOrder == argument2.BoundArgument.EvaluationOrder)) { ActivityUtilities.Add <ValidationError>(ref validationErrors, new ValidationError(System.Activities.SR.DuplicateEvaluationOrderValues(referenceActivity.DisplayName, argument.BoundArgument.EvaluationOrder), false, argument.Name, referenceActivity)); } } }
private void ValidateExpressionSubtree(ActivityUtilities.ChildActivity childActivity, ActivityUtilities.ActivityCallStack parentChain) { Fx.Assert(this.expressionRoot != null, "This callback should be called activities in the expression subtree only."); if (childActivity.Activity.InternalCanInduceIdle) { Activity activity = childActivity.Activity; Activity expressionRoot = this.expressionRoot; RuntimeArgument runtimeArgument = GetBoundRuntimeArgument(expressionRoot); ValidationError error = new ValidationError(SR.CanInduceIdleActivityInArgumentExpression(runtimeArgument.Name, expressionRoot.Parent.DisplayName, activity.DisplayName), true, runtimeArgument.Name, expressionRoot.Parent); ActivityUtilities.Add(ref this.errors, error); } }
protected override void CacheMetadata(NativeActivityMetadata metadata) { Collection <Activity> collection = null; if (this.Trigger != null) { ActivityUtilities.Add <Activity>(ref collection, this.Trigger); } if (this.Action != null) { ActivityUtilities.Add <Activity>(ref collection, this.Action); } metadata.SetChildrenCollection(collection); metadata.SetVariablesCollection(this.Variables); }
// This method checks for duplicate evaluation order entries in a collection that is // sorted in ascendng order of evaluation order values. internal static void ValidateEvaluationOrder(IList <RuntimeArgument> runtimeArguments, Activity referenceActivity, ref IList <ValidationError> validationErrors) { for (var i = 0; i < runtimeArguments.Count - 1; i++) { var argument = runtimeArguments[i]; var nextArgument = runtimeArguments[i + 1]; if (argument.IsEvaluationOrderSpecified && nextArgument.IsEvaluationOrderSpecified) { if (argument.BoundArgument.EvaluationOrder == nextArgument.BoundArgument.EvaluationOrder) { ActivityUtilities.Add(ref validationErrors, new ValidationError(SR.DuplicateEvaluationOrderValues(referenceActivity.DisplayName, argument.BoundArgument.EvaluationOrder), false, argument.Name, referenceActivity)); } } } }
private static bool ValidateOverloadGroupDefinitions(Activity activity, OverloadGroupEquivalenceInfo equivalenceInfo, Dictionary <string, List <RuntimeArgument> > overloadGroups, ref IList <ValidationError> validationErrors) { bool flag = true; if (!equivalenceInfo.EquivalentGroupsDictionary.IsNullOrEmpty()) { Hashtable hashtable = new Hashtable(equivalenceInfo.EquivalentGroupsDictionary.Count); foreach (KeyValuePair <string, List <string> > pair in equivalenceInfo.EquivalentGroupsDictionary) { if (!hashtable.Contains(pair.Key)) { string[] array = new string[pair.Value.Count + 1]; array[0] = pair.Key; pair.Value.CopyTo(array, 1); IEnumerable <string> c = array.OrderBy <string, string>(s => s, StringComparer.Ordinal); ActivityUtilities.Add <ValidationError>(ref validationErrors, new ValidationError(System.Activities.SR.OverloadGroupsAreEquivalent(c.AsCommaSeparatedValues()), false, activity)); flag = false; for (int i = 0; i < array.Length; i++) { hashtable.Add(array[i], null); } } } return(flag); } if (!equivalenceInfo.SupersetOfGroupsDictionary.IsNullOrEmpty()) { foreach (KeyValuePair <string, List <string> > pair2 in equivalenceInfo.SupersetOfGroupsDictionary) { IList <string> list = pair2.Value.OrderBy <string, string>(s => s, StringComparer.Ordinal).ToList <string>(); string[] strArray2 = new string[list.Count]; int num2 = 0; foreach (string str in list) { if (overloadGroups[str].Any <RuntimeArgument>(a => a.IsRequired)) { strArray2[num2++] = str; } } if (num2 > 0) { ActivityUtilities.Add <ValidationError>(ref validationErrors, new ValidationError(System.Activities.SR.OverloadGroupHasSubsets(pair2.Key, strArray2.AsCommaSeparatedValues()), false, activity)); flag = false; } } } return(flag); }
internal bool InitializeRelationship(Activity parent, ref IList <ValidationError> validationErrors) { if (_cacheId == parent.CacheId) { Fx.Assert(this.Owner != null, "must have an owner here"); ValidationError validationError = new ValidationError(SR.DelegateArgumentAlreadyInUseOnActivity(this.Name, parent.DisplayName, this.Owner.DisplayName), this.Owner); ActivityUtilities.Add(ref validationErrors, validationError); // Get out early since we've already initialized this argument. return(false); } this.Owner = parent; _cacheId = parent.CacheId; return(true); }
private void ValidateElement(ActivityUtilities.ChildActivity childActivity, ActivityUtilities.ActivityCallStack parentChain) { Activity objA = childActivity.Activity; if (!this.settings.SingleLevel || object.ReferenceEquals(objA, this.rootToValidate)) { if (this.settings.HasAdditionalConstraints) { bool suppressGetChildrenViolations = this.settings.OnlyUseAdditionalConstraints || this.settings.SingleLevel; for (Type type = objA.GetType(); type != null; type = type.BaseType) { IList <Constraint> list; if (this.settings.AdditionalConstraints.TryGetValue(type, out list)) { ActivityValidationServices.RunConstraints(childActivity, parentChain, list, this.options, suppressGetChildrenViolations, ref this.errors); } if (type.IsGenericType) { IList <Constraint> list2; Type genericTypeDefinition = type.GetGenericTypeDefinition(); if ((genericTypeDefinition != null) && this.settings.AdditionalConstraints.TryGetValue(genericTypeDefinition, out list2)) { ActivityValidationServices.RunConstraints(childActivity, parentChain, list2, this.options, suppressGetChildrenViolations, ref this.errors); } } } } if (childActivity.Activity.IsExpressionRoot) { if (childActivity.Activity.HasNonEmptySubtree) { this.expressionRoot = childActivity.Activity; ActivityUtilities.FinishCachingSubtree(childActivity, parentChain, ProcessActivityTreeOptions.FullCachingOptions, new ActivityUtilities.ProcessActivityCallback(this.ValidateExpressionSubtree)); this.expressionRoot = null; } else if (childActivity.Activity.InternalCanInduceIdle) { Activity activity = childActivity.Activity; RuntimeArgument boundRuntimeArgument = ActivityValidationServices.GetBoundRuntimeArgument(activity); ValidationError data = new ValidationError(System.Activities.SR.CanInduceIdleActivityInArgumentExpression(boundRuntimeArgument.Name, activity.Parent.DisplayName, activity.DisplayName), true, boundRuntimeArgument.Name, activity.Parent); ActivityUtilities.Add <ValidationError>(ref this.errors, data); } } } }
private void FindVariablesToUnregister(bool forImplementation, EnvironmentUpdateMap map, int oldVariableCount, int offset, ref bool hasMappableLocationsRemaining) { for (int i = 0; i < oldVariableCount; i++) { Location location = this.locations[i + offset]; if (location.CanBeMapped) { if ((forImplementation && map.GetNewPrivateVariableIndex(i).HasValue) || (!forImplementation && map.GetNewVariableIndex(i).HasValue)) { hasMappableLocationsRemaining = true; } else { ActivityUtilities.Add(ref this.locationsToUnregister, location); } } } }
void UpdateVariables(int newVariablesOffset, int oldVariablesOffset, int newVariableCount, int oldVariableCount, IList <EnvironmentUpdateMapEntry> variableEntries, IList <Variable> variables, Location[] newLocations) { if (variableEntries != null) { for (int i = 0; i < variableEntries.Count; i++) { EnvironmentUpdateMapEntry entry = variableEntries[i]; Fx.Assert(entry.NewOffset >= 0 && entry.NewOffset < newVariableCount, "Variable offset is out of range"); Fx.Assert(!entry.IsNewHandle, "This should have been caught in ActivityInstanceMap.UpdateRawInstance"); if (entry.IsAddition) { Variable newVariable = variables[entry.NewOffset]; Location location = newVariable.CreateLocation(); newLocations[newVariablesOffset + entry.NewOffset] = location; if (location.CanBeMapped) { ActivityUtilities.Add(ref this.locationsToRegister, newVariable); } } else { Fx.Assert(this.locations != null && this.singleLocation == null, "Caller should have copied singleLocation into locations array"); // rearrangement of existing variable // this entry here doesn't describe variable removal newLocations[newVariablesOffset + entry.NewOffset] = this.locations[oldVariablesOffset + entry.OldOffset]; } } } // copy over unchanged variable Locations for (int i = 0; i < newVariableCount; i++) { if (newLocations[newVariablesOffset + i] == null) { Fx.Assert(i < oldVariableCount, "New variable should have a location"); Fx.Assert(this.locations != null && this.locations.Length > oldVariablesOffset + i, "locations must be non-null and index i + oldVariableOffset must be within the range of locations."); newLocations[newVariablesOffset + i] = this.locations[oldVariablesOffset + i]; } } }
internal void Validate(Activity owner, ref IList <ValidationError> validationErrors) { if (this.Expression != null) { if (this.Expression.Result != null && !this.Expression.Result.IsEmpty) { ValidationError validationError = new ValidationError(SR.ResultCannotBeSetOnArgumentExpressions, false, this.RuntimeArgument.Name, owner); ActivityUtilities.Add(ref validationErrors, validationError); } ActivityWithResult actualExpression = this.Expression; if (actualExpression is IExpressionWrapper) { actualExpression = ((IExpressionWrapper)actualExpression).InnerExpression; } switch (this.Direction) { case ArgumentDirection.In: if (actualExpression.ResultType != this.ArgumentType) { ActivityUtilities.Add( ref validationErrors, new ValidationError(SR.ArgumentValueExpressionTypeMismatch(this.ArgumentType, actualExpression.ResultType), false, this.RuntimeArgument.Name, owner)); } break; case ArgumentDirection.InOut: case ArgumentDirection.Out: Type locationType; if (!ActivityUtilities.IsLocationGenericType(actualExpression.ResultType, out locationType) || locationType != this.ArgumentType) { Type expectedType = ActivityUtilities.CreateActivityWithResult(ActivityUtilities.CreateLocation(this.ArgumentType)); ActivityUtilities.Add( ref validationErrors, new ValidationError(SR.ArgumentLocationExpressionTypeMismatch(expectedType.FullName, actualExpression.GetType().FullName), false, this.RuntimeArgument.Name, owner)); } break; } } }
internal bool InitializeRelationship(Activity parent, ref IList <ValidationError> validationErrors) { if (this.cacheId == parent.CacheId) { // We're part of the same tree walk if (this.Owner == parent) { ActivityUtilities.Add(ref validationErrors, ProcessViolation(parent, SR.ArgumentIsAddedMoreThanOnce(this.Name, this.Owner.DisplayName))); // Get out early since we've already initialized this argument. return(false); } Fx.Assert(this.Owner != null, "We must have already assigned an owner."); ActivityUtilities.Add(ref validationErrors, ProcessViolation(parent, SR.ArgumentAlreadyInUse(this.Name, this.Owner.DisplayName, parent.DisplayName))); // Get out early since we've already initialized this argument. return(false); } if (this.boundArgument != null && this.boundArgument.RuntimeArgument != this) { ActivityUtilities.Add(ref validationErrors, ProcessViolation(parent, SR.RuntimeArgumentBindingInvalid(this.Name, this.boundArgument.RuntimeArgument.Name))); return(false); } this.Owner = parent; this.cacheId = parent.CacheId; if (this.boundArgument != null) { this.boundArgument.Validate(parent, ref validationErrors); if (!this.BoundArgument.IsEmpty) { return(this.BoundArgument.Expression.InitializeRelationship(this, ref validationErrors)); } } return(true); }
protected override void CacheMetadata(NativeActivityMetadata metadata) { RuntimeArgument argument = new RuntimeArgument("Condition", typeof(bool), ArgumentDirection.In, true); metadata.Bind(this.Condition, argument); metadata.SetArgumentsCollection(new Collection <RuntimeArgument> { argument }); Collection <Activity> collection = null; if (this.Then != null) { ActivityUtilities.Add <Activity>(ref collection, this.Then); } if (this.Else != null) { ActivityUtilities.Add <Activity>(ref collection, this.Else); } metadata.SetChildrenCollection(collection); }
internal bool InitializeRelationship(Activity parent, bool isPublic, ref IList <ValidationError> validationErrors) { if (_cacheId == parent.CacheId) { if (this.Owner != null) { ValidationError validationError = new ValidationError(SR.VariableAlreadyInUseOnActivity(this.Name, parent.DisplayName, this.Owner.DisplayName), false, this.Name, parent); ActivityUtilities.Add(ref validationErrors, validationError); // Get out early since we've already initialized this variable. return(false); } } this.Owner = parent; _cacheId = parent.CacheId; this.IsPublic = isPublic; if (this.Default != null) { ActivityWithResult expression = this.Default; if (expression is Argument.IExpressionWrapper) { expression = ((Argument.IExpressionWrapper)expression).InnerExpression; } if (expression.ResultType != this.Type) { ActivityUtilities.Add( ref validationErrors, new ValidationError(SR.VariableExpressionTypeMismatch(this.Name, this.Type, expression.ResultType), false, this.Name, parent)); } return(this.Default.InitializeRelationship(this, isPublic, ref validationErrors)); } return(true); }
public void Declare(LocationReference locationReference, Activity owner, ref IList <ValidationError> validationErrors) { Fx.Assert(locationReference != null, "Must not be null"); if (locationReference.Name == null) { if (_unnamedDeclarations == null) { _unnamedDeclarations = new List <LocationReference>(); } _unnamedDeclarations.Add(locationReference); } else { if (this.Declarations.ContainsKey(locationReference.Name)) { string id = null; if (owner != null) { id = owner.Id; } ValidationError validationError = new ValidationError(SR.SymbolNamesMustBeUnique(locationReference.Name)) { Source = owner, Id = id }; ActivityUtilities.Add(ref validationErrors, validationError); } else { this.Declarations.Add(locationReference.Name, locationReference); } } }
public static void ValidateArguments(Activity activity, OverloadGroupEquivalenceInfo equivalenceInfo, Dictionary <string, List <RuntimeArgument> > overloadGroups, List <RuntimeArgument> requiredArgumentsNotInOverloadGroups, IDictionary <string, object> inputs, ref IList <ValidationError> validationErrors) { Func <RuntimeArgument, bool> func3 = null; Func <RuntimeArgument, bool> func4 = null; Predicate <RuntimeArgument> predicate2 = null; if (!requiredArgumentsNotInOverloadGroups.IsNullOrEmpty()) { foreach (RuntimeArgument argument in requiredArgumentsNotInOverloadGroups) { if (CheckIfArgumentIsNotBound(argument, inputs)) { ActivityUtilities.Add <ValidationError>(ref validationErrors, new ValidationError(System.Activities.SR.RequiredArgumentValueNotSupplied(argument.Name), false, argument.Name, activity)); } } } if (!overloadGroups.IsNullOrEmpty()) { Func <string, bool> func = null; Func <string, bool> func2 = null; Dictionary <string, bool> configurationResults = new Dictionary <string, bool>(); string key = string.Empty; int num = 0; int num2 = 0; foreach (KeyValuePair <string, List <RuntimeArgument> > pair in overloadGroups) { string str2 = pair.Key; configurationResults.Add(str2, false); IEnumerable <RuntimeArgument> source = from a in pair.Value where a.IsRequired select a; if (source.Count <RuntimeArgument>() > 0) { if (func3 == null) { func3 = localArgument => CheckIfArgumentIsBound(localArgument, inputs); } if (source.All <RuntimeArgument>(func3)) { configurationResults[str2] = true; key = str2; num++; } } else { num2++; if (func4 == null) { func4 = localArgument => CheckIfArgumentIsBound(localArgument, inputs); } if ((from a in pair.Value where !a.IsRequired select a).Any <RuntimeArgument>(func4)) { configurationResults[str2] = true; key = str2; num++; } } } switch (num) { case 0: if (num2 == 0) { ActivityUtilities.Add <ValidationError>(ref validationErrors, new ValidationError(System.Activities.SR.NoOverloadGroupsAreConfigured, false, activity)); return; } return; case 1: { HashSet <RuntimeArgument> second = new HashSet <RuntimeArgument>(overloadGroups[key]); if (predicate2 == null) { predicate2 = localArgument => CheckIfArgumentIsBound(localArgument, inputs); } Predicate <RuntimeArgument> match = predicate2; List <string> list = null; if (!equivalenceInfo.DisjointGroupsDictionary.IsNullOrEmpty()) { equivalenceInfo.DisjointGroupsDictionary.TryGetValue(key, out list); } List <string> list2 = null; if (!equivalenceInfo.OverlappingGroupsDictionary.IsNullOrEmpty()) { equivalenceInfo.OverlappingGroupsDictionary.TryGetValue(key, out list2); } if (func == null) { func = k => !configurationResults[k]; } foreach (string str3 in configurationResults.Keys.Where <string>(func)) { if ((list != null) && list.Contains(str3)) { foreach (RuntimeArgument argument2 in overloadGroups[str3].FindAll(match)) { ActivityUtilities.Add <ValidationError>(ref validationErrors, new ValidationError(System.Activities.SR.ExtraOverloadGroupPropertiesConfigured(key, argument2.Name, str3), false, activity)); } } else if ((list2 != null) && list2.Contains(str3)) { HashSet <RuntimeArgument> first = new HashSet <RuntimeArgument>(overloadGroups[str3]); IEnumerable <RuntimeArgument> enumerable3 = first.Intersect <RuntimeArgument>(second); foreach (RuntimeArgument argument3 in first.Except <RuntimeArgument>(enumerable3).ToList <RuntimeArgument>().FindAll(match)) { ActivityUtilities.Add <ValidationError>(ref validationErrors, new ValidationError(System.Activities.SR.ExtraOverloadGroupPropertiesConfigured(key, argument3.Name, str3), false, activity)); } } } return; } } if (func2 == null) { func2 = k => configurationResults[k]; } IEnumerable <string> c = configurationResults.Keys.Where <string>(func2).OrderBy <string, string>(k => k, StringComparer.Ordinal); ActivityUtilities.Add <ValidationError>(ref validationErrors, new ValidationError(System.Activities.SR.MultipleOverloadGroupsConfigured(c.AsCommaSeparatedValues()), false, activity)); } }
public static void ValidateArguments(Activity activity, OverloadGroupEquivalenceInfo equivalenceInfo, Dictionary <string, List <RuntimeArgument> > overloadGroups, List <RuntimeArgument> requiredArgumentsNotInOverloadGroups, IDictionary <string, object> inputs, ref IList <ValidationError> validationErrors) { if (!requiredArgumentsNotInOverloadGroups.IsNullOrEmpty()) { // 1. Check if there are any Required arguments (outside overload groups) that were not specified. foreach (RuntimeArgument argument in requiredArgumentsNotInOverloadGroups) { if (CheckIfArgumentIsNotBound(argument, inputs)) { ActivityUtilities.Add(ref validationErrors, new ValidationError(SR.RequiredArgumentValueNotSupplied(argument.Name), false, argument.Name, activity)); } } } if (!overloadGroups.IsNullOrEmpty()) { //1. Check to see if any of the overload groups are configured. // An overload group is considered to be completely configured if all it's required arguments // are non-null. If an overload group does not have any required arguments then the group is // considered configured if any of the optional arguments are configured. Dictionary <string, bool> configurationResults = new Dictionary <string, bool>(); string configuredGroupName = string.Empty; int configuredCount = 0; int overloadGroupsWithNoRequiredArgs = 0; foreach (KeyValuePair <string, List <RuntimeArgument> > entry in overloadGroups) { string groupName = entry.Key; configurationResults.Add(groupName, false); IEnumerable <RuntimeArgument> requiredArguments = entry.Value.Where((a) => a.IsRequired); if (requiredArguments.Count() > 0) { if (requiredArguments.All(localArgument => CheckIfArgumentIsBound(localArgument, inputs))) { configurationResults[groupName] = true; configuredGroupName = groupName; configuredCount++; } } else { overloadGroupsWithNoRequiredArgs++; IEnumerable <RuntimeArgument> optionalArguments = entry.Value.Where((a) => !a.IsRequired); if (optionalArguments.Any(localArgument => CheckIfArgumentIsBound(localArgument, inputs))) { configurationResults[groupName] = true; configuredGroupName = groupName; configuredCount++; } } } //2. It's an error if none of the groups are configured unless there // is atleast one overload group with no required arguments in it. if (configuredCount == 0) { if (overloadGroupsWithNoRequiredArgs == 0) { ActivityUtilities.Add(ref validationErrors, new ValidationError(SR.NoOverloadGroupsAreConfigured, false, activity)); } } //3. If only one overload group was configured, ensure none of the disjoint/overlapping groups have any // required or optional activity arguments set. else if (configuredCount == 1) { HashSet <RuntimeArgument> configuredOverloadSet = new HashSet <RuntimeArgument>(overloadGroups[configuredGroupName]); Predicate <RuntimeArgument> checkIfArgumentIsBound = new Predicate <RuntimeArgument>(localArgument => CheckIfArgumentIsBound(localArgument, inputs)); List <string> disjointGroups = null; if (!equivalenceInfo.DisjointGroupsDictionary.IsNullOrEmpty()) { equivalenceInfo.DisjointGroupsDictionary.TryGetValue(configuredGroupName, out disjointGroups); } List <string> overlappingGroups = null; if (!equivalenceInfo.OverlappingGroupsDictionary.IsNullOrEmpty()) { equivalenceInfo.OverlappingGroupsDictionary.TryGetValue(configuredGroupName, out overlappingGroups); } // Iterate over the groups that may not be completely configured. foreach (string groupName in configurationResults.Keys.Where((k) => configurationResults[k] == false)) { // Check if the partially configured group name is in the disjoint groups list. // If so, find all configured arguments. if (disjointGroups != null && disjointGroups.Contains(groupName)) { foreach (RuntimeArgument configuredArgument in overloadGroups[groupName].FindAll(checkIfArgumentIsBound)) { ActivityUtilities.Add(ref validationErrors, new ValidationError(SR.ExtraOverloadGroupPropertiesConfigured(configuredGroupName, configuredArgument.Name, groupName), false, activity)); } } else if (overlappingGroups != null && overlappingGroups.Contains(groupName)) { // Find all arguments of the Overlapping group that are not in the configuredOverloadSet. HashSet <RuntimeArgument> overloadGroupSet = new HashSet <RuntimeArgument>(overloadGroups[groupName]); IEnumerable <RuntimeArgument> intersectSet = overloadGroupSet.Intersect(configuredOverloadSet); List <RuntimeArgument> exceptList = overloadGroupSet.Except(intersectSet).ToList(); foreach (RuntimeArgument configuredArgument in exceptList.FindAll(checkIfArgumentIsBound)) { ActivityUtilities.Add(ref validationErrors, new ValidationError(SR.ExtraOverloadGroupPropertiesConfigured(configuredGroupName, configuredArgument.Name, groupName), false, activity)); } } } } //4. If more than one overload group is configured, generate an error. else { IEnumerable <string> configuredGroups = configurationResults.Keys.Where((k) => configurationResults[k]).OrderBy((k) => k, StringComparer.Ordinal); ActivityUtilities.Add(ref validationErrors, new ValidationError(SR.MultipleOverloadGroupsConfigured(configuredGroups.AsCommaSeparatedValues()), false, activity)); } } }
internal static void RunConstraints(ActivityUtilities.ChildActivity childActivity, ActivityUtilities.ActivityCallStack parentChain, IList <Constraint> constraints, ProcessActivityTreeOptions options, bool suppressGetChildrenViolations, ref IList <ValidationError> validationErrors) { if (constraints != null) { Activity activity = childActivity.Activity; LocationReferenceEnvironment parentEnvironment = activity.GetParentEnvironment(); Dictionary <string, object> inputs = new Dictionary <string, object>(2); for (int i = 0; i < constraints.Count; i++) { Constraint workflow = constraints[i]; if (workflow != null) { object obj2; inputs["ToValidate"] = activity; ValidationContext context = new ValidationContext(childActivity, parentChain, options, parentEnvironment); inputs["ToValidateContext"] = context; IDictionary <string, object> dictionary2 = null; try { dictionary2 = WorkflowInvoker.Invoke(workflow, inputs); } catch (Exception exception) { if (Fx.IsFatal(exception)) { throw; } ValidationError data = new ValidationError(System.Activities.SR.InternalConstraintException(workflow.DisplayName, activity.GetType().FullName, activity.DisplayName, exception.ToString()), false) { Source = activity, Id = activity.Id }; ActivityUtilities.Add <ValidationError>(ref validationErrors, data); } if ((dictionary2 != null) && dictionary2.TryGetValue("ViolationList", out obj2)) { IList <ValidationError> list = (IList <ValidationError>)obj2; if (list.Count > 0) { Activity activity2; if (validationErrors == null) { validationErrors = new List <ValidationError>(); } string str = GenerateValidationErrorPrefix(childActivity.Activity, parentChain, out activity2); for (int j = 0; j < list.Count; j++) { ValidationError item = list[j]; item.Source = activity2; item.Id = activity2.Id; if (!string.IsNullOrEmpty(str)) { item.Message = str + item.Message; } validationErrors.Add(item); } } } if (!suppressGetChildrenViolations) { context.AddGetChildrenErrors(ref validationErrors); } } } } }
private void ValidateElement(ActivityUtilities.ChildActivity childActivity, ActivityUtilities.ActivityCallStack parentChain) { Activity toValidate = childActivity.Activity; if (!this.settings.SingleLevel || object.ReferenceEquals(toValidate, this.rootToValidate)) { // 0. Open time violations are captured by the CacheMetadata walk. // 1. Argument validations are done by the CacheMetadata walk. // 2. Build constraints are done by the CacheMetadata walk. // 3. Then do policy constraints if (this.settings.HasAdditionalConstraints && childActivity.CanBeExecuted && parentChain.WillExecute) { bool suppressGetChildrenViolations = this.settings.OnlyUseAdditionalConstraints || this.settings.SingleLevel; Type currentType = toValidate.GetType(); while (currentType != null) { if (this.settings.AdditionalConstraints.TryGetValue(currentType, out IList <Constraint> policyConstraints)) { RunConstraints(childActivity, parentChain, policyConstraints, this.options, suppressGetChildrenViolations, ref this.errors); } if (currentType.IsGenericType) { Type genericDefinitionType = currentType.GetGenericTypeDefinition(); if (genericDefinitionType != null) { if (this.settings.AdditionalConstraints.TryGetValue(genericDefinitionType, out IList <Constraint> genericTypePolicyConstraints)) { RunConstraints(childActivity, parentChain, genericTypePolicyConstraints, this.options, suppressGetChildrenViolations, ref this.errors); } } } currentType = currentType.BaseType; } } //4. Validate if the argument expression subtree contains an activity that can induce idle. if (childActivity.Activity.IsExpressionRoot) { if (childActivity.Activity.HasNonEmptySubtree) { this.expressionRoot = childActivity.Activity; // Back-compat: In Dev10 we always used ProcessActivityTreeOptions.FullCachingOptions here, and ignored this.options. // So we need to continue to do that, unless the new Dev11 flag SkipRootConfigurationValidation is passed. ProcessActivityTreeOptions options = this.options.SkipRootConfigurationValidation ? this.options : ProcessActivityTreeOptions.FullCachingOptions; ActivityUtilities.FinishCachingSubtree(childActivity, parentChain, options, ValidateExpressionSubtree); this.expressionRoot = null; } else if (childActivity.Activity.InternalCanInduceIdle) { Activity activity = childActivity.Activity; RuntimeArgument runtimeArgument = GetBoundRuntimeArgument(activity); ValidationError error = new ValidationError(SR.CanInduceIdleActivityInArgumentExpression(runtimeArgument.Name, activity.Parent.DisplayName, activity.DisplayName), true, runtimeArgument.Name, activity.Parent); ActivityUtilities.Add(ref this.errors, error); } } } }
internal static void RunConstraints(ActivityUtilities.ChildActivity childActivity, ActivityUtilities.ActivityCallStack parentChain, IList <Constraint> constraints, ProcessActivityTreeOptions options, bool suppressGetChildrenViolations, ref IList <ValidationError> validationErrors) { if (constraints != null) { Activity toValidate = childActivity.Activity; LocationReferenceEnvironment environment = toValidate.GetParentEnvironment(); Dictionary <string, object> inputDictionary = new Dictionary <string, object>(2); for (int constraintIndex = 0; constraintIndex < constraints.Count; constraintIndex++) { Constraint constraint = constraints[constraintIndex]; // there may be null entries here if (constraint == null) { continue; } inputDictionary[Constraint.ToValidateArgumentName] = toValidate; ValidationContext validationContext = new ValidationContext(childActivity, parentChain, options, environment); inputDictionary[Constraint.ToValidateContextArgumentName] = validationContext; IDictionary <string, object> results = null; try { results = WorkflowInvoker.Invoke(constraint, inputDictionary); } catch (Exception e) { if (Fx.IsFatal(e)) { throw; } ValidationError constraintExceptionValidationError = new ValidationError(SR.InternalConstraintException(constraint.DisplayName, toValidate.GetType().FullName, toValidate.DisplayName, e.ToString()), false) { Source = toValidate, Id = toValidate.Id }; ActivityUtilities.Add(ref validationErrors, constraintExceptionValidationError); } if (results != null) { if (results.TryGetValue(Constraint.ValidationErrorListArgumentName, out object resultValidationErrors)) { IList <ValidationError> validationErrorList = (IList <ValidationError>)resultValidationErrors; if (validationErrorList.Count > 0) { if (validationErrors == null) { validationErrors = new List <ValidationError>(); } string prefix = ActivityValidationServices.GenerateValidationErrorPrefix(childActivity.Activity, parentChain, options, out Activity source); for (int validationErrorIndex = 0; validationErrorIndex < validationErrorList.Count; validationErrorIndex++) { ValidationError validationError = validationErrorList[validationErrorIndex]; validationError.Source = source; validationError.Id = source.Id; if (!string.IsNullOrEmpty(prefix)) { validationError.Message = prefix + validationError.Message; } validationErrors.Add(validationError); } } } } if (!suppressGetChildrenViolations) { validationContext.AddGetChildrenErrors(ref validationErrors); } } } }
internal static void ValidateRootInputs(Activity rootActivity, IDictionary <string, object> inputs) { IList <ValidationError> validationErrors = null; ValidationHelper.ValidateArguments(rootActivity, rootActivity.EquivalenceInfo, rootActivity.OverloadGroups, rootActivity.RequiredArgumentsNotInOverloadGroups, inputs, ref validationErrors); // Validate if there are any extra arguments passed in the input dictionary if (inputs != null) { List <string> unusedArguments = null; IEnumerable <RuntimeArgument> arguments = rootActivity.RuntimeArguments.Where((a) => ArgumentDirectionHelper.IsIn(a.Direction)); foreach (string key in inputs.Keys) { bool found = false; foreach (RuntimeArgument argument in arguments) { if (argument.Name == key) { found = true; // Validate if the input argument type matches the expected argument type. if (inputs.TryGetValue(key, out object inputArgumentValue)) { if (!TypeHelper.AreTypesCompatible(inputArgumentValue, argument.Type)) { ActivityUtilities.Add(ref validationErrors, new ValidationError(SR.InputParametersTypeMismatch(argument.Type, argument.Name), rootActivity)); } } // The ValidateArguments will validate Required in-args and hence not duplicating that validation if the key is not found. break; } } if (!found) { if (unusedArguments == null) { unusedArguments = new List <string>(); } unusedArguments.Add(key); } } if (unusedArguments != null) { ActivityUtilities.Add(ref validationErrors, new ValidationError(SR.UnusedInputArguments(unusedArguments.AsCommaSeparatedValues()), rootActivity)); } } if (validationErrors != null && validationErrors.Count > 0) { string parameterName = "rootArgumentValues"; ExceptionReason reason = ExceptionReason.InvalidNonNullInputs; if (inputs == null) { parameterName = "program"; reason = ExceptionReason.InvalidNullInputs; } string exceptionString = GenerateExceptionString(validationErrors, reason); if (exceptionString != null) { throw FxTrace.Exception.Argument(parameterName, exceptionString); } } }
internal bool InitializeRelationship(Activity parent, ActivityCollectionType collectionType, ref IList <ValidationError> validationErrors) { if (this.cacheId == parent.CacheId) { Fx.Assert(this.owner != null, "We must have set the owner when we set the cache ID"); // This means that we've already encountered a parent in the tree // Validate that it is visible. // In order to see the activity the new parent must be // in the implementation IdSpace of an activity which has // a public reference to it. Activity referenceTarget = parent.MemberOf.Owner; if (referenceTarget == null) { Activity handler = this.Handler; if (handler == null) { ActivityUtilities.Add(ref validationErrors, new ValidationError(SR.ActivityDelegateCannotBeReferencedWithoutTargetNoHandler(parent.DisplayName, this.owner.DisplayName), false, parent)); } else { ActivityUtilities.Add(ref validationErrors, new ValidationError(SR.ActivityDelegateCannotBeReferencedWithoutTarget(handler.DisplayName, parent.DisplayName, this.owner.DisplayName), false, parent)); } return(false); } else if (!referenceTarget.Delegates.Contains(this) && !referenceTarget.ImportedDelegates.Contains(this)) { Activity handler = this.Handler; if (handler == null) { ActivityUtilities.Add(ref validationErrors, new ValidationError(SR.ActivityDelegateCannotBeReferencedNoHandler(parent.DisplayName, referenceTarget.DisplayName, this.owner.DisplayName), false, parent)); } else { ActivityUtilities.Add(ref validationErrors, new ValidationError(SR.ActivityDelegateCannotBeReferenced(handler.DisplayName, parent.DisplayName, referenceTarget.DisplayName, this.owner.DisplayName), false, parent)); } return(false); } // This is a valid reference so we want to allow // normal processing to proceed. return(true); } this.owner = parent; this.cacheId = parent.CacheId; this.parentCollectionType = collectionType; InternalCacheMetadata(); // We need to setup the delegate environment so that it is // available when we process the Handler. LocationReferenceEnvironment delegateEnvironment = null; if (collectionType == ActivityCollectionType.Implementation) { delegateEnvironment = parent.ImplementationEnvironment; } else { delegateEnvironment = parent.PublicEnvironment; } if (this.RuntimeDelegateArguments.Count > 0) { ActivityLocationReferenceEnvironment newEnvironment = new ActivityLocationReferenceEnvironment(delegateEnvironment); delegateEnvironment = newEnvironment; for (int argumentIndex = 0; argumentIndex < this.RuntimeDelegateArguments.Count; argumentIndex++) { RuntimeDelegateArgument runtimeDelegateArgument = this.RuntimeDelegateArguments[argumentIndex]; DelegateArgument delegateArgument = runtimeDelegateArgument.BoundArgument; if (delegateArgument != null) { if (delegateArgument.Direction != runtimeDelegateArgument.Direction) { ActivityUtilities.Add(ref validationErrors, new ValidationError(SR.RuntimeDelegateArgumentDirectionIncorrect, parent)); } if (delegateArgument.Type != runtimeDelegateArgument.Type) { ActivityUtilities.Add(ref validationErrors, new ValidationError(SR.RuntimeDelegateArgumentTypeIncorrect, parent)); } // NOTE: We don't initialize this relationship here because // at runtime we'll actually just place these variables in the // environment of the Handler. We'll initialize and set an // ID when we process the Handler. newEnvironment.Declare(delegateArgument, this.owner, ref validationErrors); } } } this.Environment = delegateEnvironment; if (this.Handler != null) { return(this.Handler.InitializeRelationship(this, collectionType, ref validationErrors)); } return(true); }