1 //------------------------------------------------------------ 2 // Copyright (c) Microsoft Corporation. All rights reserved. 3 //------------------------------------------------------------ 4 5 namespace System.Workflow.Activities 6 { 7 using System; 8 using System.Collections; 9 using System.Collections.Generic; 10 using System.Collections.Specialized; 11 using System.ComponentModel; 12 using System.ComponentModel.Design; 13 using System.ComponentModel.Design.Serialization; 14 using System.Diagnostics.CodeAnalysis; 15 using System.ServiceModel; 16 using System.ServiceModel.Channels; 17 using System.ServiceModel.Dispatcher; 18 using System.Workflow.ComponentModel; 19 using System.Workflow.ComponentModel.Design; 20 using System.Workflow.ComponentModel.Serialization; 21 using System.Xml; 22 23 [DesignerSerializer(typeof(DependencyObjectCodeDomSerializer), typeof(CodeDomSerializer))] 24 [TypeConverter(typeof(ChannelTokenTypeConverter))] 25 [Obsolete("The System.Workflow.* types are deprecated. Instead, please use the new types from System.Activities.*")] 26 public sealed class ChannelToken : DependencyObject, IPropertyValueProvider 27 { 28 [SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")] 29 internal static readonly DependencyProperty EndpointNameProperty = 30 DependencyProperty.Register("EndpointName", 31 typeof(string), 32 typeof(ChannelToken), 33 new PropertyMetadata(null)); 34 35 [SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")] 36 internal static readonly DependencyProperty NameProperty = 37 DependencyProperty.Register("Name", 38 typeof(string), 39 typeof(ChannelToken), 40 new PropertyMetadata(null, DependencyPropertyOptions.Metadata, 41 new Attribute[] { new BrowsableAttribute(false) })); 42 43 [SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")] 44 internal static readonly DependencyProperty OwnerActivityNameProperty = 45 DependencyProperty.Register("OwnerActivityName", 46 typeof(string), 47 typeof(ChannelToken), 48 new PropertyMetadata(null, DependencyPropertyOptions.Metadata, 49 new Attribute[] { new TypeConverterAttribute(typeof(PropertyValueProviderTypeConverter)) })); 50 ChannelToken()51 public ChannelToken() 52 { 53 } 54 ChannelToken(string name)55 internal ChannelToken(string name) 56 { 57 this.Name = name; 58 } 59 60 [DefaultValue(null)] 61 [SR2Description(SR2DescriptionAttribute.ChannelToken_EndpointName_Description)] 62 public string EndpointName 63 { 64 get 65 { 66 return (string) GetValue(EndpointNameProperty); 67 } 68 69 set 70 { 71 SetValue(EndpointNameProperty, value); 72 } 73 } 74 75 [Browsable(false)] 76 [DefaultValue(null)] 77 [SR2Description(SR2DescriptionAttribute.ChannelToken_Name_Description)] 78 public string Name 79 { 80 get 81 { 82 return (string) GetValue(NameProperty); 83 } 84 set 85 { 86 SetValue(NameProperty, value); 87 } 88 } 89 90 [DefaultValue(null)] 91 [TypeConverter(typeof(PropertyValueProviderTypeConverter))] 92 [SR2Description(SR2DescriptionAttribute.ChannelToken_OwnerActivityName_Description)] 93 public string OwnerActivityName 94 { 95 get 96 { 97 return (string) GetValue(OwnerActivityNameProperty); 98 } 99 100 set 101 { 102 SetValue(OwnerActivityNameProperty, value); 103 } 104 } 105 IPropertyValueProvider.GetPropertyValues(ITypeDescriptorContext context)106 ICollection IPropertyValueProvider.GetPropertyValues(ITypeDescriptorContext context) 107 { 108 StringCollection names = new StringCollection(); 109 110 if (string.Equals(context.PropertyDescriptor.Name, "OwnerActivityName", StringComparison.Ordinal)) 111 { 112 ISelectionService selectionService = context.GetService(typeof(ISelectionService)) as ISelectionService; 113 if (selectionService != null && selectionService.SelectionCount == 1 && selectionService.PrimarySelection is Activity) 114 { 115 // add empty string as an option 116 // 117 names.Add(string.Empty); 118 119 Activity currentActivity = selectionService.PrimarySelection as Activity; 120 121 foreach (Activity activity in GetEnclosingCompositeActivities(currentActivity)) 122 { 123 string activityId = activity.QualifiedName; 124 if (!names.Contains(activityId)) 125 { 126 names.Add(activityId); 127 } 128 } 129 } 130 } 131 return names; 132 } 133 GetLogicalChannel(Activity activity, ChannelToken endpoint, Type contractType)134 internal static LogicalChannel GetLogicalChannel(Activity activity, 135 ChannelToken endpoint, 136 Type contractType) 137 { 138 if (activity == null) 139 { 140 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("activity"); 141 } 142 if (endpoint == null) 143 { 144 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("endpoint"); 145 } 146 if (contractType == null) 147 { 148 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("contractType"); 149 } 150 151 return GetLogicalChannel(activity, endpoint.Name, endpoint.OwnerActivityName, contractType); 152 } 153 GetLogicalChannel(Activity activity, string name, string ownerActivityName, Type contractType)154 internal static LogicalChannel GetLogicalChannel(Activity activity, 155 string name, 156 string ownerActivityName, 157 Type contractType) 158 { 159 if (activity == null) 160 { 161 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("activity"); 162 } 163 if (string.IsNullOrEmpty(name)) 164 { 165 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument("name", 166 SR2.GetString(SR2.Error_ArgumentValueNullOrEmptyString)); 167 } 168 if (contractType == null) 169 { 170 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("contractType"); 171 } 172 173 Activity contextActivity = activity.ContextActivity; 174 Activity owner = null; 175 176 if (contextActivity == null) 177 { 178 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( 179 new InvalidOperationException(SR2.GetString(SR2.Error_ContextOwnerActivityMissing))); 180 } 181 182 if (string.IsNullOrEmpty(ownerActivityName)) 183 { 184 owner = contextActivity.RootActivity; 185 } 186 else 187 { 188 while (contextActivity != null) 189 { 190 owner = contextActivity.GetActivityByName(ownerActivityName, true); 191 if (owner != null) 192 { 193 break; 194 } 195 196 contextActivity = contextActivity.Parent; 197 if (contextActivity != null) 198 { 199 contextActivity = contextActivity.ContextActivity; 200 } 201 } 202 } 203 204 if (owner == null && !string.IsNullOrEmpty(ownerActivityName)) 205 { 206 owner = Helpers.ParseActivityForBind(activity, ownerActivityName); 207 } 208 209 if (owner == null) 210 { 211 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( 212 new InvalidOperationException(SR2.GetString(SR2.Error_ContextOwnerActivityMissing))); 213 } 214 215 LogicalChannel logicalChannel = null; 216 217 LogicalChannelCollection collection = 218 owner.GetValue(LogicalChannelCollection.LogicalChannelCollectionProperty) as LogicalChannelCollection; 219 if (collection == null) 220 { 221 collection = new LogicalChannelCollection(); 222 owner.SetValue(LogicalChannelCollection.LogicalChannelCollectionProperty, collection); 223 224 logicalChannel = new LogicalChannel(name, contractType); 225 collection.Add(logicalChannel); 226 } 227 else if (!collection.Contains(name)) 228 { 229 logicalChannel = new LogicalChannel(name, contractType); 230 collection.Add(logicalChannel); 231 } 232 else 233 { 234 logicalChannel = collection[name]; 235 } 236 237 if (logicalChannel.ContractType != contractType) 238 { 239 logicalChannel = null; 240 } 241 242 return logicalChannel; 243 } 244 Register(Activity activity, ChannelToken endpoint, Type contractType)245 internal static LogicalChannel Register(Activity activity, 246 ChannelToken endpoint, 247 Type contractType) 248 { 249 if (activity == null) 250 { 251 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("activity"); 252 } 253 if (endpoint == null) 254 { 255 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("endpoint"); 256 } 257 if (contractType == null) 258 { 259 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("contractType"); 260 } 261 262 LogicalChannel logicalChannel = GetLogicalChannel(activity, endpoint, contractType); 263 if (logicalChannel == null) 264 { 265 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( 266 new InvalidOperationException(SR2.GetString(SR2.Error_FailedToRegisterChannel, endpoint.Name))); 267 } 268 269 return logicalChannel; 270 } 271 GetEnclosingCompositeActivities(Activity startActivity)272 private static IEnumerable GetEnclosingCompositeActivities(Activity startActivity) 273 { 274 Activity currentActivity = null; 275 Stack<Activity> activityStack = new Stack<Activity>(); 276 activityStack.Push(startActivity); 277 278 while ((currentActivity = activityStack.Pop()) != null) 279 { 280 if (currentActivity.Enabled) 281 { 282 yield return currentActivity; 283 } 284 activityStack.Push(currentActivity.Parent); 285 } 286 yield break; 287 } 288 } 289 } 290