Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/mono.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJordi Mas i Hernandez <jordi@mono-cvs.ximian.com>2006-09-01 23:58:48 +0400
committerJordi Mas i Hernandez <jordi@mono-cvs.ximian.com>2006-09-01 23:58:48 +0400
commitfe5f3f78b87e003da314aaeba821dfe2fd84827a (patch)
tree9ead0b682195cb2e805181c337407f5993e57ca2 /mcs/class/System.Workflow.Runtime
parentdb3f43858c94de6414d6d57276d8b6a18c2fa3a3 (diff)
Initial work on System.Workflow.Runtime
svn path=/trunk/mcs/; revision=64741
Diffstat (limited to 'mcs/class/System.Workflow.Runtime')
-rw-r--r--mcs/class/System.Workflow.Runtime/Assembly/AssemblyInfo.cs65
-rw-r--r--mcs/class/System.Workflow.Runtime/Assembly/ChangeLog4
-rw-r--r--mcs/class/System.Workflow.Runtime/ChangeLog4
-rw-r--r--mcs/class/System.Workflow.Runtime/Makefile20
-rw-r--r--mcs/class/System.Workflow.Runtime/README39
-rw-r--r--mcs/class/System.Workflow.Runtime/Samples/ChangeLog4
-rw-r--r--mcs/class/System.Workflow.Runtime/Samples/SchedulerMonitor.cs324
-rw-r--r--mcs/class/System.Workflow.Runtime/Samples/WorkflowQueues.cs180
-rw-r--r--mcs/class/System.Workflow.Runtime/System.Workflow.Hosting/ChangeLog4
-rw-r--r--mcs/class/System.Workflow.Runtime/System.Workflow.Hosting/DefaultWorkflowLoaderService.cs51
-rw-r--r--mcs/class/System.Workflow.Runtime/System.Workflow.Hosting/DefaultWorkflowSchedulerService.cs60
-rw-r--r--mcs/class/System.Workflow.Runtime/System.Workflow.Hosting/WorkflowLoaderService.cs44
-rw-r--r--mcs/class/System.Workflow.Runtime/System.Workflow.Hosting/WorkflowRuntimeService.cs66
-rw-r--r--mcs/class/System.Workflow.Runtime/System.Workflow.Hosting/WorkflowRuntimeServiceState.cs35
-rw-r--r--mcs/class/System.Workflow.Runtime/System.Workflow.Hosting/WorkflowSchedulerService.cs46
-rw-r--r--mcs/class/System.Workflow.Runtime/System.Workflow.Runtime.dll.sources21
-rw-r--r--mcs/class/System.Workflow.Runtime/System.Workflow.Runtime/ChangeLog4
-rw-r--r--mcs/class/System.Workflow.Runtime/System.Workflow.Runtime/IPendingWork.cs39
-rw-r--r--mcs/class/System.Workflow.Runtime/System.Workflow.Runtime/TimerEventSubscription.cs76
-rw-r--r--mcs/class/System.Workflow.Runtime/System.Workflow.Runtime/TimerEventSubscriptionCollection.cs138
-rw-r--r--mcs/class/System.Workflow.Runtime/System.Workflow.Runtime/WorkflowCompletedEventArgs.cs52
-rw-r--r--mcs/class/System.Workflow.Runtime/System.Workflow.Runtime/WorkflowEventArgs.cs45
-rw-r--r--mcs/class/System.Workflow.Runtime/System.Workflow.Runtime/WorkflowInstance.cs191
-rw-r--r--mcs/class/System.Workflow.Runtime/System.Workflow.Runtime/WorkflowProcessor.cs239
-rw-r--r--mcs/class/System.Workflow.Runtime/System.Workflow.Runtime/WorkflowQueue.cs109
-rw-r--r--mcs/class/System.Workflow.Runtime/System.Workflow.Runtime/WorkflowQueuingService.cs83
-rw-r--r--mcs/class/System.Workflow.Runtime/System.Workflow.Runtime/WorkflowRuntime.cs277
-rw-r--r--mcs/class/System.Workflow.Runtime/System.Workflow.Runtime/WorkflowTerminatedEventArgs.cs46
-rw-r--r--mcs/class/System.Workflow.Runtime/System.Workflow.Runtime_test.dll.sources8
-rw-r--r--mcs/class/System.Workflow.Runtime/Test/System.Workflow.Runtime/TimerEventSubscriptionCollectionTest.cs97
-rw-r--r--mcs/class/System.Workflow.Runtime/Test/System.Workflow.Runtime/TimerEventSubscriptionTest.cs90
-rw-r--r--mcs/class/System.Workflow.Runtime/Test/System.Workflow.Runtime/WorkflowQueuingServiceTest.cs47
-rw-r--r--mcs/class/System.Workflow.Runtime/Test/System.Workflow.Runtime/WorkflowRuntimeTest.cs188
-rw-r--r--mcs/class/System.Workflow.Runtime/Test/Workflows/ChangeLog4
-rw-r--r--mcs/class/System.Workflow.Runtime/Test/Workflows/SimpleWorkFlowDelayTest.cs114
-rw-r--r--mcs/class/System.Workflow.Runtime/Test/Workflows/SingleActivityCodeTest.cs79
-rw-r--r--mcs/class/System.Workflow.Runtime/Test/Workflows/WorkFlowMachineStatusTest.cs296
-rw-r--r--mcs/class/System.Workflow.Runtime/Test/Workflows/WorkFlowMachineStatusTest.jpgbin0 -> 30266 bytes
-rw-r--r--mcs/class/System.Workflow.Runtime/Test/Workflows/WorkFlowParallelTest.cs229
-rw-r--r--mcs/class/System.Workflow.Runtime/Test/Workflows/WorkFlowParallelTest.jpgbin0 -> 54947 bytes
40 files changed, 3418 insertions, 0 deletions
diff --git a/mcs/class/System.Workflow.Runtime/Assembly/AssemblyInfo.cs b/mcs/class/System.Workflow.Runtime/Assembly/AssemblyInfo.cs
new file mode 100644
index 00000000000..89b22456c58
--- /dev/null
+++ b/mcs/class/System.Workflow.Runtime/Assembly/AssemblyInfo.cs
@@ -0,0 +1,65 @@
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//
+// Authors:
+//
+// Andreas Nahr (ClassDevelopment@A-SoftTech.com)
+// Jordi Mas i Hernandez <jordimash@gmail.com>
+//
+
+
+using System;
+using System.Reflection;
+using System.Resources;
+using System.Security;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+
+[assembly: AssemblyVersion ("3.0.0.0")]
+[assembly: SatelliteContractVersion ("3.0.0.0")]
+[assembly: AssemblyFileVersion("3.0.0.0")]
+[assembly: CompilationRelaxations (8)]
+
+
+[assembly: AssemblyTitle("System.Workflow.Runtime.dll")]
+[assembly: AssemblyDescription("System.Workflow.Runtime.dll")]
+[assembly: AssemblyCompany("MONO development team")]
+[assembly: AssemblyProduct("MONO CLI")]
+[assembly: AssemblyCopyright("(c) 2006 Various Authors")]
+
+#if !TARGET_JVM
+[assembly: CLSCompliant(true)]
+#endif
+[assembly: AssemblyDefaultAlias("System.Windows.Runtime.dll")]
+[assembly: AssemblyInformationalVersion("0.0.0.1")]
+[assembly: NeutralResourcesLanguage("en-US")]
+
+[assembly: ComCompatibleVersion (1, 0, 3300, 0)]
+[assembly: ComVisible(false)]
+[assembly: AllowPartiallyTrustedCallers]
+
+#if TARGET_JVM
+[assembly: AssemblyDelaySign(false)]
+#else
+[assembly: AssemblyDelaySign(true)]
+[assembly: AssemblyKeyFile("../msfinal3.pub")]
+#endif
+
diff --git a/mcs/class/System.Workflow.Runtime/Assembly/ChangeLog b/mcs/class/System.Workflow.Runtime/Assembly/ChangeLog
new file mode 100644
index 00000000000..e5d29422895
--- /dev/null
+++ b/mcs/class/System.Workflow.Runtime/Assembly/ChangeLog
@@ -0,0 +1,4 @@
+2006-09-02 Jordi Mas i Hernandez <jordimash@gmail.com>
+
+ * Initial check-in
+
diff --git a/mcs/class/System.Workflow.Runtime/ChangeLog b/mcs/class/System.Workflow.Runtime/ChangeLog
new file mode 100644
index 00000000000..e5d29422895
--- /dev/null
+++ b/mcs/class/System.Workflow.Runtime/ChangeLog
@@ -0,0 +1,4 @@
+2006-09-02 Jordi Mas i Hernandez <jordimash@gmail.com>
+
+ * Initial check-in
+
diff --git a/mcs/class/System.Workflow.Runtime/Makefile b/mcs/class/System.Workflow.Runtime/Makefile
new file mode 100644
index 00000000000..5f0e7cda214
--- /dev/null
+++ b/mcs/class/System.Workflow.Runtime/Makefile
@@ -0,0 +1,20 @@
+thisdir = class/System.Workflow.Runtime
+include ../../build/rules.make
+SUBDIRS =
+
+LIBRARY = System.Workflow.Runtime.dll
+
+LIBRARY_USE_INTERMEDIATE_FILE = yes
+
+# this c:/tmp no /cygdrive/tmp /r:/tmp/System.Workflow.ComponentModel.dll
+LIB_MCS_FLAGS = /r:$(corlib) /r:System.dll /r:System.Workflow.ComponentModel.dll /r:System.Workflow.Activities /r:System.Xml /r:System.Transactions.dll
+TEST_MCS_FLAGS = $(LIB_MCS_FLAGS)
+
+include ../../build/library.make
+
+
+
+
+
+
+
diff --git a/mcs/class/System.Workflow.Runtime/README b/mcs/class/System.Workflow.Runtime/README
new file mode 100644
index 00000000000..a96f4418ce7
--- /dev/null
+++ b/mcs/class/System.Workflow.Runtime/README
@@ -0,0 +1,39 @@
+Welcome to Windows Workflow Foundation Mono implementation
+
+* Introduction
+
+Windows Workflow Foundation (WWF) has been introduced as part of Microsoft .Net 3.0 framework (also called WinFX). It is a namespace and a set of tools designed
+for building workflow enabled applications on .Net.
+
+The WWF is implemented using three assemblies: System.Workflow.Activities, System.Workflow.ComponentModel and System.Workflow.Runtime.
+
+* Status
+
+This library is in pre-alpha state. Development is still in the very early stages. Bug reports are welcome, provided they don't just point out missing
+classes. Please use http://bugzilla.ximian.com/.
+
+* Contributions
+
+Some indications when contributing to this namespace:
+
+- Contributions providing only stubs are not useful at this point. Our goal is to have a consistent and complete working implementation. New classes, enumerator
+or interfaces should be defined as they are need it as progress is made in the implementation.
+
+- For every new class or behavior added to a class provide a clear test case to verify its functionality and it to the test case suite for the assembly.
+
+- Before committing a change or propose a patch please verify that it does not break any existing test case for any of the three assemblies used to implement
+WWF.
+
+- Check the 'CodingStyle' file at mcs/CodingStyle
+
+* Install
+
+In order to install WWF you should compile the assemblies using 'make PROFILE=net_2_0 install' in the following order:
+
+- System.Workflow.ComponentModel
+- System.Workflow.Activities
+- System.Workflow.Runtime
+- System.Workflow.ComponentModel (twice, due to cyclic dependencies)
+
+At System.Workflow.Runtime/Samples you have some examples to demonstrate some basic functionality.
+
diff --git a/mcs/class/System.Workflow.Runtime/Samples/ChangeLog b/mcs/class/System.Workflow.Runtime/Samples/ChangeLog
new file mode 100644
index 00000000000..e5d29422895
--- /dev/null
+++ b/mcs/class/System.Workflow.Runtime/Samples/ChangeLog
@@ -0,0 +1,4 @@
+2006-09-02 Jordi Mas i Hernandez <jordimash@gmail.com>
+
+ * Initial check-in
+
diff --git a/mcs/class/System.Workflow.Runtime/Samples/SchedulerMonitor.cs b/mcs/class/System.Workflow.Runtime/Samples/SchedulerMonitor.cs
new file mode 100644
index 00000000000..ea9a4d0c382
--- /dev/null
+++ b/mcs/class/System.Workflow.Runtime/Samples/SchedulerMonitor.cs
@@ -0,0 +1,324 @@
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+// Authors:
+//
+// Copyright (C) 2006 Jordi Mas i Hernandez <jordimash@gmail.com>
+//
+//
+// This sample should be executed on MS .Net runtime.
+// It helps to understand how the MS. Net runtime workflow
+// executor works internally, how interacts with the sheduler service
+// and so on
+//
+
+using System;
+using System.ComponentModel;
+using System.Collections.ObjectModel;
+using System.Collections;
+using System.Workflow.Activities;
+using System.Workflow.Runtime;
+using System.Workflow.ComponentModel;
+using System.Workflow.Runtime.Hosting;
+using System.Threading;
+using System.Workflow.ComponentModel.Compiler;
+using System.ComponentModel.Design;
+
+class Program
+{
+ public class ourDefaultWorkflowSchedulerService : DefaultWorkflowSchedulerService
+ {
+ public ourDefaultWorkflowSchedulerService ()
+ {
+
+ }
+
+ protected override void OnStarted ()
+ {
+ base.OnStarted ();
+ Console.WriteLine ("*** ourDefaultWorkflowSchedulerService::ourDefaultWorkflowSchedulerService.OnStarted",
+ Environment.StackTrace);
+ }
+
+ protected override void Schedule (WaitCallback callback, Guid workflowInstanceId)
+ {
+ Console.WriteLine ("*** ourDefaultWorkflowSchedulerService::Schedule {0} {1}",
+ callback, workflowInstanceId);
+
+ base.Schedule (callback, workflowInstanceId);
+ }
+
+ protected override void Schedule(WaitCallback callback, Guid workflowInstanceId, DateTime whenUtc, Guid timerId)
+ {
+ Console.WriteLine ("*** ourDefaultWorkflowSchedulerService::Schedule {0} {1} {2}",
+ callback, workflowInstanceId, whenUtc);
+
+ base.Schedule (callback, workflowInstanceId, whenUtc, timerId);
+ }
+
+ protected override void Stop ()
+ {
+ Console.WriteLine ("*** ourDefaultWorkflowSchedulerService::Stop");
+ base.Stop ();
+ }
+ }
+
+ public class ourCodeActivity : Activity
+ {
+ public ourCodeActivity ()
+ {
+
+ }
+
+ public event EventHandler ExecuteCode;
+
+ protected override void Initialize (IServiceProvider provider)
+ {
+ Console.WriteLine ("***ourCodeActivity.IServiceProvider {0}",
+ Environment.StackTrace);
+
+
+ }
+
+ protected sealed override ActivityExecutionStatus Execute (ActivityExecutionContext executionContext)
+ {
+ ActivityExecutionStatus status;
+ ActivityExecutionContextManager manager = executionContext.ExecutionContextManager;
+ ReadOnlyCollection <ActivityExecutionContext> contexts = manager.ExecutionContexts;
+
+ Console.WriteLine ("***ourCodeActivity.Execute {0}", contexts.Count);
+
+ IComparable queue_name = "our_queue";
+
+ WorkflowQueuingService qService = executionContext.GetService<WorkflowQueuingService> ();
+
+ if (!qService.Exists (queue_name)) {
+ Console.WriteLine ("CreatingQue");
+ qService.CreateWorkflowQueue (queue_name, true);
+ }
+
+ status = base.Execute (executionContext);
+ return status;
+ }
+ }
+
+ public sealed class SequentialWorkflow : SequentialWorkflowActivity
+ {
+ private ourCodeActivity CodeCloseMailProgram2;
+ private DelayActivity DelayWaitForSentMail2;
+ private CodeActivity PrepareMail2;
+ private CodeActivity CodeCloseMailProgram1;
+ private DelayActivity DelayWaitForSentMail1;
+ private CodeActivity CodePrepareMail1;
+ private SequenceActivity SeqSendMail2;
+ private SequenceActivity SeqSendMail1;
+ private ParallelActivity Parallel;
+ private IfElseBranchActivity IfElseBranchActivityNoNeed;
+ private IfElseBranchActivity IfElseBranchActivityNeedToSendMail;
+ private TerminateActivity TerminateFinishNoNeedToReadMail;
+ private IfElseActivity NeedToSendMail;
+
+ public SequentialWorkflow ()
+ {
+ InitializeComponent ();
+ }
+
+ private void InitializeComponent ()
+ {
+
+ CanModifyActivities = true;
+ CodeCondition codecondition1 = new CodeCondition ();
+ CodeCloseMailProgram2 = new ourCodeActivity ();
+ DelayWaitForSentMail2 = new DelayActivity ();
+ PrepareMail2 = new CodeActivity ();
+ CodeCloseMailProgram1 = new CodeActivity ();
+ DelayWaitForSentMail1 = new DelayActivity ();
+ CodePrepareMail1 = new CodeActivity ();
+ SeqSendMail2 = new SequenceActivity ();
+ SeqSendMail1 = new SequenceActivity ();
+ TerminateFinishNoNeedToReadMail = new TerminateActivity ();
+ Parallel = new ParallelActivity ();
+ IfElseBranchActivityNoNeed = new IfElseBranchActivity ();
+ IfElseBranchActivityNeedToSendMail = new IfElseBranchActivity ();
+ NeedToSendMail = new IfElseActivity ();
+
+ CodeCloseMailProgram2.Name = "CodeCloseMailProgram2";
+ CodeCloseMailProgram2.ExecuteCode += new EventHandler (CodeCloseMailProgram2_ExecuteCode);
+
+ DelayWaitForSentMail2.Name = "DelayWaitForSentMail2";
+ DelayWaitForSentMail2.TimeoutDuration = System.TimeSpan.Parse ("00:00:05");
+ DelayWaitForSentMail2.InitializeTimeoutDuration += new EventHandler (DelayWaitForSentMail2_InitializeTimeoutDuration);
+
+ PrepareMail2.Name = "PrepareMail2";
+ PrepareMail2.ExecuteCode += new EventHandler (PrepareMail2_ExecuteCode);
+
+ CodeCloseMailProgram1.Name = "CodeCloseMailProgram1";
+ CodeCloseMailProgram1.ExecuteCode += new EventHandler (CodeCloseMailProgram_ExecuteCode);
+
+ DelayWaitForSentMail1.Name = "DelayWaitForSentMail1";
+ DelayWaitForSentMail1.TimeoutDuration = System.TimeSpan.Parse ("00:00:03");
+ DelayWaitForSentMail1.InitializeTimeoutDuration += new EventHandler (DelayWaitForSentMail1_InitializeTimeoutDuration);
+
+ CodePrepareMail1.Name = "CodePrepareMail1";
+ CodePrepareMail1.ExecuteCode += new EventHandler (CodeActivity1_ExecuteCode);
+
+ SeqSendMail2.Activities.Add (PrepareMail2);
+ SeqSendMail2.Activities.Add (DelayWaitForSentMail2);
+ SeqSendMail2.Activities.Add (CodeCloseMailProgram2);
+ SeqSendMail2.Name = "SeqSendMail2";
+
+ SeqSendMail1.Activities.Add (CodePrepareMail1);
+ //SeqSendMail1.Activities.Add (DelayWaitForSentMail1);
+ SeqSendMail1.Activities.Add (CodeCloseMailProgram1);
+ SeqSendMail1.Name = "SeqSendMail1";
+
+ TerminateFinishNoNeedToReadMail.Name = "TerminateFinishNoNeedToReadMail";
+
+ Parallel.Activities.Add (SeqSendMail1);
+ Parallel.Activities.Add (SeqSendMail2);
+ Parallel.Name = "Parallel";
+
+ IfElseBranchActivityNoNeed.Activities.Add (TerminateFinishNoNeedToReadMail);
+ IfElseBranchActivityNoNeed.Name = "IfElseBranchActivityNoNeed";
+
+ IfElseBranchActivityNeedToSendMail.Activities.Add (Parallel);
+ codecondition1.Condition += new EventHandler <ConditionalEventArgs>(IfElseCondition);
+ IfElseBranchActivityNeedToSendMail.Condition = codecondition1;
+ IfElseBranchActivityNeedToSendMail.Name = "IfElseBranchActivityNeedToSendMail";
+
+ NeedToSendMail.Activities.Add (IfElseBranchActivityNeedToSendMail);
+ NeedToSendMail.Activities.Add (IfElseBranchActivityNoNeed);
+ NeedToSendMail.Name = "NeedToSendMail";
+
+ Activities.Add (NeedToSendMail);
+ Name = "IfElseParalellWorkFlow";
+ CanModifyActivities = false;
+
+ }
+
+
+
+ // The event handler that executes on ExecuteCode event of the ApprovePO activity
+ private void ExecutingCode (object sender, EventArgs e)
+ {
+ //Console.WriteLine ("**Executing. {0}", Environment.StackTrace);
+ Console.WriteLine ("**Executing.");
+ }
+
+ // The event handler that executes on ExecuteCode event of the ApprovePO activity
+ private void OnApproved(object sender, EventArgs e)
+ {
+ Console.WriteLine ("**Purchase Order Approved.");
+ }
+
+
+ // Code condition to evaluate whether to take the first branch, YesIfElseBranch
+ // Since it always returns true, the first branch is always taken.
+ private void IsCondition (object sender, ConditionalEventArgs e)
+ {
+ e.Result = true;
+ //e.Result = false;
+ Console.WriteLine ("**IsCondition called {0}", e.Result);
+ }
+
+
+ private void IfElseCondition (object sender, ConditionalEventArgs e)
+ {
+ Console.WriteLine ("IfElseCondition");
+ e.Result = true;
+ }
+
+ private void CodeActivity1_ExecuteCode (object sender, EventArgs e)
+ {
+ Console.WriteLine ("PrepareMail1_ExecuteCode");
+ }
+
+ private void DelayWaitForSentMail2_InitializeTimeoutDuration (object sender, EventArgs e)
+ {
+ Console.WriteLine ("DelayWaitForSentMail2_InitializeTimeoutDuration");
+ }
+
+ private void CodeCloseMailProgram_ExecuteCode (object sender, EventArgs e)
+ {
+ Console.WriteLine ("CodeCloseMailProgram1_ExecuteCode");
+ }
+
+ private void PrepareMail2_ExecuteCode (object sender, EventArgs e)
+ {
+ Console.WriteLine ("PrepareMail2_ExecuteCode");
+ }
+
+ private void CodeCloseMailProgram2_ExecuteCode (object sender, EventArgs e)
+ {
+ Console.WriteLine ("CodeCloseMailProgram2_ExecuteCode");
+ }
+
+ private void DelayWaitForSentMail1_InitializeTimeoutDuration (object sender, EventArgs e)
+ {
+ Console.WriteLine ("DelayWaitForSentMail1_InitializeTimeoutDuration");
+ }
+ }
+
+ static AutoResetEvent waitHandle = new AutoResetEvent(false);
+
+ static void Main ()
+ {
+ // Create the WorkflowRuntime
+ WorkflowRuntime workflowRuntime = new WorkflowRuntime ();
+
+ workflowRuntime.AddService ((object) new ourDefaultWorkflowSchedulerService ());
+
+ workflowRuntime.StartRuntime ();
+ Type type = typeof (SequentialWorkflow);
+
+ // Listen for the workflow events
+ workflowRuntime.WorkflowCompleted += OnWorkflowCompleted;
+ workflowRuntime.WorkflowTerminated += OnWorkflowTerminated;
+ WorkflowInstance wi = workflowRuntime.CreateWorkflow (type);
+ wi.Start ();
+
+ waitHandle.WaitOne ();
+
+ // Stop the runtime
+ Console.WriteLine("Program Complete.");
+ //workflowRuntime.Dispose ();
+ }
+
+ // This method will be called when a workflow instance is completed; since we have started only a single
+ // instance we are ignoring the event args and signaling the waitHandle so the main thread can continue
+ static void OnWorkflowCompleted(object sender, WorkflowCompletedEventArgs e)
+ {
+
+ //Console.WriteLine ("-->{0}", Environment.StackTrace);
+ Console.WriteLine ("OnWorkflowCompleted");
+ waitHandle.Set();
+ }
+
+ // This method is called when the workflow terminates and does not complete
+ // This should not occur in this sample; however, it is good practice to include a
+ // handler for this event so the host application can manage workflows that are
+ // unexpectedly terminated (e.g. unhandled workflow exception).
+ // waitHandle is set so the main thread can continue
+ static void OnWorkflowTerminated(object sender, WorkflowTerminatedEventArgs e)
+ {
+ Console.WriteLine(e.Exception.Message);
+ waitHandle.Set();
+ }
+}
+
diff --git a/mcs/class/System.Workflow.Runtime/Samples/WorkflowQueues.cs b/mcs/class/System.Workflow.Runtime/Samples/WorkflowQueues.cs
new file mode 100644
index 00000000000..2c12960759a
--- /dev/null
+++ b/mcs/class/System.Workflow.Runtime/Samples/WorkflowQueues.cs
@@ -0,0 +1,180 @@
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+// Authors:
+//
+// Copyright (C) 2006 Jordi Mas i Hernandez <jordimash@gmail.com>
+//
+//
+// This sample should be executed on MS .Net runtime.
+// It helps to understand how the MS. Net runtime workflow
+// executor works internally, how interacts with the sheduler service
+// and so on
+//
+
+using System;
+using System.ComponentModel;
+using System.Collections.ObjectModel;
+using System.Collections;
+using System.Workflow.Activities;
+using System.Workflow.Runtime;
+using System.Workflow.ComponentModel;
+using System.Workflow.Runtime.Hosting;
+using System.Threading;
+
+
+class Program
+{
+
+ public class ourCodeActivity : Activity
+ {
+ public WorkflowQueue workflowQueue;
+
+ public ourCodeActivity ()
+ {
+
+ }
+
+ public event EventHandler ExecuteCode;
+
+ protected override void Initialize (IServiceProvider provider)
+ {
+ Console.WriteLine ("***ourCodeActivity.Initialize thread:{0}",
+ Thread.CurrentThread.ManagedThreadId);
+
+ WorkflowQueuingService queuingService = (WorkflowQueuingService)provider.GetService (typeof(WorkflowQueuingService));
+
+ IComparable queue_name = "LaNostra_Queue";
+ WorkflowQueuingService qService = (WorkflowQueuingService) provider.GetService (typeof (WorkflowQueuingService));
+
+ if (!qService.Exists (queue_name)) {
+ workflowQueue = qService.CreateWorkflowQueue (queue_name, true);
+ }
+ else
+ workflowQueue = qService.GetWorkflowQueue (queue_name);
+
+ workflowQueue.QueueItemAvailable += OnQueueItemAvailable;
+ workflowQueue.QueueItemArrived += OnQueueItemArrived;
+ }
+
+ protected sealed override ActivityExecutionStatus Execute (ActivityExecutionContext executionContext)
+ {
+ Console.WriteLine ("***ourCodeActivity.Execute thread:{0}",
+ Thread.CurrentThread.ManagedThreadId);
+
+ ActivityExecutionStatus status;
+ //ActivityExecutionContextManager manager = executionContext.ExecutionContextManager;
+ //ReadOnlyCollection <ActivityExecutionContext> contexts = manager.ExecutionContexts;
+
+ //Console.WriteLine ("***ourCodeActivity.Execute {0}", contexts.Count);
+ object data = workflowQueue.Peek ();
+ Console.WriteLine ("OnQueueItemAvailable! {0}", data);
+
+ status = base.Execute (executionContext);
+ return status;
+ }
+
+ public void OnQueueItemArrived (Object sender, QueueEventArgs args)
+ {
+ object data = this.workflowQueue.Peek ();
+ Console.WriteLine ("OnQueueItemArrived! event {0}", data);
+ }
+
+ public void OnQueueItemAvailable (Object sender, QueueEventArgs args)
+ {
+ Console.WriteLine ("OnQueueItemAvailable!");
+ //ThreadMonitor.WriteToConsole (Thread.CurrentThread, "WaitForMessageActivity",
+ // "WaitForMessageActivity: Processed External Event");
+
+ object data = this.workflowQueue.Peek ();
+ Console.WriteLine ("OnQueueItemAvailable event! {0}", data);
+
+ ActivityExecutionContext context = sender as ActivityExecutionContext;
+ //context.CloseActivity ();
+ }
+ }
+
+ public sealed class SequentialWorkflow : SequentialWorkflowActivity
+ {
+ private ourCodeActivity activity;
+
+ public SequentialWorkflow ()
+ {
+ InitializeComponent ();
+ }
+
+ private void InitializeComponent ()
+ {
+ CanModifyActivities = true;
+ activity = new ourCodeActivity ();
+
+ activity.Name = "activity";
+ activity.ExecuteCode += new EventHandler (activity_ExecuteCode);
+
+ Activities.Add (activity);
+ CanModifyActivities = false;
+ }
+
+ private void activity_ExecuteCode (object sender, EventArgs e)
+ {
+ Console.WriteLine ("activity_ExecuteCode");
+ }
+ }
+
+ static AutoResetEvent waitHandle = new AutoResetEvent(false);
+
+ static void Main ()
+ {
+ // Create the WorkflowRuntime
+ WorkflowRuntime workflowRuntime = new WorkflowRuntime ();
+
+ Console.WriteLine ("App.Main thread:{0}", Thread.CurrentThread.ManagedThreadId);
+
+ workflowRuntime.StartRuntime ();
+ Type type = typeof (SequentialWorkflow);
+
+ // Listen for the workflow events
+ workflowRuntime.WorkflowCompleted += OnWorkflowCompleted;
+ workflowRuntime.WorkflowTerminated += OnWorkflowTerminated;
+ WorkflowInstance wi = workflowRuntime.CreateWorkflow (type);
+ wi.Start ();
+
+ Console.WriteLine ("Enquing data");
+ wi.EnqueueItem ("LaNostra_Queue", "Hello", null, null);
+
+ waitHandle.WaitOne ();
+
+ // Stop the runtime
+ Console.WriteLine ("Program Complete.");
+ //workflowRuntime.Dispose ();
+ }
+
+ static void OnWorkflowCompleted(object sender, WorkflowCompletedEventArgs e)
+ {
+ Console.WriteLine ("OnWorkflowCompleted");
+ waitHandle.Set ();
+ }
+
+ static void OnWorkflowTerminated(object sender, WorkflowTerminatedEventArgs e)
+ {
+ Console.WriteLine (e.Exception.Message);
+ waitHandle.Set ();
+ }
+}
+
diff --git a/mcs/class/System.Workflow.Runtime/System.Workflow.Hosting/ChangeLog b/mcs/class/System.Workflow.Runtime/System.Workflow.Hosting/ChangeLog
new file mode 100644
index 00000000000..e5d29422895
--- /dev/null
+++ b/mcs/class/System.Workflow.Runtime/System.Workflow.Hosting/ChangeLog
@@ -0,0 +1,4 @@
+2006-09-02 Jordi Mas i Hernandez <jordimash@gmail.com>
+
+ * Initial check-in
+
diff --git a/mcs/class/System.Workflow.Runtime/System.Workflow.Hosting/DefaultWorkflowLoaderService.cs b/mcs/class/System.Workflow.Runtime/System.Workflow.Hosting/DefaultWorkflowLoaderService.cs
new file mode 100644
index 00000000000..857617a5939
--- /dev/null
+++ b/mcs/class/System.Workflow.Runtime/System.Workflow.Hosting/DefaultWorkflowLoaderService.cs
@@ -0,0 +1,51 @@
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+// Authors:
+//
+// Copyright (C) 2006 Jordi Mas i Hernandez <jordimash@gmail.com>
+//
+
+
+using System.Xml;
+using System.Workflow.Activities;
+using System.Workflow.ComponentModel;
+
+namespace System.Workflow.Runtime.Hosting
+{
+ public class DefaultWorkflowLoaderService : WorkflowLoaderService
+ {
+ public DefaultWorkflowLoaderService ()
+ {
+
+ }
+
+ // Methods
+ protected internal override Activity CreateInstance (Type workflowType)
+ {
+ return (Activity) Activator.CreateInstance (workflowType);
+ }
+
+ protected internal override Activity CreateInstance (XmlReader workflowDefinitionReader, XmlReader rulesReader)
+ {
+ throw new NotImplementedException ();
+ }
+ }
+}
+
diff --git a/mcs/class/System.Workflow.Runtime/System.Workflow.Hosting/DefaultWorkflowSchedulerService.cs b/mcs/class/System.Workflow.Runtime/System.Workflow.Hosting/DefaultWorkflowSchedulerService.cs
new file mode 100644
index 00000000000..21862601eb5
--- /dev/null
+++ b/mcs/class/System.Workflow.Runtime/System.Workflow.Hosting/DefaultWorkflowSchedulerService.cs
@@ -0,0 +1,60 @@
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+// Authors:
+//
+// Copyright (C) 2006 Jordi Mas i Hernandez <jordimash@gmail.com>
+//
+
+
+using System.Xml;
+using System.Threading;
+using System.Workflow.Activities;
+using System.Workflow.ComponentModel;
+
+namespace System.Workflow.Runtime.Hosting
+{
+ public class DefaultWorkflowSchedulerService : WorkflowSchedulerService
+ {
+ public DefaultWorkflowSchedulerService ()
+ {
+
+ }
+
+ protected internal override void Cancel (Guid timerId)
+ {
+
+ }
+
+ protected internal override void Schedule (WaitCallback callback, Guid workflowInstanceId)
+ {
+ ThreadPool.QueueUserWorkItem (callback, workflowInstanceId);
+ }
+
+ protected internal override void Schedule (WaitCallback callback, Guid workflowInstanceId, DateTime whenUtc, Guid timerId)
+ {
+ //WorkflowInstance wi = WorkflowRuntime.GetInstanceFromGuid (workflowInstanceId);
+
+ //wi.TimerEventSubscriptionCollection.Add
+ // (new TimerEventSubscription (workflowInstanceId, timerId));
+ }
+
+ }
+}
+
diff --git a/mcs/class/System.Workflow.Runtime/System.Workflow.Hosting/WorkflowLoaderService.cs b/mcs/class/System.Workflow.Runtime/System.Workflow.Hosting/WorkflowLoaderService.cs
new file mode 100644
index 00000000000..b7124a51f08
--- /dev/null
+++ b/mcs/class/System.Workflow.Runtime/System.Workflow.Hosting/WorkflowLoaderService.cs
@@ -0,0 +1,44 @@
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+// Authors:
+//
+// Copyright (C) 2006 Jordi Mas i Hernandez <jordimash@gmail.com>
+//
+
+using System.Xml;
+using System.Workflow.ComponentModel;
+using System.Workflow.Activities;
+
+namespace System.Workflow.Runtime.Hosting
+{
+ public abstract class WorkflowLoaderService : WorkflowRuntimeService
+ {
+ protected WorkflowLoaderService ()
+ {
+
+ }
+
+ // Methods
+ protected internal abstract Activity CreateInstance (Type workflowType);
+ protected internal abstract Activity CreateInstance (XmlReader workflowDefinitionReader, XmlReader rulesReader);
+
+ }
+}
+
diff --git a/mcs/class/System.Workflow.Runtime/System.Workflow.Hosting/WorkflowRuntimeService.cs b/mcs/class/System.Workflow.Runtime/System.Workflow.Hosting/WorkflowRuntimeService.cs
new file mode 100644
index 00000000000..b8d03d9d2ab
--- /dev/null
+++ b/mcs/class/System.Workflow.Runtime/System.Workflow.Hosting/WorkflowRuntimeService.cs
@@ -0,0 +1,66 @@
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+// Authors:
+//
+// Copyright (C) 2006 Jordi Mas i Hernandez <jordimash@gmail.com>
+//
+
+namespace System.Workflow.Runtime.Hosting
+{
+ public abstract class WorkflowRuntimeService
+ {
+ protected WorkflowRuntimeService ()
+ {
+
+ }
+
+ // Methods
+ protected virtual void OnStarted ()
+ {
+
+ }
+
+ protected virtual void OnStopped ()
+ {
+
+ }
+
+ internal void RaiseExceptionNotHandledEvent (Exception exception, Guid instanceId)
+ {
+
+ }
+
+ protected void RaiseServicesExceptionNotHandledEvent (Exception exception, Guid instanceId)
+ {
+
+ }
+
+ protected internal virtual void Start ()
+ {
+
+ }
+
+ protected internal virtual void Stop ()
+ {
+
+ }
+ }
+}
+
diff --git a/mcs/class/System.Workflow.Runtime/System.Workflow.Hosting/WorkflowRuntimeServiceState.cs b/mcs/class/System.Workflow.Runtime/System.Workflow.Hosting/WorkflowRuntimeServiceState.cs
new file mode 100644
index 00000000000..bdaabf6f75c
--- /dev/null
+++ b/mcs/class/System.Workflow.Runtime/System.Workflow.Hosting/WorkflowRuntimeServiceState.cs
@@ -0,0 +1,35 @@
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+// Authors:
+//
+// Copyright (C) 2006 Jordi Mas i Hernandez <jordimash@gmail.com>
+//
+
+namespace System.Workflow.Runtime.Hosting
+{
+ public enum WorkflowRuntimeServiceState
+ {
+ Stopped = 0,
+ Starting = 1,
+ Started = 2,
+ Stopping = 3
+ }
+}
+
diff --git a/mcs/class/System.Workflow.Runtime/System.Workflow.Hosting/WorkflowSchedulerService.cs b/mcs/class/System.Workflow.Runtime/System.Workflow.Hosting/WorkflowSchedulerService.cs
new file mode 100644
index 00000000000..254d05ff2ed
--- /dev/null
+++ b/mcs/class/System.Workflow.Runtime/System.Workflow.Hosting/WorkflowSchedulerService.cs
@@ -0,0 +1,46 @@
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+// Authors:
+//
+// Copyright (C) 2006 Jordi Mas i Hernandez <jordimash@gmail.com>
+//
+
+
+using System.Xml;
+using System.Workflow.Activities;
+using System.Workflow.ComponentModel;
+using System.Threading;
+
+namespace System.Workflow.Runtime.Hosting
+{
+ public abstract class WorkflowSchedulerService : WorkflowRuntimeService
+ {
+ protected WorkflowSchedulerService ()
+ {
+
+ }
+
+ // Methods
+ protected internal abstract void Cancel (Guid timerId);
+ protected internal abstract void Schedule (WaitCallback callback, Guid workflowInstanceId);
+ protected internal abstract void Schedule (WaitCallback callback, Guid workflowInstanceId, DateTime whenUtc, Guid timerId);
+ }
+}
+
diff --git a/mcs/class/System.Workflow.Runtime/System.Workflow.Runtime.dll.sources b/mcs/class/System.Workflow.Runtime/System.Workflow.Runtime.dll.sources
new file mode 100644
index 00000000000..911cb945da1
--- /dev/null
+++ b/mcs/class/System.Workflow.Runtime/System.Workflow.Runtime.dll.sources
@@ -0,0 +1,21 @@
+Assembly/AssemblyInfo.cs
+../../build/common/Consts.cs
+../../build/common/Locale.cs
+../../build/common/MonoTODOAttribute.cs
+System.Workflow.Runtime/WorkflowQueuingService.cs
+System.Workflow.Runtime/WorkflowQueue.cs
+System.Workflow.Runtime/WorkflowRuntime.cs
+System.Workflow.Runtime/WorkflowInstance.cs
+System.Workflow.Hosting/WorkflowRuntimeService.cs
+System.Workflow.Hosting/WorkflowRuntimeServiceState.cs
+System.Workflow.Hosting/WorkflowLoaderService.cs
+System.Workflow.Hosting/DefaultWorkflowLoaderService.cs
+System.Workflow.Hosting/WorkflowSchedulerService.cs
+System.Workflow.Hosting/DefaultWorkflowSchedulerService.cs
+System.Workflow.Runtime/WorkflowTerminatedEventArgs.cs
+System.Workflow.Runtime/WorkflowEventArgs.cs
+System.Workflow.Runtime/WorkflowCompletedEventArgs.cs
+System.Workflow.Runtime/TimerEventSubscription.cs
+System.Workflow.Runtime/TimerEventSubscriptionCollection.cs
+System.Workflow.Runtime/IPendingWork.cs
+System.Workflow.Runtime/WorkflowProcessor.cs \ No newline at end of file
diff --git a/mcs/class/System.Workflow.Runtime/System.Workflow.Runtime/ChangeLog b/mcs/class/System.Workflow.Runtime/System.Workflow.Runtime/ChangeLog
new file mode 100644
index 00000000000..e5d29422895
--- /dev/null
+++ b/mcs/class/System.Workflow.Runtime/System.Workflow.Runtime/ChangeLog
@@ -0,0 +1,4 @@
+2006-09-02 Jordi Mas i Hernandez <jordimash@gmail.com>
+
+ * Initial check-in
+
diff --git a/mcs/class/System.Workflow.Runtime/System.Workflow.Runtime/IPendingWork.cs b/mcs/class/System.Workflow.Runtime/System.Workflow.Runtime/IPendingWork.cs
new file mode 100644
index 00000000000..cfca5d21a07
--- /dev/null
+++ b/mcs/class/System.Workflow.Runtime/System.Workflow.Runtime/IPendingWork.cs
@@ -0,0 +1,39 @@
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+// Authors:
+//
+// Copyright (C) 2006 Jordi Mas i Hernandez <jordimash@gmail.com>
+//
+
+using System;
+using System.Collections;
+using System.Transactions;
+
+namespace System.Workflow.Runtime
+{
+ public interface IPendingWork
+ {
+ void Commit (Transaction transaction, ICollection items);
+ void Complete (bool succeeded, ICollection items);
+ bool MustCommit (ICollection items);
+ }
+
+}
+
diff --git a/mcs/class/System.Workflow.Runtime/System.Workflow.Runtime/TimerEventSubscription.cs b/mcs/class/System.Workflow.Runtime/System.Workflow.Runtime/TimerEventSubscription.cs
new file mode 100644
index 00000000000..916d92fafc2
--- /dev/null
+++ b/mcs/class/System.Workflow.Runtime/System.Workflow.Runtime/TimerEventSubscription.cs
@@ -0,0 +1,76 @@
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+// Authors:
+//
+// Copyright (C) 2006 Jordi Mas i Hernandez <jordimash@gmail.com>
+//
+
+namespace System.Workflow.Runtime
+{
+ [Serializable]
+ public class TimerEventSubscription
+ {
+ private Guid timerId;
+ private Guid workflowInstanceId;
+ private DateTime expiresAt;
+ private IComparable name;
+
+ protected TimerEventSubscription ()
+ {
+
+ }
+
+ public TimerEventSubscription (Guid workflowInstanceId, DateTime expiresAt) : this ()
+ {
+ this.workflowInstanceId = workflowInstanceId;
+ this.expiresAt = expiresAt;
+ this.timerId = Guid.NewGuid ();
+ this.name = timerId;
+ }
+
+ public TimerEventSubscription (Guid timerId, Guid workflowInstanceId, DateTime expiresAt) : this ()
+ {
+ this.timerId = timerId;
+ this.workflowInstanceId = workflowInstanceId;
+ this.expiresAt = expiresAt;
+ this.name = timerId;
+ }
+
+ // Properties
+ public virtual DateTime ExpiresAt {
+ get { return expiresAt; }
+ }
+
+ public virtual IComparable QueueName {
+ get {return name; }
+ protected set {name = value; }
+ }
+
+ public virtual Guid SubscriptionId {
+ get { return timerId; }
+ }
+
+ public virtual Guid WorkflowInstanceId {
+ get { return workflowInstanceId; }
+ }
+ }
+}
+
+
diff --git a/mcs/class/System.Workflow.Runtime/System.Workflow.Runtime/TimerEventSubscriptionCollection.cs b/mcs/class/System.Workflow.Runtime/System.Workflow.Runtime/TimerEventSubscriptionCollection.cs
new file mode 100644
index 00000000000..e4dd413bb41
--- /dev/null
+++ b/mcs/class/System.Workflow.Runtime/System.Workflow.Runtime/TimerEventSubscriptionCollection.cs
@@ -0,0 +1,138 @@
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+// Authors:
+//
+// Copyright (C) 2006 Jordi Mas i Hernandez <jordimash@gmail.com>
+//
+
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Workflow.ComponentModel;
+
+
+namespace System.Workflow.Runtime
+{
+ [Serializable]
+ public class TimerEventSubscriptionCollection : ICollection, IEnumerable
+ {
+ public static readonly DependencyProperty TimerCollectionProperty;
+ private ArrayList list;
+
+ static TimerEventSubscriptionCollection ()
+ {
+
+ }
+
+ // Constructor is private in MS Net
+ internal TimerEventSubscriptionCollection ()
+ {
+ list = new ArrayList ();
+ }
+
+ // Properties
+ public int Count {
+ get { return list.Count; }
+ }
+
+ bool ICollection.IsSynchronized {
+ get { return false; }
+ }
+
+ object ICollection.SyncRoot {
+ get { return this; }
+ }
+
+ // Private properties
+ internal TimerEventSubscription this [int index] {
+ get {return (TimerEventSubscription) list [index];}
+ }
+
+ // Methods
+ public void Add (TimerEventSubscription item)
+ {
+ int range = list.Count;
+ int middle, cmp;
+ int left = 0;
+ int right = range-1;
+
+ // Adds items always in a stored order
+ while (left <= right) {
+
+ middle = (left + right) >> 1;
+ cmp = Comparer.Default.Compare (item.ExpiresAt,
+ ((TimerEventSubscription) list [middle]).ExpiresAt);
+
+ if (cmp == 0) {
+ break;
+ }
+
+ if (cmp > 0) {
+ left = middle + 1;
+ }
+ else {
+ right = middle - 1;
+ }
+ }
+
+ list.Insert (left, item);
+ }
+
+ public void CopyTo (Array array, int index)
+ {
+ list.CopyTo (array, index);
+ }
+
+ public IEnumerator GetEnumerator ()
+ {
+ return list.GetEnumerator ();
+ }
+
+ public TimerEventSubscription Peek ()
+ {
+ if (Count == 0)
+ return null;
+
+ return (TimerEventSubscription) list[0];
+ }
+
+ public void Remove (Guid timerSubscriptionId)
+ {
+ TimerEventSubscription te;
+
+ for (IEnumerator enumerator = GetEnumerator (); enumerator.MoveNext (); ) {
+ te = (TimerEventSubscription) enumerator.Current;
+ if (timerSubscriptionId == te.SubscriptionId) {
+ Remove (te);
+ return;
+ }
+ }
+ }
+
+ public void Remove (TimerEventSubscription item)
+ {
+ list.Remove (item);
+ }
+
+ }
+}
+
+
diff --git a/mcs/class/System.Workflow.Runtime/System.Workflow.Runtime/WorkflowCompletedEventArgs.cs b/mcs/class/System.Workflow.Runtime/System.Workflow.Runtime/WorkflowCompletedEventArgs.cs
new file mode 100644
index 00000000000..8f95c4cf594
--- /dev/null
+++ b/mcs/class/System.Workflow.Runtime/System.Workflow.Runtime/WorkflowCompletedEventArgs.cs
@@ -0,0 +1,52 @@
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+// Authors:
+//
+// Copyright (C) 2006 Jordi Mas i Hernandez <jordimash@gmail.com>
+//
+
+using System;
+using System.Workflow.ComponentModel;
+
+namespace System.Workflow.Runtime
+{
+ public class WorkflowCompletedEventArgs : WorkflowEventArgs
+ {
+ private Activity activity;
+
+ internal WorkflowCompletedEventArgs (WorkflowInstance workflow_instance, Activity activity) :
+ base (workflow_instance)
+ {
+ this.activity = activity;
+ }
+
+ // Properties
+ //public Dictionary <string, object> OutputParameters {
+ // get;
+ //}
+
+ public Activity WorkflowDefinition {
+ get {return activity;}
+ }
+
+ }
+}
+
+
diff --git a/mcs/class/System.Workflow.Runtime/System.Workflow.Runtime/WorkflowEventArgs.cs b/mcs/class/System.Workflow.Runtime/System.Workflow.Runtime/WorkflowEventArgs.cs
new file mode 100644
index 00000000000..e1bf60fa3b5
--- /dev/null
+++ b/mcs/class/System.Workflow.Runtime/System.Workflow.Runtime/WorkflowEventArgs.cs
@@ -0,0 +1,45 @@
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+// Authors:
+//
+// Copyright (C) 2006 Jordi Mas i Hernandez <jordimash@gmail.com>
+//
+
+using System;
+
+namespace System.Workflow.Runtime
+{
+ public class WorkflowEventArgs : EventArgs
+ {
+ private WorkflowInstance workflow_instance;
+
+ internal WorkflowEventArgs (WorkflowInstance workflow_instance)
+ {
+ this.workflow_instance = workflow_instance;
+ }
+
+ // Properties
+ public WorkflowInstance WorkflowInstance {
+ get {return workflow_instance; }
+ }
+ }
+}
+
+
diff --git a/mcs/class/System.Workflow.Runtime/System.Workflow.Runtime/WorkflowInstance.cs b/mcs/class/System.Workflow.Runtime/System.Workflow.Runtime/WorkflowInstance.cs
new file mode 100644
index 00000000000..dbd0dd8974b
--- /dev/null
+++ b/mcs/class/System.Workflow.Runtime/System.Workflow.Runtime/WorkflowInstance.cs
@@ -0,0 +1,191 @@
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+// Authors:
+//
+// Copyright (C) 2006 Jordi Mas i Hernandez <jordimash@gmail.com>
+//
+
+using System;
+using System.ComponentModel;
+using System.Workflow.ComponentModel;
+using System.Workflow.Runtime.Hosting;
+using System.Threading;
+
+namespace System.Workflow.Runtime
+{
+ public sealed class WorkflowInstance
+ {
+ private Guid guid;
+ private WorkflowRuntime runtime;
+ private Activity root_activity;
+ private TimerEventSubscriptionCollection subscription_collection;
+ private WorkflowQueuingService queuing_service;
+ internal Timer timer_subscriptions;
+
+ internal WorkflowInstance (Guid guid, WorkflowRuntime runtime, Activity root_activity)
+ {
+ this.guid = guid;
+ this.runtime = runtime;
+ this.root_activity = root_activity;
+ subscription_collection = new TimerEventSubscriptionCollection ();
+ queuing_service = new WorkflowQueuingService ();
+ }
+
+ // Properties
+ public Guid InstanceId {
+ get {
+ return guid;
+ }
+ }
+
+ public WorkflowRuntime WorkflowRuntime {
+ get {
+ return runtime;
+ }
+ }
+
+ // TODO: This breaks .Net API signature compatibility
+ public TimerEventSubscriptionCollection TimerEventSubscriptionCollection {
+ get {
+ return subscription_collection;
+ }
+ }
+
+ // TODO: This breaks .Net API signature compatibility
+ public WorkflowQueuingService WorkflowQueuingService {
+ get {
+ return queuing_service;
+ }
+ }
+
+ // Methods
+ public void Abort ()
+ {
+ timer_subscriptions.Dispose ();
+ }
+
+ //public void ApplyWorkflowChanges (WorkflowChanges workflowChanges);
+
+ public void EnqueueItem (IComparable queueName, object item, IPendingWork pendingWork, object workItem)
+ {
+ WorkflowQueue queue;
+
+ // TODO: What to do with pendingWork and workItem?
+ if (queuing_service.Exists (queueName)) {
+ queue = queuing_service.GetWorkflowQueue (queueName);
+ } else {
+ queue = queuing_service.CreateWorkflowQueue (queueName, true);
+ }
+
+ queue.Enqueue (item);
+ }
+
+ public void EnqueueItemOnIdle (IComparable queueName, object item, IPendingWork pendingWork, object workItem)
+ {
+
+ }
+
+ public override bool Equals (object obj)
+ {
+ WorkflowInstance wi = (WorkflowInstance) obj;
+
+ if (wi == null) {
+ return false;
+ }
+
+ return wi.InstanceId.Equals (guid);
+ }
+
+ public override int GetHashCode ()
+ {
+ return guid.GetHashCode ();
+ }
+
+ public Activity GetWorkflowDefinition ()
+ {
+ return root_activity;
+ }
+
+ public DateTime GetWorkflowNextTimerExpiration ()
+ {
+ TimerEventSubscription timer;
+ timer = subscription_collection.Peek ();
+
+ if (timer == null) {
+ return DateTime.MaxValue;
+ }
+
+ return timer.ExpiresAt;
+ }
+
+ /*public ReadOnlyCollection<WorkflowQueueInfo> GetWorkflowQueueData();*/
+ public void Load ()
+ {
+
+ }
+
+ public void ReloadTrackingProfiles ()
+ {
+
+ }
+
+ public void Resume ()
+ {
+
+ }
+
+ public void Start ()
+ {
+ WorkflowSchedulerService sheduler;
+
+ // init all activities
+ ActivityExecutionContextManager manager = new ActivityExecutionContextManager (this);
+ ActivityExecutionContext context = manager.CreateExecutionContext (GetWorkflowDefinition ());
+
+ GetWorkflowDefinition ().InitializeInternal (context);
+
+ sheduler = (WorkflowSchedulerService) runtime.GetService (typeof (WorkflowSchedulerService));
+ //sheduler.Schedule (new WaitCallback (WorkflowProcessor.RunWorkflow), guid);
+
+ WorkflowProcessor.RunWorkflow (guid);
+ }
+
+ public void Suspend (string error)
+ {
+
+ }
+
+ public void Terminate (string error)
+ {
+
+ }
+
+ public bool TryUnload ()
+ {
+ throw new NotImplementedException ();
+ }
+
+ public void Unload ()
+ {
+
+ }
+ }
+}
+
diff --git a/mcs/class/System.Workflow.Runtime/System.Workflow.Runtime/WorkflowProcessor.cs b/mcs/class/System.Workflow.Runtime/System.Workflow.Runtime/WorkflowProcessor.cs
new file mode 100644
index 00000000000..b15191067a9
--- /dev/null
+++ b/mcs/class/System.Workflow.Runtime/System.Workflow.Runtime/WorkflowProcessor.cs
@@ -0,0 +1,239 @@
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+// Authors:
+//
+// Copyright (C) 2006 Jordi Mas i Hernandez <jordimash@gmail.com>
+//
+
+//#define DEBUG_EXECUTIONLOOP
+
+using System;
+using System.Threading;
+using System.Collections;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Workflow.ComponentModel;
+using System.Workflow.Runtime.Hosting;
+using System.Workflow.Activities;
+
+namespace System.Workflow.Runtime
+{
+ internal class WorkflowProcessor
+ {
+ static WorkflowProcessor ()
+ {
+
+ }
+
+ // Workflow processor
+ internal static void RunWorkflow (Object stateInfo)
+ {
+ Stack <Activity> stack = new Stack <Activity> ();
+ WorkflowInstance wi = WorkflowRuntime.GetInstanceFromGuid ((Guid)stateInfo);
+ wi.timer_subscriptions = new Timer (TimerSubscriptionsCallback, wi, 0, 1000);
+ Activity activity = wi.GetWorkflowDefinition ();
+ Activity next_activity;
+ ActivityExecutionContextManager manager = new ActivityExecutionContextManager (wi);
+ ActivityExecutionContext context;
+ List <DelayActivity> waiting = new List <DelayActivity> ();
+ bool wait = false;
+ StateMachineWorkflowActivity state_machine = null;
+
+ #if DEBUG_EXECUTIONLOOP
+ Console.WriteLine ("Initiating thread for activity {0}", wi.GetWorkflowDefinition ());
+ #endif
+ context = manager.CreateExecutionContext (activity);
+
+ // Main Workflow execution loop
+ while (activity != null) {
+
+ next_activity = null;
+ if (activity.NeedsExecution) {
+ #if DEBUG_EXECUTIONLOOP
+ Console.WriteLine ("*** Executing {0}, parallel {1}", activity, activity.ParallelParent);
+ #endif
+ context.ExecuteActivity (activity);
+ }
+
+ // If this a state machine changing its statge update StateMachineWorkflowActivity
+ if (state_machine != null && IsBasedOnType (activity, typeof (SetStateActivity))) {
+ state_machine.SetCurrentStateName (((SetStateActivity) activity).TargetStateName);
+ }
+
+
+ #if DEBUG_EXECUTIONLOOP
+ Console.WriteLine (" ActivitiesToExecute.Count {0}, stack {1}, waiting {2}",
+ activity.ActivitiesToExecute.Count, stack.Count, waiting.Count);
+ #endif
+ wait = false;
+
+ // State machine workflow, first activity is InitialStateName
+ if (IsBasedOnType (activity, typeof (StateMachineWorkflowActivity))) {
+ state_machine = (StateMachineWorkflowActivity) activity;
+ stack.Push (activity.GetActivityByName (state_machine.InitialStateName));
+ state_machine.SetCurrentStateName (state_machine.InitialStateName);
+
+ #if DEBUG_EXECUTIONLOOP
+ Console.WriteLine (" StateMachineWorkflowActivity, pushing {0}",
+ activity.GetActivityByName (sm.InitialStateName));
+ #endif
+ }
+
+ // TODO: if (IsBasedOnType (current, typeof (CompositeActivity))) {
+ if (activity.GetType () == typeof (DelayActivity)) {
+ if (activity.ParallelParent == null) {
+ wi.WorkflowRuntime.OnWorkflowIdled (wi);
+ waiting.Add ((DelayActivity) activity);
+ wait = true;
+ } else {
+ // Continue from parent activities
+ // TODO: This can be moved to the Execute method
+ // of the paralell activity
+ if (activity.ParallelParent.ActivitiesToExecute.Count > 0) {
+ stack.Push (activity.ParallelParent);
+ #if DEBUG_EXECUTIONLOOP
+ Console.WriteLine ("Pushing parent {0}", activity.ParallelParent);
+ #endif
+ waiting.Add ((DelayActivity) activity);
+ } else { // If not possible, wait for the delay
+ #if DEBUG_EXECUTIONLOOP
+ Console.WriteLine ("Schedule Waiting");
+ #endif
+ waiting.Add ((DelayActivity) activity);
+ wait = true;
+ }
+ }
+ }
+
+ if (activity.NeedsExecution) { // ex. While
+ stack.Push (activity);
+ }
+
+ if (activity.ActivitiesToExecute.Count == 0 && stack.Count == 0 && waiting.Count == 0) {
+ #if DEBUG_EXECUTIONLOOP
+ Console.WriteLine ("Exiting...");
+ #endif
+ break;
+ }
+
+ // Does it have sub-activities to run?
+ // Delay is not composite, cannot have children activities
+ if (wait == false) {
+ if (activity.ActivitiesToExecute.Count > 0) {
+ next_activity = activity.ActivitiesToExecute.Dequeue ();
+ #if DEBUG_EXECUTIONLOOP
+ Console.WriteLine ("Next Activity A {0}", next_activity);
+ #endif
+ if (activity.ActivitiesToExecute.Count > 0) {
+ stack.Push (activity);
+ }
+ } else {
+ if (stack.Count > 0) {
+ next_activity = stack.Pop ();
+ }
+
+ if (next_activity != null && next_activity.NeedsExecution == false) {
+ if (next_activity.ActivitiesToExecute.Count > 0) {
+ next_activity = next_activity.ActivitiesToExecute.Dequeue ();
+ }
+ }
+
+ #if DEBUG_EXECUTIONLOOP
+ Console.WriteLine ("Next Activity B {0}", next_activity);
+ #endif
+ }
+ }
+
+ if (next_activity == null) {
+ if (waiting.Count > 0) {
+ #if DEBUG_EXECUTIONLOOP
+ Console.WriteLine ("Waiting for {0} handles...", waiting.Count);
+ #endif
+ wi.WorkflowRuntime.OnWorkflowIdled (wi);
+ DelayActivity.WaitEvent.WaitOne ();
+ }
+ }
+
+ // Do we have delay activities no longer waiting?
+ foreach (DelayActivity delay in waiting) {
+ if (delay.Delayed == false) {
+ bool flag = false;
+ // Continue with the list of activities pending in the parent
+ next_activity = delay.Parent;
+ waiting.Remove (delay);
+ #if DEBUG_EXECUTIONLOOP
+ Console.WriteLine ("Delayed Parent {0}", next_activity);
+ #endif
+ if (next_activity.ActivitiesToExecute.Count > 0) {
+ if (next_activity.ActivitiesToExecute.Count > 1)
+ flag = true;
+
+ if (next_activity != null) {
+ next_activity = next_activity.ActivitiesToExecute.Dequeue ();
+
+ if (flag == true) {
+ stack.Push (delay.Parent);
+ }
+ }
+ }
+ break;
+ }
+ }
+
+ #if DEBUG_EXECUTIONLOOP
+ Console.WriteLine ("Next activity to process {0}", next_activity);
+ #endif
+ activity = next_activity;
+ }
+ wi.WorkflowRuntime.OnWorkflowCompleted (wi);
+ }
+
+ // This is called by the timer to process the TimeEventSubcriptionCollection
+ static private void TimerSubscriptionsCallback (object state)
+ {
+ WorkflowInstance wi = (WorkflowInstance) state;
+
+ if (wi.TimerEventSubscriptionCollection.Count == 0) {
+ return;
+ }
+
+ if (wi.TimerEventSubscriptionCollection.Peek ().ExpiresAt > DateTime.UtcNow) {
+ return;
+ }
+
+ TimerEventSubscription ti = wi.TimerEventSubscriptionCollection [0];
+ // Event has arrived, send a message to the queue
+ wi.EnqueueItem (ti.QueueName, ti, null, null);
+ wi.TimerEventSubscriptionCollection.Remove (ti);
+ }
+
+ static private bool IsBasedOnType (object obj, Type target)
+ {
+ for (Type type = obj.GetType (); type != null; type = type.BaseType) {
+ if (type == target) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+ }
+}
+
diff --git a/mcs/class/System.Workflow.Runtime/System.Workflow.Runtime/WorkflowQueue.cs b/mcs/class/System.Workflow.Runtime/System.Workflow.Runtime/WorkflowQueue.cs
new file mode 100644
index 00000000000..dc6fe04c2bc
--- /dev/null
+++ b/mcs/class/System.Workflow.Runtime/System.Workflow.Runtime/WorkflowQueue.cs
@@ -0,0 +1,109 @@
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+// Authors:
+//
+// Copyright (C) 2006 Jordi Mas i Hernandez <jordimash@gmail.com>
+//
+
+using System;
+using System.ComponentModel;
+using System.Collections.Generic;
+using System.Workflow.ComponentModel;
+
+namespace System.Workflow.Runtime
+{
+ public sealed class WorkflowQueue
+ {
+ private Queue <object> queue;
+ private WorkflowQueuingService service;
+ private IComparable queue_name;
+
+ internal WorkflowQueue (WorkflowQueuingService service, IComparable queue_name)
+ {
+ queue = new Queue <object> ();
+ this.service = service;
+ this.queue_name = queue_name;
+ }
+
+ // Properties
+ public int Count {
+ get { return queue.Count; }
+ }
+
+ //public bool Enabled { get; set; }
+ public IComparable QueueName {
+ get { return queue_name; }
+ }
+
+ public WorkflowQueuingService QueuingService {
+ get {return service; }
+ }
+
+ // Events
+ public event EventHandler <QueueEventArgs> QueueItemArrived;
+ public event EventHandler <QueueEventArgs> QueueItemAvailable;
+
+ // Methods
+ public object Dequeue ()
+ {
+ return queue.Dequeue ();
+ }
+
+ public void Enqueue (object item)
+ {
+ queue.Enqueue (item);
+
+ if (QueueItemArrived != null) {
+ QueueItemArrived (this, new QueueEventArgs (queue_name));
+ }
+ }
+
+ public object Peek ()
+ {
+ return queue.Peek ();
+ }
+
+ public void RegisterForQueueItemArrived (IActivityEventListener<QueueEventArgs> eventListener)
+ {
+
+ }
+
+ public void RegisterForQueueItemAvailable (IActivityEventListener<QueueEventArgs> eventListener)
+ {
+
+ }
+
+ public void RegisterForQueueItemAvailable (IActivityEventListener<QueueEventArgs> eventListener, string subscriberQualifiedName)
+ {
+
+ }
+
+ public void UnregisterForQueueItemArrived (IActivityEventListener<QueueEventArgs> eventListener)
+ {
+
+ }
+
+ public void UnregisterForQueueItemAvailable (IActivityEventListener<QueueEventArgs> eventListener)
+ {
+
+ }
+ }
+}
+
diff --git a/mcs/class/System.Workflow.Runtime/System.Workflow.Runtime/WorkflowQueuingService.cs b/mcs/class/System.Workflow.Runtime/System.Workflow.Runtime/WorkflowQueuingService.cs
new file mode 100644
index 00000000000..2f89d37e9de
--- /dev/null
+++ b/mcs/class/System.Workflow.Runtime/System.Workflow.Runtime/WorkflowQueuingService.cs
@@ -0,0 +1,83 @@
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+// Authors:
+//
+// Copyright (C) 2006 Jordi Mas i Hernandez <jordimash@gmail.com>
+//
+
+using System;
+using System.ComponentModel;
+using System.Workflow.ComponentModel;
+using System.Collections;
+using System.Collections.Generic;
+using System.Threading;
+
+namespace System.Workflow.Runtime
+{
+ public sealed class WorkflowQueuingService
+ {
+ private IDictionary <IComparable, WorkflowQueue> queues;
+ public static readonly DependencyProperty PendingMessagesProperty;
+
+ static WorkflowQueuingService ()
+ {
+ PendingMessagesProperty = DependencyProperty.RegisterAttached ("PendingMessages",
+ typeof (Queue), typeof (WorkflowQueuingService), new PropertyMetadata ());
+ }
+
+ internal WorkflowQueuingService ()
+ {
+ queues = new Dictionary <IComparable, WorkflowQueue> ();
+ }
+
+ // Methods
+ public WorkflowQueue CreateWorkflowQueue (IComparable queueName, bool transactional)
+ {
+ WorkflowQueue queue;
+
+ if (Exists (queueName)) {
+ throw new InvalidOperationException ("A queue with this name already exists.");
+ }
+
+ queue = new WorkflowQueue (this, queueName);
+ queues.Add (queueName, queue);
+
+ //Console.WriteLine ("CreateWorkflowQueue {0}", queueName);
+ return queue;
+ }
+
+ public void DeleteWorkflowQueue (IComparable queueName)
+ {
+ queues.Remove (queueName);
+ }
+
+ public bool Exists (IComparable queueName)
+ {
+ WorkflowQueue queue;
+ return queues.TryGetValue (queueName, out queue);
+ }
+
+ public WorkflowQueue GetWorkflowQueue (IComparable queueName)
+ {
+ return queues [queueName];
+ }
+ }
+}
+
diff --git a/mcs/class/System.Workflow.Runtime/System.Workflow.Runtime/WorkflowRuntime.cs b/mcs/class/System.Workflow.Runtime/System.Workflow.Runtime/WorkflowRuntime.cs
new file mode 100644
index 00000000000..4519907011f
--- /dev/null
+++ b/mcs/class/System.Workflow.Runtime/System.Workflow.Runtime/WorkflowRuntime.cs
@@ -0,0 +1,277 @@
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+// Authors:
+//
+// Copyright (C) 2006 Jordi Mas i Hernandez <jordimash@gmail.com>
+//
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Workflow.ComponentModel;
+using System.Workflow.Runtime.Hosting;
+using System.Xml;
+
+namespace System.Workflow.Runtime
+{
+ public sealed class WorkflowRuntime : IDisposable
+
+ {
+ private bool is_started;
+ private string name;
+ private List <object> services;
+ internal Dictionary <Guid, WorkflowInstance> instances; // for this runtime
+ private static List <WorkflowRuntime> runtimes; // all runtimes
+
+ public WorkflowRuntime ()
+ {
+ services = new List <object> ();
+ runtimes = new List <WorkflowRuntime> ();
+ instances = new Dictionary <Guid, WorkflowInstance> ();
+ is_started = false;
+ }
+
+ public WorkflowRuntime (string configSectionName) : this ()
+ {
+
+ }
+
+ /*public WorkflowRuntime (WorkflowRuntimeSection settings) {} */
+
+ // Events
+ //public event EventHandler<WorkflowRuntimeEventArgs> Started;
+ //public event EventHandler<WorkflowRuntimeEventArgs> Stopped;
+ public event EventHandler <WorkflowCompletedEventArgs> WorkflowCompleted;
+ public event EventHandler <WorkflowEventArgs> WorkflowCreated;
+ public event EventHandler <WorkflowEventArgs> WorkflowResumed;
+ public event EventHandler <WorkflowEventArgs> WorkflowStarted;
+ public event EventHandler <WorkflowTerminatedEventArgs> WorkflowTerminated;
+ public event EventHandler <WorkflowEventArgs> WorkflowIdled;
+
+ // Properties
+ public bool IsStarted {
+ get { return is_started; }
+ }
+
+ public string Name {
+ get { return name; }
+ set { name = value; }
+ }
+
+ // Methods
+ public void AddService (object service_toadd)
+ {
+ foreach (object service in services) {
+ if (service == service_toadd) {
+ throw new InvalidOperationException ("Cannot add a service that already exists.");
+ }
+ }
+
+ services.Add (service_toadd);
+ }
+
+ public WorkflowInstance CreateWorkflow (Type workflowType)
+ {
+ return CreateWorkflow (workflowType, null, Guid.NewGuid ());
+ }
+
+ public WorkflowInstance CreateWorkflow (XmlReader workflowDefinitionReader)
+ {
+ throw new NotImplementedException ();
+ }
+
+ public WorkflowInstance CreateWorkflow (Type workflowType, Dictionary <string, object> namedArgumentValues)
+ {
+ return CreateWorkflow (workflowType, namedArgumentValues, Guid.NewGuid ());
+ }
+
+ public WorkflowInstance CreateWorkflow (Type workflowType, Dictionary <string, object> namedArgumentValues, Guid instanceId)
+ {
+ WorkflowLoaderService loader;
+ Activity root_activity;
+ WorkflowInstance instance;
+
+ if (is_started == false) {
+ StartRuntime ();
+ }
+
+ loader = (WorkflowLoaderService) GetService (typeof (WorkflowLoaderService));
+ root_activity = loader.CreateInstance (workflowType);
+ instance = new WorkflowInstance (instanceId, this, root_activity);
+ instances.Add (instanceId, instance);
+
+ if (WorkflowStarted != null) {
+ WorkflowStarted (this, new WorkflowEventArgs (instance));
+ }
+
+ return instance;
+ }
+
+ public WorkflowInstance CreateWorkflow (XmlReader workflowDefinitionReader, XmlReader rulesReader, Dictionary <string, object> namedArgumentValues)
+ {
+ throw new NotImplementedException ();
+ }
+
+ public WorkflowInstance CreateWorkflow (XmlReader workflowDefinitionReader, XmlReader rulesReader, Dictionary <string, object> namedArgumentValues, Guid instanceId)
+ {
+ throw new NotImplementedException ();
+ }
+
+ public void Dispose ()
+ {
+ StopRuntime ();
+ }
+
+ public ReadOnlyCollection <T> GetAllServices <T> ()
+ {
+ List <T> services_req = new List <T> ();
+
+ foreach (T service in services) {
+ // To determine if we have a service in the list we have to
+ // check the class and its base types
+ for (Type type = service.GetType (); type != null; type = type.BaseType) {
+ if (type == typeof (T)) {
+ services_req.Add (service);
+ }
+ }
+ }
+
+ return new ReadOnlyCollection <T> (services_req);
+ }
+
+ public ReadOnlyCollection <object> GetAllServices (Type serviceType)
+ {
+ List <object> services_req = new List <object> ();
+
+ foreach (object service in services) {
+
+ // To determine if we have a service in the list we have to
+ // check the class and its base types
+ for (Type type = service.GetType (); type != null; type = type.BaseType) {
+ if (type == serviceType) {
+ services_req.Add (service);
+ }
+ }
+ }
+
+ return new ReadOnlyCollection <object> (services_req);
+ }
+
+
+ public ReadOnlyCollection <WorkflowInstance> GetLoadedWorkflows ()
+ {
+ throw new NotImplementedException ();
+ }
+
+ public T GetService <T> ()
+ {
+ return (T) GetService (typeof (T));
+ }
+
+ public WorkflowInstance GetWorkflow (Guid instanceId)
+ {
+ // TODO: This is related to persistence services
+ if (IsStarted == false) {
+ throw new InvalidOperationException ("This operation can only be performed with a started WorkflowRuntime");
+ }
+
+ throw new NotImplementedException ();
+ }
+
+ public object GetService (Type serviceType)
+ {
+ ReadOnlyCollection <object> objs = GetAllServices (serviceType);
+
+ if (objs.Count > 1) {
+ throw new InvalidOperationException ("More than one runtime service exists");
+ }
+
+ return objs[0];
+ }
+
+ public void RemoveService (object service)
+ {
+ if (services.Contains (service) == false) {
+ throw new InvalidOperationException ("Cannot remove a service that has not been added");
+ }
+
+ services.Remove (service);
+ }
+
+ public void StartRuntime ()
+ {
+ // Provide default services if the user has not provided them
+ if ((GetAllServices (typeof (WorkflowLoaderService))).Count == 0) {
+ AddService (new DefaultWorkflowLoaderService ());
+ }
+
+ if ((GetAllServices (typeof (WorkflowSchedulerService))).Count == 0) {
+ AddService (new DefaultWorkflowSchedulerService ());
+ }
+
+ is_started = true;
+ runtimes.Add (this);
+ }
+
+ public void StopRuntime ()
+ {
+ is_started = false;
+
+ foreach (WorkflowInstance wi in instances.Values) {
+ wi.Abort ();
+ }
+
+ runtimes.Remove (this);
+ }
+
+ // Private
+ internal void OnWorkflowCompleted (WorkflowInstance wi)
+ {
+ if (WorkflowCompleted != null) {
+ WorkflowCompleted (this, new WorkflowCompletedEventArgs (wi,
+ wi.GetWorkflowDefinition ()));
+ }
+ }
+
+ internal void OnWorkflowIdled (WorkflowInstance wi)
+ {
+ if (WorkflowIdled != null) {
+ WorkflowIdled (this, new WorkflowEventArgs (wi));
+ }
+ }
+
+ static internal WorkflowInstance GetInstanceFromGuid (Guid instanceId)
+ {
+ WorkflowInstance wi;
+ foreach (WorkflowRuntime rt in runtimes) {
+ wi = rt.instances [instanceId];
+
+ if (wi != null) {
+ return wi;
+ }
+ }
+
+ return null;
+ }
+
+ }
+}
+
diff --git a/mcs/class/System.Workflow.Runtime/System.Workflow.Runtime/WorkflowTerminatedEventArgs.cs b/mcs/class/System.Workflow.Runtime/System.Workflow.Runtime/WorkflowTerminatedEventArgs.cs
new file mode 100644
index 00000000000..2cddd6f7f03
--- /dev/null
+++ b/mcs/class/System.Workflow.Runtime/System.Workflow.Runtime/WorkflowTerminatedEventArgs.cs
@@ -0,0 +1,46 @@
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+// Authors:
+//
+// Copyright (C) 2006 Jordi Mas i Hernandez <jordimash@gmail.com>
+//
+
+using System;
+
+namespace System.Workflow.Runtime
+{
+ public class WorkflowTerminatedEventArgs : WorkflowEventArgs
+ {
+ private Exception exception;
+
+ internal WorkflowTerminatedEventArgs (WorkflowInstance workflow_instance, Exception exception) :
+ base (workflow_instance)
+ {
+ this.exception = exception;
+ }
+
+ // Properties
+ public Exception Exception {
+ get {return exception; }
+ }
+ }
+}
+
+
diff --git a/mcs/class/System.Workflow.Runtime/System.Workflow.Runtime_test.dll.sources b/mcs/class/System.Workflow.Runtime/System.Workflow.Runtime_test.dll.sources
new file mode 100644
index 00000000000..8e8f77984fb
--- /dev/null
+++ b/mcs/class/System.Workflow.Runtime/System.Workflow.Runtime_test.dll.sources
@@ -0,0 +1,8 @@
+System.Workflow.Runtime/WorkflowQueuingServiceTest.cs
+System.Workflow.Runtime/WorkflowRuntimeTest.cs
+Workflows/SingleActivityCodeTest.cs
+Workflows/SimpleWorkFlowDelayTest.cs
+System.Workflow.Runtime/TimerEventSubscriptionTest.cs
+Workflows/WorkFlowParallelTest.cs
+Workflows/WorkFlowMachineStatusTest.cs
+System.Workflow.Runtime/TimerEventSubscriptionCollectionTest.cs \ No newline at end of file
diff --git a/mcs/class/System.Workflow.Runtime/Test/System.Workflow.Runtime/TimerEventSubscriptionCollectionTest.cs b/mcs/class/System.Workflow.Runtime/Test/System.Workflow.Runtime/TimerEventSubscriptionCollectionTest.cs
new file mode 100644
index 00000000000..dfd59e1ccac
--- /dev/null
+++ b/mcs/class/System.Workflow.Runtime/Test/System.Workflow.Runtime/TimerEventSubscriptionCollectionTest.cs
@@ -0,0 +1,97 @@
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+// Authors:
+//
+// Copyright (C) 2006 Jordi Mas i Hernandez <jordimash@gmail.com>
+//
+
+using System;
+using NUnit.Framework;
+using System.Collections;
+using System.Collections.Generic;
+using System.Workflow.Runtime;
+using System.Reflection;
+
+namespace MonoTests.System.Workflow.Runtime
+{
+
+ [TestFixture]
+ [Category ("NotDotNet")] // Cannot test on .Net since internal constructors (there no public) are different
+ public class TimerEventSubscriptionCollectionTest
+ {
+ [Test]
+ public void TestCollection ()
+ {
+ TimerEventSubscriptionCollection col;
+
+ // There is no public constructor for TimerEventSubscriptionCollection
+ col = (TimerEventSubscriptionCollection) Activator.CreateInstance
+ (typeof (TimerEventSubscriptionCollection),
+ BindingFlags.Instance |BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public,
+ null, null, null);
+
+ TimerEventSubscription event1 = new TimerEventSubscription (Guid.NewGuid (),
+ new DateTime (2006, 07, 30));
+
+ TimerEventSubscription event2 = new TimerEventSubscription (Guid.NewGuid (),
+ new DateTime (2006, 07, 28));
+
+ TimerEventSubscription event3 = new TimerEventSubscription (Guid.NewGuid (),
+ new DateTime (2006, 08, 28));
+
+ TimerEventSubscription event4 = new TimerEventSubscription (Guid.NewGuid (),
+ new DateTime (2007, 08, 28));
+
+ TimerEventSubscription event5 = new TimerEventSubscription (Guid.NewGuid (),
+ new DateTime (2006, 05, 28));
+
+ TimerEventSubscription event6 = new TimerEventSubscription (Guid.NewGuid (),
+ new DateTime (2008, 02, 28));
+
+ TimerEventSubscription event7 = new TimerEventSubscription (Guid.NewGuid (),
+ new DateTime (2005, 05, 28));
+
+ col.Add (event1);
+ col.Add (event2);
+ col.Add (event3);
+ col.Add (event4);
+ col.Add (event5);
+ col.Add (event6);
+ col.Add (event7);
+
+ Assert.AreEqual (event7.ExpiresAt, col.Peek ().ExpiresAt, "C1#1");
+ col.Remove (col.Peek ());
+ Assert.AreEqual (event5.ExpiresAt, col.Peek ().ExpiresAt, "C1#2");
+ col.Remove (col.Peek ());
+ Assert.AreEqual (event2.ExpiresAt, col.Peek ().ExpiresAt, "C1#3");
+ col.Remove (col.Peek ());
+ Assert.AreEqual (event1.ExpiresAt, col.Peek ().ExpiresAt, "C1#4");
+ col.Remove (col.Peek ());
+ Assert.AreEqual (event3.ExpiresAt, col.Peek ().ExpiresAt, "C1#5");
+ col.Remove (col.Peek ());
+ Assert.AreEqual (event4.ExpiresAt, col.Peek ().ExpiresAt, "C1#6");
+
+ }
+
+
+
+ }
+}
+
diff --git a/mcs/class/System.Workflow.Runtime/Test/System.Workflow.Runtime/TimerEventSubscriptionTest.cs b/mcs/class/System.Workflow.Runtime/Test/System.Workflow.Runtime/TimerEventSubscriptionTest.cs
new file mode 100644
index 00000000000..81bd7637d3e
--- /dev/null
+++ b/mcs/class/System.Workflow.Runtime/Test/System.Workflow.Runtime/TimerEventSubscriptionTest.cs
@@ -0,0 +1,90 @@
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+// Authors:
+//
+// Copyright (C) 2006 Jordi Mas i Hernandez <jordimash@gmail.com>
+//
+
+using System;
+using NUnit.Framework;
+using System.Collections;
+using System.Collections.Generic;
+using System.Workflow.Runtime;
+
+namespace MonoTests.System.Workflow.Runtime
+{
+ public class ourTimerEventSubscription : TimerEventSubscription
+ {
+ public ourTimerEventSubscription () : base ()
+ {
+
+ }
+
+ public void SetQueueName (IComparable name)
+ {
+ QueueName = name;
+ }
+ }
+
+ [TestFixture]
+ public class TimerEventSubscriptionTest
+ {
+ [Test]
+ public void Constructor1 ()
+ {
+ TimerEventSubscription timer;
+ Guid timerId = Guid.NewGuid ();
+ Guid workflowInstanceId = Guid.NewGuid ();
+ DateTime expiresAt = DateTime.Today;
+
+ timer = new TimerEventSubscription (timerId, workflowInstanceId, expiresAt);
+
+ Assert.AreEqual (timerId, timer.SubscriptionId, "C1#1");
+ Assert.AreEqual (workflowInstanceId, timer.WorkflowInstanceId, "C1#2");
+ Assert.AreEqual (timerId, timer.QueueName, "C1#3");
+ }
+
+ [Test]
+ public void Constructor2 ()
+ {
+ TimerEventSubscription timer;
+ Guid workflowInstanceId = Guid.NewGuid ();
+ DateTime expiresAt = DateTime.Today;
+
+ timer = new TimerEventSubscription (workflowInstanceId, expiresAt);
+ Assert.AreEqual (workflowInstanceId, timer.WorkflowInstanceId, "C1#1");
+ Assert.AreEqual (timer.SubscriptionId, timer.QueueName, "C1#2");
+ }
+
+ [Test]
+ public void Constructor3 ()
+ {
+ ourTimerEventSubscription timer = new ourTimerEventSubscription ();
+ Assert.AreEqual (Guid.Empty, timer.WorkflowInstanceId, "C1#1");
+ Assert.AreEqual (null, timer.QueueName, "C1#2");
+ Assert.AreEqual (Guid.Empty, timer.WorkflowInstanceId, "C1#3");
+
+ timer.SetQueueName ("OurName");
+ Assert.AreEqual ("OurName", timer.QueueName, "C1#4");
+ }
+
+ }
+}
+
diff --git a/mcs/class/System.Workflow.Runtime/Test/System.Workflow.Runtime/WorkflowQueuingServiceTest.cs b/mcs/class/System.Workflow.Runtime/Test/System.Workflow.Runtime/WorkflowQueuingServiceTest.cs
new file mode 100644
index 00000000000..d7edb8b5d15
--- /dev/null
+++ b/mcs/class/System.Workflow.Runtime/Test/System.Workflow.Runtime/WorkflowQueuingServiceTest.cs
@@ -0,0 +1,47 @@
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+// Authors:
+//
+// Copyright (C) 2006 Jordi Mas i Hernandez <jordimash@gmail.com>
+//
+
+using System;
+using NUnit.Framework;
+using System.Collections;
+using System.Collections.Generic;
+
+namespace MonoTests.System.Workflow.Runtime
+{
+ [TestFixture]
+ public class WorkflowQueuingServiceTest
+ {
+ [Test]
+ public void SetGet ()
+ {
+ //WorkflowQueuingService qs = new WorkflowQueuingService ();
+ //CreateWorkflowQueue
+ //Assert.AreEqual ("Activity", activity.QualifiedName, "C1#6");
+
+ }
+
+
+ }
+}
+
diff --git a/mcs/class/System.Workflow.Runtime/Test/System.Workflow.Runtime/WorkflowRuntimeTest.cs b/mcs/class/System.Workflow.Runtime/Test/System.Workflow.Runtime/WorkflowRuntimeTest.cs
new file mode 100644
index 00000000000..8bff620b35e
--- /dev/null
+++ b/mcs/class/System.Workflow.Runtime/Test/System.Workflow.Runtime/WorkflowRuntimeTest.cs
@@ -0,0 +1,188 @@
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+// Authors:
+//
+// Copyright (C) 2006 Jordi Mas i Hernandez <jordimash@gmail.com>
+//
+
+using System;
+using NUnit.Framework;
+using System.Workflow.ComponentModel;
+using System.Workflow.Runtime.Hosting;
+using System.Workflow.Runtime;
+using System.Workflow.Activities;
+using System.Collections;
+using System.Collections.Generic;
+using System.Xml;
+
+namespace MonoTests.System.Workflow.Runtime
+{
+ public class WorkflowLoaderServiceTest1 : WorkflowLoaderService
+ {
+ public WorkflowLoaderServiceTest1 ()
+ {
+
+ }
+
+ protected override Activity CreateInstance (Type workflowType)
+ {
+ return null;
+ }
+
+ protected override Activity CreateInstance (XmlReader workflowDefinitionReader, XmlReader rulesReader)
+ {
+ return null;
+ }
+ }
+
+ public class WorkflowLoaderServiceTest2 : WorkflowLoaderService
+ {
+ public WorkflowLoaderServiceTest2 ()
+ {
+
+ }
+
+ protected override Activity CreateInstance (Type workflowType)
+ {
+ return null;
+ }
+
+ protected override Activity CreateInstance (XmlReader workflowDefinitionReader, XmlReader rulesReader)
+ {
+ return null;
+ }
+ }
+
+ [TestFixture]
+ public class WorkflowRuntimeTest
+ {
+
+ [Test]
+ public void Services ()
+ {
+ // By default there are no services
+ WorkflowRuntime wr = new WorkflowRuntime ();
+ Assert.AreEqual (0, (wr.GetAllServices (typeof (WorkflowLoaderService))).Count, "C1#1");
+ //Assert.AreEqual (0, (wr.GetAllServices (typeof (WorkflowPersistenceService))).Count, "C1#2");
+ //Assert.AreEqual (0, (wr.GetAllServices (typeof (WorkflowQueuingService))).Count, "C1#3");
+
+ // Can have to diferent instances of the same class
+ WorkflowRuntime wr3 = new WorkflowRuntime ();
+ WorkflowLoaderServiceTest1 wls = new WorkflowLoaderServiceTest1 ();
+ wr3.AddService (wls);
+ Assert.AreEqual (wls, wr3.GetService (typeof (WorkflowLoaderService)), "C1#2");
+
+ wr3.AddService (new WorkflowLoaderServiceTest1 ());
+
+ Assert.AreEqual (2, (wr3.GetAllServices (typeof (WorkflowLoaderService))).Count, "C1#3");
+ Assert.AreEqual (2, wr3.GetAllServices <WorkflowLoaderService> ().Count, "C1#3");
+
+ wr.AddService (new WorkflowLoaderServiceTest1 ());
+
+ //foreach (object t in wr.GetAllServices (typeof (WorkflowLoaderService))) {
+ // Console.WriteLine ("Types {0}", t.GetType ());
+ //}
+ }
+
+ [Test]
+ public void Start ()
+ {
+ WorkflowRuntime wr = new WorkflowRuntime ();
+ wr.StartRuntime ();
+
+ Assert.AreEqual (1, (wr.GetAllServices (typeof (WorkflowLoaderService))).Count, "C1#1");
+
+ foreach (object t in wr.GetAllServices (typeof (WorkflowLoaderService))) {
+ Console.WriteLine ("Types {0}", t.GetType ());
+ }
+ }
+
+ [Test]
+ public void CreateGetWorkflow ()
+ {
+ Guid guid1 = Guid.NewGuid ();
+ Guid guid2 = Guid.NewGuid ();
+
+ WorkflowRuntime wr = new WorkflowRuntime ();
+ Assert.AreEqual (false, wr.IsStarted, "C1#1");
+ WorkflowInstance wi1 = wr.CreateWorkflow (typeof (SequentialWorkflowActivity), null, guid1);
+ Assert.AreEqual (wi1.InstanceId, guid1, "C1#2");
+
+ Assert.AreEqual (true, wr.IsStarted, "C1#3");
+ WorkflowInstance wi2 = wr.CreateWorkflow (typeof (SequenceActivity), null, guid2);
+ Assert.AreEqual (wi2.InstanceId, guid2, "C1#4");
+ }
+
+
+ // Exceptions
+ [Test]
+ [ExpectedException (typeof (InvalidOperationException))]
+ public void AddServiceTwice ()
+ {
+ WorkflowRuntime wr = new WorkflowRuntime ();
+ WorkflowLoaderServiceTest1 wl = new WorkflowLoaderServiceTest1 ();
+ wr.AddService (wl);
+ wr.AddService (wl);
+ }
+
+ [Test]
+ [ExpectedException (typeof (InvalidOperationException))]
+ public void RemoveUnexistantService ()
+ {
+ WorkflowRuntime wr = new WorkflowRuntime ();
+ WorkflowLoaderServiceTest1 wl = new WorkflowLoaderServiceTest1 ();
+ wr.RemoveService (wl);
+ }
+
+ [Test]
+ [ExpectedException (typeof (InvalidOperationException))]
+ public void GetServiceWithTwoA ()
+ {
+ WorkflowRuntime wr = new WorkflowRuntime ();
+ WorkflowLoaderServiceTest1 wl = new WorkflowLoaderServiceTest1 ();
+ WorkflowLoaderServiceTest2 w2 = new WorkflowLoaderServiceTest2 ();
+ wr.AddService (wl);
+ wr.AddService (w2);
+ wr.GetService (typeof (WorkflowLoaderService));
+ }
+
+ [Test]
+ [ExpectedException (typeof (InvalidOperationException))]
+ public void GetServiceWithTwoB ()
+ {
+ WorkflowRuntime wr = new WorkflowRuntime ();
+ WorkflowLoaderServiceTest1 wl = new WorkflowLoaderServiceTest1 ();
+ WorkflowLoaderServiceTest2 w2 = new WorkflowLoaderServiceTest2 ();
+ wr.AddService (wl);
+ wr.AddService (w2);
+ wr.GetService <WorkflowLoaderService> ();
+ }
+
+ [Test]
+ [ExpectedException (typeof (InvalidOperationException))]
+ public void GetInstanceNoRuntimeStarted ()
+ {
+ // This operation can only be performed with a started WorkflowRuntime
+ WorkflowRuntime wr = new WorkflowRuntime ();
+ wr.GetWorkflow (Guid.NewGuid ());
+ }
+ }
+}
+
diff --git a/mcs/class/System.Workflow.Runtime/Test/Workflows/ChangeLog b/mcs/class/System.Workflow.Runtime/Test/Workflows/ChangeLog
new file mode 100644
index 00000000000..e5d29422895
--- /dev/null
+++ b/mcs/class/System.Workflow.Runtime/Test/Workflows/ChangeLog
@@ -0,0 +1,4 @@
+2006-09-02 Jordi Mas i Hernandez <jordimash@gmail.com>
+
+ * Initial check-in
+
diff --git a/mcs/class/System.Workflow.Runtime/Test/Workflows/SimpleWorkFlowDelayTest.cs b/mcs/class/System.Workflow.Runtime/Test/Workflows/SimpleWorkFlowDelayTest.cs
new file mode 100644
index 00000000000..17cc4df7d89
--- /dev/null
+++ b/mcs/class/System.Workflow.Runtime/Test/Workflows/SimpleWorkFlowDelayTest.cs
@@ -0,0 +1,114 @@
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+// Authors:
+//
+// Copyright (C) 2006 Jordi Mas i Hernandez <jordimash@gmail.com>
+//
+//
+// This a simple Sequential WorkFlow with a Delay, While and Code activities
+//
+//
+
+using System;
+using NUnit.Framework;
+using System.Workflow.ComponentModel;
+using System.Workflow.Activities;
+using System.Workflow.Runtime;
+using System.Threading;
+
+namespace MonoTests.System.Workflow.Runtime
+{
+
+ public sealed class SimpleWorkFlowDelay : SequentialWorkflowActivity
+ {
+ private WhileActivity WhileFilesToBackup;
+ private CodeActivity BackUpFile;
+ private DelayActivity DelaySystemReady;
+
+ public SimpleWorkFlowDelay ()
+ {
+ CanModifyActivities = true;
+ CodeCondition codecondition1 = new CodeCondition ();
+ BackUpFile = new CodeActivity ();
+ WhileFilesToBackup = new WhileActivity ();
+ DelaySystemReady = new DelayActivity ();
+
+ BackUpFile.ExecuteCode += new EventHandler (BackUpFile_ExecuteCode);
+
+ WhileFilesToBackup.Activities.Add(BackUpFile);
+ codecondition1.Condition += new EventHandler <ConditionalEventArgs>(MoreFiles);
+
+ WhileFilesToBackup.Condition = codecondition1;
+
+ DelaySystemReady.TimeoutDuration = TimeSpan.Parse ("00:00:02");
+
+ Activities.Add (DelaySystemReady);
+ Activities.Add (WhileFilesToBackup);
+ Name = "SimpleWorkFlowDelay";
+ CanModifyActivities = false;
+ }
+
+ private void MoreFiles (object sender, ConditionalEventArgs e)
+ {
+ SimpleWorkFlowDelayTest.files_counted++;
+ if (SimpleWorkFlowDelayTest.files_counted < 3) {
+ e.Result = true;
+ }
+ else {
+ e.Result = false;
+ }
+ }
+
+ private void BackUpFile_ExecuteCode (object sender, EventArgs e)
+ {
+ SimpleWorkFlowDelayTest.backup_executed++;
+ }
+ }
+
+ [TestFixture]
+ public class SimpleWorkFlowDelayTest
+ {
+ static public int files_counted = 0;
+ static public int backup_executed = 0;
+ static AutoResetEvent waitHandle = new AutoResetEvent (false);
+
+ [Test]
+ public void WorkFlowTest ()
+ {
+ WorkflowRuntime workflowRuntime = new WorkflowRuntime ();
+
+ Type type = typeof (SimpleWorkFlowDelay);
+ workflowRuntime.WorkflowCompleted += OnWorkflowCompleted;
+
+ workflowRuntime.CreateWorkflow (type).Start ();
+ waitHandle.WaitOne ();
+ workflowRuntime.Dispose ();
+
+ Assert.AreEqual (3, files_counted, "C1#1");
+ Assert.AreEqual (3, backup_executed, "C1#2");
+ }
+
+ void OnWorkflowCompleted (object sender, WorkflowCompletedEventArgs e)
+ {
+ waitHandle.Set ();
+ }
+ }
+}
+
diff --git a/mcs/class/System.Workflow.Runtime/Test/Workflows/SingleActivityCodeTest.cs b/mcs/class/System.Workflow.Runtime/Test/Workflows/SingleActivityCodeTest.cs
new file mode 100644
index 00000000000..46ab3f28401
--- /dev/null
+++ b/mcs/class/System.Workflow.Runtime/Test/Workflows/SingleActivityCodeTest.cs
@@ -0,0 +1,79 @@
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+// Authors:
+//
+// Copyright (C) 2006 Jordi Mas i Hernandez <jordimash@gmail.com>
+//
+//
+// This a simple Sequential WorkFlow with a Code Activity
+//
+
+using System;
+using NUnit.Framework;
+using System.Workflow.ComponentModel;
+using System.Workflow.Activities;
+using System.Workflow.Runtime;
+using System.Threading;
+
+namespace MonoTests.System.Workflow.Runtime
+{
+ public sealed class SequentialWorkflow : SequentialWorkflowActivity
+ {
+ public SequentialWorkflow ()
+ {
+ CodeActivity code = new CodeActivity ();
+ code.ExecuteCode += OnCodeExecute;
+ Activities.Add (code);
+ }
+
+ private void OnCodeExecute (object sender, EventArgs e)
+ {
+ SingleActivityCodeTest.code_execute = true;
+ }
+ }
+
+ [TestFixture]
+ public class SingleActivityCodeTest
+ {
+ static public bool code_execute = false;
+ static AutoResetEvent waitHandle = new AutoResetEvent(false);
+
+ [Test]
+ public void WorkFlowTest ()
+ {
+ WorkflowRuntime workflowRuntime = new WorkflowRuntime ();
+
+ Type type = typeof (SequentialWorkflow);
+ workflowRuntime.WorkflowCompleted += OnWorkflowCompleted;
+
+ workflowRuntime.CreateWorkflow (type).Start ();
+ waitHandle.WaitOne ();
+ workflowRuntime.Dispose ();
+
+ Assert.AreEqual (true, code_execute, "C1#1");
+ }
+
+ void OnWorkflowCompleted (object sender, WorkflowCompletedEventArgs e)
+ {
+ waitHandle.Set ();
+ }
+ }
+}
+
diff --git a/mcs/class/System.Workflow.Runtime/Test/Workflows/WorkFlowMachineStatusTest.cs b/mcs/class/System.Workflow.Runtime/Test/Workflows/WorkFlowMachineStatusTest.cs
new file mode 100644
index 00000000000..8f3f1899b84
--- /dev/null
+++ b/mcs/class/System.Workflow.Runtime/Test/Workflows/WorkFlowMachineStatusTest.cs
@@ -0,0 +1,296 @@
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+// Authors:
+//
+// Copyright (C) 2006 Jordi Mas i Hernandez <jordimash@gmail.com>
+//
+// This is a State Machine workflow test
+//
+//
+
+using System;
+using NUnit.Framework;
+using System.Workflow.ComponentModel;
+using System.Workflow.Activities;
+using System.Workflow.Runtime;
+using System.Threading;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+
+namespace MonoTests.Workflow.Runtime
+{
+ public sealed class DocumentCreation : StateMachineWorkflowActivity
+ {
+ private SetStateActivity DocumentSetState;
+ private CodeActivity CodeDocument;
+ private EventDrivenActivity CreateDriven;
+ private EventDrivenActivity ProofReadEventDriven;
+ private StateActivity ProofRead;
+ private SetStateActivity ProofReadSetStateQualityNotOK;
+ private SetStateActivity ProofReadSetStateQualityOK;
+ private IfElseBranchActivity ProofReadElseBranchActivity2;
+ private IfElseBranchActivity ProofReadElseBranch;
+ private IfElseActivity ProofReadIfElse;
+ private EventDrivenActivity PrintEventDriven;
+ private StateActivity Print;
+ private CodeActivity PrintCode;
+ private DelayActivity PrintDelay;
+ private StateActivity End;
+ private SetStateActivity PrintSetState;
+ private DelayActivity ProofReadDelay;
+ private DelayActivity CreateDelay;
+ private CodeActivity CreateInitCode;
+ private StateInitializationActivity CreateInitialization;
+ private CodeActivity PrintFinalizationCode;
+ private StateFinalizationActivity PrintFinalization;
+ private StateActivity Create;
+
+ public DocumentCreation ()
+ {
+ InitializeComponent ();
+ }
+
+ private void InitializeComponent ()
+ {
+ CanModifyActivities = true;
+ CodeCondition codecondition1 = new CodeCondition ();
+ ProofReadSetStateQualityNotOK = new SetStateActivity ();
+ ProofReadSetStateQualityOK = new SetStateActivity ();
+ ProofReadElseBranchActivity2 = new IfElseBranchActivity ();
+ ProofReadElseBranch = new IfElseBranchActivity ();
+ PrintFinalizationCode = new CodeActivity ();
+ PrintSetState = new SetStateActivity ();
+ PrintCode = new CodeActivity ();
+ PrintDelay = new DelayActivity ();
+ ProofReadIfElse = new IfElseActivity ();
+ ProofReadDelay = new DelayActivity ();
+ CreateInitCode = new CodeActivity ();
+ DocumentSetState = new SetStateActivity ();
+ CodeDocument = new CodeActivity ();
+ CreateDelay = new DelayActivity ();
+ PrintFinalization = new StateFinalizationActivity ();
+ PrintEventDriven = new EventDrivenActivity ();
+ ProofReadEventDriven = new EventDrivenActivity ();
+ CreateInitialization = new StateInitializationActivity ();
+ CreateDriven = new EventDrivenActivity ();
+ End = new StateActivity ();
+ Print = new StateActivity ();
+ ProofRead = new StateActivity ();
+ Create = new StateActivity ();
+
+ // ProofReadSetStateQualityNotOK
+ ProofReadSetStateQualityNotOK.Name = "ProofReadSetStateQualityNotOK";
+ ProofReadSetStateQualityNotOK.TargetStateName = "Print";
+
+ // ProofReadSetStateQualityOK
+ ProofReadSetStateQualityOK.Name = "ProofReadSetStateQualityOK";
+ ProofReadSetStateQualityOK.TargetStateName = "End";
+
+ // ProofReadElseBranchActivity2
+ ProofReadElseBranchActivity2.Activities.Add (ProofReadSetStateQualityNotOK);
+ ProofReadElseBranchActivity2.Name = "ProofReadElseBranchActivity2";
+
+ // ProofReadElseBranch
+ ProofReadElseBranch.Activities.Add (ProofReadSetStateQualityOK);
+ codecondition1.Condition += new EventHandler <ConditionalEventArgs> (ProofReadIfElseConditionFunction);
+ ProofReadElseBranch.Condition = codecondition1;
+ ProofReadElseBranch.Name = "ProofReadElseBranch";
+
+ // PrintFinalizationCode
+ PrintFinalizationCode.Name = "PrintFinalizationCode";
+ PrintFinalizationCode.ExecuteCode += new EventHandler (PrintFinalizationCodeFunction);
+
+ // PrintSetState
+ PrintSetState.Name = "PrintSetState";
+ PrintSetState.TargetStateName = "End";
+
+ // PrintCode
+ PrintCode.Name = "PrintCode";
+ PrintCode.ExecuteCode += new EventHandler (PrintCodeFunction);
+
+ // PrintDelay
+ PrintDelay.Name = "PrintDelay";
+ PrintDelay.TimeoutDuration = TimeSpan.Parse ("00:00:02");
+
+ // ProofReadIfElse
+ ProofReadIfElse.Activities.Add (ProofReadElseBranch);
+ ProofReadIfElse.Activities.Add (ProofReadElseBranchActivity2);
+ ProofReadIfElse.Description = "Quality is OK?";
+ ProofReadIfElse.Name = "ProofReadIfElse";
+
+ // ProofReadDelay
+ ProofReadDelay.Name = "ProofReadDelay";
+ ProofReadDelay.TimeoutDuration = TimeSpan.Parse ("00:00:01");
+
+ // CreateInitCode
+ CreateInitCode.Name = "CreateInitCode";
+ CreateInitCode.ExecuteCode += new EventHandler (CreateInitCodeFunction);
+
+ // DocumentSetState
+ DocumentSetState.Name = "DocumentSetState";
+ DocumentSetState.TargetStateName = "ProofRead";
+
+ // CodeDocument
+ CodeDocument.Name = "CodeDocument";
+ CodeDocument.ExecuteCode += new EventHandler (CodeDocumentFunction);
+
+ // CreateDelay
+ CreateDelay.Name = "CreateDelay";
+ CreateDelay.TimeoutDuration = TimeSpan.Parse ("00:00:01");
+
+ // PrintFinalization
+ PrintFinalization.Activities.Add (PrintFinalizationCode);
+ PrintFinalization.Name = "PrintFinalization";
+
+ // PrintEventDriven
+ PrintEventDriven.Activities.Add (PrintDelay);
+ PrintEventDriven.Activities.Add (PrintCode);
+ PrintEventDriven.Activities.Add (PrintSetState);
+ PrintEventDriven.Name = "PrintEventDriven";
+
+ // ProofReadEventDriven
+ ProofReadEventDriven.Activities.Add (ProofReadDelay);
+ ProofReadEventDriven.Activities.Add (ProofReadIfElse);
+ ProofReadEventDriven.Name = "ProofReadEventDriven";
+
+ // CreateInitialization
+ CreateInitialization.Activities.Add (CreateInitCode);
+ CreateInitialization.Name = "CreateInitialization";
+
+ // CreateDriven
+ CreateDriven.Activities.Add (CreateDelay);
+ CreateDriven.Activities.Add (CodeDocument);
+ CreateDriven.Activities.Add (DocumentSetState);
+ CreateDriven.Name = "CreateDriven";
+
+ // End
+ End.Name = "End";
+
+ // Print
+ Print.Activities.Add (PrintEventDriven);
+ Print.Activities.Add (PrintFinalization);
+ Print.Name = "Print";
+
+ // ProofRead
+ ProofRead.Activities.Add (ProofReadEventDriven);
+ ProofRead.Name = "ProofRead";
+
+ // Create
+ Create.Activities.Add (CreateDriven);
+ Create.Activities.Add (CreateInitialization);
+ Create.Name = "Create";
+
+ // DocumentCreation
+ Activities.Add (Create);
+ Activities.Add (ProofRead);
+ Activities.Add (Print);
+ Activities.Add (End);
+ CompletedStateName = "End";
+ InitialStateName = "Create";
+ Name = "DocumentCreation";
+ CanModifyActivities = false;
+ }
+
+ private void PrintCodeFunction (object sender, EventArgs e)
+ {
+ WorkFlowMachineStatusTest.Events.Add ("PrintCodeFunction");
+ }
+
+ private void ProofReadIfElseConditionFunction (object sender, ConditionalEventArgs e)
+ {
+ e.Result = false;
+ WorkFlowMachineStatusTest.Events.Add ("ProofReadIfElseConditionFunction");
+
+ Activity activity = (Activity) sender;
+ while (activity.Parent != null) {
+ activity = activity.Parent;
+ }
+
+ DocumentCreation doc = (DocumentCreation) activity;
+ WorkFlowMachineStatusTest.Events.Add ("State:" + doc.CurrentStateName);
+ }
+
+ private void CodeDocumentFunction (object sender, EventArgs e)
+ {
+ WorkFlowMachineStatusTest.Events.Add ("CodeDocumentFunction");
+ }
+
+ private void CreateInitCodeFunction (object sender, EventArgs e)
+ {
+ WorkFlowMachineStatusTest.Events.Add ("CreateInitCodeFunction");
+ }
+
+ private void PrintFinalizationCodeFunction (object sender, EventArgs e)
+ {
+ WorkFlowMachineStatusTest.Events.Add ("PrintFinalizationCodeFunction");
+
+ Activity activity = (Activity) sender;
+ while (activity.Parent != null) {
+ activity = activity.Parent;
+ }
+
+ DocumentCreation doc = (DocumentCreation) activity;
+ WorkFlowMachineStatusTest.Events.Add ("State:" + doc.CurrentStateName);
+ WorkFlowMachineStatusTest.Events.Add ("Previous state:" + doc.PreviousStateName);
+ }
+ }
+
+ [TestFixture]
+ public class WorkFlowMachineStatusTest
+ {
+ static public List <string> events;
+
+ static public List <string> Events {
+ get {return events;}
+ }
+
+ [Test]
+ public void WorkFlowTest ()
+ {
+ events = new List <string> ();
+ using (WorkflowRuntime workflowRuntime = new WorkflowRuntime ())
+ {
+ AutoResetEvent waitHandle = new AutoResetEvent (false);
+ workflowRuntime.WorkflowCompleted += delegate (object sender, WorkflowCompletedEventArgs e) {waitHandle.Set ();};
+ workflowRuntime.WorkflowTerminated += delegate (object sender, WorkflowTerminatedEventArgs e)
+ {
+ Console.WriteLine (e.Exception.Message);
+ waitHandle.Set ();
+ };
+
+ WorkflowInstance instance = workflowRuntime.CreateWorkflow (typeof (DocumentCreation));
+ instance.Start ();
+
+ waitHandle.WaitOne ();
+ }
+
+ Assert.AreEqual ("CreateInitCodeFunction", events[0], "C1#1");
+ Assert.AreEqual ("CodeDocumentFunction", events[1], "C1#2");
+ Assert.AreEqual ("ProofReadIfElseConditionFunction", events[2], "C1#3");
+ Assert.AreEqual ("State:ProofRead", events[3], "C1#4");
+ Assert.AreEqual ("PrintCodeFunction", events[4], "C1#5");
+ Assert.AreEqual ("PrintFinalizationCodeFunction", events[5], "C1#6");
+ Assert.AreEqual ("State:End", events[6], "C1#7");
+ Assert.AreEqual ("Previous state:Print", events[7], "C1#8");
+ Assert.AreEqual (8, events.Count, "C1#9");
+ }
+ }
+}
+
diff --git a/mcs/class/System.Workflow.Runtime/Test/Workflows/WorkFlowMachineStatusTest.jpg b/mcs/class/System.Workflow.Runtime/Test/Workflows/WorkFlowMachineStatusTest.jpg
new file mode 100644
index 00000000000..f668f960eda
--- /dev/null
+++ b/mcs/class/System.Workflow.Runtime/Test/Workflows/WorkFlowMachineStatusTest.jpg
Binary files differ
diff --git a/mcs/class/System.Workflow.Runtime/Test/Workflows/WorkFlowParallelTest.cs b/mcs/class/System.Workflow.Runtime/Test/Workflows/WorkFlowParallelTest.cs
new file mode 100644
index 00000000000..faf6e68313e
--- /dev/null
+++ b/mcs/class/System.Workflow.Runtime/Test/Workflows/WorkFlowParallelTest.cs
@@ -0,0 +1,229 @@
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+// Authors:
+//
+// Copyright (C) 2006 Jordi Mas i Hernandez <jordimash@gmail.com>
+//
+//
+// This workflow uses Paralell and Delays activities
+//
+//
+
+using System;
+using NUnit.Framework;
+using System.Workflow.ComponentModel;
+using System.Workflow.Activities;
+using System.Workflow.Runtime;
+using System.Threading;
+using System.Collections.Generic;
+
+namespace MonoTests.System.Workflow.Runtime
+{
+ public sealed class SequentialWorkflowParallel : SequentialWorkflowActivity
+ {
+ private CodeActivity CodeCloseMailProgram2;
+ private DelayActivity DelayWaitForSentMail2;
+ private CodeActivity PrepareMail2;
+ private CodeActivity CodeCloseMailProgram1;
+ private DelayActivity DelayWaitForSentMail1;
+ private CodeActivity CodePrepareMail1;
+ private SequenceActivity SeqSendMail2;
+ private SequenceActivity SeqSendMail1;
+ private ParallelActivity Parallel;
+ private IfElseBranchActivity IfElseBranchActivityNoNeed;
+ private IfElseBranchActivity IfElseBranchActivityNeedToSendMail;
+ private TerminateActivity TerminateFinishNoNeedToReadMail;
+ private IfElseActivity NeedToSendMail;
+ private CodeActivity CodeCloseMailProgram3;
+ private DelayActivity DelayWaitForSentMail3;
+ private CodeActivity PrepareMail3;
+ private SequenceActivity SeqSendMail3;
+
+ public SequentialWorkflowParallel ()
+ {
+ InitializeComponent ();
+ }
+
+ private void InitializeComponent ()
+ {
+ Console.WriteLine ("1");
+
+ CanModifyActivities = true;
+ CodeCondition codecondition1 = new CodeCondition ();
+ CodeCloseMailProgram2 = new CodeActivity ();
+ CodeCloseMailProgram3 = new CodeActivity ();
+ DelayWaitForSentMail2 = new DelayActivity ();
+ DelayWaitForSentMail3 = new DelayActivity ();
+ PrepareMail2 = new CodeActivity ();
+ PrepareMail3 = new CodeActivity ();
+ CodeCloseMailProgram1 = new CodeActivity ();
+ DelayWaitForSentMail1 = new DelayActivity ();
+ CodePrepareMail1 = new CodeActivity ();
+ SeqSendMail2 = new SequenceActivity ();
+ SeqSendMail1 = new SequenceActivity ();
+ SeqSendMail3 = new SequenceActivity ();
+ TerminateFinishNoNeedToReadMail = new TerminateActivity ();
+ Parallel = new ParallelActivity ();
+ IfElseBranchActivityNoNeed = new IfElseBranchActivity ();
+ IfElseBranchActivityNeedToSendMail = new IfElseBranchActivity ();
+ NeedToSendMail = new IfElseActivity ();
+
+ PrepareMail3.Name = "PrepareMail3";
+ PrepareMail3.ExecuteCode += new EventHandler (PrepareMail3_ExecuteCode);
+
+ CodeCloseMailProgram3.Name = "CodeCloseMailProgram3";
+ CodeCloseMailProgram3.ExecuteCode += new EventHandler (CodeCloseMailProgram3_ExecuteCode);
+
+ DelayWaitForSentMail3.Name = "DelayWaitForSentMail3";
+ DelayWaitForSentMail3.TimeoutDuration = TimeSpan.Parse ("00:00:03");
+
+ CodeCloseMailProgram2.Name = "CodeCloseMailProgram2";
+ CodeCloseMailProgram2.ExecuteCode += new EventHandler (CodeCloseMailProgram2_ExecuteCode);
+
+ DelayWaitForSentMail2.Name = "DelayWaitForSentMail2";
+ DelayWaitForSentMail2.TimeoutDuration = TimeSpan.Parse ("00:00:02");
+
+ PrepareMail2.Name = "PrepareMail2";
+ PrepareMail2.ExecuteCode += new EventHandler (PrepareMail2_ExecuteCode);
+
+ CodeCloseMailProgram1.Name = "CodeCloseMailProgram1";
+ CodeCloseMailProgram1.ExecuteCode += new EventHandler (CodeCloseMailProgram_ExecuteCode);
+
+ DelayWaitForSentMail1.Name = "DelayWaitForSentMail1";
+ DelayWaitForSentMail1.TimeoutDuration = TimeSpan.Parse ("00:00:05");
+ CodePrepareMail1.Name = "CodePrepareMail1";
+ CodePrepareMail1.ExecuteCode += new EventHandler (CodeActivity1_ExecuteCode);
+
+ SeqSendMail2.Activities.Add (PrepareMail2);
+ SeqSendMail2.Activities.Add (DelayWaitForSentMail2);
+ SeqSendMail2.Activities.Add (CodeCloseMailProgram2);
+ SeqSendMail2.Name = "SeqSendMail2";
+
+ SeqSendMail3.Activities.Add (PrepareMail3);
+ SeqSendMail3.Activities.Add (DelayWaitForSentMail3);
+ SeqSendMail3.Activities.Add (CodeCloseMailProgram3);
+ SeqSendMail3.Name = "SeqSendMail3";
+
+ SeqSendMail1.Activities.Add (CodePrepareMail1);
+ SeqSendMail1.Activities.Add (DelayWaitForSentMail1);
+ SeqSendMail1.Activities.Add (CodeCloseMailProgram1);
+ SeqSendMail1.Name = "SeqSendMail1";
+
+ TerminateFinishNoNeedToReadMail.Name = "TerminateFinishNoNeedToReadMail";
+
+ Parallel.Activities.Add (SeqSendMail1);
+ Parallel.Activities.Add (SeqSendMail2);
+ Parallel.Activities.Add (SeqSendMail3);
+ Parallel.Name = "Parallel";
+
+ IfElseBranchActivityNoNeed.Activities.Add (TerminateFinishNoNeedToReadMail);
+ IfElseBranchActivityNoNeed.Name = "IfElseBranchActivityNoNeed";
+
+ IfElseBranchActivityNeedToSendMail.Activities.Add (Parallel);
+ codecondition1.Condition += new EventHandler <ConditionalEventArgs>(IfElseCondition);
+ IfElseBranchActivityNeedToSendMail.Condition = codecondition1;
+ IfElseBranchActivityNeedToSendMail.Name = "IfElseBranchActivityNeedToSendMail";
+
+ NeedToSendMail.Activities.Add (IfElseBranchActivityNeedToSendMail);
+ NeedToSendMail.Activities.Add (IfElseBranchActivityNoNeed);
+ NeedToSendMail.Name = "NeedToSendMail";
+
+ Activities.Add (NeedToSendMail);
+ Name = "IfElseParalellWorkFlow";
+ CanModifyActivities = false;
+ }
+
+ private void IfElseCondition (object sender, ConditionalEventArgs e)
+ {
+ WorkFlowParallelTest.Events.Add ("IfElseCondition");
+ e.Result = true;
+ }
+
+ private void CodeActivity1_ExecuteCode (object sender, EventArgs e)
+ {
+ WorkFlowParallelTest.Events.Add ("PrepareMail1_ExecuteCode");
+ }
+
+ private void CodeCloseMailProgram_ExecuteCode (object sender, EventArgs e)
+ {
+ WorkFlowParallelTest.Events.Add ("CodeCloseMailProgram1_ExecuteCode");
+ }
+
+ private void PrepareMail2_ExecuteCode (object sender, EventArgs e)
+ {
+ WorkFlowParallelTest.Events.Add ("PrepareMail2_ExecuteCode");
+ }
+
+ private void CodeCloseMailProgram2_ExecuteCode (object sender, EventArgs e)
+ {
+ WorkFlowParallelTest.Events.Add ("CodeCloseMailProgram2_ExecuteCode");
+ }
+
+ private void PrepareMail3_ExecuteCode (object sender, EventArgs e)
+ {
+ WorkFlowParallelTest.Events.Add ("PrepareMail3_ExecuteCode");
+ }
+
+ private void CodeCloseMailProgram3_ExecuteCode (object sender, EventArgs e)
+ {
+ WorkFlowParallelTest.Events.Add ("CodeCloseMailProgram3_ExecuteCode");
+ }
+ }
+
+ [TestFixture]
+ public class WorkFlowParallelTest
+ {
+ static public List <string> events;
+ static AutoResetEvent waitHandle = new AutoResetEvent(false);
+
+ [Test]
+ public void WorkFlowTest ()
+ {
+ events = new List <string> ();
+ WorkflowRuntime workflowRuntime = new WorkflowRuntime ();
+
+ Type type = typeof (SequentialWorkflowParallel);
+ workflowRuntime.WorkflowCompleted += OnWorkflowCompleted;
+
+ workflowRuntime.CreateWorkflow (type).Start ();
+
+ waitHandle.WaitOne ();
+ workflowRuntime.Dispose ();
+
+ Assert.AreEqual ("IfElseCondition", events[0], "C1#1");
+ Assert.AreEqual ("PrepareMail1_ExecuteCode", events[1], "C1#2");
+ Assert.AreEqual ("PrepareMail2_ExecuteCode", events[2], "C1#3");
+ Assert.AreEqual ("PrepareMail3_ExecuteCode", events[3], "C1#4");
+ Assert.AreEqual ("CodeCloseMailProgram2_ExecuteCode", events[4], "C1#8");
+ Assert.AreEqual ("CodeCloseMailProgram3_ExecuteCode", events[5], "C1#9");
+ Assert.AreEqual ("CodeCloseMailProgram1_ExecuteCode", events[6], "C1#10");
+ }
+
+ static public List <string> Events {
+ get {return events;}
+ }
+
+ void OnWorkflowCompleted (object sender, WorkflowCompletedEventArgs e)
+ {
+ waitHandle.Set ();
+ }
+ }
+}
+
diff --git a/mcs/class/System.Workflow.Runtime/Test/Workflows/WorkFlowParallelTest.jpg b/mcs/class/System.Workflow.Runtime/Test/Workflows/WorkFlowParallelTest.jpg
new file mode 100644
index 00000000000..3e24dea4f1e
--- /dev/null
+++ b/mcs/class/System.Workflow.Runtime/Test/Workflows/WorkFlowParallelTest.jpg
Binary files differ