WebServiceResponse.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / cdf / src / WF / Activities / WebServiceResponse.cs / 1305376 / WebServiceResponse.cs

                            using System; 
using System.Reflection;
using System.Drawing;
using System.Drawing.Design;
using System.Collections; 
using System.Collections.Generic;
using System.Collections.Specialized; 
using System.ComponentModel; 
using System.ComponentModel.Design;
using System.Workflow.ComponentModel; 
using System.Workflow.Runtime;
using System.Workflow.ComponentModel.Design;
using System.Workflow.ComponentModel.Compiler;
using System.Runtime.Remoting.Messaging; 
using System.Diagnostics;
using System.Workflow.Activities.Common; 
 
namespace System.Workflow.Activities
{ 
    [SRDescription(SR.WebServiceResponseActivityDescription)]
    [SRCategory(SR.Standard)]
    [ToolboxBitmap(typeof(WebServiceOutputActivity), "Resources.WebServiceOut.png")]
    [Designer(typeof(WebServiceResponseDesigner), typeof(IDesigner))] 
    [ActivityValidator(typeof(WebServiceResponseValidator))]
    [DefaultEvent("SendingOutput")] 
    public sealed class WebServiceOutputActivity : Activity, IPropertyValueProvider, IDynamicPropertyTypeProvider 
    {
        //metadata properties 
        public static readonly DependencyProperty InputActivityNameProperty = DependencyProperty.Register("InputActivityName", typeof(string), typeof(WebServiceOutputActivity), new PropertyMetadata("",DependencyPropertyOptions.Metadata));

        //instance properties
        public static readonly DependencyProperty ParameterBindingsProperty = DependencyProperty.Register("ParameterBindings", typeof(WorkflowParameterBindingCollection), typeof(WebServiceOutputActivity), new PropertyMetadata(DependencyPropertyOptions.Metadata | DependencyPropertyOptions.ReadOnly, new Attribute[] { new BrowsableAttribute(false), new DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Content) })); 

        //event 
        public static readonly DependencyProperty SendingOutputEvent = DependencyProperty.Register("SendingOutput", typeof(EventHandler), typeof(WebServiceOutputActivity)); 

        #region Constructors 

        public WebServiceOutputActivity()
        {
            // 
            base.SetReadOnlyPropertyValue(ParameterBindingsProperty, new WorkflowParameterBindingCollection(this));
        } 
 
        public WebServiceOutputActivity(string name)
            : base(name) 
        {
            //
            base.SetReadOnlyPropertyValue(ParameterBindingsProperty, new WorkflowParameterBindingCollection(this));
        } 

        #endregion 
 
        [SRCategory(SR.Activity)]
        [SRDescription(SR.ReceiveActivityNameDescription)] 
        [TypeConverter(typeof(PropertyValueProviderTypeConverter))]
        [RefreshProperties(RefreshProperties.All)]
        [MergablePropertyAttribute(false)]
        [DefaultValue("")] 
        public string InputActivityName
        { 
            get 
            {
                return base.GetValue(InputActivityNameProperty) as string; 
            }

            set
            { 
                base.SetValue(InputActivityNameProperty, value);
            } 
        } 

        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] 
        [Browsable(false)]
        public WorkflowParameterBindingCollection ParameterBindings
        {
            get 
            {
                return base.GetValue(ParameterBindingsProperty) as WorkflowParameterBindingCollection; 
            } 
        }
 
        [SRDescription(SR.OnBeforeResponseDescr)]
        [SRCategory(SR.Handlers)]
        [MergableProperty(false)]
        public event EventHandler SendingOutput 
        {
            add 
            { 
                base.AddHandler(SendingOutputEvent, value);
            } 
            remove
            {
                base.RemoveHandler(SendingOutputEvent, value);
            } 
        }
 
 
        ICollection IPropertyValueProvider.GetPropertyValues(ITypeDescriptorContext context)
        { 
            StringCollection names = new StringCollection();
            if (context.PropertyDescriptor.Name == "InputActivityName")
            {
                foreach (Activity activity in WebServiceActivityHelpers.GetPreceedingActivities(this)) 
                {
                    if (activity is WebServiceInputActivity) 
                    { 
                        names.Add(activity.QualifiedName);
                    } 
                }
            }
            return names;
        } 
        protected override void Initialize(IServiceProvider provider)
        { 
            if (this.Parent == null) 
                throw new InvalidOperationException(SR.GetString(SR.Error_MustHaveParent));
 
            base.Initialize(provider);
        }

        #region Execute 
        protected override ActivityExecutionStatus Execute(ActivityExecutionContext executionContext)
        { 
            if (executionContext == null) 
                throw new ArgumentNullException("executionContext");
 
            WorkflowQueuingService queueService = executionContext.GetService();

            // fire event
            this.RaiseEvent(WebServiceOutputActivity.SendingOutputEvent, this, EventArgs.Empty); 

            WebServiceInputActivity webservicereceive = this.GetActivityByName(this.InputActivityName) as WebServiceInputActivity; 
            if (webservicereceive == null) 
            {
                Activity parent = this.Parent; 
                while (parent != null)
                {
                    //typically if defined inside a custom activity
                    string qualifiedName = parent.QualifiedName + "." + this.InputActivityName; 
                    webservicereceive = this.GetActivityByName(qualifiedName) as WebServiceInputActivity;
                    if (webservicereceive != null) 
                        break; 
                    parent = this.Parent;
                } 
            }
            if (webservicereceive == null)
                throw new InvalidOperationException(SR.GetString(SR.Error_CannotResolveWebServiceInput, this.QualifiedName, this.InputActivityName));
 
            IComparable queueId = new EventQueueName(webservicereceive.InterfaceType, webservicereceive.MethodName, webservicereceive.QualifiedName);
 
            MethodInfo mInfo = webservicereceive.InterfaceType.GetMethod(webservicereceive.MethodName); 
            if (!queueService.Exists(queueId))
            { 
                // determine if no response is required,
                // compiler did not catch it, do the runtime check and return
                if (mInfo.ReturnType == typeof(void))
                { 
                    return ActivityExecutionStatus.Closed;
                } 
 
                bool isresponseRequired = false;
                foreach (ParameterInfo formalParameter in mInfo.GetParameters()) 
                {
                    if (formalParameter.ParameterType.IsByRef || (formalParameter.IsIn && formalParameter.IsOut))
                    {
                        isresponseRequired = true; 
                    }
                } 
 
                if (isresponseRequired)
                { 
                    return ActivityExecutionStatus.Closed;
                }
            }
 
            if (!queueService.Exists(queueId))
                throw new InvalidOperationException(SR.GetString(SR.Error_WebServiceInputNotProcessed, webservicereceive.QualifiedName)); 
 
            IMethodResponseMessage responseMessage = null;
            WorkflowQueue queue = queueService.GetWorkflowQueue(queueId); 

            if (queue.Count != 0)
                responseMessage = queue.Dequeue() as IMethodResponseMessage;
 
            IMethodMessage message = responseMessage as IMethodMessage;
 
            WorkflowParameterBindingCollection parameterBindings = this.ParameterBindings; 
            ArrayList outArgs = new ArrayList();
            // populate result 
            if (this.ParameterBindings.Contains("(ReturnValue)"))
            {
                WorkflowParameterBinding retBind = this.ParameterBindings["(ReturnValue)"];
                if (retBind != null) 
                {
                    outArgs.Add(retBind.Value); 
                } 
            }
 
            foreach (ParameterInfo formalParameter in mInfo.GetParameters())
            {
                // update out and byref values
                if (formalParameter.ParameterType.IsByRef || (formalParameter.IsIn && formalParameter.IsOut)) 
                {
                    WorkflowParameterBinding binding = parameterBindings[formalParameter.Name]; 
                    outArgs.Add(binding.Value); 
                }
            } 

            // reset the waiting thread
            responseMessage.SendResponse(outArgs);
 
            return ActivityExecutionStatus.Closed;
        } 
        #endregion 

 

        #region IDynamicPropertyTypeProvider

        Type IDynamicPropertyTypeProvider.GetPropertyType(IServiceProvider serviceProvider, string propertyName) 
        {
            if (propertyName == null) 
                throw new ArgumentNullException("propertyName"); 

            Dictionary parameters = new Dictionary(); 
            this.GetParameterPropertyDescriptors(parameters);
            if (parameters.ContainsKey(propertyName))
            {
                ParameterInfoBasedPropertyDescriptor descriptor = parameters[propertyName] as ParameterInfoBasedPropertyDescriptor; 
                if (descriptor != null)
                    return descriptor.ParameterType; 
            } 

            return null; 
        }

        AccessTypes IDynamicPropertyTypeProvider.GetAccessType(IServiceProvider serviceProvider, string propertyName)
        { 
            if (propertyName == null)
                throw new ArgumentNullException("propertyName"); 
 
            return AccessTypes.Read;
        } 

        internal void GetParameterPropertyDescriptors(IDictionary properties)
        {
            if (((IComponent)this).Site == null) 
                return;
 
            ITypeProvider typeProvider = (ITypeProvider)((IComponent)this).Site.GetService(typeof(ITypeProvider)); 
            if (typeProvider == null)
                throw new InvalidOperationException(SR.GetString(SR.General_MissingService, typeof(ITypeProvider).FullName)); 

            if (this.InputActivityName != null && !String.IsNullOrEmpty(this.InputActivityName.Trim()))
            {
                WebServiceInputActivity webServiceReceive = Helpers.ParseActivity(Helpers.GetRootActivity(this), this.InputActivityName) as WebServiceInputActivity; 
                if (webServiceReceive != null)
                { 
                    Type type = null; 
                    if (webServiceReceive.InterfaceType != null)
                        type = typeProvider.GetType(webServiceReceive.InterfaceType.AssemblyQualifiedName); 

                    if (type != null)
                    {
 
                        MethodInfo method = Helpers.GetInterfaceMethod(type, webServiceReceive.MethodName);
                        if (method != null && WebServiceActivityHelpers.ValidateParameterTypes(method).Count == 0) 
                        { 
                            List inputParameters, outParameters;
                            WebServiceActivityHelpers.GetParameterInfo(method, out inputParameters, out outParameters); 

                            foreach (ParameterInfo paramInfo in outParameters)
                            {
                                PropertyDescriptor prop = null; 
                                if (paramInfo.Position == -1)
                                    prop = new ParameterInfoBasedPropertyDescriptor(typeof(WebServiceOutputActivity), paramInfo, false, DesignOnlyAttribute.Yes); 
                                else 
                                    prop = new ParameterInfoBasedPropertyDescriptor(typeof(WebServiceOutputActivity), paramInfo, true, DesignOnlyAttribute.Yes);
 
                                if (prop != null)
                                    properties[prop.Name] = prop;
                            }
                        } 
                    }
                } 
            } 
        }
        #endregion 

    }

    internal sealed class WebServiceResponseValidator : ActivityValidator 
    {
        public override ValidationErrorCollection Validate(ValidationManager manager, object obj) 
        { 
            ValidationErrorCollection validationErrors = base.Validate(manager, obj);
 
            WebServiceOutputActivity webServiceResponse = obj as WebServiceOutputActivity;
            if (webServiceResponse == null)
                throw new ArgumentException(SR.GetString(SR.Error_UnexpectedArgumentType, typeof(WebServiceOutputActivity).FullName), "obj");
 
            if (Helpers.IsActivityLocked(webServiceResponse))
            { 
                return validationErrors; 
            }
 
            WebServiceInputActivity webServiceReceive = null;

            if (String.IsNullOrEmpty(webServiceResponse.InputActivityName))
                validationErrors.Add(ValidationError.GetNotSetValidationError("InputActivityName")); 
            else
            { 
                ITypeProvider typeProvider = (ITypeProvider)manager.GetService(typeof(ITypeProvider)); 
                if (typeProvider == null)
                    throw new InvalidOperationException(SR.GetString(SR.General_MissingService, typeof(ITypeProvider).FullName)); 

                bool foundMatchingReceive = false;
                foreach (Activity activity in WebServiceActivityHelpers.GetPreceedingActivities(webServiceResponse))
                { 
                    if ((activity is WebServiceOutputActivity && String.Compare(((WebServiceOutputActivity)activity).InputActivityName, webServiceResponse.InputActivityName, StringComparison.Ordinal) == 0) ||
                        (activity is WebServiceFaultActivity && String.Compare(((WebServiceFaultActivity)activity).InputActivityName, webServiceResponse.InputActivityName, StringComparison.Ordinal) == 0)) 
                    { 
                        if (activity is WebServiceOutputActivity)
                            validationErrors.Add(new ValidationError(SR.GetString(SR.Error_DuplicateWebServiceResponseFound, activity.QualifiedName, webServiceResponse.InputActivityName), ErrorNumbers.Error_DuplicateWebServiceResponseFound)); 
                        else
                            validationErrors.Add(new ValidationError(SR.GetString(SR.Error_DuplicateWebServiceFaultFound, activity.QualifiedName, webServiceResponse.InputActivityName), ErrorNumbers.Error_DuplicateWebServiceFaultFound));
                        return validationErrors;
                    } 
                }
 
                foreach (Activity activity in WebServiceActivityHelpers.GetPreceedingActivities(webServiceResponse)) 
                {
                    if (String.Compare(activity.QualifiedName, webServiceResponse.InputActivityName, StringComparison.Ordinal) == 0) 
                    {
                        if (activity is WebServiceInputActivity)
                        {
                            webServiceReceive = activity as WebServiceInputActivity; 
                            foundMatchingReceive = true;
                        } 
                        else 
                        {
                            foundMatchingReceive = false; 
                            validationErrors.Add(new ValidationError(SR.GetString(SR.Error_WebServiceReceiveNotValid, webServiceResponse.InputActivityName), ErrorNumbers.Error_WebServiceReceiveNotValid));
                            return validationErrors;
                        }
                        break; 
                    }
                } 
 
                if (!foundMatchingReceive)
                { 
                    validationErrors.Add(new ValidationError(SR.GetString(SR.Error_WebServiceReceiveNotFound, webServiceResponse.InputActivityName), ErrorNumbers.Error_WebServiceReceiveNotFound));
                    return validationErrors;
                }
                else 
                {
                    Type interfaceType = null; 
                    if (webServiceReceive.InterfaceType != null) 
                        interfaceType = typeProvider.GetType(webServiceReceive.InterfaceType.AssemblyQualifiedName);
 
                    if (interfaceType == null)
                    {
                        validationErrors.Add(new ValidationError(SR.GetString(SR.Error_WebServiceReceiveNotConfigured, webServiceReceive.Name), ErrorNumbers.Error_WebServiceReceiveNotConfigured));
                    } 
                    else
                    { 
                        // Validate method 
                        if (String.IsNullOrEmpty(webServiceReceive.MethodName))
                            validationErrors.Add(new ValidationError(SR.GetString(SR.Error_WebServiceReceiveNotConfigured, webServiceReceive.Name), ErrorNumbers.Error_WebServiceReceiveNotConfigured)); 
                        else
                        {
                            MethodInfo methodInfo = Helpers.GetInterfaceMethod(interfaceType, webServiceReceive.MethodName);
 
                            if (methodInfo == null)
                            { 
                                validationErrors.Add(new ValidationError(SR.GetString(SR.Error_WebServiceReceiveNotConfigured, webServiceReceive.Name), ErrorNumbers.Error_WebServiceReceiveNotConfigured)); 
                            }
                            else 
                            {
                                ValidationErrorCollection parameterTypeErrors = WebServiceActivityHelpers.ValidateParameterTypes(methodInfo);
                                if (parameterTypeErrors.Count > 0)
                                { 
                                    foreach (ValidationError parameterTypeError in parameterTypeErrors)
                                    { 
                                        parameterTypeError.PropertyName = "InputActivityName"; 
                                    }
                                    validationErrors.AddRange(parameterTypeErrors); 
                                }
                                else
                                {
                                    List inputParameters, outParameters; 
                                    WebServiceActivityHelpers.GetParameterInfo(methodInfo, out inputParameters, out outParameters);
 
                                    if (outParameters.Count == 0) 
                                    {
                                        validationErrors.Add(new ValidationError(SR.GetString(SR.Error_WebServiceResponseNotNeeded), ErrorNumbers.Error_WebServiceResponseNotNeeded)); 
                                    }
                                    else
                                    {
                                        // Check to see if all output parameters have a valid bindings. 
                                        foreach (ParameterInfo paramInfo in outParameters)
                                        { 
                                            string paramName = paramInfo.Name; 
                                            Type paramType = paramInfo.ParameterType.IsByRef ? paramInfo.ParameterType.GetElementType() : paramInfo.ParameterType;
 
                                            if (paramInfo.Position == -1)
                                                paramName = "(ReturnValue)";

                                            object paramValue = null; 
                                            if (webServiceResponse.ParameterBindings.Contains(paramName))
                                            { 
                                                if (webServiceResponse.ParameterBindings[paramName].IsBindingSet(WorkflowParameterBinding.ValueProperty)) 
                                                    paramValue = webServiceResponse.ParameterBindings[paramName].GetBinding(WorkflowParameterBinding.ValueProperty);
                                                else 
                                                    paramValue = webServiceResponse.ParameterBindings[paramName].GetValue(WorkflowParameterBinding.ValueProperty);
                                            }

                                            if (!paramType.IsPublic || !paramType.IsSerializable) 
                                            {
                                                ValidationError validationError = new ValidationError(SR.GetString(SR.Error_TypeNotPublicSerializable, paramName, paramType.FullName), ErrorNumbers.Error_TypeNotPublicSerializable); 
                                                validationError.PropertyName = (String.Compare(paramName, "(ReturnValue)", StringComparison.Ordinal) == 0) ? paramName : ParameterInfoBasedPropertyDescriptor.GetParameterPropertyName(webServiceReceive.GetType(), paramName); 
                                                validationErrors.Add(validationError);
                                            } 
                                            else if (!webServiceResponse.ParameterBindings.Contains(paramName) || paramValue == null)
                                            {
                                                ValidationError validationError = ValidationError.GetNotSetValidationError(paramName);
                                                validationError.PropertyName = (String.Compare(paramName, "(ReturnValue)", StringComparison.Ordinal) == 0) ? paramName : ParameterInfoBasedPropertyDescriptor.GetParameterPropertyName(webServiceReceive.GetType(), paramName); 
                                                validationErrors.Add(validationError);
                                            } 
                                            else 
                                            {
                                                AccessTypes access = AccessTypes.Read; 
                                                if (paramInfo.IsOut || paramInfo.IsRetval || paramInfo.Position == -1)
                                                    access = AccessTypes.Write;

                                                ValidationErrorCollection variableErrors = ValidationHelpers.ValidateProperty(manager, webServiceResponse, paramValue, 
                                                                                                new PropertyValidationContext(webServiceResponse.ParameterBindings[paramName], null, paramName), new BindValidationContext(paramInfo.ParameterType.IsByRef ? paramInfo.ParameterType.GetElementType() : paramInfo.ParameterType, access));
                                                foreach (ValidationError variableError in variableErrors) 
                                                { 
                                                    if (String.Compare(paramName, "(ReturnValue)", StringComparison.Ordinal) != 0)
                                                        variableError.PropertyName = ParameterInfoBasedPropertyDescriptor.GetParameterPropertyName(webServiceReceive.GetType(), paramName); 
                                                }
                                                validationErrors.AddRange(variableErrors);
                                            }
                                        } 

                                        if(webServiceResponse.ParameterBindings.Count > outParameters.Count) 
                                            validationErrors.Add(new ValidationError(SR.GetString(SR.Warning_AdditionalBindingsFound), ErrorNumbers.Warning_AdditionalBindingsFound, true)); 
                                    }
                                } 
                            }
                        }
                    }
                } 
            }
            return validationErrors; 
        } 
    }
 
    internal static class WebServiceActivityHelpers
    {
        private static IEnumerable GetContainedActivities(CompositeActivity activity)
        { 
            if (!activity.Enabled)
                yield break; 
 
            foreach (Activity containedActivity in activity.Activities)
            { 
                if (containedActivity is CompositeActivity && !Helpers.IsCustomActivity((CompositeActivity)containedActivity))
                {
                    foreach (Activity nestedActivity in WebServiceActivityHelpers.GetContainedActivities((CompositeActivity)containedActivity))
                    { 
                        if (nestedActivity.Enabled)
                            yield return nestedActivity; 
                    } 
                }
                else 
                {
                    if (containedActivity.Enabled)
                        yield return containedActivity;
                } 
            }
            yield break; 
        } 

        internal static IEnumerable GetPreceedingActivities(Activity startActivity) 
        {
            return GetPreceedingActivities(startActivity, false);
        }
 
        internal static IEnumerable GetPreceedingActivities(Activity startActivity, bool crossOverLoop)
        { 
            Activity currentActivity = null; 
            Stack activityStack = new Stack();
            activityStack.Push(startActivity); 

            while ((currentActivity = activityStack.Pop()) != null)
            {
                if (currentActivity is CompositeActivity && Helpers.IsCustomActivity((CompositeActivity)currentActivity)) 
                    break;
 
                if (currentActivity.Parent != null) 
                {
                    foreach (Activity siblingActivity in currentActivity.Parent.Activities) 
                    {
                        //
                        if (siblingActivity == currentActivity && ((currentActivity.Parent is ParallelActivity && !Helpers.IsFrameworkActivity(currentActivity)) || (currentActivity.Parent is StateActivity && !Helpers.IsFrameworkActivity(currentActivity))))
                            continue; 

                        // 
                        if (currentActivity.Parent is IfElseActivity  && !Helpers.IsFrameworkActivity(currentActivity)) 
                            continue;
 
                        //For Listen Case.
                        if (currentActivity.Parent is ListenActivity && !Helpers.IsFrameworkActivity(currentActivity))
                            continue;
 
                        // State Machine logic:
                        // If startActivity was in the InitialState, then 
                        // there are no preceeding activities. 
                        // Otherwise, we just return the parent state as
                        // the preceeding activity. 
                        StateActivity currentState = currentActivity.Parent as StateActivity;
                        if (currentState != null)
                        {
                            StateActivity enclosingState = StateMachineHelpers.FindEnclosingState(startActivity); 
                            //If we are at Initial State there is no preceeding above us.
                            if (StateMachineHelpers.IsInitialState(enclosingState)) 
                                yield break; 
                            else
                                yield return currentState; 
                        }

                        if (siblingActivity == currentActivity)
                            break; 

                        if (siblingActivity.Enabled) 
                        { 
                            if (siblingActivity is CompositeActivity && !Helpers.IsCustomActivity((CompositeActivity)siblingActivity) && (crossOverLoop || !IsLoopActivity(siblingActivity)))
                            { 
                                foreach (Activity containedActivity in WebServiceActivityHelpers.GetContainedActivities((CompositeActivity)siblingActivity))
                                    yield return containedActivity;
                            }
                            else 
                            {
                                yield return siblingActivity; 
                            } 
                        }
                    } 
                }

                if (!crossOverLoop && IsLoopActivity(currentActivity.Parent))
                    break; 
                else
                    activityStack.Push(currentActivity.Parent); 
 
            }
            yield break; 
        }

        internal static bool IsLoopActivity(Activity activity)
        { 
            //
            if (activity is WhileActivity || activity is ReplicatorActivity || activity is ConditionedActivityGroup) 
                return true; 

            return false; 
        }

        internal static bool IsInsideLoop(Activity webServiceActivity, Activity searchBoundary)
        { 
            IEnumerable searchBoundaryPath = GetActivityPath(searchBoundary);
            IEnumerable currentActivityPath = GetActivityPath(webServiceActivity); 
 
            String leastCommonParent = FindLeastCommonParent(searchBoundaryPath, currentActivityPath);
 
            Activity currentActivity = webServiceActivity;

            while (currentActivity.Parent != null && currentActivity.Parent.QualifiedName != leastCommonParent)
            { 
                if (IsLoopActivity(currentActivity))
                    return true; 
 
                currentActivity = currentActivity.Parent;
            } 

            return false;
        }
 
        static IEnumerable GetActivityPath(Activity activity)
        { 
            if(activity != null) 
            {
                foreach(String path in GetActivityPath(activity.Parent)) 
                    yield return path;

                yield return activity.QualifiedName;
            } 
        }
 
        static String FindLeastCommonParent(IEnumerable source, IEnumerable dest) 
        {
            IEnumerator srcEnum = source.GetEnumerator(); 
            IEnumerator destEnum = dest.GetEnumerator();

            String leastCommonParent = null;
 
            while (srcEnum.MoveNext() && destEnum.MoveNext())
            { 
                if (srcEnum.Current.Equals(destEnum.Current)) 
                    leastCommonParent = (String)srcEnum.Current;
                else 
                    return leastCommonParent;
            }

            return leastCommonParent; 
        }
 
        internal static IEnumerable GetSucceedingActivities(Activity startActivity) 
        {
            Activity currentActivity = null; 
            Stack activityStack = new Stack();
            activityStack.Push(startActivity);

            while ((currentActivity = activityStack.Pop()) != null) 
            {
                if (currentActivity is CompositeActivity && Helpers.IsCustomActivity((CompositeActivity)currentActivity)) 
                    break; 

                if (currentActivity.Parent != null) 
                {
                    bool pastCurrentActivity = false;

                    foreach (Activity siblingActivity in currentActivity.Parent.Activities) 
                    {
                        if (siblingActivity == currentActivity) 
                        { 
                            pastCurrentActivity = true;
                            continue; 
                        }

                        if (!pastCurrentActivity)
                            continue; 

                        if (siblingActivity.Enabled) 
                        { 
                            if (siblingActivity is CompositeActivity && !Helpers.IsCustomActivity((CompositeActivity)siblingActivity))
                            { 
                                foreach (Activity containedActivity in WebServiceActivityHelpers.GetContainedActivities((CompositeActivity)siblingActivity))
                                    yield return containedActivity;
                            }
                            else 
                            {
                                yield return siblingActivity; 
                            } 
                        }
                    } 
                }
                activityStack.Push(currentActivity.Parent);
            }
            yield break; 
        }
 
        internal static void GetParameterInfo(MethodInfo methodInfo, out List inParameters, out List outParameters) 
        {
            inParameters = new List(); outParameters = new List(); 
            foreach (ParameterInfo paramInfo in methodInfo.GetParameters())
            {
                if (paramInfo.IsOut || paramInfo.IsRetval || paramInfo.ParameterType.IsByRef)
                    outParameters.Add(paramInfo); 

                if (!paramInfo.IsOut && !paramInfo.IsRetval) 
                    inParameters.Add(paramInfo); 
            }
 
            if (methodInfo.ReturnType != typeof(void))
                outParameters.Add(methodInfo.ReturnParameter);

            return; 
        }
 
        internal static ValidationErrorCollection ValidateParameterTypes(MethodInfo methodInfo) 
        {
            ValidationErrorCollection validationErrors = new ValidationErrorCollection(); 
            if (methodInfo == null)
                return validationErrors;
            foreach (ParameterInfo paramInfo in methodInfo.GetParameters())
            { 
                if (paramInfo.ParameterType == null)
                { 
                    validationErrors.Add(new ValidationError(SR.GetString(SR.Error_ParameterTypeNotFound, methodInfo.Name, paramInfo.Name), ErrorNumbers.Error_ParameterTypeNotFound)); 
                }
            } 

            if (methodInfo.ReturnType != typeof(void) && methodInfo.ReturnParameter.ParameterType == null)
            {
                validationErrors.Add(new ValidationError(SR.GetString(SR.Error_ReturnTypeNotFound, methodInfo.Name), ErrorNumbers.Error_ReturnTypeNotFound)); 
            }
 
            return validationErrors; 
        }
    } 
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
using System; 
using System.Reflection;
using System.Drawing;
using System.Drawing.Design;
using System.Collections; 
using System.Collections.Generic;
using System.Collections.Specialized; 
using System.ComponentModel; 
using System.ComponentModel.Design;
using System.Workflow.ComponentModel; 
using System.Workflow.Runtime;
using System.Workflow.ComponentModel.Design;
using System.Workflow.ComponentModel.Compiler;
using System.Runtime.Remoting.Messaging; 
using System.Diagnostics;
using System.Workflow.Activities.Common; 
 
namespace System.Workflow.Activities
{ 
    [SRDescription(SR.WebServiceResponseActivityDescription)]
    [SRCategory(SR.Standard)]
    [ToolboxBitmap(typeof(WebServiceOutputActivity), "Resources.WebServiceOut.png")]
    [Designer(typeof(WebServiceResponseDesigner), typeof(IDesigner))] 
    [ActivityValidator(typeof(WebServiceResponseValidator))]
    [DefaultEvent("SendingOutput")] 
    public sealed class WebServiceOutputActivity : Activity, IPropertyValueProvider, IDynamicPropertyTypeProvider 
    {
        //metadata properties 
        public static readonly DependencyProperty InputActivityNameProperty = DependencyProperty.Register("InputActivityName", typeof(string), typeof(WebServiceOutputActivity), new PropertyMetadata("",DependencyPropertyOptions.Metadata));

        //instance properties
        public static readonly DependencyProperty ParameterBindingsProperty = DependencyProperty.Register("ParameterBindings", typeof(WorkflowParameterBindingCollection), typeof(WebServiceOutputActivity), new PropertyMetadata(DependencyPropertyOptions.Metadata | DependencyPropertyOptions.ReadOnly, new Attribute[] { new BrowsableAttribute(false), new DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Content) })); 

        //event 
        public static readonly DependencyProperty SendingOutputEvent = DependencyProperty.Register("SendingOutput", typeof(EventHandler), typeof(WebServiceOutputActivity)); 

        #region Constructors 

        public WebServiceOutputActivity()
        {
            // 
            base.SetReadOnlyPropertyValue(ParameterBindingsProperty, new WorkflowParameterBindingCollection(this));
        } 
 
        public WebServiceOutputActivity(string name)
            : base(name) 
        {
            //
            base.SetReadOnlyPropertyValue(ParameterBindingsProperty, new WorkflowParameterBindingCollection(this));
        } 

        #endregion 
 
        [SRCategory(SR.Activity)]
        [SRDescription(SR.ReceiveActivityNameDescription)] 
        [TypeConverter(typeof(PropertyValueProviderTypeConverter))]
        [RefreshProperties(RefreshProperties.All)]
        [MergablePropertyAttribute(false)]
        [DefaultValue("")] 
        public string InputActivityName
        { 
            get 
            {
                return base.GetValue(InputActivityNameProperty) as string; 
            }

            set
            { 
                base.SetValue(InputActivityNameProperty, value);
            } 
        } 

        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] 
        [Browsable(false)]
        public WorkflowParameterBindingCollection ParameterBindings
        {
            get 
            {
                return base.GetValue(ParameterBindingsProperty) as WorkflowParameterBindingCollection; 
            } 
        }
 
        [SRDescription(SR.OnBeforeResponseDescr)]
        [SRCategory(SR.Handlers)]
        [MergableProperty(false)]
        public event EventHandler SendingOutput 
        {
            add 
            { 
                base.AddHandler(SendingOutputEvent, value);
            } 
            remove
            {
                base.RemoveHandler(SendingOutputEvent, value);
            } 
        }
 
 
        ICollection IPropertyValueProvider.GetPropertyValues(ITypeDescriptorContext context)
        { 
            StringCollection names = new StringCollection();
            if (context.PropertyDescriptor.Name == "InputActivityName")
            {
                foreach (Activity activity in WebServiceActivityHelpers.GetPreceedingActivities(this)) 
                {
                    if (activity is WebServiceInputActivity) 
                    { 
                        names.Add(activity.QualifiedName);
                    } 
                }
            }
            return names;
        } 
        protected override void Initialize(IServiceProvider provider)
        { 
            if (this.Parent == null) 
                throw new InvalidOperationException(SR.GetString(SR.Error_MustHaveParent));
 
            base.Initialize(provider);
        }

        #region Execute 
        protected override ActivityExecutionStatus Execute(ActivityExecutionContext executionContext)
        { 
            if (executionContext == null) 
                throw new ArgumentNullException("executionContext");
 
            WorkflowQueuingService queueService = executionContext.GetService();

            // fire event
            this.RaiseEvent(WebServiceOutputActivity.SendingOutputEvent, this, EventArgs.Empty); 

            WebServiceInputActivity webservicereceive = this.GetActivityByName(this.InputActivityName) as WebServiceInputActivity; 
            if (webservicereceive == null) 
            {
                Activity parent = this.Parent; 
                while (parent != null)
                {
                    //typically if defined inside a custom activity
                    string qualifiedName = parent.QualifiedName + "." + this.InputActivityName; 
                    webservicereceive = this.GetActivityByName(qualifiedName) as WebServiceInputActivity;
                    if (webservicereceive != null) 
                        break; 
                    parent = this.Parent;
                } 
            }
            if (webservicereceive == null)
                throw new InvalidOperationException(SR.GetString(SR.Error_CannotResolveWebServiceInput, this.QualifiedName, this.InputActivityName));
 
            IComparable queueId = new EventQueueName(webservicereceive.InterfaceType, webservicereceive.MethodName, webservicereceive.QualifiedName);
 
            MethodInfo mInfo = webservicereceive.InterfaceType.GetMethod(webservicereceive.MethodName); 
            if (!queueService.Exists(queueId))
            { 
                // determine if no response is required,
                // compiler did not catch it, do the runtime check and return
                if (mInfo.ReturnType == typeof(void))
                { 
                    return ActivityExecutionStatus.Closed;
                } 
 
                bool isresponseRequired = false;
                foreach (ParameterInfo formalParameter in mInfo.GetParameters()) 
                {
                    if (formalParameter.ParameterType.IsByRef || (formalParameter.IsIn && formalParameter.IsOut))
                    {
                        isresponseRequired = true; 
                    }
                } 
 
                if (isresponseRequired)
                { 
                    return ActivityExecutionStatus.Closed;
                }
            }
 
            if (!queueService.Exists(queueId))
                throw new InvalidOperationException(SR.GetString(SR.Error_WebServiceInputNotProcessed, webservicereceive.QualifiedName)); 
 
            IMethodResponseMessage responseMessage = null;
            WorkflowQueue queue = queueService.GetWorkflowQueue(queueId); 

            if (queue.Count != 0)
                responseMessage = queue.Dequeue() as IMethodResponseMessage;
 
            IMethodMessage message = responseMessage as IMethodMessage;
 
            WorkflowParameterBindingCollection parameterBindings = this.ParameterBindings; 
            ArrayList outArgs = new ArrayList();
            // populate result 
            if (this.ParameterBindings.Contains("(ReturnValue)"))
            {
                WorkflowParameterBinding retBind = this.ParameterBindings["(ReturnValue)"];
                if (retBind != null) 
                {
                    outArgs.Add(retBind.Value); 
                } 
            }
 
            foreach (ParameterInfo formalParameter in mInfo.GetParameters())
            {
                // update out and byref values
                if (formalParameter.ParameterType.IsByRef || (formalParameter.IsIn && formalParameter.IsOut)) 
                {
                    WorkflowParameterBinding binding = parameterBindings[formalParameter.Name]; 
                    outArgs.Add(binding.Value); 
                }
            } 

            // reset the waiting thread
            responseMessage.SendResponse(outArgs);
 
            return ActivityExecutionStatus.Closed;
        } 
        #endregion 

 

        #region IDynamicPropertyTypeProvider

        Type IDynamicPropertyTypeProvider.GetPropertyType(IServiceProvider serviceProvider, string propertyName) 
        {
            if (propertyName == null) 
                throw new ArgumentNullException("propertyName"); 

            Dictionary parameters = new Dictionary(); 
            this.GetParameterPropertyDescriptors(parameters);
            if (parameters.ContainsKey(propertyName))
            {
                ParameterInfoBasedPropertyDescriptor descriptor = parameters[propertyName] as ParameterInfoBasedPropertyDescriptor; 
                if (descriptor != null)
                    return descriptor.ParameterType; 
            } 

            return null; 
        }

        AccessTypes IDynamicPropertyTypeProvider.GetAccessType(IServiceProvider serviceProvider, string propertyName)
        { 
            if (propertyName == null)
                throw new ArgumentNullException("propertyName"); 
 
            return AccessTypes.Read;
        } 

        internal void GetParameterPropertyDescriptors(IDictionary properties)
        {
            if (((IComponent)this).Site == null) 
                return;
 
            ITypeProvider typeProvider = (ITypeProvider)((IComponent)this).Site.GetService(typeof(ITypeProvider)); 
            if (typeProvider == null)
                throw new InvalidOperationException(SR.GetString(SR.General_MissingService, typeof(ITypeProvider).FullName)); 

            if (this.InputActivityName != null && !String.IsNullOrEmpty(this.InputActivityName.Trim()))
            {
                WebServiceInputActivity webServiceReceive = Helpers.ParseActivity(Helpers.GetRootActivity(this), this.InputActivityName) as WebServiceInputActivity; 
                if (webServiceReceive != null)
                { 
                    Type type = null; 
                    if (webServiceReceive.InterfaceType != null)
                        type = typeProvider.GetType(webServiceReceive.InterfaceType.AssemblyQualifiedName); 

                    if (type != null)
                    {
 
                        MethodInfo method = Helpers.GetInterfaceMethod(type, webServiceReceive.MethodName);
                        if (method != null && WebServiceActivityHelpers.ValidateParameterTypes(method).Count == 0) 
                        { 
                            List inputParameters, outParameters;
                            WebServiceActivityHelpers.GetParameterInfo(method, out inputParameters, out outParameters); 

                            foreach (ParameterInfo paramInfo in outParameters)
                            {
                                PropertyDescriptor prop = null; 
                                if (paramInfo.Position == -1)
                                    prop = new ParameterInfoBasedPropertyDescriptor(typeof(WebServiceOutputActivity), paramInfo, false, DesignOnlyAttribute.Yes); 
                                else 
                                    prop = new ParameterInfoBasedPropertyDescriptor(typeof(WebServiceOutputActivity), paramInfo, true, DesignOnlyAttribute.Yes);
 
                                if (prop != null)
                                    properties[prop.Name] = prop;
                            }
                        } 
                    }
                } 
            } 
        }
        #endregion 

    }

    internal sealed class WebServiceResponseValidator : ActivityValidator 
    {
        public override ValidationErrorCollection Validate(ValidationManager manager, object obj) 
        { 
            ValidationErrorCollection validationErrors = base.Validate(manager, obj);
 
            WebServiceOutputActivity webServiceResponse = obj as WebServiceOutputActivity;
            if (webServiceResponse == null)
                throw new ArgumentException(SR.GetString(SR.Error_UnexpectedArgumentType, typeof(WebServiceOutputActivity).FullName), "obj");
 
            if (Helpers.IsActivityLocked(webServiceResponse))
            { 
                return validationErrors; 
            }
 
            WebServiceInputActivity webServiceReceive = null;

            if (String.IsNullOrEmpty(webServiceResponse.InputActivityName))
                validationErrors.Add(ValidationError.GetNotSetValidationError("InputActivityName")); 
            else
            { 
                ITypeProvider typeProvider = (ITypeProvider)manager.GetService(typeof(ITypeProvider)); 
                if (typeProvider == null)
                    throw new InvalidOperationException(SR.GetString(SR.General_MissingService, typeof(ITypeProvider).FullName)); 

                bool foundMatchingReceive = false;
                foreach (Activity activity in WebServiceActivityHelpers.GetPreceedingActivities(webServiceResponse))
                { 
                    if ((activity is WebServiceOutputActivity && String.Compare(((WebServiceOutputActivity)activity).InputActivityName, webServiceResponse.InputActivityName, StringComparison.Ordinal) == 0) ||
                        (activity is WebServiceFaultActivity && String.Compare(((WebServiceFaultActivity)activity).InputActivityName, webServiceResponse.InputActivityName, StringComparison.Ordinal) == 0)) 
                    { 
                        if (activity is WebServiceOutputActivity)
                            validationErrors.Add(new ValidationError(SR.GetString(SR.Error_DuplicateWebServiceResponseFound, activity.QualifiedName, webServiceResponse.InputActivityName), ErrorNumbers.Error_DuplicateWebServiceResponseFound)); 
                        else
                            validationErrors.Add(new ValidationError(SR.GetString(SR.Error_DuplicateWebServiceFaultFound, activity.QualifiedName, webServiceResponse.InputActivityName), ErrorNumbers.Error_DuplicateWebServiceFaultFound));
                        return validationErrors;
                    } 
                }
 
                foreach (Activity activity in WebServiceActivityHelpers.GetPreceedingActivities(webServiceResponse)) 
                {
                    if (String.Compare(activity.QualifiedName, webServiceResponse.InputActivityName, StringComparison.Ordinal) == 0) 
                    {
                        if (activity is WebServiceInputActivity)
                        {
                            webServiceReceive = activity as WebServiceInputActivity; 
                            foundMatchingReceive = true;
                        } 
                        else 
                        {
                            foundMatchingReceive = false; 
                            validationErrors.Add(new ValidationError(SR.GetString(SR.Error_WebServiceReceiveNotValid, webServiceResponse.InputActivityName), ErrorNumbers.Error_WebServiceReceiveNotValid));
                            return validationErrors;
                        }
                        break; 
                    }
                } 
 
                if (!foundMatchingReceive)
                { 
                    validationErrors.Add(new ValidationError(SR.GetString(SR.Error_WebServiceReceiveNotFound, webServiceResponse.InputActivityName), ErrorNumbers.Error_WebServiceReceiveNotFound));
                    return validationErrors;
                }
                else 
                {
                    Type interfaceType = null; 
                    if (webServiceReceive.InterfaceType != null) 
                        interfaceType = typeProvider.GetType(webServiceReceive.InterfaceType.AssemblyQualifiedName);
 
                    if (interfaceType == null)
                    {
                        validationErrors.Add(new ValidationError(SR.GetString(SR.Error_WebServiceReceiveNotConfigured, webServiceReceive.Name), ErrorNumbers.Error_WebServiceReceiveNotConfigured));
                    } 
                    else
                    { 
                        // Validate method 
                        if (String.IsNullOrEmpty(webServiceReceive.MethodName))
                            validationErrors.Add(new ValidationError(SR.GetString(SR.Error_WebServiceReceiveNotConfigured, webServiceReceive.Name), ErrorNumbers.Error_WebServiceReceiveNotConfigured)); 
                        else
                        {
                            MethodInfo methodInfo = Helpers.GetInterfaceMethod(interfaceType, webServiceReceive.MethodName);
 
                            if (methodInfo == null)
                            { 
                                validationErrors.Add(new ValidationError(SR.GetString(SR.Error_WebServiceReceiveNotConfigured, webServiceReceive.Name), ErrorNumbers.Error_WebServiceReceiveNotConfigured)); 
                            }
                            else 
                            {
                                ValidationErrorCollection parameterTypeErrors = WebServiceActivityHelpers.ValidateParameterTypes(methodInfo);
                                if (parameterTypeErrors.Count > 0)
                                { 
                                    foreach (ValidationError parameterTypeError in parameterTypeErrors)
                                    { 
                                        parameterTypeError.PropertyName = "InputActivityName"; 
                                    }
                                    validationErrors.AddRange(parameterTypeErrors); 
                                }
                                else
                                {
                                    List inputParameters, outParameters; 
                                    WebServiceActivityHelpers.GetParameterInfo(methodInfo, out inputParameters, out outParameters);
 
                                    if (outParameters.Count == 0) 
                                    {
                                        validationErrors.Add(new ValidationError(SR.GetString(SR.Error_WebServiceResponseNotNeeded), ErrorNumbers.Error_WebServiceResponseNotNeeded)); 
                                    }
                                    else
                                    {
                                        // Check to see if all output parameters have a valid bindings. 
                                        foreach (ParameterInfo paramInfo in outParameters)
                                        { 
                                            string paramName = paramInfo.Name; 
                                            Type paramType = paramInfo.ParameterType.IsByRef ? paramInfo.ParameterType.GetElementType() : paramInfo.ParameterType;
 
                                            if (paramInfo.Position == -1)
                                                paramName = "(ReturnValue)";

                                            object paramValue = null; 
                                            if (webServiceResponse.ParameterBindings.Contains(paramName))
                                            { 
                                                if (webServiceResponse.ParameterBindings[paramName].IsBindingSet(WorkflowParameterBinding.ValueProperty)) 
                                                    paramValue = webServiceResponse.ParameterBindings[paramName].GetBinding(WorkflowParameterBinding.ValueProperty);
                                                else 
                                                    paramValue = webServiceResponse.ParameterBindings[paramName].GetValue(WorkflowParameterBinding.ValueProperty);
                                            }

                                            if (!paramType.IsPublic || !paramType.IsSerializable) 
                                            {
                                                ValidationError validationError = new ValidationError(SR.GetString(SR.Error_TypeNotPublicSerializable, paramName, paramType.FullName), ErrorNumbers.Error_TypeNotPublicSerializable); 
                                                validationError.PropertyName = (String.Compare(paramName, "(ReturnValue)", StringComparison.Ordinal) == 0) ? paramName : ParameterInfoBasedPropertyDescriptor.GetParameterPropertyName(webServiceReceive.GetType(), paramName); 
                                                validationErrors.Add(validationError);
                                            } 
                                            else if (!webServiceResponse.ParameterBindings.Contains(paramName) || paramValue == null)
                                            {
                                                ValidationError validationError = ValidationError.GetNotSetValidationError(paramName);
                                                validationError.PropertyName = (String.Compare(paramName, "(ReturnValue)", StringComparison.Ordinal) == 0) ? paramName : ParameterInfoBasedPropertyDescriptor.GetParameterPropertyName(webServiceReceive.GetType(), paramName); 
                                                validationErrors.Add(validationError);
                                            } 
                                            else 
                                            {
                                                AccessTypes access = AccessTypes.Read; 
                                                if (paramInfo.IsOut || paramInfo.IsRetval || paramInfo.Position == -1)
                                                    access = AccessTypes.Write;

                                                ValidationErrorCollection variableErrors = ValidationHelpers.ValidateProperty(manager, webServiceResponse, paramValue, 
                                                                                                new PropertyValidationContext(webServiceResponse.ParameterBindings[paramName], null, paramName), new BindValidationContext(paramInfo.ParameterType.IsByRef ? paramInfo.ParameterType.GetElementType() : paramInfo.ParameterType, access));
                                                foreach (ValidationError variableError in variableErrors) 
                                                { 
                                                    if (String.Compare(paramName, "(ReturnValue)", StringComparison.Ordinal) != 0)
                                                        variableError.PropertyName = ParameterInfoBasedPropertyDescriptor.GetParameterPropertyName(webServiceReceive.GetType(), paramName); 
                                                }
                                                validationErrors.AddRange(variableErrors);
                                            }
                                        } 

                                        if(webServiceResponse.ParameterBindings.Count > outParameters.Count) 
                                            validationErrors.Add(new ValidationError(SR.GetString(SR.Warning_AdditionalBindingsFound), ErrorNumbers.Warning_AdditionalBindingsFound, true)); 
                                    }
                                } 
                            }
                        }
                    }
                } 
            }
            return validationErrors; 
        } 
    }
 
    internal static class WebServiceActivityHelpers
    {
        private static IEnumerable GetContainedActivities(CompositeActivity activity)
        { 
            if (!activity.Enabled)
                yield break; 
 
            foreach (Activity containedActivity in activity.Activities)
            { 
                if (containedActivity is CompositeActivity && !Helpers.IsCustomActivity((CompositeActivity)containedActivity))
                {
                    foreach (Activity nestedActivity in WebServiceActivityHelpers.GetContainedActivities((CompositeActivity)containedActivity))
                    { 
                        if (nestedActivity.Enabled)
                            yield return nestedActivity; 
                    } 
                }
                else 
                {
                    if (containedActivity.Enabled)
                        yield return containedActivity;
                } 
            }
            yield break; 
        } 

        internal static IEnumerable GetPreceedingActivities(Activity startActivity) 
        {
            return GetPreceedingActivities(startActivity, false);
        }
 
        internal static IEnumerable GetPreceedingActivities(Activity startActivity, bool crossOverLoop)
        { 
            Activity currentActivity = null; 
            Stack activityStack = new Stack();
            activityStack.Push(startActivity); 

            while ((currentActivity = activityStack.Pop()) != null)
            {
                if (currentActivity is CompositeActivity && Helpers.IsCustomActivity((CompositeActivity)currentActivity)) 
                    break;
 
                if (currentActivity.Parent != null) 
                {
                    foreach (Activity siblingActivity in currentActivity.Parent.Activities) 
                    {
                        //
                        if (siblingActivity == currentActivity && ((currentActivity.Parent is ParallelActivity && !Helpers.IsFrameworkActivity(currentActivity)) || (currentActivity.Parent is StateActivity && !Helpers.IsFrameworkActivity(currentActivity))))
                            continue; 

                        // 
                        if (currentActivity.Parent is IfElseActivity  && !Helpers.IsFrameworkActivity(currentActivity)) 
                            continue;
 
                        //For Listen Case.
                        if (currentActivity.Parent is ListenActivity && !Helpers.IsFrameworkActivity(currentActivity))
                            continue;
 
                        // State Machine logic:
                        // If startActivity was in the InitialState, then 
                        // there are no preceeding activities. 
                        // Otherwise, we just return the parent state as
                        // the preceeding activity. 
                        StateActivity currentState = currentActivity.Parent as StateActivity;
                        if (currentState != null)
                        {
                            StateActivity enclosingState = StateMachineHelpers.FindEnclosingState(startActivity); 
                            //If we are at Initial State there is no preceeding above us.
                            if (StateMachineHelpers.IsInitialState(enclosingState)) 
                                yield break; 
                            else
                                yield return currentState; 
                        }

                        if (siblingActivity == currentActivity)
                            break; 

                        if (siblingActivity.Enabled) 
                        { 
                            if (siblingActivity is CompositeActivity && !Helpers.IsCustomActivity((CompositeActivity)siblingActivity) && (crossOverLoop || !IsLoopActivity(siblingActivity)))
                            { 
                                foreach (Activity containedActivity in WebServiceActivityHelpers.GetContainedActivities((CompositeActivity)siblingActivity))
                                    yield return containedActivity;
                            }
                            else 
                            {
                                yield return siblingActivity; 
                            } 
                        }
                    } 
                }

                if (!crossOverLoop && IsLoopActivity(currentActivity.Parent))
                    break; 
                else
                    activityStack.Push(currentActivity.Parent); 
 
            }
            yield break; 
        }

        internal static bool IsLoopActivity(Activity activity)
        { 
            //
            if (activity is WhileActivity || activity is ReplicatorActivity || activity is ConditionedActivityGroup) 
                return true; 

            return false; 
        }

        internal static bool IsInsideLoop(Activity webServiceActivity, Activity searchBoundary)
        { 
            IEnumerable searchBoundaryPath = GetActivityPath(searchBoundary);
            IEnumerable currentActivityPath = GetActivityPath(webServiceActivity); 
 
            String leastCommonParent = FindLeastCommonParent(searchBoundaryPath, currentActivityPath);
 
            Activity currentActivity = webServiceActivity;

            while (currentActivity.Parent != null && currentActivity.Parent.QualifiedName != leastCommonParent)
            { 
                if (IsLoopActivity(currentActivity))
                    return true; 
 
                currentActivity = currentActivity.Parent;
            } 

            return false;
        }
 
        static IEnumerable GetActivityPath(Activity activity)
        { 
            if(activity != null) 
            {
                foreach(String path in GetActivityPath(activity.Parent)) 
                    yield return path;

                yield return activity.QualifiedName;
            } 
        }
 
        static String FindLeastCommonParent(IEnumerable source, IEnumerable dest) 
        {
            IEnumerator srcEnum = source.GetEnumerator(); 
            IEnumerator destEnum = dest.GetEnumerator();

            String leastCommonParent = null;
 
            while (srcEnum.MoveNext() && destEnum.MoveNext())
            { 
                if (srcEnum.Current.Equals(destEnum.Current)) 
                    leastCommonParent = (String)srcEnum.Current;
                else 
                    return leastCommonParent;
            }

            return leastCommonParent; 
        }
 
        internal static IEnumerable GetSucceedingActivities(Activity startActivity) 
        {
            Activity currentActivity = null; 
            Stack activityStack = new Stack();
            activityStack.Push(startActivity);

            while ((currentActivity = activityStack.Pop()) != null) 
            {
                if (currentActivity is CompositeActivity && Helpers.IsCustomActivity((CompositeActivity)currentActivity)) 
                    break; 

                if (currentActivity.Parent != null) 
                {
                    bool pastCurrentActivity = false;

                    foreach (Activity siblingActivity in currentActivity.Parent.Activities) 
                    {
                        if (siblingActivity == currentActivity) 
                        { 
                            pastCurrentActivity = true;
                            continue; 
                        }

                        if (!pastCurrentActivity)
                            continue; 

                        if (siblingActivity.Enabled) 
                        { 
                            if (siblingActivity is CompositeActivity && !Helpers.IsCustomActivity((CompositeActivity)siblingActivity))
                            { 
                                foreach (Activity containedActivity in WebServiceActivityHelpers.GetContainedActivities((CompositeActivity)siblingActivity))
                                    yield return containedActivity;
                            }
                            else 
                            {
                                yield return siblingActivity; 
                            } 
                        }
                    } 
                }
                activityStack.Push(currentActivity.Parent);
            }
            yield break; 
        }
 
        internal static void GetParameterInfo(MethodInfo methodInfo, out List inParameters, out List outParameters) 
        {
            inParameters = new List(); outParameters = new List(); 
            foreach (ParameterInfo paramInfo in methodInfo.GetParameters())
            {
                if (paramInfo.IsOut || paramInfo.IsRetval || paramInfo.ParameterType.IsByRef)
                    outParameters.Add(paramInfo); 

                if (!paramInfo.IsOut && !paramInfo.IsRetval) 
                    inParameters.Add(paramInfo); 
            }
 
            if (methodInfo.ReturnType != typeof(void))
                outParameters.Add(methodInfo.ReturnParameter);

            return; 
        }
 
        internal static ValidationErrorCollection ValidateParameterTypes(MethodInfo methodInfo) 
        {
            ValidationErrorCollection validationErrors = new ValidationErrorCollection(); 
            if (methodInfo == null)
                return validationErrors;
            foreach (ParameterInfo paramInfo in methodInfo.GetParameters())
            { 
                if (paramInfo.ParameterType == null)
                { 
                    validationErrors.Add(new ValidationError(SR.GetString(SR.Error_ParameterTypeNotFound, methodInfo.Name, paramInfo.Name), ErrorNumbers.Error_ParameterTypeNotFound)); 
                }
            } 

            if (methodInfo.ReturnType != typeof(void) && methodInfo.ReturnParameter.ParameterType == null)
            {
                validationErrors.Add(new ValidationError(SR.GetString(SR.Error_ReturnTypeNotFound, methodInfo.Name), ErrorNumbers.Error_ReturnTypeNotFound)); 
            }
 
            return validationErrors; 
        }
    } 
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.

                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK