/// <summary> /// Validates the inputs. Returns true if all of the UI controls contain valid values. Otherwise, returns false. /// </summary> /// <returns>true if all of the UI controls contain valid values. Otherwise, false.</returns> public override bool ValidateInputs() { Logger.Instance.WriteMethodEntry(); try { // Use the controller to validate standard activity controls // and return false if a problem was identified if (!this.controller.ValidateInputs()) { return(false); } ExpressionEvaluator evaluator = new ExpressionEvaluator(); if (this.advanced.Value) { if (this.queryResources.Value) { // Loop through all active query listings and make sure they are valid foreach (DefinitionListing query in this.queries.DefinitionListings.Where(query => query.Active)) { // If a value is missing for key or query, the definition // will be null and the listing fails validation if (query.Definition == null) { this.controller.ValidationError = ActivitySettings.QueryDefinitionValidationError; return(false); } // Make sure that the specified query key is properly formatted if (!Regex.Match(query.Definition.Left, RegexPattern).Success) { this.controller.ValidationError = string.Format(CultureInfo.CurrentUICulture, ActivitySettings.QueryDefintionLeftValidationError, query.Definition.Left); return(false); } // Make sure that the specified XPath filter is properly formatted if (!ExpressionEvaluator.IsXPath(query.Definition.Right)) { this.controller.ValidationError = string.Format(CultureInfo.CurrentUICulture, ActivitySettings.QueryDefintionRightValidationError, query.Definition.Left); return(false); } } } try { if (!string.IsNullOrEmpty(this.activityExecutionCondition.Value)) { evaluator.ParseExpression(this.activityExecutionCondition.Value); // Verify that the activity execution condition resolves to a Boolean value if (!evaluator.IsBooleanExpression(this.activityExecutionCondition.Value)) { this.controller.ValidationError = ActivitySettings.ActivityExecutionConditionValidationError; return(false); } } if (!string.IsNullOrEmpty(this.iteration.Value)) { evaluator.ParseExpression(this.iteration.Value); } if (GetActorType(this.actorType.Value) == ActorType.Resolve) { evaluator.ParseExpression(this.actorString.Value); } } catch (WorkflowActivityLibraryException ex) { this.controller.ValidationError = ex.Message; return(false); } if (this.applyAuthorizationPolicy.Value && GetActorType(this.actorType.Value) == ActorType.Service) { this.controller.ValidationError = ActivitySettings.RequestActorValidationError; return(false); } } // Loop through all active update listings and make sure they are valid foreach (DefinitionListing update in this.updates.DefinitionListings.Where(update => update.Active)) { if (update.Definition == null) { // If a value is missing for source or target, the definition // will be null and the listing fails validation this.controller.ValidationError = ActivitySettings.UpdateDefinitionValidationError; return(false); } // Attempt to parse the source expression and target lookup or variable // Fail validation if an exception is thrown for either try { evaluator.ParseExpression(update.Definition.Left); ParameterType targetType = ParameterType.Lookup; try { targetType = ExpressionEvaluator.DetermineParameterType(update.Definition.Right); } catch (WorkflowActivityLibraryException) { } // Target variables are valid // Target lookups require further evaluation to determine if they represent a valid target if (targetType != ParameterType.Variable) { LookupEvaluator lookup = new LookupEvaluator(update.Definition.Right); if (!lookup.IsValidTarget) { this.controller.ValidationError = string.Format(CultureInfo.CurrentUICulture, ActivitySettings.TargetLookupValidationError, update.Definition.Right); return(false); } } } catch (WorkflowActivityLibraryException ex) { this.controller.ValidationError = ex.Message; return(false); } } // Verify that no [//Query/...] or [//Value/...] expressions exist // if the query resources or iteration options are not enabled, respectively bool containsQueryExpressions = false; bool containsValueExpressions = false; foreach (LookupEvaluator lookup in evaluator.LookupCache.Keys.Select(key => new LookupEvaluator(key))) { if (lookup.Parameter == LookupParameter.Queries) { containsQueryExpressions = true; } if (lookup.Parameter == LookupParameter.Value) { containsValueExpressions = true; } } if (!this.queryResources.Value && containsQueryExpressions) { this.controller.ValidationError = ActivitySettings.QueryResourcesValidationError; return(false); } if (string.IsNullOrEmpty(this.iteration.Value) && containsValueExpressions) { this.controller.ValidationError = ActivitySettings.IterationValidationError; return(false); } // If no errors were found, clear any validation error and return true this.controller.ValidationError = string.Empty; return(true); } catch (Exception e) { Logger.Instance.ReportError(e); throw; } finally { Logger.Instance.WriteMethodExit(); } }
/// <summary> /// Validates the inputs. Returns true if all of the UI controls contain valid values. Otherwise, returns false. /// </summary> /// <returns>true if all of the UI controls contain valid values. Otherwise, false.</returns> public override bool ValidateInputs() { Logger.Instance.WriteMethodEntry(); try { // Use the controller to validate standard activity controls // and return false if a problem was identified if (!this.controller.ValidateInputs()) { return(false); } ExpressionEvaluator evaluator = new ExpressionEvaluator(); // Verify that the resource type is valid if (!Regex.Match(this.resourceType.Value, RegexPattern).Success) { this.controller.ValidationError = string.Format(CultureInfo.CurrentUICulture, ActivitySettings.ResourceTypeValidationError, this.resourceType.Value); return(false); } if (this.advanced.Value) { if (this.queryResources.Value) { // Loop through all active query listings and make sure they are valid foreach (DefinitionListing query in this.queries.DefinitionListings) { if (query.Active) { // If a value is missing for key or query, the definition // will be null and the listing fails validation if (query.Definition == null) { this.controller.ValidationError = ActivitySettings.QueryDefinitionValidationError; return(false); } // Make sure that the specified query key is properly formatted if (!Regex.Match(query.Definition.Left, RegexPattern).Success) { this.controller.ValidationError = string.Format(CultureInfo.CurrentUICulture, ActivitySettings.QueryDefintionLeftValidationError, query.Definition.Left); return(false); } // Make sure that the specified XPath filter is properly formatted if (!ExpressionEvaluator.IsXPath(query.Definition.Right)) { this.controller.ValidationError = string.Format(CultureInfo.CurrentUICulture, ActivitySettings.QueryDefintionRightValidationError, query.Definition.Left); return(false); } } } } try { if (!string.IsNullOrEmpty(this.activityExecutionCondition.Value)) { evaluator.ParseExpression(this.activityExecutionCondition.Value); // Verify that the activity execution condition resolves to a Boolean value if (!evaluator.IsBooleanExpression(this.activityExecutionCondition.Value)) { this.controller.ValidationError = ActivitySettings.ActivityExecutionConditionValidationError; return(false); } } if (!string.IsNullOrEmpty(this.iteration.Value)) { evaluator.ParseExpression(this.iteration.Value); } if (GetActorType(this.actorType.Value) == ActorType.Resolve) { evaluator.ParseExpression(this.actorString.Value); } // Verify that the supplied conflict filter is a valid XPath query, if necessary if (this.checkForConflict.Value && !ExpressionEvaluator.IsXPath(this.conflictFilter.Value)) { this.controller.ValidationError = ActivitySettings.ConflictResourceSearchFilterValidationError; return(false); } // If necessary, parse the created resource ID target lookup to ensure its validity if (!string.IsNullOrEmpty(this.createdResourceIdTarget.Value)) { LookupEvaluator createdTargetLookup = new LookupEvaluator(this.createdResourceIdTarget.Value); if (!createdTargetLookup.IsValidTarget) { this.controller.ValidationError = string.Format(CultureInfo.CurrentUICulture, ActivitySettings.TargetLookupValidationError, this.createdResourceIdTarget.Value); return(false); } } // If necessary, parse the conflicting resource ID target lookup to ensure its validity if (this.checkForConflict.Value && !string.IsNullOrEmpty(this.conflictingResourceIdTarget.Value)) { LookupEvaluator conflictingTargetLookup = new LookupEvaluator(this.conflictingResourceIdTarget.Value); if (!conflictingTargetLookup.IsValidTarget) { this.controller.ValidationError = string.Format(CultureInfo.CurrentUICulture, ActivitySettings.TargetLookupValidationError, this.conflictingResourceIdTarget.Value); return(false); } } } catch (WorkflowActivityLibraryException ex) { // If an exception was thrown while attempting to parse lookups, report the error this.controller.ValidationError = ex.Message; return(false); } if (this.applyAuthorizationPolicy.Value && GetActorType(this.actorType.Value) == ActorType.Service) { this.controller.ValidationError = ActivitySettings.RequestActorValidationError; return(false); } } // Loop through all active definition listings and make sure they are valid foreach (DefinitionListing listing in this.attributes.DefinitionListings) { if (!listing.Active) { continue; } if (listing.Definition == null) { // If a value is missing for source or target, the definition // will be null and the listing fails validation // Because the activity allows for the creation of a resource without any attributes, // we need to check if this is the only active listing for the form and, if so, // verify that all fields have been left blank before failing validation int countActive = this.attributes.DefinitionListings.Count(l => l.Active); if (countActive != 1 || !string.IsNullOrEmpty(listing.State.Left) || !string.IsNullOrEmpty(listing.State.Right)) { this.controller.ValidationError = ActivitySettings.AttributeDefinitionValidationError; return(false); } } else { // Attempt to parse the source expression and fail validation // if an exception is thrown by the expression evaluator try { evaluator.ParseExpression(listing.Definition.Left); } catch (WorkflowActivityLibraryException ex) { this.controller.ValidationError = ex.Message; return(false); } ParameterType targetType = ParameterType.String; try { targetType = ExpressionEvaluator.DetermineParameterType(listing.Definition.Right, true); } catch (WorkflowActivityLibraryException) { } // Target variables are valid // For anything else, make sure that the target attribute matches the regular // expression for FIM attributes if (targetType != ParameterType.Variable) { if (!Regex.Match(listing.Definition.Right, RegexPattern).Success) { this.controller.ValidationError = string.Format(CultureInfo.CurrentUICulture, ActivitySettings.TargetValidationError, listing.Definition.Right); return(false); } } } } // Verify that no [//Query/...] or [//Value/...] expressions exist // if the query resources or iteration options are not enabled, respectively bool containsQueryExpressions = false; bool containsValueExpressions = false; foreach (LookupEvaluator lookup in evaluator.LookupCache.Keys.Select(key => new LookupEvaluator(key))) { if (lookup.Parameter == LookupParameter.Queries) { containsQueryExpressions = true; } if (lookup.Parameter == LookupParameter.Value) { containsValueExpressions = true; } } if (!this.queryResources.Value && containsQueryExpressions) { this.controller.ValidationError = ActivitySettings.QueryResourcesValidationError; return(false); } if (string.IsNullOrEmpty(this.iteration.Value) && containsValueExpressions) { this.controller.ValidationError = ActivitySettings.IterationValidationError; return(false); } // If no errors were found, clear any validation error and return true this.controller.ValidationError = string.Empty; return(true); } catch (Exception e) { Logger.Instance.ReportError(e); throw; } finally { Logger.Instance.WriteMethodExit(); } }
/// <summary> /// Handles the ExecuteCode event of the BuildRequests CodeActivity. /// </summary> /// <param name="sender">The source of the event.</param> /// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param> private void BuildRequests_ExecuteCode(object sender, EventArgs e) { Logger.Instance.WriteMethodEntry(EventIdentifier.UpdateLookupsBuildRequestsExecuteCode); try { foreach (UpdateLookupDefinition update in this.UpdateLookupDefinitions) { LookupEvaluator lookup = new LookupEvaluator(update.TargetLookup); if (lookup.TargetIsWorkflowDictionary) { // Get the parent workflow to facilitate access to the workflow dictionary SequentialWorkflow parentWorkflow; SequentialWorkflow.TryGetContainingWorkflow(this, out parentWorkflow); // For simplicity, start by adding the key to the parent workflow dictionary so we can assume that its there if (!parentWorkflow.WorkflowDictionary.ContainsKey(lookup.TargetAttribute)) { parentWorkflow.WorkflowDictionary.Add(lookup.TargetAttribute, null); } if (update.Mode == UpdateMode.Modify) { parentWorkflow.WorkflowDictionary[lookup.TargetAttribute] = update.Value; } else if (update.Value != null) { // Use reflection to determine the expected List<> type based on the value // Also get the Add and Remove methods for the list Type listType = typeof(List <>).MakeGenericType(new Type[] { update.Value.GetType() }); MethodInfo add = listType.GetMethod("Add"); MethodInfo remove = listType.GetMethod("Remove"); switch (update.Mode) { case UpdateMode.Insert: if (parentWorkflow.WorkflowDictionary[lookup.TargetAttribute] == null) { parentWorkflow.WorkflowDictionary[lookup.TargetAttribute] = update.Value; } else if (parentWorkflow.WorkflowDictionary[lookup.TargetAttribute].GetType() == update.Value.GetType()) { // Single value, create a new instance of the appropriate List<> type // and add both values: existing and new object existingValue = parentWorkflow.WorkflowDictionary[lookup.TargetAttribute]; parentWorkflow.WorkflowDictionary[lookup.TargetAttribute] = Activator.CreateInstance(listType); add.Invoke(parentWorkflow.WorkflowDictionary[lookup.TargetAttribute], new object[] { existingValue }); add.Invoke(parentWorkflow.WorkflowDictionary[lookup.TargetAttribute], new object[] { update.Value }); } else if (parentWorkflow.WorkflowDictionary[lookup.TargetAttribute].GetType() == listType) { // The dictionary key is a list of the expected type, add the value add.Invoke(parentWorkflow.WorkflowDictionary[lookup.TargetAttribute], new object[] { update.Value }); } else { // We have a problem and need to report an error throw Logger.Instance.ReportError(new WorkflowActivityLibraryException(Messages.UpdateLookup_InsertVariableError, update.Value.GetType(), lookup.TargetAttribute, parentWorkflow.WorkflowDictionary[lookup.TargetAttribute].GetType())); } break; case UpdateMode.Remove: if (parentWorkflow.WorkflowDictionary[lookup.TargetAttribute] == null) { // Do nothing } else if (parentWorkflow.WorkflowDictionary[lookup.TargetAttribute].Equals(update.Value)) { // A single matching value exists, clear the variable parentWorkflow.WorkflowDictionary[lookup.TargetAttribute] = null; } else if (parentWorkflow.WorkflowDictionary[lookup.TargetAttribute].GetType() == listType) { // The variable is a list of the expected type, attempt to remove the value remove.Invoke(parentWorkflow.WorkflowDictionary[lookup.TargetAttribute], new object[] { update.Value }); // Check the count on the list to determine if we are down to a single value or have no value // If so, adjust the value of the variable accordingly to eliminate the list object listValue = null; int i = 0; foreach (object o in (IEnumerable)parentWorkflow.WorkflowDictionary[lookup.TargetAttribute]) { i += 1; listValue = o; } if (i <= 1) { parentWorkflow.WorkflowDictionary[lookup.TargetAttribute] = listValue; } } break; } } // If we ended up with a null value in the workflow dictionary key, // remove the key to cleanup after ourselves if (parentWorkflow.WorkflowDictionary[lookup.TargetAttribute] == null) { parentWorkflow.WorkflowDictionary.Remove(lookup.TargetAttribute); } } else if (!string.IsNullOrEmpty(lookup.TargetResourceLookup) && this.TargetLookups.ContainsKey(lookup.TargetResourceLookup) && this.TargetLookups[lookup.TargetResourceLookup] != null) { // Based on the type of the resolved target lookup (should be Guid or List<Guid>) // build the list of target resources for the update List <Guid> targets = new List <Guid>(); if (this.TargetLookups[lookup.TargetResourceLookup] is Guid) { targets.Add((Guid)this.TargetLookups[lookup.TargetResourceLookup]); } else if (this.TargetLookups[lookup.TargetResourceLookup].GetType() == typeof(List <Guid>)) { targets.AddRange((List <Guid>) this.TargetLookups[lookup.TargetResourceLookup]); } foreach (Guid target in targets) { // Add the target to the update requests dictionary, if it doesn't already exist, // and add the new update request parameter if (!this.PendingRequests.ContainsKey(target)) { this.PendingRequests.Add(target, new List <UpdateRequestParameter>()); } this.PendingRequests[target].Add(new UpdateRequestParameter(lookup.TargetAttribute, update.Mode, update.Value)); } } } // If there are requests that need to be submitted to fulfill the updates, // assign the list of targets to the for each loop which will evaluate each change // to determine if they will result in changes if (this.PendingRequests.Count > 0) { this.ForEachPending.InitialChildData = this.PendingRequests.Keys.ToList(); } Logger.Instance.WriteVerbose(EventIdentifier.UpdateLookupsBuildRequestsExecuteCode, "The number of requests that need to be submitted to fulfill the updates: '{0}'.", this.PendingRequests.Count); } finally { Logger.Instance.WriteMethodExit(EventIdentifier.UpdateLookupsBuildRequestsExecuteCode); } }
/// <summary> /// Evaluate a string based expression. /// </summary> /// <param name="expression">The expression to evaluate</param> /// <param name="variableLookup">A delegate that should return the value of the variable specified.</param> /// <returns>An evaluated expression</returns> public static int Evaluate(string expression, LookupEvaluator variableLookup) { // Get all tokens then remap and strip all whitespace // var tokens = Regex.Split(expression, "(?<=[-+*/(),])(?=.)|(?<=.)(?=[-+*/(),])") .Select(element => Regex.Replace(element, "\\s+", "")) .Where(element => element != "") .ToArray(); var OperationStack = new Stack <OperationToken>(); var NumberStack = new Stack <double>(); // Will either be a 1 or -1 int?sign = null; for (int i = 0; i < tokens.Length; i++) { var token = tokens[i]; double?possibleNumber = getNumberOrNothing(token); var operation = new OperationToken { Operation = token[0] }; if (!operation.IsValid && !possibleNumber.HasValue) { // Is a variable // possibleNumber = variableLookup(token); } // Handle negatives and positives // if (sign.HasValue) { possibleNumber = possibleNumber * sign; sign = null; } if (possibleNumber.HasValue) { // Is number // if (!OperationStack.IsEmpty()) { var topOperation = OperationStack.Peek(); if (topOperation.IsDivision || topOperation.IsMultiplication) { if (NumberStack.Count < 1) { throw new ArgumentException("Invalid Syntax"); } OperationStack.Pop(); // Passed our test, remove from stack // var number = NumberStack.Pop(); NumberStack.Push(topOperation.Apply(number, possibleNumber.Value)); continue; } } NumberStack.Push(possibleNumber.Value); } else { if (operation.IsAddition || operation.IsSubtraction) { var previousIndex = i - 1; if (previousIndex < 0) { // The sign provided was the first sign, it must be a + or - signifying that its positive or negative // sign = operation.IsSubtraction ? -1 : 1; continue; } else { var previousOperation = new OperationToken() { Operation = tokens[previousIndex][0] }; // If the previous token was an operation then this token must mean positive or negative // // Also make sure its not the last operation either // if (previousOperation.IsOperation && i + 1 < tokens.Length) { sign = operation.IsSubtraction ? -1 : 1; continue; } else if (!OperationStack.IsEmpty()) { // There's a pending operation, let's do that instead // var topOperation = OperationStack.Peek(); if (topOperation.IsAddition || topOperation.IsSubtraction) { if (NumberStack.Count < 2) { throw new ArgumentException("Invalid Syntax"); } OperationStack.Pop(); var number1 = NumberStack.Pop(); var number2 = NumberStack.Pop(); NumberStack.Push(topOperation.Apply(number2, number1)); } } } OperationStack.Push(operation); } else if (operation.IsMultiplication || operation.IsDivision || operation.IsOpenBrace) { // Nothing complex, just push operation to stack // OperationStack.Push(operation); } else if (operation.IsClosingBrace) { if (!OperationStack.IsEmpty()) { // If there's already a pending operation. // var topOperation = OperationStack.Peek(); if (topOperation.IsAddition || topOperation.IsSubtraction) { if (NumberStack.Count < 2) { throw new ArgumentException("Invalid Syntax"); } OperationStack.Pop(); var number1 = NumberStack.Pop(); var number2 = NumberStack.Pop(); NumberStack.Push(topOperation.Apply(number2, number1)); } } // Check for ending parenthesis // if (OperationStack.IsEmpty() || !OperationStack.Pop().IsOpenBrace) { throw new ArgumentException("Expecting '('. Invalid syntax."); } // Operation size could have changed, we need to check again // if (!OperationStack.IsEmpty()) { var topOperation = OperationStack.Peek(); if (topOperation.IsDivision || topOperation.IsMultiplication) { if (NumberStack.Count < 1) { throw new ArgumentException("Invalid Syntax"); } OperationStack.Pop(); // Passed our test, remove from stack // var b = NumberStack.Pop(); if (!possibleNumber.HasValue) { possibleNumber = NumberStack.Pop(); } NumberStack.Push(topOperation.Apply(possibleNumber.Value, b)); } } } else { throw new ArgumentException("Invalid Syntax. Cannot handle given operation."); } } } if (OperationStack.Count >= 2) { throw new ArgumentException("Invalid Syntax. Cannot handle given operation."); } if (OperationStack.Count == 1) { var b = NumberStack.Pop(); var a = NumberStack.Pop(); return((int)OperationStack.Pop().Apply(a, b)); } else { return((int)NumberStack.Pop()); } }
/// <summary> /// Validates the inputs. Returns true if all of the UI controls contain valid values. Otherwise, returns false. /// </summary> /// <returns>true if all of the UI controls contain valid values. Otherwise, false.</returns> public override bool ValidateInputs() { Logger.Instance.WriteMethodEntry(); try { // Use the controller to validate standard activity controls // and return false if a problem was identified if (!this.controller.ValidateInputs()) { return(false); } try { // Verify that the target lookup is valid LookupEvaluator targetLookup = new LookupEvaluator(this.publicationTarget.Value); if (!targetLookup.IsValidTarget) { this.controller.ValidationError = string.Format(CultureInfo.CurrentUICulture, ActivitySettings.TargetLookupValidationError, this.publicationTarget.Value); return(false); } } catch (WorkflowActivityLibraryException ex) { // If an exception was thrown while attempting to parse lookups, report the error this.controller.ValidationError = ex.Message; return(false); } // Verify that the supplied conflict filter is a valid XPath query if (!ExpressionEvaluator.IsXPath(this.conflictFilter.Value)) { this.controller.ValidationError = ActivitySettings.ConflictFilterValidationError; return(false); } // Verify that the supplied conflict filter contains the [//Value] lookup if (!this.conflictFilter.Value.ToUpperInvariant().Contains("[//VALUE]")) { this.controller.ValidationError = ActivitySettings.ConflictFilterValueLookupValidationError; return(false); } ExpressionEvaluator evaluator = new ExpressionEvaluator(); if (this.queryLdap.Value) { // Loop through all active query listings and make sure they are valid foreach (DefinitionListing query in this.ldapQueries.DefinitionListings.Where(query => query.Active)) { // If a value is missing for key or query, the definition // will be null and the listing fails validation if (query.Definition == null) { this.controller.ValidationError = ActivitySettings.LdapQueryDefinitionValidationError; return(false); } // Make sure that the specified XPath filter is properly formatted if (!query.Definition.Right.ToUpperInvariant().Contains("[//VALUE]")) { this.controller.ValidationError = ActivitySettings.LdapQueryDefinitionValueLookupValidationError; return(false); } // If it's an expression, make sure it's properly formatted if (ExpressionEvaluator.IsExpression(query.Definition.Left)) { try { evaluator.ParseExpression(query.Definition.Left); } catch (WorkflowActivityLibraryException ex) { this.controller.ValidationError = ex.Message; return(false); } } } } // Count the active value expressions int count = this.valueExpressions.DefinitionListings.Count(valueExpression => valueExpression.Active); // Loop through all active update listings and make sure they are valid int i = 1; foreach (DefinitionListing valueExpression in this.valueExpressions.DefinitionListings.Where(valueExpression => valueExpression.Active)) { if (string.IsNullOrEmpty(valueExpression.State.Left)) { // If a value is missing for the expression, fail validation this.controller.ValidationError = ActivitySettings.ValueExpressionValidationError; return(false); } // Attempt to parse the value expression try { evaluator.ParseExpression(valueExpression.State.Left); } catch (WorkflowActivityLibraryException ex) { this.controller.ValidationError = ex.Message; return(false); } // Verify that the [//UniquenessKey] lookup is only present in the last value expression bool containsKey = valueExpression.State.Left.ToUpperInvariant().Contains("[//UNIQUENESSKEY]"); if (i < count && containsKey) { this.controller.ValidationError = ActivitySettings.ValueExpressionUniquenessKeyValidationError; return(false); } if (i == count && !containsKey) { this.controller.ValidationError = ActivitySettings.ValueExpressionMissingUniquenessKeyValidationError; return(false); } i += 1; } try { if (!string.IsNullOrEmpty(this.activityExecutionCondition.Value)) { evaluator.ParseExpression(this.activityExecutionCondition.Value); // Verify that the activity execution condition resolves to a Boolean value if (!evaluator.IsBooleanExpression(this.activityExecutionCondition.Value)) { this.controller.ValidationError = ActivitySettings.ActivityExecutionConditionValidationError; return(false); } } } catch (WorkflowActivityLibraryException ex) { this.controller.ValidationError = ex.Message; return(false); } // If no errors were found, clear any validation error and return true this.controller.ValidationError = string.Empty; return(true); } catch (Exception e) { Logger.Instance.ReportError(e); throw; } finally { Logger.Instance.WriteMethodExit(); } }