1 // --------------------------------------------------------------------------- 2 // Copyright (C) 2006 Microsoft Corporation All Rights Reserved 3 // --------------------------------------------------------------------------- 4 5 #define CODE_ANALYSIS 6 using System.Collections.Generic; 7 using System.ComponentModel; 8 using System.Diagnostics.CodeAnalysis; 9 using System.Workflow.ComponentModel; 10 11 namespace System.Workflow.Activities.Rules 12 { 13 #region class RuleDefinitions 14 15 public sealed class RuleDefinitions : IWorkflowChangeDiff 16 { 17 18 [SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")] 19 public static readonly DependencyProperty RuleDefinitionsProperty = DependencyProperty.RegisterAttached("RuleDefinitions", typeof(RuleDefinitions), typeof(RuleDefinitions), new PropertyMetadata(null, DependencyPropertyOptions.Metadata, new GetValueOverride(OnGetRuleConditions), null, new Attribute[] { new DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden) })); 20 21 private RuleConditionCollection conditions; 22 private RuleSetCollection ruleSets; 23 private bool runtimeInitialized; 24 [NonSerialized] 25 private object syncLock = new object(); 26 27 [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] 28 public RuleConditionCollection Conditions 29 { 30 get 31 { 32 if (this.conditions == null) 33 this.conditions = new RuleConditionCollection(); 34 return conditions; 35 } 36 } 37 38 [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] 39 public RuleSetCollection RuleSets 40 { 41 get 42 { 43 if (this.ruleSets == null) 44 this.ruleSets = new RuleSetCollection(); 45 return this.ruleSets; 46 } 47 } 48 OnGetRuleConditions(DependencyObject dependencyObject)49 internal static object OnGetRuleConditions(DependencyObject dependencyObject) 50 { 51 if (dependencyObject == null) 52 throw new ArgumentNullException("dependencyObject"); 53 54 RuleDefinitions rules = dependencyObject.GetValueBase(RuleDefinitions.RuleDefinitionsProperty) as RuleDefinitions; 55 if (rules != null) 56 return rules; 57 58 Activity rootActivity = dependencyObject as Activity; 59 if (rootActivity.Parent == null) 60 { 61 rules = ConditionHelper.GetRuleDefinitionsFromManifest(rootActivity.GetType()); 62 if (rules != null) 63 dependencyObject.SetValue(RuleDefinitions.RuleDefinitionsProperty, rules); 64 } 65 return rules; 66 } 67 OnRuntimeInitialized()68 internal void OnRuntimeInitialized() 69 { 70 lock (syncLock) 71 { 72 if (runtimeInitialized) 73 return; 74 Conditions.OnRuntimeInitialized(); 75 RuleSets.OnRuntimeInitialized(); 76 runtimeInitialized = true; 77 } 78 } 79 80 #region IWorkflowChangeDiff Members 81 Diff(object originalDefinition, object changedDefinition)82 public IList<WorkflowChangeAction> Diff(object originalDefinition, object changedDefinition) 83 { 84 RuleDefinitions originalRules = originalDefinition as RuleDefinitions; 85 RuleDefinitions changedRules = changedDefinition as RuleDefinitions; 86 if ((originalRules == null) || (changedRules == null)) 87 return new List<WorkflowChangeAction>(); 88 89 IList<WorkflowChangeAction> cdiff = Conditions.Diff(originalRules.Conditions, changedRules.Conditions); 90 IList<WorkflowChangeAction> rdiff = RuleSets.Diff(originalRules.RuleSets, changedRules.RuleSets); 91 92 // quick optimization -- if no condition changes, simply return the ruleset changes 93 if (cdiff.Count == 0) 94 return rdiff; 95 96 // merge ruleset changes into condition changes 97 for (int i = 0; i < rdiff.Count; ++i) 98 { 99 cdiff.Add(rdiff[i]); 100 } 101 return cdiff; 102 } 103 #endregion 104 Clone()105 internal RuleDefinitions Clone() 106 { 107 RuleDefinitions newRuleDefinitions = new RuleDefinitions(); 108 109 if (this.ruleSets != null) 110 { 111 newRuleDefinitions.ruleSets = new RuleSetCollection(); 112 foreach (RuleSet r in this.ruleSets) 113 newRuleDefinitions.ruleSets.Add(r.Clone()); 114 } 115 116 if (this.conditions != null) 117 { 118 newRuleDefinitions.conditions = new RuleConditionCollection(); 119 foreach (RuleCondition r in this.conditions) 120 newRuleDefinitions.conditions.Add(r.Clone()); 121 } 122 123 return newRuleDefinitions; 124 } 125 } 126 #endregion 127 } 128