Code:
/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / cdf / src / WF / Activities / Rules / RuleSet.cs / 1305376 / RuleSet.cs
// ----------------------------------------------------------------------------
// Copyright (C) 2005 Microsoft Corporation All Rights Reserved
// ---------------------------------------------------------------------------
using System.Collections.Generic;
using System.ComponentModel;
using System.Workflow.ComponentModel;
using System.Workflow.ComponentModel.Compiler;
using System.Workflow.Activities.Common;
namespace System.Workflow.Activities.Rules
{
public enum RuleChainingBehavior
{
None,
UpdateOnly,
Full
};
[Serializable]
public class RuleSet
{
internal const string RuleSetTrackingKey = "RuleSet.";
internal string name;
internal string description;
internal List rules;
internal RuleChainingBehavior behavior = RuleChainingBehavior.Full;
private bool runtimeInitialized;
private object syncLock = new object();
// keep track of cached data
[NonSerialized]
private RuleEngine cachedEngine;
[NonSerialized]
private RuleValidation cachedValidation;
public RuleSet()
{
this.rules = new List();
}
public RuleSet(string name)
: this()
{
this.name = name;
}
public RuleSet(string name, string description)
: this(name)
{
this.description = description;
}
public string Name
{
get { return name; }
set
{
if (runtimeInitialized)
throw new InvalidOperationException(SR.GetString(SR.Error_CanNotChangeAtRuntime));
name = value;
}
}
public string Description
{
get { return description; }
set
{
if (runtimeInitialized)
throw new InvalidOperationException(SR.GetString(SR.Error_CanNotChangeAtRuntime));
description = value;
}
}
public RuleChainingBehavior ChainingBehavior
{
get { return behavior; }
set
{
if (runtimeInitialized)
throw new InvalidOperationException(SR.GetString(SR.Error_CanNotChangeAtRuntime));
behavior = value;
}
}
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
public ICollection Rules
{
get { return rules; }
}
public bool Validate(RuleValidation validation)
{
if (validation == null)
throw new ArgumentNullException("validation");
// Validate each rule.
Dictionary ruleNames = new Dictionary();
foreach (Rule r in rules)
{
if (!string.IsNullOrEmpty(r.Name)) // invalid names caught when validating the rule
{
if (ruleNames.ContainsKey(r.Name))
{
// Duplicate rule name found.
ValidationError error = new ValidationError(Messages.Error_DuplicateRuleName, ErrorNumbers.Error_DuplicateConditions);
error.UserData[RuleUserDataKeys.ErrorObject] = r;
validation.AddError(error);
}
else
{
ruleNames.Add(r.Name, null);
}
}
r.Validate(validation);
}
if (validation.Errors == null || validation.Errors.Count == 0)
return true;
return false;
}
public void Execute(RuleExecution ruleExecution)
{
// we have no way of knowing if the ruleset has been changed, so no caching done
if (ruleExecution == null)
throw new ArgumentNullException("ruleExecution");
if (ruleExecution.Validation == null)
throw new ArgumentException(SR.GetString(SR.Error_MissingValidationProperty), "ruleExecution");
RuleEngine engine = new RuleEngine(this, ruleExecution.Validation, ruleExecution.ActivityExecutionContext);
engine.Execute(ruleExecution);
}
internal void Execute(Activity activity, ActivityExecutionContext executionContext)
{
// this can be called from multiple threads if multiple workflows are
// running at the same time (only a single workflow is single-threaded)
// we want to only lock around the validation and preprocessing, so that
// execution can run in parallel.
if (activity == null)
throw new ArgumentNullException("activity");
Type activityType = activity.GetType();
RuleEngine engine = null;
lock (syncLock)
{
// do we have something useable cached?
if ((cachedEngine == null) || (cachedValidation == null) || (cachedValidation.ThisType != activityType))
{
// no cache (or its invalid)
RuleValidation validation = new RuleValidation(activityType, null);
engine = new RuleEngine(this, validation, executionContext);
cachedValidation = validation;
cachedEngine = engine;
}
else
{
// this will happen if the ruleset has already been processed
// we can simply use the previously processed engine
engine = cachedEngine;
}
}
// when we get here, we have a local RuleEngine all ready to go
// we are outside the lock, so these can run in parallel
engine.Execute(activity, executionContext);
}
public RuleSet Clone()
{
RuleSet newRuleSet = (RuleSet)this.MemberwiseClone();
newRuleSet.runtimeInitialized = false;
if (this.rules != null)
{
newRuleSet.rules = new List();
foreach (Rule r in this.rules)
newRuleSet.rules.Add(r.Clone());
}
return newRuleSet;
}
public override bool Equals(object obj)
{
RuleSet other = obj as RuleSet;
if (other == null)
return false;
if ((this.Name != other.Name)
|| (this.Description != other.Description)
|| (this.ChainingBehavior != other.ChainingBehavior)
|| (this.Rules.Count != other.Rules.Count))
return false;
// look similar, compare each rule
for (int i = 0; i < this.rules.Count; ++i)
{
if (!this.rules[i].Equals(other.rules[i]))
return false;
}
return true;
}
public override int GetHashCode()
{
return base.GetHashCode();
}
internal void OnRuntimeInitialized()
{
lock (syncLock)
{
if (runtimeInitialized)
return;
foreach (Rule rule in rules)
{
rule.OnRuntimeInitialized();
}
runtimeInitialized = true;
}
}
}
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
// ----------------------------------------------------------------------------
// Copyright (C) 2005 Microsoft Corporation All Rights Reserved
// ---------------------------------------------------------------------------
using System.Collections.Generic;
using System.ComponentModel;
using System.Workflow.ComponentModel;
using System.Workflow.ComponentModel.Compiler;
using System.Workflow.Activities.Common;
namespace System.Workflow.Activities.Rules
{
public enum RuleChainingBehavior
{
None,
UpdateOnly,
Full
};
[Serializable]
public class RuleSet
{
internal const string RuleSetTrackingKey = "RuleSet.";
internal string name;
internal string description;
internal List rules;
internal RuleChainingBehavior behavior = RuleChainingBehavior.Full;
private bool runtimeInitialized;
private object syncLock = new object();
// keep track of cached data
[NonSerialized]
private RuleEngine cachedEngine;
[NonSerialized]
private RuleValidation cachedValidation;
public RuleSet()
{
this.rules = new List();
}
public RuleSet(string name)
: this()
{
this.name = name;
}
public RuleSet(string name, string description)
: this(name)
{
this.description = description;
}
public string Name
{
get { return name; }
set
{
if (runtimeInitialized)
throw new InvalidOperationException(SR.GetString(SR.Error_CanNotChangeAtRuntime));
name = value;
}
}
public string Description
{
get { return description; }
set
{
if (runtimeInitialized)
throw new InvalidOperationException(SR.GetString(SR.Error_CanNotChangeAtRuntime));
description = value;
}
}
public RuleChainingBehavior ChainingBehavior
{
get { return behavior; }
set
{
if (runtimeInitialized)
throw new InvalidOperationException(SR.GetString(SR.Error_CanNotChangeAtRuntime));
behavior = value;
}
}
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
public ICollection Rules
{
get { return rules; }
}
public bool Validate(RuleValidation validation)
{
if (validation == null)
throw new ArgumentNullException("validation");
// Validate each rule.
Dictionary ruleNames = new Dictionary();
foreach (Rule r in rules)
{
if (!string.IsNullOrEmpty(r.Name)) // invalid names caught when validating the rule
{
if (ruleNames.ContainsKey(r.Name))
{
// Duplicate rule name found.
ValidationError error = new ValidationError(Messages.Error_DuplicateRuleName, ErrorNumbers.Error_DuplicateConditions);
error.UserData[RuleUserDataKeys.ErrorObject] = r;
validation.AddError(error);
}
else
{
ruleNames.Add(r.Name, null);
}
}
r.Validate(validation);
}
if (validation.Errors == null || validation.Errors.Count == 0)
return true;
return false;
}
public void Execute(RuleExecution ruleExecution)
{
// we have no way of knowing if the ruleset has been changed, so no caching done
if (ruleExecution == null)
throw new ArgumentNullException("ruleExecution");
if (ruleExecution.Validation == null)
throw new ArgumentException(SR.GetString(SR.Error_MissingValidationProperty), "ruleExecution");
RuleEngine engine = new RuleEngine(this, ruleExecution.Validation, ruleExecution.ActivityExecutionContext);
engine.Execute(ruleExecution);
}
internal void Execute(Activity activity, ActivityExecutionContext executionContext)
{
// this can be called from multiple threads if multiple workflows are
// running at the same time (only a single workflow is single-threaded)
// we want to only lock around the validation and preprocessing, so that
// execution can run in parallel.
if (activity == null)
throw new ArgumentNullException("activity");
Type activityType = activity.GetType();
RuleEngine engine = null;
lock (syncLock)
{
// do we have something useable cached?
if ((cachedEngine == null) || (cachedValidation == null) || (cachedValidation.ThisType != activityType))
{
// no cache (or its invalid)
RuleValidation validation = new RuleValidation(activityType, null);
engine = new RuleEngine(this, validation, executionContext);
cachedValidation = validation;
cachedEngine = engine;
}
else
{
// this will happen if the ruleset has already been processed
// we can simply use the previously processed engine
engine = cachedEngine;
}
}
// when we get here, we have a local RuleEngine all ready to go
// we are outside the lock, so these can run in parallel
engine.Execute(activity, executionContext);
}
public RuleSet Clone()
{
RuleSet newRuleSet = (RuleSet)this.MemberwiseClone();
newRuleSet.runtimeInitialized = false;
if (this.rules != null)
{
newRuleSet.rules = new List();
foreach (Rule r in this.rules)
newRuleSet.rules.Add(r.Clone());
}
return newRuleSet;
}
public override bool Equals(object obj)
{
RuleSet other = obj as RuleSet;
if (other == null)
return false;
if ((this.Name != other.Name)
|| (this.Description != other.Description)
|| (this.ChainingBehavior != other.ChainingBehavior)
|| (this.Rules.Count != other.Rules.Count))
return false;
// look similar, compare each rule
for (int i = 0; i < this.rules.Count; ++i)
{
if (!this.rules[i].Equals(other.rules[i]))
return false;
}
return true;
}
public override int GetHashCode()
{
return base.GetHashCode();
}
internal void OnRuntimeInitialized()
{
lock (syncLock)
{
if (runtimeInitialized)
return;
foreach (Rule rule in rules)
{
rule.OnRuntimeInitialized();
}
runtimeInitialized = true;
}
}
}
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- IndependentlyAnimatedPropertyMetadata.cs
- StyleHelper.cs
- ListBindingConverter.cs
- TdsEnums.cs
- SafeThreadHandle.cs
- Lease.cs
- EditingMode.cs
- cryptoapiTransform.cs
- XslTransform.cs
- documentsequencetextcontainer.cs
- ParseChildrenAsPropertiesAttribute.cs
- TriggerCollection.cs
- HandoffBehavior.cs
- WebPartManagerInternals.cs
- WindowsListViewGroupHelper.cs
- PathGeometry.cs
- WindowsHyperlink.cs
- MultiSelector.cs
- DesignerTextWriter.cs
- FormViewPageEventArgs.cs
- GridEntryCollection.cs
- BitmapMetadataBlob.cs
- GeneralTransformCollection.cs
- RuntimeUtils.cs
- RuntimeArgument.cs
- SubstitutionDesigner.cs
- LayoutEngine.cs
- ImmutableCollection.cs
- SmiXetterAccessMap.cs
- HtmlHistory.cs
- StylusPlugInCollection.cs
- HttpFileCollectionBase.cs
- ResourceAssociationSetEnd.cs
- LogWriteRestartAreaAsyncResult.cs
- WindowPattern.cs
- DatePickerAutomationPeer.cs
- FuncTypeConverter.cs
- SchemaHelper.cs
- ValidatingReaderNodeData.cs
- CellTreeNodeVisitors.cs
- PrintDialog.cs
- DrawingVisual.cs
- SoapSchemaImporter.cs
- DPTypeDescriptorContext.cs
- NotifyIcon.cs
- ConfigXmlCDataSection.cs
- UshortList2.cs
- GridToolTip.cs
- PropertyPath.cs
- NavigationPropertyEmitter.cs
- XmlnsCache.cs
- EntityDataSourceSelectingEventArgs.cs
- ArraySortHelper.cs
- ActivityPropertyReference.cs
- OdbcErrorCollection.cs
- TraceHandler.cs
- RecipientInfo.cs
- SoapHttpTransportImporter.cs
- Identifier.cs
- ResourceDescriptionAttribute.cs
- CorrelationTokenTypeConvertor.cs
- ExceptionUtil.cs
- TextSelectionHelper.cs
- FunctionDetailsReader.cs
- Odbc32.cs
- FrameworkElementFactoryMarkupObject.cs
- Debug.cs
- XmlWrappingReader.cs
- Schema.cs
- TargetInvocationException.cs
- RegexTree.cs
- Funcletizer.cs
- PortCache.cs
- PeerMaintainer.cs
- AttachmentCollection.cs
- TemplateParser.cs
- BitmapFrame.cs
- XmlSchemaAttributeGroup.cs
- CodeObject.cs
- LogConverter.cs
- ExpandoObject.cs
- AnnotationHelper.cs
- securitymgrsite.cs
- TypeInitializationException.cs
- PaginationProgressEventArgs.cs
- SharedHttpsTransportManager.cs
- Parser.cs
- ScrollProviderWrapper.cs
- DiscoveryRequestHandler.cs
- AssemblyBuilderData.cs
- InputBuffer.cs
- SpotLight.cs
- StylusCaptureWithinProperty.cs
- WindowsPrincipal.cs
- ValidationHelpers.cs
- RelationshipConverter.cs
- Logging.cs
- RemotingServices.cs
- TypeReference.cs
- ReferenceService.cs