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