e79aa3c0ed
Former-commit-id: a2155e9bd80020e49e72e86c44da02a8ac0e57a4
128 lines
4.9 KiB
C#
128 lines
4.9 KiB
C#
#region Using directives
|
|
|
|
using System;
|
|
using System.Diagnostics;
|
|
using System.Collections.Generic;
|
|
using System.Text;
|
|
using System.Reflection;
|
|
using System.Runtime.Remoting;
|
|
using System.Runtime.Remoting.Messaging;
|
|
using System.Workflow.Runtime.Hosting;
|
|
using System.Workflow.ComponentModel;
|
|
using System.Workflow.Runtime;
|
|
|
|
#endregion
|
|
|
|
namespace System.Workflow.Activities
|
|
{
|
|
internal static class InboundActivityHelper
|
|
{
|
|
internal static ActivityExecutionStatus ExecuteForActivity(HandleExternalEventActivity activity, ActivityExecutionContext context, Type interfaceType, string operation, out object[] args)
|
|
{
|
|
WorkflowQueuingService queueSvcs = (WorkflowQueuingService)context.GetService(typeof(WorkflowQueuingService));
|
|
args = null;
|
|
IComparable queueName = CorrelationService.ResolveQueueName(activity, interfaceType, operation);
|
|
if (queueName != null)
|
|
{
|
|
WorkflowQueue queue;
|
|
object message = DequeueMessage(queueName, queueSvcs, activity, out queue);
|
|
CorrelationService.UninitializeFollowers(interfaceType, operation, queue);
|
|
if (message != null)
|
|
{
|
|
args = ProcessEvent(activity, context, message, interfaceType, operation);
|
|
return ActivityExecutionStatus.Closed;
|
|
}
|
|
}
|
|
|
|
return ActivityExecutionStatus.Executing;
|
|
}
|
|
|
|
internal static object DequeueMessage(IComparable queueId, WorkflowQueuingService queueSvcs, Activity activity, out WorkflowQueue queue)
|
|
{
|
|
object message = null;
|
|
queue = queueSvcs.GetWorkflowQueue(queueId);
|
|
|
|
if (queue.Count != 0)
|
|
{
|
|
message = queue.Dequeue();
|
|
if (message == null)
|
|
throw new ArgumentException(SR.GetString(SR.Error_InvalidEventMessage, activity.QualifiedName));
|
|
}
|
|
return message;
|
|
}
|
|
|
|
private static object[] ProcessEvent(HandleExternalEventActivity activity, ActivityExecutionContext context, object msg, Type interfaceType, string operation)
|
|
{
|
|
IMethodMessage message = msg as IMethodMessage;
|
|
if (message == null)
|
|
{
|
|
Exception excp = msg as Exception;
|
|
if (excp != null)
|
|
throw excp;
|
|
throw new InvalidOperationException(SR.GetString(SR.Error_InvalidLocalServiceMessage));
|
|
}
|
|
|
|
CorrelationService.InvalidateCorrelationToken(activity, interfaceType, operation, message.Args);
|
|
|
|
IdentityContextData identityData =
|
|
(IdentityContextData)message.LogicalCallContext.GetData(IdentityContextData.IdentityContext);
|
|
ValidateRoles(activity, identityData.Identity);
|
|
|
|
if (ProcessEventParameters(activity.ParameterBindings, message, interfaceType, operation))
|
|
return message.Args;
|
|
|
|
return null;
|
|
}
|
|
|
|
private static bool ProcessEventParameters(WorkflowParameterBindingCollection parameters, IMethodMessage message, Type interfaceType, string operation)
|
|
{
|
|
bool isKnownSignature = false;
|
|
if (parameters == null)
|
|
return isKnownSignature;
|
|
|
|
EventInfo eventInfo = interfaceType.GetEvent(operation);
|
|
MethodInfo methodInfo = eventInfo.EventHandlerType.GetMethod("Invoke");
|
|
int index = 0;
|
|
|
|
foreach (ParameterInfo formalParameter in methodInfo.GetParameters())
|
|
{
|
|
if ((typeof(ExternalDataEventArgs).IsAssignableFrom(formalParameter.ParameterType)))
|
|
{
|
|
if (index == 1)
|
|
isKnownSignature = true;
|
|
}
|
|
|
|
if (parameters.Contains(formalParameter.Name))
|
|
{
|
|
WorkflowParameterBinding binding = parameters[formalParameter.Name];
|
|
binding.Value = message.Args[index];
|
|
}
|
|
index++;
|
|
}
|
|
return isKnownSignature;
|
|
}
|
|
|
|
internal static void ValidateRoles(Activity activity, string identity)
|
|
{
|
|
DependencyProperty dependencyProperty = DependencyProperty.FromName("Roles", activity.GetType().BaseType);
|
|
if (dependencyProperty == null)
|
|
dependencyProperty = DependencyProperty.FromName("Roles", activity.GetType());
|
|
|
|
if (dependencyProperty == null)
|
|
return;
|
|
|
|
ActivityBind rolesBind = activity.GetBinding(dependencyProperty) as ActivityBind;
|
|
if (rolesBind == null)
|
|
return;
|
|
|
|
WorkflowRoleCollection roles = rolesBind.GetRuntimeValue(activity) as WorkflowRoleCollection;
|
|
if (roles == null)
|
|
return;
|
|
|
|
if (!roles.IncludesIdentity(identity))
|
|
throw new WorkflowAuthorizationException(activity.Name, identity);
|
|
}
|
|
}
|
|
|
|
}
|