1 #pragma warning disable 1634, 1691
2 
3 namespace System.Workflow.ComponentModel
4 {
5     #region Imports
6 
7     using System;
8     using System.CodeDom;
9     using System.CodeDom.Compiler;
10     using System.Xml;
11     using System.Text;
12     using System.IO;
13     using System.Reflection;
14     using System.Collections;
15     using System.Runtime.Serialization;
16     using System.Collections.Generic;
17     using System.ComponentModel;
18     using System.ComponentModel.Design;
19     using System.ComponentModel.Design.Serialization;
20     using System.Drawing.Design;
21     using System.Workflow.ComponentModel.Design;
22     using System.Workflow.ComponentModel.Compiler;
23     using System.Resources;
24     using System.Globalization;
25     using System.Diagnostics;
26     using System.Collections.Specialized;
27     using System.Collections.ObjectModel;
28     using System.Runtime.Serialization.Formatters.Binary;
29     using System.Workflow.ComponentModel.Serialization;
30 
31     #endregion
32 
33     #region Classes ActivityResolveEventArgs and WorkflowChangeActionsResolveEventArgs
34 
ActivityResolveEventHandler(object sender, ActivityResolveEventArgs e)35     internal delegate Activity ActivityResolveEventHandler(object sender, ActivityResolveEventArgs e);
WorkflowChangeActionsResolveEventHandler(object sender, WorkflowChangeActionsResolveEventArgs e)36     internal delegate ArrayList WorkflowChangeActionsResolveEventHandler(object sender, WorkflowChangeActionsResolveEventArgs e);
37 
38     internal sealed class ActivityResolveEventArgs : EventArgs
39     {
40         private Type activityType = null;
41         private string activityDefinition = null;
42         private string rulesDefinition = null;
43         private bool createNew = false;
44         private bool initForRuntime = true;
45         private IServiceProvider serviceProvider = null;
46 
ActivityResolveEventArgs(Type activityType, string workflowMarkup, string rulesMarkup, bool createNew, bool initForRuntime, IServiceProvider serviceProvider)47         internal ActivityResolveEventArgs(Type activityType, string workflowMarkup, string rulesMarkup, bool createNew, bool initForRuntime, IServiceProvider serviceProvider)
48         {
49             if (!(string.IsNullOrEmpty(workflowMarkup) ^ activityType == null))
50                 throw new ArgumentException(SR.GetString(SR.Error_WrongParamForActivityResolveEventArgs));
51 
52             this.activityType = activityType;
53             this.activityDefinition = workflowMarkup;
54             this.rulesDefinition = rulesMarkup;
55             this.createNew = createNew;
56             this.initForRuntime = initForRuntime;
57             this.serviceProvider = serviceProvider;
58         }
59 
60         public Type Type
61         {
62             get
63             {
64                 return this.activityType;
65             }
66         }
67         public string WorkflowMarkup
68         {
69             get
70             {
71                 return this.activityDefinition;
72             }
73         }
74         public string RulesMarkup
75         {
76             get
77             {
78                 return this.rulesDefinition;
79             }
80         }
81         public bool CreateNewDefinition
82         {
83             get
84             {
85                 return this.createNew;
86             }
87         }
88         public bool InitializeForRuntime
89         {
90             get
91             {
92                 return this.initForRuntime;
93             }
94         }
95         public IServiceProvider ServiceProvider
96         {
97             get
98             {
99                 return this.serviceProvider;
100             }
101         }
102     }
103 
104     internal sealed class WorkflowChangeActionsResolveEventArgs : EventArgs
105     {
106         private string workflowChangesMarkup;
107 
WorkflowChangeActionsResolveEventArgs(string workflowChangesMarkup)108         public WorkflowChangeActionsResolveEventArgs(string workflowChangesMarkup)
109         {
110             this.workflowChangesMarkup = workflowChangesMarkup;
111         }
112 
113         public string WorkflowChangesMarkup
114         {
115             get
116             {
117                 return this.workflowChangesMarkup;
118             }
119         }
120     }
121 
122     #endregion
123 
124     #region Class Activity
125 
126 
127     [ActivityCodeGenerator(typeof(ActivityCodeGenerator))]
128     [ActivityValidator(typeof(ActivityValidator))]
129     [System.Drawing.ToolboxBitmap(typeof(Activity), "Design.Resources.Activity.png")]
130     [ToolboxItemFilter("Microsoft.Workflow.VSDesigner", ToolboxItemFilterType.Require)]
131     [ToolboxItemFilter("System.Workflow.ComponentModel.Design.ActivitySet", ToolboxItemFilterType.Allow)]
132     [DesignerSerializer(typeof(ActivityMarkupSerializer), typeof(WorkflowMarkupSerializer))]
133     [DesignerSerializer(typeof(ActivityCodeDomSerializer), typeof(CodeDomSerializer))]
134     [DesignerSerializer(typeof(ActivityTypeCodeDomSerializer), typeof(TypeCodeDomSerializer))]
135     [DesignerCategory("Component")]
136     [ActivityExecutor(typeof(ActivityExecutor<Activity>))]
137     [Designer(typeof(ActivityDesigner), typeof(IDesigner))]
138     [Designer(typeof(ActivityDesigner), typeof(IRootDesigner))]
139     [ToolboxItem(typeof(ActivityToolboxItem))]
140     [RuntimeNameProperty("Name")]
141     [Obsolete("The System.Workflow.* types are deprecated.  Instead, please use the new types from System.Activities.*")]
142     public class Activity : DependencyObject
143     {
144         private static DependencyProperty NameProperty = DependencyProperty.Register("Name", typeof(string), typeof(Activity), new PropertyMetadata("", DependencyPropertyOptions.Metadata, new ValidationOptionAttribute(ValidationOption.Required)));
145         private static DependencyProperty DescriptionProperty = DependencyProperty.Register("Description", typeof(string), typeof(Activity), new PropertyMetadata("", DependencyPropertyOptions.Metadata));
146         private static DependencyProperty EnabledProperty = DependencyProperty.Register("Enabled", typeof(bool), typeof(Activity), new PropertyMetadata(true, DependencyPropertyOptions.Metadata));
147         private static DependencyProperty QualifiedNameProperty = DependencyProperty.Register("QualifiedName", typeof(string), typeof(Activity), new PropertyMetadata(DependencyPropertyOptions.Metadata | DependencyPropertyOptions.ReadOnly));
148         private static DependencyProperty DottedPathProperty = DependencyProperty.Register("DottedPath", typeof(string), typeof(Activity), new PropertyMetadata(DependencyPropertyOptions.Metadata | DependencyPropertyOptions.ReadOnly));
149         internal static readonly DependencyProperty WorkflowXamlMarkupProperty = DependencyProperty.Register("WorkflowXamlMarkup", typeof(string), typeof(Activity));
150         internal static readonly DependencyProperty WorkflowRulesMarkupProperty = DependencyProperty.Register("WorkflowRulesMarkup", typeof(string), typeof(Activity));
151 
152         internal static readonly DependencyProperty SynchronizationHandlesProperty = DependencyProperty.Register("SynchronizationHandles", typeof(ICollection<String>), typeof(Activity), new PropertyMetadata(DependencyPropertyOptions.Metadata));
153 
154         internal static readonly DependencyProperty ActivityExecutionContextInfoProperty = DependencyProperty.RegisterAttached("ActivityExecutionContextInfo", typeof(ActivityExecutionContextInfo), typeof(Activity));
155         public static readonly DependencyProperty ActivityContextGuidProperty = DependencyProperty.RegisterAttached("ActivityContextGuid", typeof(Guid), typeof(Activity), new PropertyMetadata(Guid.Empty));
156         internal static readonly DependencyProperty CompletedExecutionContextsProperty = DependencyProperty.RegisterAttached("CompletedExecutionContexts", typeof(IList), typeof(Activity));
157         internal static readonly DependencyProperty ActiveExecutionContextsProperty = DependencyProperty.RegisterAttached("ActiveExecutionContexts", typeof(IList), typeof(Activity));
158         internal static readonly DependencyProperty CompletedOrderIdProperty = DependencyProperty.Register("CompletedOrderId", typeof(int), typeof(Activity), new PropertyMetadata(new Int32()));
159         private static readonly DependencyProperty SerializedStreamLengthProperty = DependencyProperty.RegisterAttached("SerializedStreamLength", typeof(long), typeof(Activity), new PropertyMetadata(DependencyPropertyOptions.NonSerialized));
160 
161         // activity runtime state
162         internal static readonly DependencyProperty ExecutionStatusProperty = DependencyProperty.RegisterAttached("ExecutionStatus", typeof(ActivityExecutionStatus), typeof(Activity), new PropertyMetadata(ActivityExecutionStatus.Initialized, new Attribute[] { new BrowsableAttribute(false), new DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden) }));
163         internal static readonly DependencyProperty ExecutionResultProperty = DependencyProperty.RegisterAttached("ExecutionResult", typeof(ActivityExecutionResult), typeof(Activity), new PropertyMetadata(ActivityExecutionResult.None, new Attribute[] { new BrowsableAttribute(false), new DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden) }));
164         internal static readonly DependencyProperty WasExecutingProperty = DependencyProperty.RegisterAttached("WasExecuting", typeof(bool), typeof(Activity), new PropertyMetadata(false, new Attribute[] { new BrowsableAttribute(false), new DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden) }));
165 
166         // lock count on status change property
167         private static readonly DependencyProperty LockCountOnStatusChangeProperty = DependencyProperty.RegisterAttached("LockCountOnStatusChange", typeof(int), typeof(Activity), new PropertyMetadata(new Int32()));
168         internal static readonly DependencyProperty HasPrimaryClosedProperty = DependencyProperty.RegisterAttached("HasPrimaryClosed", typeof(bool), typeof(Activity), new PropertyMetadata(false));
169 
170         // nested activity collection used at serialization time
171         private static readonly DependencyProperty NestedActivitiesProperty = DependencyProperty.RegisterAttached("NestedActivities", typeof(IList<Activity>), typeof(Activity));
172 
173         // Workflow Definition property, should only be visible to runtime
174         internal static readonly DependencyProperty WorkflowDefinitionProperty = DependencyProperty.RegisterAttached("WorkflowDefinition", typeof(Activity), typeof(Activity), new PropertyMetadata(DependencyPropertyOptions.NonSerialized));
175 
176         // Workflow Runtime property, should only be visible to runtime
177         internal static readonly DependencyProperty WorkflowRuntimeProperty = DependencyProperty.RegisterAttached("WorkflowRuntime", typeof(IServiceProvider), typeof(Activity), new PropertyMetadata(DependencyPropertyOptions.NonSerialized));
178 
179         [ThreadStatic]
180         internal static Hashtable ContextIdToActivityMap = null;
181         [ThreadStatic]
182         internal static Activity DefinitionActivity = null;
183         [ThreadStatic]
184         internal static ArrayList ActivityRoots = null;
185 
186         private static readonly BinaryFormatter binaryFormatter = null;
187         private static ActivityResolveEventHandler activityDefinitionResolve = null;
188         private static WorkflowChangeActionsResolveEventHandler workflowChangeActionsResolve = null;
189 
190         [NonSerialized]
191         private string cachedDottedPath = null;
192 
193         [NonSerialized]
194         private IWorkflowCoreRuntime workflowCoreRuntime = null;
195 
196         [NonSerialized]
197         internal CompositeActivity parent = null;
198 
199         private static object staticSyncRoot = new object();
200 
201         internal static readonly DependencyProperty CustomActivityProperty = DependencyProperty.Register("CustomActivity", typeof(bool), typeof(Activity), new PropertyMetadata(DependencyPropertyOptions.Metadata));
202         internal static Type ActivityType = null;
203 
Activity()204         static Activity()
205         {
206             binaryFormatter = new BinaryFormatter();
207             binaryFormatter.SurrogateSelector = ActivitySurrogateSelector.Default;
208 
209             // register known properties
210             DependencyProperty.RegisterAsKnown(ActivityExecutionContextInfoProperty, (byte)1, DependencyProperty.PropertyValidity.Reexecute);
211             DependencyProperty.RegisterAsKnown(CompletedExecutionContextsProperty, (byte)2, DependencyProperty.PropertyValidity.Reexecute);
212             DependencyProperty.RegisterAsKnown(ActiveExecutionContextsProperty, (byte)3, DependencyProperty.PropertyValidity.Uninitialize);
213             DependencyProperty.RegisterAsKnown(CompletedOrderIdProperty, (byte)4, DependencyProperty.PropertyValidity.Uninitialize);
214             DependencyProperty.RegisterAsKnown(ExecutionStatusProperty, (byte)5, DependencyProperty.PropertyValidity.Reexecute);
215             DependencyProperty.RegisterAsKnown(ExecutionResultProperty, (byte)6, DependencyProperty.PropertyValidity.Reexecute);
216             DependencyProperty.RegisterAsKnown(WasExecutingProperty, (byte)7, DependencyProperty.PropertyValidity.Uninitialize);
217             DependencyProperty.RegisterAsKnown(LockCountOnStatusChangeProperty, (byte)8, DependencyProperty.PropertyValidity.Uninitialize);
218             DependencyProperty.RegisterAsKnown(HasPrimaryClosedProperty, (byte)9, DependencyProperty.PropertyValidity.Uninitialize);
219             DependencyProperty.RegisterAsKnown(NestedActivitiesProperty, (byte)10, DependencyProperty.PropertyValidity.Uninitialize);
220             DependencyProperty.RegisterAsKnown(ActivityContextGuidProperty, (byte)11, DependencyProperty.PropertyValidity.Reexecute);
221             DependencyProperty.RegisterAsKnown(WorkflowXamlMarkupProperty, (byte)12, DependencyProperty.PropertyValidity.Uninitialize);
222             DependencyProperty.RegisterAsKnown(WorkflowRulesMarkupProperty, (byte)13, DependencyProperty.PropertyValidity.Uninitialize);
223 
224             // other classes
225             DependencyProperty.RegisterAsKnown(ActivityExecutionContext.CurrentExceptionProperty, (byte)23, DependencyProperty.PropertyValidity.Reexecute);
226             DependencyProperty.RegisterAsKnown(ActivityExecutionContext.GrantedLocksProperty, (byte)24, DependencyProperty.PropertyValidity.Uninitialize);
227             DependencyProperty.RegisterAsKnown(ActivityExecutionContext.LockAcquiredCallbackProperty, (byte)25, DependencyProperty.PropertyValidity.Uninitialize);
228 
229 
230             // events
231             DependencyProperty.RegisterAsKnown(ExecutingEvent, (byte)31, DependencyProperty.PropertyValidity.Uninitialize);
232             DependencyProperty.RegisterAsKnown(CancelingEvent, (byte)32, DependencyProperty.PropertyValidity.Uninitialize);
233             DependencyProperty.RegisterAsKnown(ClosedEvent, (byte)33, DependencyProperty.PropertyValidity.Uninitialize);
234             DependencyProperty.RegisterAsKnown(CompensatingEvent, (byte)34, DependencyProperty.PropertyValidity.Uninitialize);
235             DependencyProperty.RegisterAsKnown(StatusChangedEvent, (byte)35, DependencyProperty.PropertyValidity.Uninitialize);
236             DependencyProperty.RegisterAsKnown(StatusChangedLockedEvent, (byte)36, DependencyProperty.PropertyValidity.Uninitialize);
237             DependencyProperty.RegisterAsKnown(LockCountOnStatusChangeChangedEvent, (byte)37, DependencyProperty.PropertyValidity.Uninitialize);
238             DependencyProperty.RegisterAsKnown(FaultingEvent, (byte)38, DependencyProperty.PropertyValidity.Uninitialize);
239 
240             // misc. others
241             DependencyProperty.RegisterAsKnown(FaultAndCancellationHandlingFilter.FaultProcessedProperty, (byte)41, DependencyProperty.PropertyValidity.Uninitialize);
242             DependencyProperty.RegisterAsKnown(CompensationHandlingFilter.CompensateProcessedProperty, (byte)43, DependencyProperty.PropertyValidity.Uninitialize);
243             DependencyProperty.RegisterAsKnown(CompensationHandlingFilter.LastCompensatedOrderIdProperty, (byte)44, DependencyProperty.PropertyValidity.Uninitialize);
244         }
245 
Activity()246         public Activity()
247         {
248             SetValue(CustomActivityProperty, false);
249             SetValue(NameProperty, GetType().Name);
250         }
251 
Activity(string name)252         public Activity(string name)
253         {
254             if (name == null)
255                 throw new ArgumentNullException("name");
256 
257             SetValue(CustomActivityProperty, false);
258             SetValue(NameProperty, name);
259         }
260 
261         #region Execution Signals
262 
Initialize(IServiceProvider provider)263         protected internal virtual void Initialize(IServiceProvider provider)
264         {
265             if (provider == null)
266                 throw new ArgumentNullException("provider");
267 
268         }
Execute(ActivityExecutionContext executionContext)269         protected internal virtual ActivityExecutionStatus Execute(ActivityExecutionContext executionContext)
270         {
271             if (executionContext == null)
272                 throw new ArgumentNullException("executionContext");
273 
274             return ActivityExecutionStatus.Closed;
275         }
Cancel(ActivityExecutionContext executionContext)276         protected internal virtual ActivityExecutionStatus Cancel(ActivityExecutionContext executionContext)
277         {
278             if (executionContext == null)
279                 throw new ArgumentNullException("executionContext");
280 
281             return ActivityExecutionStatus.Closed;
282         }
HandleFault(ActivityExecutionContext executionContext, Exception exception)283         protected internal virtual ActivityExecutionStatus HandleFault(ActivityExecutionContext executionContext, Exception exception)
284         {
285             if (executionContext == null)
286                 throw new ArgumentNullException("executionContext");
287 
288             return ActivityExecutionStatus.Closed;
289         }
290 
291         /// <summary>
292         /// Derived implementation may do necessary cleanup here such as removing serializable instance
293         /// dependency properties before the activity status is set to closed.
294         /// </summary>
OnClosed(IServiceProvider provider)295         protected virtual void OnClosed(IServiceProvider provider)
296         {
297         }
298 
299         /// <summary>
300         /// Called Immediatly once activity is done with it life time
301         /// i.e Simple Activity when they transition to close.
302         ///     CompensatableActivity & any activity which is in compensation chain
303         ///     when root activity close.
304         /// </summary>
305         /// <param name="serviceProvider"></param>
Uninitialize(IServiceProvider provider)306         protected internal virtual void Uninitialize(IServiceProvider provider)
307         {
308             if (provider == null)
309                 throw new ArgumentNullException("provider");
310 
311             ResetKnownDependencyProperties(false);
312         }
313 
OnActivityExecutionContextLoad(IServiceProvider provider)314         protected internal virtual void OnActivityExecutionContextLoad(IServiceProvider provider)
315         {
316             if (provider == null)
317                 throw new ArgumentNullException("provider");
318         }
319 
OnActivityExecutionContextUnload(IServiceProvider provider)320         protected internal virtual void OnActivityExecutionContextUnload(IServiceProvider provider)
321         {
322             if (provider == null)
323                 throw new ArgumentNullException("provider");
324         }
325         #endregion
326 
327         #region Activity Execution Helper Methods
328 
329         protected internal void RaiseGenericEvent<T>(DependencyProperty dependencyEvent, object sender, T e) where T : EventArgs
330         {
331             if (dependencyEvent == null)
332                 throw new ArgumentNullException("dependencyEvent");
333 
334             if (e == null)
335                 throw new ArgumentNullException("e");
336 
337             if (this.WorkflowCoreRuntime == null)
338                 throw new InvalidOperationException(SR.GetString(SR.Error_NoRuntimeAvailable));
339 
340             EventHandler<T>[] eventHandlers = ((IDependencyObjectAccessor)this).GetInvocationList<EventHandler<T>>(dependencyEvent);
341             if (eventHandlers != null)
342             {
343                 foreach (EventHandler<T> eventHandler in eventHandlers)
344                 {
345                     this.WorkflowCoreRuntime.RaiseHandlerInvoking(eventHandler);
346                     try
347                     {
348                         eventHandler(sender, e);
349                     }
350                     finally
351                     {
352                         this.WorkflowCoreRuntime.RaiseHandlerInvoked();
353                     }
354                 }
355             }
356         }
357 
RaiseEvent(DependencyProperty dependencyEvent, object sender, EventArgs e)358         protected internal void RaiseEvent(DependencyProperty dependencyEvent, object sender, EventArgs e)
359         {
360             if (sender == null)
361                 throw new ArgumentNullException("sender");
362 
363             if (dependencyEvent == null)
364                 throw new ArgumentNullException("dependencyEvent");
365 
366             if (e == null)
367                 throw new ArgumentNullException("e");
368 
369             if (this.WorkflowCoreRuntime == null)
370                 throw new InvalidOperationException(SR.GetString(SR.Error_NoRuntimeAvailable));
371 
372             EventHandler[] eventHandlers = ((IDependencyObjectAccessor)this).GetInvocationList<EventHandler>(dependencyEvent);
373             if (eventHandlers != null)
374             {
375                 foreach (EventHandler eventHandler in eventHandlers)
376                 {
377                     this.WorkflowCoreRuntime.RaiseHandlerInvoking(eventHandler);
378                     try
379                     {
380                         eventHandler(sender, e);
381                     }
382                     finally
383                     {
384                         this.WorkflowCoreRuntime.RaiseHandlerInvoked();
385                     }
386                 }
387             }
388         }
389 
TrackData(object userData)390         protected void TrackData(object userData)
391         {
392             if (userData == null)
393                 throw new ArgumentNullException("userData");
394             if (this.WorkflowCoreRuntime == null)
395                 throw new InvalidOperationException(SR.GetString(SR.Error_NoRuntimeAvailable));
396 
397             this.WorkflowCoreRuntime.Track(null, userData);
398         }
TrackData(string userDataKey, object userData)399         protected void TrackData(string userDataKey, object userData)
400         {
401             if (userData == null)
402                 throw new ArgumentNullException("userData");
403             if (this.WorkflowCoreRuntime == null)
404                 throw new InvalidOperationException(SR.GetString(SR.Error_NoRuntimeAvailable));
405 
406             this.WorkflowCoreRuntime.Track(userDataKey, userData);
407         }
408         protected Guid WorkflowInstanceId
409         {
410             get
411             {
412                 if (this.WorkflowCoreRuntime == null)
413 #pragma warning suppress 56503
414                     throw new InvalidOperationException(SR.GetString(SR.Error_NoRuntimeAvailable));
415                 return this.WorkflowCoreRuntime.InstanceID;
416             }
417         }
418         protected internal void Invoke<T>(EventHandler<T> handler, T e) where T : EventArgs
419         {
420 
421             if (handler == null)
422                 throw new ArgumentNullException("handler");
423 
424             if (e == null)
425                 throw new ArgumentNullException("e");
426 
427             if (this.WorkflowCoreRuntime == null)
428                 throw new InvalidOperationException(SR.GetString(System.Globalization.CultureInfo.CurrentCulture, SR.Error_NoRuntimeAvailable));
429 
430             if (this.ExecutionStatus == ActivityExecutionStatus.Initialized || this.ExecutionStatus == ActivityExecutionStatus.Closed)
431                 throw new InvalidOperationException(SR.GetString(System.Globalization.CultureInfo.CurrentCulture, SR.Error_InvalidInvokingState));
432 
433             // create subscriber
434             ActivityExecutorDelegateInfo<T> activityExecutorDelegate = null;
435             using (this.WorkflowCoreRuntime.SetCurrentActivity(this))
436                 activityExecutorDelegate = new ActivityExecutorDelegateInfo<T>(handler, this.ContextActivity);
437 
438             activityExecutorDelegate.InvokeDelegate(this.WorkflowCoreRuntime.CurrentActivity.ContextActivity, e, false);
439         }
440 
441         protected internal void Invoke<T>(IActivityEventListener<T> eventListener, T e) where T : EventArgs
442         {
443             if (eventListener == null)
444                 throw new ArgumentNullException("eventListener");
445 
446             if (e == null)
447                 throw new ArgumentNullException("e");
448 
449             if (this.WorkflowCoreRuntime == null)
450                 throw new InvalidOperationException(SR.GetString(System.Globalization.CultureInfo.CurrentCulture, SR.Error_NoRuntimeAvailable));
451 
452             if (this.ExecutionStatus == ActivityExecutionStatus.Initialized || this.ExecutionStatus == ActivityExecutionStatus.Closed)
453                 throw new InvalidOperationException(SR.GetString(System.Globalization.CultureInfo.CurrentCulture, SR.Error_InvalidInvokingState));
454 
455             // create subscriber
456             ActivityExecutorDelegateInfo<T> activityExecutorDelegate = null;
457             using (this.WorkflowCoreRuntime.SetCurrentActivity(this))
458                 activityExecutorDelegate = new ActivityExecutorDelegateInfo<T>(eventListener, this.ContextActivity);
459 
460             activityExecutorDelegate.InvokeDelegate(this.WorkflowCoreRuntime.CurrentActivity.ContextActivity, e, false);
461         }
462         #endregion
463 
464         #region Activity Meta Properties
465 
466         [Browsable(false)]
467         [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
468         public CompositeActivity Parent
469         {
470             get
471             {
472                 return this.parent;
473             }
474         }
475 
SetParent(CompositeActivity compositeActivity)476         internal void SetParent(CompositeActivity compositeActivity)
477         {
478             this.parent = compositeActivity;
479         }
480 
481         [Browsable(true)]
482         [SRCategory(SR.Activity)]
483         [ParenthesizePropertyName(true)]
484         [SRDescription(SR.NameDescr)]
485         [MergableProperty(false)]
486         [DefaultValue("")]
487         public string Name
488         {
489             get
490             {
491                 return (string)GetValue(NameProperty);
492             }
493             set
494             {
495                 SetValue(NameProperty, value);
496             }
497         }
498 
499         [Browsable(true)]
500         [SRCategory(SR.Activity)]
501         [SRDescription(SR.EnabledDescr)]
502         [DefaultValue(true)]
503         public bool Enabled
504         {
505             get
506             {
507                 return (bool)GetValue(EnabledProperty);
508             }
509             set
510             {
511                 SetValue(EnabledProperty, value);
512             }
513         }
514 
515         [Browsable(false)]
516         [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
517         public string QualifiedName
518         {
519             get
520             {
521                 if (!this.DesignMode && !this.DynamicUpdateMode)
522                 {
523                     string cachedQualifiedName = (string)GetValue(QualifiedNameProperty);
524                     if (cachedQualifiedName != null)
525                         return cachedQualifiedName;
526                 }
527 
528                 string sbQId = null;
529                 if (Helpers.IsActivityLocked(this))
530                     sbQId = InternalHelpers.GenerateQualifiedNameForLockedActivity(this, null);
531                 else
532                     sbQId = (string)GetValue(NameProperty);
533                 return sbQId;
534             }
535         }
536 
537         [Browsable(true)]
538         [SRCategory(SR.Activity)]
539         [SRDescription(SR.DescriptionDescr)]
540         [Editor(typeof(MultilineStringEditor), typeof(UITypeEditor))]
541         [DefaultValue("")]
542         public string Description
543         {
544             get
545             {
546                 return (string)GetValue(DescriptionProperty);
547             }
548             set
549             {
550                 SetValue(DescriptionProperty, value);
551             }
552         }
553         #endregion
554 
555         #region Activity Instance Properties
556 
557         public static readonly DependencyProperty StatusChangedEvent = DependencyProperty.Register("StatusChanged", typeof(EventHandler<ActivityExecutionStatusChangedEventArgs>), typeof(Activity));
558         [Browsable(false)]
559         [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
560         public event EventHandler<ActivityExecutionStatusChangedEventArgs> StatusChanged
561         {
562             add
563             {
564                 this.AddStatusChangeHandler(StatusChangedEvent, value);
565             }
566             remove
567             {
568                 this.RemoveStatusChangeHandler(StatusChangedEvent, value);
569             }
570         }
571 
572         internal static readonly DependencyProperty LockCountOnStatusChangeChangedEvent = DependencyProperty.Register("LockCountOnStatusChangeChanged", typeof(EventHandler<ActivityExecutionStatusChangedEventArgs>), typeof(Activity));
573         internal static readonly DependencyProperty StatusChangedLockedEvent = DependencyProperty.Register("StatusChangedLocked", typeof(EventHandler<ActivityExecutionStatusChangedEventArgs>), typeof(Activity));
HoldLockOnStatusChange(IActivityEventListener<ActivityExecutionStatusChangedEventArgs> eventListener)574         internal void HoldLockOnStatusChange(IActivityEventListener<ActivityExecutionStatusChangedEventArgs> eventListener)
575         {
576             this.RegisterForStatusChange(StatusChangedLockedEvent, eventListener);
577 
578             // increment count
579             this.SetValue(LockCountOnStatusChangeProperty, this.LockCountOnStatusChange + 1);
580         }
ReleaseLockOnStatusChange(IActivityEventListener<ActivityExecutionStatusChangedEventArgs> eventListener)581         internal void ReleaseLockOnStatusChange(IActivityEventListener<ActivityExecutionStatusChangedEventArgs> eventListener)
582         {
583             // remove it
584             this.UnregisterForStatusChange(StatusChangedLockedEvent, eventListener);
585 
586             // decrement count and fire event
587             int lockCountOnStatusChange = this.LockCountOnStatusChange;
588             Debug.Assert(lockCountOnStatusChange > 0, "lock count on status change should be > 0");
589             this.SetValue(LockCountOnStatusChangeProperty, --lockCountOnStatusChange);
590             if (lockCountOnStatusChange == 0)
591             {
592                 // Work around: if primary activity was never closed, then we set it to Canceled outcome
593                 if (!this.HasPrimaryClosed)
594                     this.SetValue(ExecutionResultProperty, ActivityExecutionResult.Canceled);
595 
596                 try
597                 {
598                     this.MarkClosed();
599                 }
600                 catch
601                 {
602                     // roll back the lock count changes which we did
603                     this.SetValue(LockCountOnStatusChangeProperty, ++lockCountOnStatusChange);
604                     this.RegisterForStatusChange(StatusChangedLockedEvent, eventListener);
605                     throw;
606                 }
607             }
608             else
609             {
610                 FireStatusChangedEvents(Activity.LockCountOnStatusChangeChangedEvent, false);
611             }
612         }
613 
614         [Browsable(false)]
615         [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
616         internal int LockCountOnStatusChange
617         {
618             get
619             {
620                 return (int)this.GetValue(LockCountOnStatusChangeProperty);
621             }
622         }
623 
624         [Browsable(false)]
625         [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
626         internal bool HasPrimaryClosed
627         {
628             get
629             {
630                 return (bool)this.GetValue(HasPrimaryClosedProperty);
631             }
632         }
633 
634         public static readonly DependencyProperty CancelingEvent = DependencyProperty.Register("Canceling", typeof(EventHandler<ActivityExecutionStatusChangedEventArgs>), typeof(Activity));
635 
636         [Browsable(false)]
637         [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
638         public event EventHandler<ActivityExecutionStatusChangedEventArgs> Canceling
639         {
640             add
641             {
642                 this.AddStatusChangeHandler(CancelingEvent, value);
643             }
644             remove
645             {
646                 this.RemoveStatusChangeHandler(CancelingEvent, value);
647             }
648         }
649 
650         public static readonly DependencyProperty FaultingEvent = DependencyProperty.Register("Faulting", typeof(EventHandler<ActivityExecutionStatusChangedEventArgs>), typeof(Activity));
651 
652         [Browsable(false)]
653         [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
654         public event EventHandler<ActivityExecutionStatusChangedEventArgs> Faulting
655         {
656             add
657             {
658                 this.AddStatusChangeHandler(FaultingEvent, value);
659             }
660             remove
661             {
662                 this.RemoveStatusChangeHandler(FaultingEvent, value);
663             }
664         }
665 
666 
667         public static readonly DependencyProperty ClosedEvent = DependencyProperty.Register("Closed", typeof(EventHandler<ActivityExecutionStatusChangedEventArgs>), typeof(Activity));
668 
669         [Browsable(false)]
670         [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
671         public event EventHandler<ActivityExecutionStatusChangedEventArgs> Closed
672         {
673             add
674             {
675                 this.AddStatusChangeHandler(ClosedEvent, value);
676             }
677             remove
678             {
679                 this.RemoveStatusChangeHandler(ClosedEvent, value);
680             }
681         }
682 
683         public static readonly DependencyProperty ExecutingEvent = DependencyProperty.Register("Executing", typeof(EventHandler<ActivityExecutionStatusChangedEventArgs>), typeof(Activity));
684 
685         [Browsable(false)]
686         [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
687         public event EventHandler<ActivityExecutionStatusChangedEventArgs> Executing
688         {
689             add
690             {
691                 this.AddStatusChangeHandler(ExecutingEvent, value);
692             }
693             remove
694             {
695                 this.RemoveStatusChangeHandler(ExecutingEvent, value);
696             }
697         }
698 
699         public static readonly DependencyProperty CompensatingEvent = DependencyProperty.Register("Compensating", typeof(EventHandler<ActivityExecutionStatusChangedEventArgs>), typeof(Activity));
700 
701         [Browsable(false)]
702         [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
703         public event EventHandler<ActivityExecutionStatusChangedEventArgs> Compensating
704         {
705             add
706             {
707                 this.AddStatusChangeHandler(CompensatingEvent, value);
708             }
709             remove
710             {
711                 this.RemoveStatusChangeHandler(CompensatingEvent, value);
712             }
713         }
AddStatusChangeHandler(DependencyProperty dependencyProp, EventHandler<ActivityExecutionStatusChangedEventArgs> delegateValue)714         private void AddStatusChangeHandler(DependencyProperty dependencyProp, EventHandler<ActivityExecutionStatusChangedEventArgs> delegateValue)
715         {
716             IList handlers = null;
717             if (this.DependencyPropertyValues.ContainsKey(dependencyProp))
718             {
719                 handlers = this.DependencyPropertyValues[dependencyProp] as IList;
720             }
721             else
722             {
723                 handlers = new ArrayList();
724                 this.DependencyPropertyValues[dependencyProp] = handlers;
725             }
726             handlers.Add(new ActivityExecutorDelegateInfo<ActivityExecutionStatusChangedEventArgs>(true, delegateValue, this.ContextActivity ?? this.RootActivity));
727         }
RemoveStatusChangeHandler(DependencyProperty dependencyProp, EventHandler<ActivityExecutionStatusChangedEventArgs> delegateValue)728         private void RemoveStatusChangeHandler(DependencyProperty dependencyProp, EventHandler<ActivityExecutionStatusChangedEventArgs> delegateValue)
729         {
730             if (this.DependencyPropertyValues.ContainsKey(dependencyProp))
731             {
732                 IList handlers = this.DependencyPropertyValues[dependencyProp] as IList;
733                 if (handlers != null)
734                 {
735                     handlers.Remove(new ActivityExecutorDelegateInfo<ActivityExecutionStatusChangedEventArgs>(true, delegateValue, this.ContextActivity));
736                     if (handlers.Count == 0)
737                         this.DependencyPropertyValues.Remove(dependencyProp);
738                 }
739             }
740         }
GetStatusChangeHandlers(DependencyProperty dependencyProp)741         private IList GetStatusChangeHandlers(DependencyProperty dependencyProp)
742         {
743             IList handlers = null;
744             if (this.DependencyPropertyValues.ContainsKey(dependencyProp))
745                 handlers = this.DependencyPropertyValues[dependencyProp] as IList;
746             return handlers;
747         }
748 
RegisterForStatusChange(DependencyProperty dependencyProp, IActivityEventListener<ActivityExecutionStatusChangedEventArgs> activityStatusChangeListener)749         public void RegisterForStatusChange(DependencyProperty dependencyProp, IActivityEventListener<ActivityExecutionStatusChangedEventArgs> activityStatusChangeListener)
750         {
751             if (dependencyProp == null)
752                 throw new ArgumentNullException("dependencyProp");
753             if (activityStatusChangeListener == null)
754                 throw new ArgumentNullException("activityStatusChangeListener");
755 
756             if (dependencyProp != Activity.ExecutingEvent &&
757                 dependencyProp != Activity.CancelingEvent &&
758                 dependencyProp != Activity.ClosedEvent &&
759                 dependencyProp != Activity.CompensatingEvent &&
760                 dependencyProp != Activity.FaultingEvent &&
761                 dependencyProp != Activity.StatusChangedEvent &&
762                 dependencyProp != Activity.StatusChangedLockedEvent &&
763                 dependencyProp != Activity.LockCountOnStatusChangeChangedEvent)
764                 throw new ArgumentException();
765 
766             IList handlers = null;
767             if (this.DependencyPropertyValues.ContainsKey(dependencyProp))
768             {
769                 handlers = this.DependencyPropertyValues[dependencyProp] as IList;
770             }
771             else
772             {
773                 handlers = new ArrayList();
774                 this.DependencyPropertyValues[dependencyProp] = handlers;
775             }
776             handlers.Add(new ActivityExecutorDelegateInfo<ActivityExecutionStatusChangedEventArgs>(true, activityStatusChangeListener, this.ContextActivity));
777         }
UnregisterForStatusChange(DependencyProperty dependencyProp, IActivityEventListener<ActivityExecutionStatusChangedEventArgs> activityStatusChangeListener)778         public void UnregisterForStatusChange(DependencyProperty dependencyProp, IActivityEventListener<ActivityExecutionStatusChangedEventArgs> activityStatusChangeListener)
779         {
780             if (dependencyProp == null)
781                 throw new ArgumentNullException("dependencyProp");
782             if (activityStatusChangeListener == null)
783                 throw new ArgumentNullException("activityStatusChangeListener");
784 
785             if (dependencyProp != Activity.ExecutingEvent &&
786                 dependencyProp != Activity.CancelingEvent &&
787                 dependencyProp != Activity.ClosedEvent &&
788                 dependencyProp != Activity.CompensatingEvent &&
789                 dependencyProp != Activity.FaultingEvent &&
790                 dependencyProp != Activity.StatusChangedEvent &&
791                 dependencyProp != Activity.StatusChangedLockedEvent &&
792                 dependencyProp != Activity.LockCountOnStatusChangeChangedEvent)
793                 throw new ArgumentException();
794 
795             if (this.DependencyPropertyValues.ContainsKey(dependencyProp))
796             {
797                 IList handlers = this.DependencyPropertyValues[dependencyProp] as IList;
798                 if (handlers != null)
799                 {
800                     handlers.Remove(new ActivityExecutorDelegateInfo<ActivityExecutionStatusChangedEventArgs>(true, activityStatusChangeListener, this.ContextActivity));
801                     if (handlers.Count == 0)
802                         this.DependencyPropertyValues.Remove(dependencyProp);
803                 }
804             }
805         }
806 
807         [Browsable(false)]
808         [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
809         public ActivityExecutionStatus ExecutionStatus
810         {
811             get
812             {
813                 return (ActivityExecutionStatus)this.GetValue(ExecutionStatusProperty);
814             }
815         }
816 
817         [Browsable(false)]
818         [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
819         public ActivityExecutionResult ExecutionResult
820         {
821             get
822             {
823                 return (ActivityExecutionResult)this.GetValue(ExecutionResultProperty);
824             }
825         }
826 
827         [Browsable(false)]
828         [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
829         public bool IsDynamicActivity
830         {
831             get
832             {
833                 if (this.DesignMode)
834                     return false;
835                 else
836                     return (this.ContextActivity != this.RootActivity);
837             }
838         }
839 
840 
841         [Browsable(false)]
842         [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
843         internal bool WasExecuting
844         {
845             get
846             {
847                 return (bool)this.GetValue(WasExecutingProperty);
848             }
849         }
GetActivityByName(string activityQualifiedName)850         public Activity GetActivityByName(string activityQualifiedName)
851         {
852             return GetActivityByName(activityQualifiedName, false);
853         }
GetActivityByName(string activityQualifiedName, bool withinThisActivityOnly)854         public Activity GetActivityByName(string activityQualifiedName, bool withinThisActivityOnly)
855         {
856             if (activityQualifiedName == null)
857                 throw new ArgumentNullException("activityQualifiedName");
858 
859             if (this.QualifiedName == activityQualifiedName)
860                 return this;
861 
862             Activity resolvedActivity = null;
863 
864             // try with just the passed qualified id
865             resolvedActivity = ResolveActivityByName(activityQualifiedName, withinThisActivityOnly);
866 
867             if (resolvedActivity == null)
868             {
869                 // if custom then append its qualified id and then try it
870                 if (this is CompositeActivity && Helpers.IsCustomActivity(this as CompositeActivity))
871                     resolvedActivity = ResolveActivityByName(this.QualifiedName + "." + activityQualifiedName, withinThisActivityOnly);
872             }
873 
874             return resolvedActivity;
875         }
876 
ResolveActivityByName(string activityQualifiedName, bool withinThisActivityOnly)877         private Activity ResolveActivityByName(string activityQualifiedName, bool withinThisActivityOnly)
878         {
879             Activity resolvedActivity = null;
880             if (!this.DesignMode && !this.DynamicUpdateMode)
881             {
882                 Activity rootActivity = this.RootActivity;
883 
884                 Hashtable lookupPaths = (Hashtable)rootActivity.UserData[UserDataKeys.LookupPaths];
885                 if (lookupPaths != null)
886                 {
887                     string path = (string)lookupPaths[activityQualifiedName];
888                     if (path != null)
889                     {
890                         if (path.Length != 0)
891                         {
892                             string thisPath = (string)lookupPaths[this.QualifiedName];
893                             if (path.StartsWith(thisPath, StringComparison.Ordinal))
894                             {
895                                 if (path.Length == thisPath.Length)
896                                     resolvedActivity = this;
897                                 else if (thisPath.Length == 0 || path[thisPath.Length] == '.')
898                                     resolvedActivity = this.TraverseDottedPath(path.Substring(thisPath.Length > 0 ? thisPath.Length + 1 : 0));
899                             }
900                             else if (!withinThisActivityOnly)
901                             {
902                                 resolvedActivity = rootActivity.TraverseDottedPath(path);
903                             }
904                         }
905                         else if (!withinThisActivityOnly)
906                         {
907                             resolvedActivity = rootActivity;
908                         }
909                     }
910                 }
911             }
912             else if (!this.DesignMode)
913             {
914                 // WinOE Bug 20584: Fix this for dynamic updates only.  See bug description for details.
915                 CompositeActivity parent = (withinThisActivityOnly ? this : this.RootActivity) as CompositeActivity;
916                 if (parent != null)
917                 {
918                     foreach (Activity childActivity in Helpers.GetNestedActivities(parent))
919                     {
920                         if (childActivity.QualifiedName == activityQualifiedName)
921                         {
922                             resolvedActivity = childActivity;
923                             break;
924                         }
925                     }
926                 }
927             }
928             else
929             {
930                 //
931                 resolvedActivity = Helpers.ParseActivity(this, activityQualifiedName);
932 
933                 if (resolvedActivity == null && !withinThisActivityOnly)
934                     resolvedActivity = Helpers.ParseActivity(this.RootActivity, activityQualifiedName);
935             }
936 
937             return resolvedActivity;
938         }
939 
ResetAllKnownDependencyProperties()940         internal void ResetAllKnownDependencyProperties()
941         {
942             ResetKnownDependencyProperties(true);
943         }
944 
ResetKnownDependencyProperties(bool forReexecute)945         private void ResetKnownDependencyProperties(bool forReexecute)
946         {
947             DependencyProperty[] propertyClone = new DependencyProperty[this.DependencyPropertyValues.Keys.Count];
948             this.DependencyPropertyValues.Keys.CopyTo(propertyClone, 0);
949 
950             foreach (DependencyProperty property in propertyClone)
951             {
952                 if (property.IsKnown && (property.Validity == DependencyProperty.PropertyValidity.Uninitialize || (forReexecute && property.Validity == DependencyProperty.PropertyValidity.Reexecute)))
953                     this.RemoveProperty(property);
954             }
955         }
956 
TraverseDottedPath(string dottedPath)957         internal virtual Activity TraverseDottedPath(string dottedPath)
958         {
959             return null;
960         }
TraverseDottedPathFromRoot(string dottedPathFromRoot)961         internal Activity TraverseDottedPathFromRoot(string dottedPathFromRoot)
962         {
963             string thisActivityDottedPath = this.DottedPath;
964             if (dottedPathFromRoot == thisActivityDottedPath)
965                 return this;
966 
967             // if it start with the smae dotted path then it's ok, otherwise return
968             if (!dottedPathFromRoot.StartsWith(thisActivityDottedPath, StringComparison.Ordinal))
969                 return null;
970 
971             // calculate relative path
972             string relativeDottedPath = dottedPathFromRoot;
973             if (thisActivityDottedPath.Length > 0)
974                 relativeDottedPath = dottedPathFromRoot.Substring(thisActivityDottedPath.Length + 1);
975 
976             return this.TraverseDottedPath(relativeDottedPath);
977         }
978         internal string DottedPath
979         {
980             get
981             {
982                 if (!this.DesignMode && !this.DynamicUpdateMode)
983                 {
984                     string cachedDottedPath = (string)GetValue(DottedPathProperty);
985                     if (cachedDottedPath != null)
986                         return cachedDottedPath;
987                 }
988 
989                 StringBuilder dottedPathBuilder = new StringBuilder();
990                 Activity thisActivity = this;
991                 while (thisActivity.parent != null)
992                 {
993                     int thisActivityIndex = thisActivity.parent.Activities.IndexOf(thisActivity);
994                     dottedPathBuilder.Insert(0, thisActivityIndex.ToString(CultureInfo.InvariantCulture)); //15
995                     dottedPathBuilder.Insert(0, '.'); //.15
996                     thisActivity = thisActivity.parent;
997                 }
998                 if (dottedPathBuilder.Length > 0)
999                     dottedPathBuilder.Remove(0, 1); // remove the first dot
1000                 return dottedPathBuilder.ToString();
1001             }
1002         }
1003 
1004         [Browsable(false)]
1005         [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
1006         internal IWorkflowCoreRuntime WorkflowCoreRuntime
1007         {
1008             get
1009             {
1010                 return this.workflowCoreRuntime;
1011             }
1012         }
1013         internal bool DynamicUpdateMode
1014         {
1015             get
1016             {
1017                 return (this.cachedDottedPath != null);
1018             }
1019             set
1020             {
1021                 if (value)
1022                     this.cachedDottedPath = this.DottedPath;
1023                 else
1024                     this.cachedDottedPath = null;
1025             }
1026         }
1027         internal string CachedDottedPath
1028         {
1029             get
1030             {
1031                 return this.cachedDottedPath;
1032             }
1033         }
1034 
1035         #endregion
1036 
1037         #region Load/Save Static Methods
1038 
Clone()1039         public Activity Clone()
1040         {
1041             if (this.DesignMode)
1042                 throw new InvalidOperationException(SR.GetString(SR.Error_NoRuntimeAvailable));
1043 
1044             long max = (long)this.GetValue(SerializedStreamLengthProperty);
1045             if (max == 0)
1046                 max = 10240;
1047             MemoryStream memoryStream = new MemoryStream((int)max);
1048             Save(memoryStream);
1049             memoryStream.Position = 0;
1050             this.SetValue(SerializedStreamLengthProperty, memoryStream.Length > max ? memoryStream.Length : max);
1051             return Activity.Load(memoryStream, this);
1052         }
1053 
Save(Stream stream)1054         public void Save(Stream stream)
1055         {
1056             this.Save(stream, binaryFormatter);
1057         }
Save(Stream stream, IFormatter formatter)1058         public void Save(Stream stream, IFormatter formatter)
1059         {
1060             if (stream == null)
1061                 throw new ArgumentNullException("stream");
1062             if (formatter == null)
1063                 throw new ArgumentNullException("formatter");
1064 
1065             if (this.DesignMode)
1066                 throw new InvalidOperationException(SR.GetString(SR.Error_NoRuntimeAvailable));
1067 
1068             // cache the old values so that this fucntion can be re-entrant
1069             Hashtable oldContextIdToActivityMap = ContextIdToActivityMap;
1070 
1071             ContextIdToActivityMap = new Hashtable();
1072             try
1073             {
1074                 // fill context id to Activity map
1075                 FillContextIdToActivityMap(this);
1076 
1077                 // walk through all nested activity roots and set nested activities
1078                 foreach (Activity activityRoot in ContextIdToActivityMap.Values)
1079                 {
1080                     IList<Activity> nestedActivities = activityRoot.CollectNestedActivities();
1081                     if (nestedActivities != null && nestedActivities.Count > 0)
1082                         activityRoot.SetValue(Activity.NestedActivitiesProperty, nestedActivities);
1083                 }
1084 
1085                 // serialize the graph
1086                 formatter.Serialize(stream, this);
1087             }
1088             finally
1089             {
1090                 foreach (Activity activityRoot in ContextIdToActivityMap.Values)
1091                     activityRoot.RemoveProperty(Activity.NestedActivitiesProperty);
1092                 ContextIdToActivityMap = oldContextIdToActivityMap;
1093                 ActivityRoots = null;
1094             }
1095         }
Load(Stream stream, Activity outerActivity)1096         public static Activity Load(Stream stream, Activity outerActivity)
1097         {
1098             return Load(stream, outerActivity, binaryFormatter);
1099         }
Load(Stream stream, Activity outerActivity, IFormatter formatter)1100         public static Activity Load(Stream stream, Activity outerActivity, IFormatter formatter)
1101         {
1102             if (stream == null)
1103                 throw new ArgumentNullException("stream");
1104             if (formatter == null)
1105                 throw new ArgumentNullException("formatter");
1106 
1107             if (outerActivity != null && outerActivity.DesignMode)
1108                 throw new InvalidOperationException(SR.GetString(SR.Error_NoRuntimeAvailable));
1109 
1110             Activity returnActivity = null;
1111 
1112             // cache the old values, so that this fucntion can be re-entrant
1113             Hashtable oldContextIdToActivityMap = ContextIdToActivityMap;
1114             Activity oldDefinitionActivity = DefinitionActivity;
1115 
1116             // initialize the thread static guys
1117             ContextIdToActivityMap = new Hashtable();
1118             DefinitionActivity = outerActivity;
1119 
1120             try
1121             {
1122                 // fill in the context id to activity map for surrounding contexts
1123                 if (outerActivity != null)
1124                     FillContextIdToActivityMap(outerActivity.RootActivity);
1125 
1126                 // deserialize the stream
1127                 returnActivity = (Activity)formatter.Deserialize(stream);
1128 
1129                 // fix up parent child relation ships for root activity and al nested context activities
1130                 Queue<Activity> deserializedActivityRootsQueue = new Queue<Activity>();
1131                 deserializedActivityRootsQueue.Enqueue(returnActivity);
1132                 while (deserializedActivityRootsQueue.Count > 0)
1133                 {
1134                     Activity deserializedActivityRoot = deserializedActivityRootsQueue.Dequeue();
1135 
1136                     // determine the parent activity and definition activity
1137                     Activity definitionActivity = DefinitionActivity;
1138                     Activity parentActivity = outerActivity != null ? outerActivity.parent : null;
1139 
1140                     if (deserializedActivityRoot.IsContextActivity)
1141                     {
1142                         // get the corresponding definition activity
1143                         ActivityExecutionContextInfo contextInfo = (ActivityExecutionContextInfo)deserializedActivityRoot.GetValue(Activity.ActivityExecutionContextInfoProperty);
1144                         definitionActivity = definitionActivity.GetActivityByName(contextInfo.ActivityQualifiedName);
1145 
1146                         // get the corresponding parent activity
1147                         Activity parentContextActivity = (Activity)ContextIdToActivityMap[contextInfo.ParentContextId];
1148                         if (parentContextActivity != null)
1149                             parentActivity = parentContextActivity.GetActivityByName(contextInfo.ActivityQualifiedName).parent;
1150 
1151                         // fill up the cached context activities
1152                         ContextIdToActivityMap[deserializedActivityRoot.ContextId] = deserializedActivityRoot;
1153 
1154                         // get nested context activities and queue them for processing
1155                         IList<Activity> deserializedNestedActivityRoots = (IList<Activity>)deserializedActivityRoot.GetValue(Activity.ActiveExecutionContextsProperty);
1156                         if (deserializedNestedActivityRoots != null)
1157                         {
1158                             foreach (Activity deserializedNestedActivityRoot in deserializedNestedActivityRoots)
1159                                 deserializedActivityRootsQueue.Enqueue(deserializedNestedActivityRoot);
1160                         }
1161                     }
1162 
1163                     // prepare hash of id to activity
1164                     Hashtable idToActivityMap = new Hashtable();
1165                     IList<Activity> nestedActivities = (IList<Activity>)deserializedActivityRoot.GetValue(Activity.NestedActivitiesProperty);
1166                     if (nestedActivities != null)
1167                     {
1168                         foreach (Activity nestedActivity in nestedActivities)
1169                             idToActivityMap.Add(nestedActivity.DottedPath, nestedActivity);
1170                     }
1171 
1172                     // fix up parent child relation ship for this activity
1173                     deserializedActivityRoot.FixUpParentChildRelationship(definitionActivity, parentActivity, idToActivityMap);
1174                     deserializedActivityRoot.FixUpMetaProperties(definitionActivity);
1175                     deserializedActivityRoot.RemoveProperty(Activity.NestedActivitiesProperty);
1176                 }
1177 
1178                 // set the Workflow Definition in case of root activity
1179                 if (returnActivity.Parent == null)
1180                     returnActivity.SetValue(Activity.WorkflowDefinitionProperty, DefinitionActivity);
1181             }
1182             finally
1183             {
1184                 ContextIdToActivityMap = oldContextIdToActivityMap;
1185                 DefinitionActivity = oldDefinitionActivity;
1186                 ActivityRoots = null;
1187             }
1188             return returnActivity;
1189         }
FillContextIdToActivityMap(Activity seedActivity)1190         private static void FillContextIdToActivityMap(Activity seedActivity)
1191         {
1192             Queue<Activity> activityRootsQueue = new Queue<Activity>();
1193             activityRootsQueue.Enqueue(seedActivity);
1194             while (activityRootsQueue.Count > 0)
1195             {
1196                 Activity activityRoot = activityRootsQueue.Dequeue();
1197                 if (activityRoot.IsContextActivity)
1198                 {
1199                     ContextIdToActivityMap[activityRoot.ContextId] = activityRoot;
1200                     IList<Activity> activeActivityRoots = (IList<Activity>)activityRoot.GetValue(Activity.ActiveExecutionContextsProperty);
1201                     if (activeActivityRoots != null)
1202                     {
1203                         foreach (Activity activeActivityRoot in activeActivityRoots)
1204                             activityRootsQueue.Enqueue(activeActivityRoot);
1205                     }
1206                 }
1207                 else
1208                 {
1209                     ContextIdToActivityMap[0] = activityRoot;
1210                 }
1211             }
1212             ActivityRoots = new ArrayList(ContextIdToActivityMap.Values);
1213         }
1214 
1215         internal static event ActivityResolveEventHandler ActivityResolve
1216         {
1217             add
1218             {
1219                 lock (staticSyncRoot)
1220                 {
1221                     activityDefinitionResolve += value;
1222                 }
1223             }
1224             remove
1225             {
1226                 lock (staticSyncRoot)
1227                 {
1228                     activityDefinitionResolve -= value;
1229                 }
1230             }
1231         }
1232 
1233         internal static event WorkflowChangeActionsResolveEventHandler WorkflowChangeActionsResolve
1234         {
1235             add
1236             {
1237                 lock (staticSyncRoot)
1238                 {
1239                     workflowChangeActionsResolve += value;
1240                 }
1241             }
1242 
1243             remove
1244             {
1245                 lock (staticSyncRoot)
1246                 {
1247                     workflowChangeActionsResolve -= value;
1248                 }
1249             }
1250         }
1251 
OnResolveActivityDefinition(Type type, string workflowMarkup, string rulesMarkup, bool createNew, bool initForRuntime, IServiceProvider serviceProvider)1252         internal static Activity OnResolveActivityDefinition(Type type, string workflowMarkup, string rulesMarkup, bool createNew, bool initForRuntime, IServiceProvider serviceProvider)
1253         {
1254             // get invocation list
1255             Delegate[] invocationList = null;
1256             lock (staticSyncRoot)
1257             {
1258                 if (activityDefinitionResolve != null)
1259                     invocationList = activityDefinitionResolve.GetInvocationList();
1260             }
1261 
1262             // call resovlers one by one
1263             Activity activityDefinition = null;
1264             if (invocationList != null)
1265             {
1266                 foreach (ActivityResolveEventHandler activityDefinitionResolver in invocationList)
1267                 {
1268                     activityDefinition = activityDefinitionResolver(null, new ActivityResolveEventArgs(type, workflowMarkup, rulesMarkup, createNew, initForRuntime, serviceProvider));
1269                     if (activityDefinition != null)
1270                         return activityDefinition;
1271                 }
1272             }
1273             return null;
1274         }
1275 
OnResolveWorkflowChangeActions(string workflowChangesMarkup, Activity root)1276         internal static ArrayList OnResolveWorkflowChangeActions(string workflowChangesMarkup, Activity root)
1277         {
1278             // get invocation list
1279             Delegate[] invocationList = null;
1280             lock (staticSyncRoot)
1281             {
1282                 if (workflowChangeActionsResolve != null)
1283                     invocationList = workflowChangeActionsResolve.GetInvocationList();
1284             }
1285 
1286             // call resovlers one by one
1287             ArrayList changeActions = null;
1288             if (invocationList != null)
1289             {
1290                 foreach (WorkflowChangeActionsResolveEventHandler workflowChangeActionsResolver in invocationList)
1291                 {
1292                     changeActions = workflowChangeActionsResolver(root, new WorkflowChangeActionsResolveEventArgs(workflowChangesMarkup));
1293                     if (changeActions != null)
1294                         return changeActions;
1295                 }
1296             }
1297             return null;
1298         }
1299 
1300         #endregion
1301 
1302         #region Context Activity properties
1303 
1304         internal bool IsContextActivity
1305         {
1306             get
1307             {
1308                 return this.GetValue(Activity.ActivityExecutionContextInfoProperty) != null;
1309             }
1310         }
1311         internal int ContextId
1312         {
1313             get
1314             {
1315                 return ((ActivityExecutionContextInfo)this.ContextActivity.GetValue(Activity.ActivityExecutionContextInfoProperty)).ContextId;
1316             }
1317         }
1318         internal Guid ContextGuid
1319         {
1320             get
1321             {
1322                 return ((ActivityExecutionContextInfo)this.ContextActivity.GetValue(Activity.ActivityExecutionContextInfoProperty)).ContextGuid;
1323             }
1324         }
1325         internal Activity ContextActivity
1326         {
1327             get
1328             {
1329                 Activity contextActivity = this;
1330                 while (contextActivity != null && contextActivity.GetValue(Activity.ActivityExecutionContextInfoProperty) == null)
1331                     contextActivity = contextActivity.parent;
1332                 return contextActivity;
1333             }
1334         }
1335         internal Activity ParentContextActivity
1336         {
1337             get
1338             {
1339                 Activity contextActivity = this.ContextActivity;
1340                 ActivityExecutionContextInfo executionContextInfo = (ActivityExecutionContextInfo)contextActivity.GetValue(Activity.ActivityExecutionContextInfoProperty);
1341                 if (executionContextInfo.ParentContextId == -1)
1342                     return null;
1343                 return this.WorkflowCoreRuntime.GetContextActivityForId(executionContextInfo.ParentContextId);
1344             }
1345         }
1346         internal Activity RootContextActivity
1347         {
1348             get
1349             {
1350                 return this.WorkflowCoreRuntime.RootActivity;
1351             }
1352         }
1353         internal Activity RootActivity
1354         {
1355             get
1356             {
1357                 Activity parent = this;
1358                 while (parent.parent != null)
1359                     parent = parent.parent;
1360                 return parent;
1361             }
1362         }
1363 
1364         #endregion
1365 
1366         #region Runtime Initialization
1367 
OnInitializeDefinitionForRuntime()1368         internal override void OnInitializeDefinitionForRuntime()
1369         {
1370             // only if we are in design mode, execute this code, other wise ignore this call
1371             if (this.DesignMode)
1372             {
1373                 // call base
1374                 base.OnInitializeDefinitionForRuntime();
1375 
1376                 this.UserData[UserDataKeys.CustomActivity] = this.GetValue(CustomActivityProperty);
1377 
1378                 // Work around !! Supports Synchronization and atomic transaction isolation
1379                 ICollection<String> handles = (ICollection<String>)GetValue(SynchronizationHandlesProperty);
1380                 if (this.SupportsTransaction)
1381                 {
1382                     if (handles == null)
1383                         handles = new List<string>();
1384                     handles.Add(TransactionScopeActivity.TransactionScopeActivityIsolationHandle);
1385                 }
1386                 if (handles != null)
1387                     this.SetValue(SynchronizationHandlesProperty, new ReadOnlyCollection<string>(new List<string>(handles)));
1388 
1389                 // lookup paths for root activity
1390                 if (this.Parent == null)
1391                 {
1392                     Hashtable lookupPaths = new Hashtable();
1393                     this.UserData[UserDataKeys.LookupPaths] = lookupPaths;
1394                     lookupPaths.Add(this.QualifiedName, string.Empty);
1395                 }
1396 
1397                 // Initialize the cache at runtime
1398                 SetReadOnlyPropertyValue(QualifiedNameProperty, this.QualifiedName);
1399                 SetReadOnlyPropertyValue(DottedPathProperty, this.DottedPath);
1400 
1401                 // cache attributes
1402                 this.UserData[typeof(PersistOnCloseAttribute)] = (this.GetType().GetCustomAttributes(typeof(PersistOnCloseAttribute), true).Length > 0);
1403             }
1404         }
OnInitializeInstanceForRuntime(IWorkflowCoreRuntime workflowCoreRuntime)1405         internal override void OnInitializeInstanceForRuntime(IWorkflowCoreRuntime workflowCoreRuntime)
1406         {
1407             base.OnInitializeInstanceForRuntime(workflowCoreRuntime);
1408             this.workflowCoreRuntime = workflowCoreRuntime;
1409 
1410         }
1411 
OnInitializeActivatingInstanceForRuntime(IWorkflowCoreRuntime workflowCoreRuntime)1412         internal override void OnInitializeActivatingInstanceForRuntime(IWorkflowCoreRuntime workflowCoreRuntime)
1413         {
1414             //doing this will call OnRuntimeInitialized() which is a hook for the activity writers
1415             //to initialize/wire up their DPs correctly for the activating instance
1416             base.OnInitializeActivatingInstanceForRuntime(workflowCoreRuntime);
1417             this.workflowCoreRuntime = workflowCoreRuntime;
1418         }
1419 
FixUpMetaProperties(DependencyObject originalObject)1420         internal override void FixUpMetaProperties(DependencyObject originalObject)
1421         {
1422             if (originalObject == null)
1423                 throw new ArgumentNullException();
1424 
1425             // call base class
1426             base.FixUpMetaProperties(originalObject);
1427         }
FixUpParentChildRelationship(Activity definitionActivity, Activity parentActivity, Hashtable deserializedActivities)1428         internal virtual void FixUpParentChildRelationship(Activity definitionActivity, Activity parentActivity, Hashtable deserializedActivities)
1429         {
1430             // set parent for myself, root activity will have null parent
1431             if (parentActivity != null)
1432                 this.SetParent((CompositeActivity)parentActivity);
1433         }
CollectNestedActivities()1434         internal virtual IList<Activity> CollectNestedActivities()
1435         {
1436             return null;
1437         }
1438         #endregion
1439 
1440         #region Activity Status Change Signals
1441 
SetStatus(ActivityExecutionStatus newStatus, bool transacted)1442         internal void SetStatus(ActivityExecutionStatus newStatus, bool transacted)
1443         {
1444             System.Workflow.Runtime.WorkflowTrace.Runtime.TraceEvent(TraceEventType.Information, 0, "Activity Status Change - Activity: {0} Old:{1}; New:{2}", this.QualifiedName, ActivityExecutionStatusEnumToString(this.ExecutionStatus), ActivityExecutionStatusEnumToString(newStatus));
1445 
1446             // Set Was Executing
1447             if (newStatus == ActivityExecutionStatus.Faulting &&
1448                     this.ExecutionStatus == ActivityExecutionStatus.Executing)
1449             {
1450                 this.SetValue(WasExecutingProperty, true);
1451             }
1452             this.SetValue(ExecutionStatusProperty, newStatus);
1453 
1454             // fire status change events
1455             FireStatusChangedEvents(Activity.StatusChangedEvent, transacted);
1456             switch (newStatus)
1457             {
1458                 case ActivityExecutionStatus.Closed:
1459                     FireStatusChangedEvents(Activity.ClosedEvent, transacted);
1460                     break;
1461                 case ActivityExecutionStatus.Executing:
1462                     FireStatusChangedEvents(Activity.ExecutingEvent, transacted);
1463                     break;
1464                 case ActivityExecutionStatus.Canceling:
1465                     FireStatusChangedEvents(Activity.CancelingEvent, transacted);
1466                     break;
1467                 case ActivityExecutionStatus.Faulting:
1468                     FireStatusChangedEvents(Activity.FaultingEvent, transacted);
1469                     break;
1470                 case ActivityExecutionStatus.Compensating:
1471                     FireStatusChangedEvents(Activity.CompensatingEvent, transacted);
1472                     break;
1473                 default:
1474                     return;
1475             }
1476 
1477             // inform the workflow synchronously about this
1478             this.WorkflowCoreRuntime.ActivityStatusChanged(this, transacted, false);
1479             if (newStatus == ActivityExecutionStatus.Closed)
1480             {
1481                 // remove these
1482                 this.RemoveProperty(Activity.LockCountOnStatusChangeProperty);
1483                 this.RemoveProperty(Activity.HasPrimaryClosedProperty);
1484                 this.RemoveProperty(Activity.WasExecutingProperty);
1485             }
1486         }
FireStatusChangedEvents(DependencyProperty dependencyProperty, bool transacted)1487         private void FireStatusChangedEvents(DependencyProperty dependencyProperty, bool transacted)
1488         {
1489             IList eventListeners = this.GetStatusChangeHandlers(dependencyProperty);
1490             if (eventListeners != null)
1491             {
1492                 ActivityExecutionStatusChangedEventArgs statusChangeEventArgs = new ActivityExecutionStatusChangedEventArgs(this.ExecutionStatus, this.ExecutionResult, this);
1493                 foreach (ActivityExecutorDelegateInfo<ActivityExecutionStatusChangedEventArgs> delegateInfo in eventListeners)
1494                     delegateInfo.InvokeDelegate(this.ContextActivity, statusChangeEventArgs, delegateInfo.ActivityQualifiedName == null, transacted);
1495             }
1496         }
MarkCanceled()1497         internal void MarkCanceled()
1498         {
1499             if (this.ExecutionStatus != ActivityExecutionStatus.Closed)
1500             {
1501                 if (this.ExecutionStatus != ActivityExecutionStatus.Canceling)
1502                     throw new InvalidOperationException(SR.GetString(SR.Error_InvalidCancelActivityState)); //DCR01
1503                 this.SetValue(ExecutionResultProperty, ActivityExecutionResult.Canceled);
1504                 this.MarkClosed();
1505             }
1506         }
MarkCompleted()1507         internal void MarkCompleted()
1508         {
1509             this.SetValue(ExecutionResultProperty, ActivityExecutionResult.Succeeded);
1510             this.MarkClosed();
1511         }
MarkCompensated()1512         internal void MarkCompensated()
1513         {
1514             if (this.ExecutionStatus != ActivityExecutionStatus.Compensating)
1515                 throw new InvalidOperationException(SR.GetString(SR.Error_InvalidCompensateActivityState)); //DCR01
1516 
1517             this.SetValue(ExecutionResultProperty, ActivityExecutionResult.Compensated);
1518             this.MarkClosed();
1519         }
MarkFaulted()1520         internal void MarkFaulted()
1521         {
1522             this.SetValue(ExecutionResultProperty, ActivityExecutionResult.Faulted);
1523             this.MarkClosed();
1524         }
MarkClosed()1525         private void MarkClosed()
1526         {
1527             switch (this.ExecutionStatus)
1528             {
1529                 case ActivityExecutionStatus.Executing:
1530                 case ActivityExecutionStatus.Faulting:
1531                 case ActivityExecutionStatus.Compensating:
1532                 case ActivityExecutionStatus.Canceling:
1533                     break;
1534                 default:
1535                     throw new InvalidOperationException(SR.GetString(SR.Error_InvalidCloseActivityState)); //DCR01
1536             }
1537 
1538             if (this is CompositeActivity)
1539             {
1540                 foreach (Activity childActivity in ((CompositeActivity)this).Activities)
1541                     if (childActivity.Enabled && !(childActivity.ExecutionStatus == ActivityExecutionStatus.Initialized || childActivity.ExecutionStatus == ActivityExecutionStatus.Closed))
1542                         throw new InvalidOperationException(SR.GetString(System.Globalization.CultureInfo.CurrentCulture, SR.Error_ActiveChildExist));
1543 
1544                 ActivityExecutionContext currentContext = new ActivityExecutionContext(this);
1545 
1546                 foreach (ActivityExecutionContext childContext in currentContext.ExecutionContextManager.ExecutionContexts)
1547                 {
1548                     if (this.GetActivityByName(childContext.Activity.QualifiedName, true) != null)
1549                         throw new InvalidOperationException(SR.GetString(System.Globalization.CultureInfo.CurrentCulture, SR.Error_ActiveChildContextExist));
1550                 }
1551             }
1552 
1553             if (this.LockCountOnStatusChange > 0)
1554             {
1555                 this.SetValue(HasPrimaryClosedProperty, true);
1556                 this.FireStatusChangedEvents(Activity.StatusChangedLockedEvent, false);
1557             }
1558             else if (this.parent == null ||
1559                         (this.ExecutionResult == ActivityExecutionResult.Succeeded && (this is ICompensatableActivity || this.PersistOnClose))
1560                     )
1561             {
1562                 ActivityExecutionStatus oldStatus = this.ExecutionStatus;
1563                 ActivityExecutionResult oldOutcome = this.ExecutionResult;
1564 
1565                 this.SetStatus(ActivityExecutionStatus.Closed, true);
1566                 try
1567                 {
1568                     // The activity may remove any instance specific dependency properties to reduce serialization size
1569                     this.OnClosed(this.RootActivity.WorkflowCoreRuntime);
1570                 }
1571                 catch (Exception e)
1572                 {
1573                     this.SetValue(ExecutionResultProperty, ActivityExecutionResult.Faulted);
1574                     this.SetValueCommon(ActivityExecutionContext.CurrentExceptionProperty, e, ActivityExecutionContext.CurrentExceptionProperty.DefaultMetadata, false);
1575                 }
1576 
1577 
1578                 if (this.parent != null && (this is ICompensatableActivity))
1579                 {
1580                     this.SetValue(CompletedOrderIdProperty, this.IncrementCompletedOrderId());
1581                 }
1582                 if (CanUninitializeNow)
1583                 {
1584                     //
1585 
1586                     this.Uninitialize(this.RootActivity.WorkflowCoreRuntime);
1587                     this.SetValue(ExecutionResultProperty, ActivityExecutionResult.Uninitialized);
1588                 }
1589                 else if (this.parent == null) //Root Activity Closure
1590                 {
1591                     UninitializeCompletedContext(this, new ActivityExecutionContext(this));
1592                 }
1593 
1594                 try
1595                 {
1596                     Exception exception = (Exception)this.GetValue(ActivityExecutionContext.CurrentExceptionProperty);
1597                     if (exception != null && this.parent == null)
1598                     {
1599                         this.WorkflowCoreRuntime.ActivityStatusChanged(this, false, true);
1600                         // terminate the workflow instance
1601                         string errorString = "Uncaught exception escaped to the root of the workflow.\n"
1602                             + string.Format(CultureInfo.CurrentCulture, "    In instance {0} in activity {1}\n", new object[] { this.WorkflowInstanceId, string.Empty })
1603                             + string.Format(CultureInfo.CurrentCulture, "Inner exception: {0}", new object[] { exception });
1604                         System.Workflow.Runtime.WorkflowTrace.Runtime.TraceEvent(TraceEventType.Critical, 0, errorString);
1605                         this.WorkflowCoreRuntime.TerminateInstance(exception);
1606                     }
1607                     else if (exception != null && this.parent != null)
1608                     {
1609                         this.WorkflowCoreRuntime.RaiseException(exception, this.Parent, string.Empty);
1610                         this.RemoveProperty(ActivityExecutionContext.CurrentExceptionProperty);
1611                     }
1612                     else if (this.parent == null || this.PersistOnClose)
1613                     {
1614                         this.WorkflowCoreRuntime.PersistInstanceState(this);
1615                         this.WorkflowCoreRuntime.ActivityStatusChanged(this, false, true);
1616 
1617                         // throw exception to outer
1618                         if (exception != null)
1619                         {
1620                             this.WorkflowCoreRuntime.RaiseException(exception, this.Parent, string.Empty);
1621                             this.RemoveProperty(ActivityExecutionContext.CurrentExceptionProperty);
1622                         }
1623                     }
1624 
1625                     // remove the cached lock values
1626                     Activity parent = this.parent;
1627                     while (parent != null)
1628                     {
1629                         if (parent.SupportsSynchronization || parent.Parent == null)
1630                             parent.RemoveProperty(ActivityExecutionContext.CachedGrantedLocksProperty);
1631 
1632                         parent = parent.parent;
1633                     }
1634 
1635                 }
1636                 catch
1637                 {
1638                     if (this.parent != null && (this is ICompensatableActivity))
1639                     {
1640                         this.RemoveProperty(CompletedOrderIdProperty);
1641                         this.DecrementCompletedOrderId();
1642                     }
1643                     this.SetValue(ExecutionResultProperty, oldOutcome);
1644                     this.SetStatus(oldStatus, true);
1645 
1646                     // copy back the old locks values
1647                     Activity parent = this.parent;
1648                     while (parent != null)
1649                     {
1650                         if (parent.SupportsSynchronization || parent.Parent == null)
1651                         {
1652                             object cachedGrantedLocks = parent.GetValue(ActivityExecutionContext.CachedGrantedLocksProperty);
1653                             if (cachedGrantedLocks != null)
1654                                 parent.SetValue(ActivityExecutionContext.GrantedLocksProperty, cachedGrantedLocks);
1655                             parent.RemoveProperty(ActivityExecutionContext.CachedGrantedLocksProperty);
1656                         }
1657                         parent = parent.parent;
1658                     }
1659                     throw;
1660                 }
1661             }
1662             else
1663             {
1664                 // The activity may remove any instance specific dependency properties to reduce serialization size
1665                 this.SetStatus(ActivityExecutionStatus.Closed, false);
1666                 try
1667                 {
1668                     this.OnClosed(this.RootActivity.WorkflowCoreRuntime);
1669                 }
1670                 catch (Exception e)
1671                 {
1672                     this.SetValue(ExecutionResultProperty, ActivityExecutionResult.Faulted);
1673                     this.SetValueCommon(ActivityExecutionContext.CurrentExceptionProperty, e, ActivityExecutionContext.CurrentExceptionProperty.DefaultMetadata, false);
1674                 }
1675                 if (CanUninitializeNow)
1676                 {
1677                     //
1678 
1679                     this.Uninitialize(this.RootActivity.WorkflowCoreRuntime);
1680                     this.SetValue(ExecutionResultProperty, ActivityExecutionResult.Uninitialized);
1681                 }
1682 
1683                 Exception exception = (Exception)this.GetValue(ActivityExecutionContext.CurrentExceptionProperty);
1684                 if (exception != null)
1685                 {
1686                     this.WorkflowCoreRuntime.RaiseException(exception, this.Parent, string.Empty);
1687                     this.RemoveProperty(ActivityExecutionContext.CurrentExceptionProperty);
1688                 }
1689             }
1690         }
1691 
1692         internal bool CanUninitializeNow
1693         {
1694             get
1695             {
1696                 //This check finds
1697                 //1) Existence of Succeeded ISC in same context.
1698                 //2) If activity is ContextActivity? Checks existence of completed child
1699                 //context which needs compensation
1700                 if (this.NeedsCompensation)
1701                     return false;
1702 
1703                 //3) If this activity is not a context activity, check for completed child context
1704                 //which needs compensation.
1705                 Activity contextActivity = this.ContextActivity;
1706 
1707                 if (contextActivity != this)
1708                 {
1709                     IList<ActivityExecutionContextInfo> childsCompletedContexts = contextActivity.GetValue(Activity.CompletedExecutionContextsProperty) as IList<ActivityExecutionContextInfo>;
1710 
1711                     if (childsCompletedContexts != null && childsCompletedContexts.Count > 0)
1712                     {
1713                         foreach (ActivityExecutionContextInfo contextInfo in childsCompletedContexts)
1714                         {
1715                             if ((contextInfo.Flags & PersistFlags.NeedsCompensation) != 0 && this.GetActivityByName(contextInfo.ActivityQualifiedName, true) != null)
1716                             {
1717                                 return false;
1718                             }
1719                         }
1720                     }
1721                 }
1722 
1723                 //Safe to Uninitialize this activity now.
1724                 return true;
1725             }
1726         }
1727 
UninitializeCompletedContext(Activity activity, ActivityExecutionContext executionContext)1728         static void UninitializeCompletedContext(Activity activity, ActivityExecutionContext executionContext)
1729         {
1730             //Uninitialize Compensatable Children which ran in Sub Contextee.
1731             IList<ActivityExecutionContextInfo> childsCompletedContexts = activity.GetValue(Activity.CompletedExecutionContextsProperty) as IList<ActivityExecutionContextInfo>;
1732 
1733             if (childsCompletedContexts != null && childsCompletedContexts.Count > 0)
1734             {
1735                 IList<ActivityExecutionContextInfo> childsCompletedContextsClone = new List<ActivityExecutionContextInfo>(childsCompletedContexts);
1736                 foreach (ActivityExecutionContextInfo contextInfo in childsCompletedContextsClone)
1737                 {
1738                     if ((contextInfo.Flags & PersistFlags.NeedsCompensation) != 0 && activity.GetActivityByName(contextInfo.ActivityQualifiedName, true) != null)
1739                     {
1740                         ActivityExecutionContext resurrectedContext = executionContext.ExecutionContextManager.DiscardPersistedExecutionContext(contextInfo);
1741                         UninitializeCompletedContext(resurrectedContext.Activity, resurrectedContext);
1742                         executionContext.ExecutionContextManager.CompleteExecutionContext(resurrectedContext);
1743                     }
1744                 }
1745             }
1746 
1747             //UnInitialize any compensatable children which ran in same context.
1748             CompositeActivity compositeActivity = activity as CompositeActivity;
1749             if (compositeActivity != null)
1750             {
1751                 Activity[] compensatableChildren = CompensationUtils.GetCompensatableChildren(compositeActivity);
1752 
1753                 for (int i = compensatableChildren.Length - 1; i >= 0; --i)
1754                 {
1755                     Activity compensatableChild = (Activity)compensatableChildren.GetValue(i);
1756                     compensatableChild.Uninitialize(activity.RootActivity.WorkflowCoreRuntime);
1757                     compensatableChild.SetValue(ExecutionResultProperty, ActivityExecutionResult.Uninitialized);
1758                 }
1759             }
1760 
1761             //UnInitialize Self
1762             activity.Uninitialize(activity.RootActivity.WorkflowCoreRuntime);
1763             activity.SetValue(ExecutionResultProperty, ActivityExecutionResult.Uninitialized);
1764         }
1765 
1766         internal bool NeedsCompensation
1767         {
1768             get
1769             {
1770                 IList<ActivityExecutionContextInfo> childsCompletedContexts = this.GetValue(Activity.CompletedExecutionContextsProperty) as IList<ActivityExecutionContextInfo>;
1771                 if (childsCompletedContexts != null && childsCompletedContexts.Count > 0)
1772                 {
1773                     foreach (ActivityExecutionContextInfo completedActivityInfo in childsCompletedContexts)
1774                     {
1775                         if ((completedActivityInfo.Flags & PersistFlags.NeedsCompensation) != 0 && this.GetActivityByName(completedActivityInfo.ActivityQualifiedName, true) != null)
1776                             return true;
1777                     }
1778                 }
1779 
1780                 // walk through all compensatable children and compensate them
1781                 Queue<Activity> completedActivities = new Queue<Activity>();
1782                 completedActivities.Enqueue(this);
1783                 while (completedActivities.Count > 0)
1784                 {
1785                     Activity completedChild = completedActivities.Dequeue();
1786                     if (completedChild is ICompensatableActivity &&
1787                          completedChild.ExecutionStatus == ActivityExecutionStatus.Closed &&
1788                          completedChild.ExecutionResult == ActivityExecutionResult.Succeeded)
1789                         return true;
1790 
1791                     if (completedChild is CompositeActivity)
1792                     {
1793                         foreach (Activity completedChild2 in ((CompositeActivity)completedChild).Activities)
1794                         {
1795                             if (completedChild2.Enabled)
1796                                 completedActivities.Enqueue(completedChild2);
1797                         }
1798                     }
1799                 }
1800                 return false;
1801             }
1802         }
1803 
1804         #endregion
1805 
1806         #region Behaviors Supports
1807 
1808         internal bool SupportsTransaction
1809         {
1810             get
1811             {
1812                 return this is CompensatableTransactionScopeActivity || this is TransactionScopeActivity;
1813             }
1814         }
1815         internal bool SupportsSynchronization
1816         {
1817             get
1818             {
1819                 return this is SynchronizationScopeActivity;
1820             }
1821         }
1822         internal bool PersistOnClose
1823         {
1824             get
1825             {
1826                 if (this.UserData.Contains(typeof(PersistOnCloseAttribute)))
1827                     return (bool)this.UserData[typeof(PersistOnCloseAttribute)];
1828 
1829                 object[] attributes = this.GetType().GetCustomAttributes(typeof(PersistOnCloseAttribute), true);
1830                 return (attributes != null && attributes.Length > 0);
1831             }
1832         }
1833 
IncrementCompletedOrderId()1834         internal int IncrementCompletedOrderId()
1835         {
1836             int completedOrderId = (int)this.RootActivity.GetValue(Activity.CompletedOrderIdProperty);
1837             this.RootActivity.SetValue(Activity.CompletedOrderIdProperty, completedOrderId + 1);
1838             return (completedOrderId + 1);
1839         }
DecrementCompletedOrderId()1840         internal void DecrementCompletedOrderId()
1841         {
1842             int completedOrderId = (int)this.RootActivity.GetValue(Activity.CompletedOrderIdProperty);
1843             this.RootActivity.SetValue(Activity.CompletedOrderIdProperty, completedOrderId - 1);
1844         }
1845 
1846         #endregion
1847 
1848         #region EnumToString Converters
1849 
ActivityExecutionStatusEnumToString(ActivityExecutionStatus status)1850         internal static string ActivityExecutionStatusEnumToString(ActivityExecutionStatus status)
1851         {
1852             string retVal = string.Empty;
1853             switch (status)
1854             {
1855                 case ActivityExecutionStatus.Initialized:
1856                     retVal = "Initialized";
1857                     break;
1858                 case ActivityExecutionStatus.Executing:
1859                     retVal = "Executing";
1860                     break;
1861                 case ActivityExecutionStatus.Canceling:
1862                     retVal = "Canceling";
1863                     break;
1864                 case ActivityExecutionStatus.Faulting:
1865                     retVal = "Faulting";
1866                     break;
1867                 case ActivityExecutionStatus.Compensating:
1868                     retVal = "Compensating";
1869                     break;
1870                 case ActivityExecutionStatus.Closed:
1871                     retVal = "Closed";
1872                     break;
1873             }
1874             return retVal;
1875         }
ActivityExecutionResultEnumToString(ActivityExecutionResult activityExecutionResult)1876         internal static string ActivityExecutionResultEnumToString(ActivityExecutionResult activityExecutionResult)
1877         {
1878             string retVal = string.Empty;
1879             switch (activityExecutionResult)
1880             {
1881                 case ActivityExecutionResult.None:
1882                     retVal = "None";
1883                     break;
1884                 case ActivityExecutionResult.Succeeded:
1885                     retVal = "Succeeded";
1886                     break;
1887                 case ActivityExecutionResult.Canceled:
1888                     retVal = "Canceled";
1889                     break;
1890                 case ActivityExecutionResult.Faulted:
1891                     retVal = "Faulted";
1892                     break;
1893                 case ActivityExecutionResult.Compensated:
1894                     retVal = "Compensated";
1895                     break;
1896             }
1897             return retVal;
1898         }
1899 
1900         #endregion
1901 
ToString()1902         public override String ToString()
1903         {
1904             return this.QualifiedName + " [" + GetType().FullName + "]";
1905         }
1906     }
1907     #endregion
1908 
1909     #region Class CompositeActivity
1910 
1911     [ContentProperty("Activities")]
1912     [DesignerSerializer(typeof(CompositeActivityMarkupSerializer), typeof(WorkflowMarkupSerializer))]
1913     [ActivityCodeGenerator(typeof(CompositeActivityCodeGenerator))]
1914     [ActivityValidator(typeof(CompositeActivityValidator))]
1915     [ActivityExecutor(typeof(CompositeActivityExecutor<CompositeActivity>))]
1916     [TypeDescriptionProvider(typeof(CompositeActivityTypeDescriptorProvider))]
1917     [Obsolete("The System.Workflow.* types are deprecated.  Instead, please use the new types from System.Activities.*")]
1918     public class CompositeActivity : Activity, ISupportAlternateFlow
1919     {
1920         private static DependencyProperty CanModifyActivitiesProperty = DependencyProperty.Register("CanModifyActivities", typeof(bool), typeof(CompositeActivity), new PropertyMetadata(DependencyPropertyOptions.Metadata, new Attribute[] { new DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden) }));
1921 
1922         [NonSerialized]
1923         private ActivityCollection activities = null;
1924 
CompositeActivity()1925         public CompositeActivity()
1926         {
1927             this.activities = new ActivityCollection(this);
1928             this.activities.ListChanging += new EventHandler<ActivityCollectionChangeEventArgs>(OnListChangingEventHandler);
1929             this.activities.ListChanged += new EventHandler<ActivityCollectionChangeEventArgs>(OnListChangedEventHandler);
1930 
1931             SetValue(CanModifyActivitiesProperty, false);
1932         }
1933 
CompositeActivity(IEnumerable<Activity> children)1934         public CompositeActivity(IEnumerable<Activity> children)
1935             : this()
1936         {
1937             if (children == null)
1938                 throw new ArgumentNullException("children");
1939 
1940             foreach (Activity child in children)
1941                 this.activities.Add(child);
1942         }
1943 
CompositeActivity(string name)1944         public CompositeActivity(string name)
1945             : base(name)
1946         {
1947             this.activities = new ActivityCollection(this);
1948             this.activities.ListChanging += new EventHandler<ActivityCollectionChangeEventArgs>(OnListChangingEventHandler);
1949             this.activities.ListChanged += new EventHandler<ActivityCollectionChangeEventArgs>(OnListChangedEventHandler);
1950 
1951             SetValue(CanModifyActivitiesProperty, false);
1952         }
1953 
GetDynamicActivities(Activity activity)1954         protected Activity[] GetDynamicActivities(Activity activity)
1955         {
1956             if (activity == null)
1957                 throw new ArgumentNullException("activity");
1958 
1959             // Work around - make sure that we return the parent property value
1960             // otherwise .Parent property would have set the workflowCoreRuntime for parent
1961             if (activity.parent != this)
1962                 throw new ArgumentException(SR.GetString(SR.GetDynamicActivities_InvalidActivity), "activity");
1963 
1964             // get context activity
1965             Activity contextActivity = this.ContextActivity;
1966             List<Activity> dynamicActivities = new List<Activity>();
1967             if (contextActivity != null)
1968             {
1969                 IList<Activity> activeContextActivities = (IList<Activity>)contextActivity.GetValue(Activity.ActiveExecutionContextsProperty);
1970                 if (activeContextActivities != null)
1971                 {
1972                     foreach (Activity activeContextActivity in activeContextActivities)
1973                     {
1974                         if (activeContextActivity.MetaEquals(activity))
1975                             dynamicActivities.Add(activeContextActivity);
1976                     }
1977                 }
1978             }
1979             return dynamicActivities.ToArray();
1980         }
1981 
Initialize(IServiceProvider provider)1982         protected internal override void Initialize(IServiceProvider provider)
1983         {
1984             if (provider == null)
1985                 throw new ArgumentNullException("provider");
1986 
1987             if (!(provider is ActivityExecutionContext))
1988                 throw new ArgumentException(SR.GetString(SR.Error_InvalidServiceProvider, "provider"));
1989 
1990             foreach (Activity childActivity in Helpers.GetAllEnabledActivities(this))
1991             {
1992                 ActivityExecutionContext executionContext = provider as ActivityExecutionContext;
1993                 executionContext.InitializeActivity(childActivity);
1994             }
1995         }
1996 
Uninitialize(IServiceProvider provider)1997         protected internal override void Uninitialize(IServiceProvider provider)
1998         {
1999             if (provider == null)
2000                 throw new ArgumentNullException("provider");
2001 
2002             foreach (Activity childActivity in Helpers.GetAllEnabledActivities(this))
2003             {
2004                 //Case for Template/Conditional Branch/Non Context based Composite which
2005                 //exists in path between compensatable context.
2006                 if (childActivity.ExecutionResult != ActivityExecutionResult.Uninitialized)
2007                 {
2008                     childActivity.Uninitialize(provider);
2009                     childActivity.SetValue(ExecutionResultProperty, ActivityExecutionResult.Uninitialized);
2010                 }
2011             }
2012             base.Uninitialize(provider);
2013         }
OnActivityExecutionContextLoad(IServiceProvider provider)2014         protected internal override void OnActivityExecutionContextLoad(IServiceProvider provider)
2015         {
2016             if (provider == null)
2017                 throw new ArgumentNullException("provider");
2018 
2019             base.OnActivityExecutionContextLoad(provider);
2020 
2021             foreach (Activity childActivity in Helpers.GetAllEnabledActivities(this))
2022             {
2023                 childActivity.OnActivityExecutionContextLoad(provider);
2024             }
2025         }
OnActivityExecutionContextUnload(IServiceProvider provider)2026         protected internal override void OnActivityExecutionContextUnload(IServiceProvider provider)
2027         {
2028             if (provider == null)
2029                 throw new ArgumentNullException("provider");
2030 
2031             base.OnActivityExecutionContextUnload(provider);
2032 
2033             foreach (Activity childActivity in Helpers.GetAllEnabledActivities(this))
2034             {
2035                 childActivity.OnActivityExecutionContextUnload(provider);
2036             }
2037         }
2038 
HandleFault(ActivityExecutionContext executionContext, Exception exception)2039         protected internal override ActivityExecutionStatus HandleFault(ActivityExecutionContext executionContext, Exception exception)
2040         {
2041             if (executionContext == null)
2042                 throw new ArgumentNullException("executionContext");
2043 
2044             if (exception == null)
2045                 throw new ArgumentNullException("exception");
2046 
2047             ActivityExecutionStatus newStatus = this.Cancel(executionContext);
2048             if (newStatus == ActivityExecutionStatus.Canceling)
2049                 return ActivityExecutionStatus.Faulting;
2050 
2051             return newStatus;
2052         }
2053 
ApplyWorkflowChanges(WorkflowChanges workflowChanges)2054         protected void ApplyWorkflowChanges(WorkflowChanges workflowChanges)
2055         {
2056             if (workflowChanges == null)
2057                 throw new ArgumentNullException("workflowChanges");
2058 
2059             if (this.Parent != null)
2060                 throw new InvalidOperationException(SR.GetString(SR.Error_InvalidActivityForWorkflowChanges));
2061 
2062             if (this.RootActivity == null)
2063                 throw new InvalidOperationException(SR.GetString(SR.Error_MissingRootActivity));
2064 
2065             if (this.WorkflowCoreRuntime == null)
2066                 throw new InvalidOperationException(SR.GetString(SR.Error_NoRuntimeAvailable));
2067 
2068             workflowChanges.ApplyTo(this);
2069         }
2070 
2071 
2072         #region Workflow Change Notification Methods
OnActivityChangeAdd(ActivityExecutionContext executionContext, Activity addedActivity)2073         protected internal virtual void OnActivityChangeAdd(ActivityExecutionContext executionContext, Activity addedActivity)
2074         {
2075             if (executionContext == null)
2076                 throw new ArgumentNullException("executionContext");
2077 
2078             if (addedActivity == null)
2079                 throw new ArgumentNullException("addedActivity");
2080 
2081 
2082         }
2083 
OnActivityChangeRemove(ActivityExecutionContext executionContext, Activity removedActivity)2084         protected internal virtual void OnActivityChangeRemove(ActivityExecutionContext executionContext, Activity removedActivity)
2085         {
2086 
2087         }
2088 
OnWorkflowChangesCompleted(ActivityExecutionContext rootContext)2089         protected internal virtual void OnWorkflowChangesCompleted(ActivityExecutionContext rootContext)
2090         {
2091 
2092         }
2093         #endregion
2094 
2095         #region CompositeActivity Meta Properties
2096 
2097         [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
2098         [Browsable(false)]
2099         public ActivityCollection Activities
2100         {
2101             get
2102             {
2103                 return this.activities;
2104             }
2105         }
2106 
2107         protected internal bool CanModifyActivities
2108         {
2109             get
2110             {
2111                 return (bool)GetValue(CanModifyActivitiesProperty);
2112             }
2113             set
2114             {
2115                 SetValue(CanModifyActivitiesProperty, value);
2116                 if (this.Activities.Count > 0)
2117                     SetValue(CustomActivityProperty, true);
2118             }
2119         }
2120 
2121         #endregion
2122 
2123         #region CompositeActivity Instance Properties
2124 
2125         [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
2126         [Browsable(false)]
2127         public ReadOnlyCollection<Activity> EnabledActivities
2128         {
2129             get
2130             {
2131                 List<Activity> executableActivities = new List<Activity>();
2132                 foreach (Activity activity in this.activities)
2133                 {
2134                     // This check makes sure that only Enabled activities are returned
2135                     // and the framwork provided activities are skipped.
2136                     if (activity.Enabled && !Helpers.IsFrameworkActivity(activity))
2137                         executableActivities.Add(activity);
2138                 }
2139                 return executableActivities.AsReadOnly();
2140             }
2141         }
2142 
2143         [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
2144         [Browsable(false)]
2145         IList<Activity> ISupportAlternateFlow.AlternateFlowActivities
2146         {
2147             get
2148             {
2149                 List<Activity> secondaryFlowActivities = new List<Activity>();
2150                 foreach (Activity activity in this.activities)
2151                 {
2152                     if (activity.Enabled && Helpers.IsFrameworkActivity(activity))
2153                         secondaryFlowActivities.Add(activity);
2154                 }
2155                 return secondaryFlowActivities.AsReadOnly();
2156             }
2157         }
2158 
TraverseDottedPath(string dottedPath)2159         internal override Activity TraverseDottedPath(string dottedPath)
2160         {
2161             string subPath = dottedPath;
2162             string remainingPath = string.Empty;
2163             int indexOfDot = dottedPath.IndexOf('.');
2164             if (indexOfDot != -1)
2165             {
2166                 subPath = dottedPath.Substring(0, indexOfDot);
2167                 remainingPath = dottedPath.Substring(indexOfDot + 1);
2168             }
2169 
2170             int index = Convert.ToInt32(subPath, CultureInfo.InvariantCulture);
2171             if (index >= this.activities.Count)
2172                 return null;
2173 
2174             Activity nextActivity = this.activities[index];
2175             if (!string.IsNullOrEmpty(remainingPath))
2176                 return nextActivity.TraverseDottedPath(remainingPath);
2177             return nextActivity;
2178         }
2179 
2180         #endregion
2181 
2182         #region Runtime Initialize
2183 
OnInitializeDefinitionForRuntime()2184         internal override void OnInitializeDefinitionForRuntime()
2185         {
2186             // only if we are in design mode, execute this code, other wise ignore this call
2187             if (this.DesignMode)
2188             {
2189                 // call base
2190                 base.OnInitializeDefinitionForRuntime();
2191 
2192                 // get the lookup path
2193                 Activity rootActivity = this.RootActivity;
2194                 Hashtable lookupPaths = (Hashtable)rootActivity.UserData[UserDataKeys.LookupPaths];
2195                 string thisLookupPath = (string)lookupPaths[this.QualifiedName];
2196 
2197                 // call initializeForRuntime for every activity
2198                 foreach (Activity childActivity in (IList)this.activities)
2199                 {
2200                     if (childActivity.Enabled)
2201                     {
2202                         // setup lookup path
2203                         string lookupPath = thisLookupPath;
2204                         if (!string.IsNullOrEmpty(thisLookupPath))
2205                             lookupPath += ".";
2206                         lookupPath += this.activities.IndexOf(childActivity).ToString(CultureInfo.InvariantCulture);
2207                         lookupPaths.Add(childActivity.QualifiedName, lookupPath);
2208 
2209                         // initialize for runtime
2210                         ((IDependencyObjectAccessor)childActivity).InitializeDefinitionForRuntime(null);
2211                     }
2212                     else
2213                     {
2214                         // There are sevrel properties that are required even for disabled activities.  They include
2215                         // DottedPath, QualifiedName and Readonly.  To initialize these properties, we call
2216                         // OnInitializeDefinitionForRuntime directly and skip the InitializeProperties call inside
2217                         // IDependencyObjectAccessor.InitializeDefinitionForRuntime because other properties are not
2218                         // validated and they may not initialize properly, which the runtime really doesn't care.
2219                         childActivity.OnInitializeDefinitionForRuntime();
2220                         childActivity.Readonly = true;
2221                     }
2222                 }
2223             }
2224         }
2225 
OnInitializeInstanceForRuntime(IWorkflowCoreRuntime workflowCoreRuntime)2226         internal override void OnInitializeInstanceForRuntime(IWorkflowCoreRuntime workflowCoreRuntime)
2227         {
2228             base.OnInitializeInstanceForRuntime(workflowCoreRuntime);
2229 
2230             // call children to do initialize runtime instance
2231             foreach (Activity childActivity in this.activities)
2232             {
2233                 if (childActivity.Enabled)
2234                     ((IDependencyObjectAccessor)childActivity).InitializeInstanceForRuntime(workflowCoreRuntime);
2235             }
2236         }
2237 
OnInitializeActivatingInstanceForRuntime(IWorkflowCoreRuntime workflowCoreRuntime)2238         internal override void OnInitializeActivatingInstanceForRuntime(IWorkflowCoreRuntime workflowCoreRuntime)
2239         {
2240             // call base: this will call activity
2241             base.OnInitializeActivatingInstanceForRuntime(workflowCoreRuntime);
2242 
2243             // call children to do initialize runtime instance
2244             foreach (Activity childActivity in this.activities)
2245             {
2246                 if (childActivity.Enabled)
2247                     ((IDependencyObjectAccessor)childActivity).InitializeActivatingInstanceForRuntime(null, workflowCoreRuntime);
2248                 else
2249                     this.Readonly = true;
2250             }
2251         }
2252 
FixUpMetaProperties(DependencyObject originalObject)2253         internal override void FixUpMetaProperties(DependencyObject originalObject)
2254         {
2255             if (originalObject == null)
2256                 throw new ArgumentNullException();
2257             if (!(originalObject is CompositeActivity))
2258                 throw new ArgumentException();
2259 
2260             // call base
2261             base.FixUpMetaProperties(originalObject);
2262 
2263             // ask each child to fixup
2264             if (this.activities != null)
2265             {
2266                 CompositeActivity originalCompositeActivity = originalObject as CompositeActivity;
2267                 if (originalCompositeActivity != null)
2268                 {
2269                     int index = 0;
2270                     foreach (Activity childActivity in this.activities)
2271                         childActivity.FixUpMetaProperties(originalCompositeActivity.activities[index++]);
2272                 }
2273             }
2274         }
FixUpParentChildRelationship(Activity definitionActivity, Activity parentActivity, Hashtable deserializedActivities)2275         internal override void FixUpParentChildRelationship(Activity definitionActivity, Activity parentActivity, Hashtable deserializedActivities)
2276         {
2277             CompositeActivity definitionCompositeActivity = definitionActivity as CompositeActivity;
2278             if (definitionCompositeActivity == null)
2279                 throw new ArgumentException("definitionActivity");
2280 
2281             // call base
2282             base.FixUpParentChildRelationship(definitionActivity, parentActivity, deserializedActivities);
2283 
2284             // fix up the children collection
2285             this.activities = new ActivityCollection(this);
2286             this.activities.ListChanging += new EventHandler<ActivityCollectionChangeEventArgs>(OnListChangingEventHandler);
2287             this.activities.ListChanged += new EventHandler<ActivityCollectionChangeEventArgs>(OnListChangedEventHandler);
2288 
2289             // detect if there was a context
2290             string prefix = this.DottedPath;
2291 
2292             // fixup all the children, and then call them to fixup their relation ships
2293             int index = 0;
2294             foreach (Activity definitionChildActivity in definitionCompositeActivity.activities)
2295             {
2296                 Activity childActivity = (Activity)deserializedActivities[prefix.Length == 0 ? index.ToString(CultureInfo.InvariantCulture) : prefix + "." + index.ToString(CultureInfo.InvariantCulture)];
2297                 this.activities.InnerAdd(childActivity);
2298 
2299                 // ask child to fix up its parent child relation ship
2300                 childActivity.FixUpParentChildRelationship(definitionChildActivity, this, deserializedActivities);
2301                 index++;
2302             }
2303         }
CollectNestedActivities()2304         internal override IList<Activity> CollectNestedActivities()
2305         {
2306             List<Activity> nestedActivities = new List<Activity>();
2307             Queue<Activity> activityQueue = new Queue<Activity>(this.activities);
2308             while (activityQueue.Count > 0)
2309             {
2310                 Activity nestedActivity = activityQueue.Dequeue();
2311                 nestedActivities.Add(nestedActivity);
2312                 if (nestedActivity is CompositeActivity)
2313                 {
2314                     foreach (Activity nestedChildActivity in ((CompositeActivity)nestedActivity).activities)
2315                         activityQueue.Enqueue(nestedChildActivity);
2316                 }
2317             }
2318             return nestedActivities;
2319         }
2320 
2321         #endregion
2322 
2323         #region Collection's Event Handlers
OnListChangingEventHandler(object sender, ActivityCollectionChangeEventArgs e)2324         private void OnListChangingEventHandler(object sender, ActivityCollectionChangeEventArgs e)
2325         {
2326             if (!this.DesignMode && !this.DynamicUpdateMode)
2327                 throw new InvalidOperationException(SR.GetString(SR.Error_CanNotChangeAtRuntime));
2328 
2329             if (!this.CanModifyActivities)
2330             {
2331                 // Check the ActivityType only during design mode
2332                 if (this.DesignMode && Activity.ActivityType != null && this.GetType() == Activity.ActivityType)
2333                     throw new InvalidOperationException(SR.GetString(SR.Error_Missing_CanModifyProperties_True, this.GetType().FullName));
2334 
2335                 if (!IsDynamicMode(this) && CannotModifyChildren(this, false))
2336                     throw new InvalidOperationException(SR.GetString(SR.Error_CannotAddRemoveChildActivities));
2337 
2338                 if (IsDynamicMode(this) && CannotModifyChildren(this, true))
2339                     throw new InvalidOperationException(SR.GetString(SR.Error_CannotAddRemoveChildActivities));
2340             }
2341 
2342             if (e.Action == ActivityCollectionChangeAction.Add && e.AddedItems != null)
2343             {
2344                 Activity parent = this;
2345                 while (parent != null)
2346                 {
2347                     if (e.AddedItems.Contains(parent))
2348                         throw new InvalidOperationException(SR.GetString(SR.Error_ActivityCircularReference));
2349 
2350                     parent = parent.Parent;
2351                 }
2352             }
2353 
2354             OnListChanging(e);
2355         }
2356 
2357         protected virtual void OnListChanging(ActivityCollectionChangeEventArgs e)
2358         {
2359             if (e == null)
2360                 throw new ArgumentNullException("e");
2361             if (e.Action == ActivityCollectionChangeAction.Add && e.AddedItems != null)
2362             {
2363                 foreach (Activity activity in e.AddedItems)
2364                 {
2365                     if (activity.Parent != null)
2366                         throw new InvalidOperationException(SR.GetString(SR.Error_ActivityHasParent, activity.QualifiedName, activity.Parent.QualifiedName));
2367                     if (activity == this)
2368                         throw new InvalidOperationException(SR.GetString(SR.Error_Recursion, activity.QualifiedName));
2369                 }
2370             }
2371             if (((IComponent)this).Site != null)
2372             {
2373                 IComponentChangeService changeService = ((IComponent)this).Site.GetService(typeof(IComponentChangeService)) as IComponentChangeService;
2374                 if (changeService != null)
2375                     changeService.OnComponentChanging(this, null);
2376             }
2377         }
2378 
2379         private void OnListChangedEventHandler(object sender, ActivityCollectionChangeEventArgs e)
2380         {
2381             OnListChanged(e);
2382         }
2383 
2384         protected virtual void OnListChanged(ActivityCollectionChangeEventArgs e)
2385         {
2386             if (e == null)
2387                 throw new ArgumentNullException("e");
2388             // remove the parent
2389             if ((e.Action == ActivityCollectionChangeAction.Replace || e.Action == ActivityCollectionChangeAction.Remove) &&
2390                     e.RemovedItems != null)
2391             {
2392                 foreach (Activity activity in e.RemovedItems)
2393                     activity.SetParent(null);
2394             }
2395 
2396             // set the parent on the activity
2397             if ((e.Action == ActivityCollectionChangeAction.Replace || e.Action == ActivityCollectionChangeAction.Add) &&
2398                     e.AddedItems != null)
2399             {
2400                 foreach (Activity activity in e.AddedItems)
2401                     activity.SetParent(this);
2402 
2403                 Queue<Activity> queue = new Queue<Activity>(e.AddedItems as IEnumerable<Activity>);
2404                 while (queue.Count > 0)
2405                 {
2406                     Activity activity = queue.Dequeue() as Activity;
2407                     if (activity != null && (activity.Name == null || activity.Name.Length == 0 || activity.Name == activity.GetType().Name))
2408                     {
2409                         Activity rootActivity = Helpers.GetRootActivity(activity);
2410                         string className = rootActivity.GetValue(WorkflowMarkupSerializer.XClassProperty) as string;
2411                         if (rootActivity.Parent == null || !string.IsNullOrEmpty(className))
2412                         {
2413                             ArrayList identifiers = new ArrayList();
2414                             identifiers.AddRange(Helpers.GetIdentifiersInCompositeActivity(rootActivity as CompositeActivity));
2415                             activity.Name = DesignerHelpers.GenerateUniqueIdentifier(((IComponent)this).Site, Helpers.GetBaseIdentifier(activity), (string[])identifiers.ToArray(typeof(string)));
2416                         }
2417                     }
2418                     if (activity is CompositeActivity)
2419                     {
2420                         foreach (Activity activity2 in ((CompositeActivity)activity).Activities)
2421                             queue.Enqueue(activity2);
2422                     }
2423                 }
2424             }
2425 
2426             //
2427             if (((IComponent)this).Site != null)
2428             {
2429                 IComponentChangeService changeService = ((IComponent)this).Site.GetService(typeof(IComponentChangeService)) as IComponentChangeService;
2430                 if (changeService != null)
2431                     changeService.OnComponentChanged(this, null, e, null);
2432             }
2433         }
2434 
2435         private static bool IsDynamicMode(CompositeActivity compositeActivity)
2436         {
2437             if (compositeActivity == null)
2438                 throw new ArgumentNullException("compositeActivity");
2439 
2440             while (compositeActivity.Parent != null)
2441             {
2442                 if (compositeActivity.DynamicUpdateMode)
2443                     return true;
2444                 compositeActivity = compositeActivity.Parent;
2445             }
2446             return compositeActivity.DynamicUpdateMode;
2447         }
2448 
2449         private static bool CannotModifyChildren(CompositeActivity compositeActivity, bool parent)
2450         {
2451             if (compositeActivity == null)
2452                 throw new ArgumentNullException("compositeActivity");
2453 
2454             if (parent && compositeActivity.Parent == null)
2455                 return false;
2456 
2457             if ((bool)compositeActivity.GetValue(CustomActivityProperty) == true)
2458                 return true;
2459 
2460             if (compositeActivity.Parent != null)
2461                 return CannotModifyChildren(compositeActivity.Parent, parent);
2462 
2463             return false;
2464         }
2465 
2466         #endregion
2467 
2468         #region IDisposable
2469         protected override void Dispose(bool disposing)
2470         {
2471             if (disposing)
2472             {
2473                 foreach (Activity activity in this.Activities)
2474                     activity.Dispose();
2475             }
2476             base.Dispose(disposing);
2477         }
2478         #endregion
2479     }
2480     #endregion
2481 }
2482