Code:
/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / cdf / src / NetFx40 / Tools / System.Activities.Core.Presentation / System / Activities / Core / Presentation / GenericFlowSwitchHelper.cs / 1305376 / GenericFlowSwitchHelper.cs
//------------------------------------------------------------ // Copyright (c) Microsoft Corporation. All rights reserved. //----------------------------------------------------------- namespace System.Activities.Core.Presentation { using System.Activities.Presentation; using System.Activities.Presentation.Model; using System.Activities.Statements; using System.Collections.Generic; using System.Reflection; using System.ComponentModel; using System.Runtime; using System.Globalization; static class GenericFlowSwitchHelper { static readonly MethodInfo genericCopy = typeof(GenericFlowSwitchHelper).GetMethod("GenericCopy"); static readonly MethodInfo genericCreateGenericFlowSwitchLink = typeof(GenericFlowSwitchHelper).GetMethod("CreateGenericFlowSwitchLink"); static readonly MethodInfo genericGetCaseName = typeof(GenericFlowSwitchHelper).GetMethod("GenericGetCaseName"); const string flowSwitchCasesKeyIdentifier = "key"; const string flowSwitchNullCaseKeyIdentifier = "(null)"; const string flowSwitchEmptyCaseKeyIdentifier = "(empty)"; public static string FlowSwitchCasesKeyIdentifier { get { return flowSwitchCasesKeyIdentifier; } } public static string FlowSwitchNullCaseKeyIdentifier { get { return flowSwitchNullCaseKeyIdentifier; } } public static string FlowSwitchEmptyCaseKeyIdentifier { get { return flowSwitchEmptyCaseKeyIdentifier; } } public static void Copy(Type genericType, FlowNode currentFlowElement, DictionaryclonedFlowElements) { MethodInfo copy = genericCopy.MakeGenericMethod(new Type[] { genericType }); copy.Invoke(null, new object[] { currentFlowElement, clonedFlowElements }); } public static void GenericCopy (FlowNode currentFlowElement, Dictionary clonedFlowElements) { FlowSwitch currentFlowSwitch = (FlowSwitch )currentFlowElement; FlowSwitch clonedFlowSwitch = (FlowSwitch )clonedFlowElements[currentFlowElement]; //Update the default case. FlowNode defaultCase = currentFlowSwitch.Default; if (defaultCase != null && clonedFlowElements.ContainsKey(defaultCase)) { clonedFlowSwitch.Default = clonedFlowElements[defaultCase]; } else { clonedFlowSwitch.Default = null; } //Update the Cases dictionary. foreach (T key in currentFlowSwitch.Cases.Keys) { if (clonedFlowElements.ContainsKey(currentFlowSwitch.Cases[key])) { clonedFlowSwitch.Cases.Add(key, clonedFlowElements[currentFlowSwitch.Cases[key]]); } } } public static bool IsGenericFlowSwitch(Type type) { return type.IsGenericType && type.GetGenericTypeDefinition() == typeof(FlowSwitch<>); } public static IFlowSwitchLink CreateFlowSwitchLink(Type flowSwitchType, ModelItem currentMI, object caseValue, bool isDefault) { Type genericType = null; object key = null; genericType = flowSwitchType.GetGenericArguments()[0]; if (caseValue is string) { key = GetObject(caseValue as string, genericType); } else { key = caseValue; } MethodInfo method = genericCreateGenericFlowSwitchLink.MakeGenericMethod(genericType); return method.Invoke(null, new object[] { currentMI, key, isDefault }) as IFlowSwitchLink; } public static IFlowSwitchLink CreateGenericFlowSwitchLink (ModelItem currentMI, T caseValue, bool isDefault) { FlowSwitchLink link = new FlowSwitchLink (currentMI, caseValue, isDefault); return link; } public static string GetCaseName(ModelProperty casesProperties, Type type, out string errorMessage) { object casesDict = casesProperties.Dictionary.GetCurrentValue(); ModelItemCollection collection = casesProperties.Value.Properties["ItemsCollection"].Collection; MethodInfo method = genericGetCaseName.MakeGenericMethod(type); object[] parameters = new object[] { collection, null }; string result = (string)method.Invoke(null, parameters); errorMessage = (string)parameters[1]; return result; } public static string GenericGetCaseName (ModelItemCollection collection, out string errorMessage) { int maxName = 100000; Type type = typeof(T); errorMessage = string.Empty; if (typeof(string).IsAssignableFrom(type)) { string caseName = "caseN"; for (int i = 1; i <= maxName; i++) { caseName = string.Format(CultureInfo.InvariantCulture, SR.CaseFormat, i); if (!GenericFlowSwitchHelper.ContainsCaseKey(collection, caseName)) { break; } } return caseName; } else if (GenericFlowSwitchHelper.IsIntegralType(type)) { if (type == typeof(sbyte)) { sbyte maxCount = (sbyte.MaxValue < maxName) ? sbyte.MaxValue : (sbyte)maxName; for (sbyte i = 0; i <= maxCount; i++) { if (!GenericFlowSwitchHelper.ContainsCaseKey(collection, i)) { return GenericFlowSwitchHelper.GetString(i, type); } } } else if (type == typeof(byte)) { byte maxCount = (byte.MaxValue < maxName) ? byte.MaxValue : (byte)maxName; for (byte i = 0; i <= maxCount; i++) { if (!GenericFlowSwitchHelper.ContainsCaseKey(collection, i)) { return GenericFlowSwitchHelper.GetString(i, type); } } } else if (type == typeof(char)) { char maxCount = unchecked((char)maxName); for (char i = (char)48; i <= maxCount; i++) { if (!GenericFlowSwitchHelper.ContainsCaseKey(collection, i)) { return GenericFlowSwitchHelper.GetString(i, type); } } } else if (type == typeof(short)) { short maxCount = (short)maxName; for (short i = 0; i <= maxCount; i++) { if (!GenericFlowSwitchHelper.ContainsCaseKey(collection, i)) { return GenericFlowSwitchHelper.GetString(i, type); } } } else if (type == typeof(ushort)) { ushort maxCount = (ushort)maxName; for (ushort i = 0; i <= maxCount; i++) { if (!GenericFlowSwitchHelper.ContainsCaseKey(collection, i)) { return GenericFlowSwitchHelper.GetString(i, type); } } } else if (type == typeof(int)) { for (int i = 0; i <= maxName; i++) { if (!GenericFlowSwitchHelper.ContainsCaseKey(collection, i)) { return GenericFlowSwitchHelper.GetString(i, type); } } } else if (type == typeof(uint)) { for (uint i = 0; i <= (uint)maxName; i++) { if (!GenericFlowSwitchHelper.ContainsCaseKey(collection, i)) { return GenericFlowSwitchHelper.GetString(i, type); } } } else if (type == typeof(long)) { for (long i = 0; i <= (long)maxName; i++) { if (!GenericFlowSwitchHelper.ContainsCaseKey(collection, i)) { return GenericFlowSwitchHelper.GetString(i, type); } } } else if (type == typeof(ulong)) { for (ulong i = 0; i <= (ulong)maxName; i++) { if (!GenericFlowSwitchHelper.ContainsCaseKey(collection, i)) { return GenericFlowSwitchHelper.GetString(i, type); } } } errorMessage = SR.InvalidFlowSwitchCaseMessage; return string.Empty; } else if (type.IsEnum) { Array array = type.GetEnumValues(); foreach (object value in array) { if (!GenericFlowSwitchHelper.ContainsCaseKey(collection, value)) { return GenericFlowSwitchHelper.GetString(value, type); } } errorMessage = SR.InvalidFlowSwitchCaseMessage; return string.Empty; } else if (type == typeof(bool)) { if (!GenericFlowSwitchHelper.ContainsCaseKey(collection, true)) { return GenericFlowSwitchHelper.GetString(true, type); } else if (!GenericFlowSwitchHelper.ContainsCaseKey(collection, false)) { return GenericFlowSwitchHelper.GetString(false, type); } errorMessage = SR.InvalidFlowSwitchCaseMessage; return string.Empty; } return string.Empty; } public static bool IsIntegralType(Type type) { if (type == typeof(sbyte) || type == typeof(byte) || type == typeof(char) || type == typeof(short) || type == typeof(ushort) || type == typeof(int) || type == typeof(uint) || type == typeof(long) || type == typeof(ulong)) { return true; } else { return false; } } public static string GetString(object key, Type type) { string result = null; if (key == null && !type.IsValueType) { result = FlowSwitchNullCaseKeyIdentifier; } else { Fx.Assert(key != null, "Value type should not have null value"); result = GetRawString(key); if (result == string.Empty && typeof(string).IsAssignableFrom(type)) { result = FlowSwitchEmptyCaseKeyIdentifier; } } return result; } //Raw string means the null is not represented as " " and string.Empty is not represented as " ". static string GetRawString(object caseObject) { string result = null; if (caseObject == null) { return null; } if (!(caseObject is string)) { result = XamlUtilities.GetConverter(caseObject.GetType()).ConvertToString(caseObject); } else { result = (string)caseObject; } return result; } public static object GetObject(string caseString, Type genericType) { object result; if (!genericType.IsValueType && caseString == FlowSwitchNullCaseKeyIdentifier) { result = null; } else if (typeof(string).IsAssignableFrom(genericType)) { if (caseString == FlowSwitchEmptyCaseKeyIdentifier) { result = string.Empty; } else { result = caseString; } } else { //If target type is value type and the caseString is null, we should leave converter to process it. //If target type is reference type, the caseString is a non-null value here. result = XamlUtilities.GetConverter(genericType).ConvertFromString(caseString); } return result; } public static bool ContainsCaseKey(ModelProperty casesProp, object key) { ModelItemCollection itemsCollection = casesProp.Value.Properties["ItemsCollection"].Collection; return ContainsCaseKey(itemsCollection, key); } static bool ContainsCaseKey(ModelItemCollection itemsCollection, object key) { if (GenericFlowSwitchHelper.FlowSwitchNullCaseKeyIdentifier.Equals(key)) { key = null; } foreach (ModelItem item in itemsCollection) { object value = item.Properties["Key"].ComputedValue; if (value == key || ((value != null) && item.Properties["Key"].ComputedValue.Equals(key))) { return true; } } return false; } public static ModelItem GetCaseModelItem(ModelProperty casesProp, object key) { ModelItemCollection itemsCollection = casesProp.Value.Properties["ItemsCollection"].Collection; return GenericFlowSwitchHelper.GetCaseModelItem(itemsCollection, key); } static ModelItem GetCaseModelItem(ModelItemCollection itemsCollection, object key) { if (GenericFlowSwitchHelper.FlowSwitchNullCaseKeyIdentifier.Equals(key)) { key = null; } foreach (ModelItem item in itemsCollection) { object value = item.Properties["Key"].ComputedValue; if (value == key || (value != null && item.Properties["Key"].ComputedValue.Equals(key))) { return item.Properties["Value"].Value; } } string caseName = GetString(key, itemsCollection.ItemType); throw FxTrace.Exception.AsError(new KeyNotFoundException(caseName)); } public static object GetCase(ModelItemCollection itemsCollection, object key) { return GenericFlowSwitchHelper.GetCaseModelItem(itemsCollection, key).GetCurrentValue(); } public static ModelItem[] GetCaseKeys(ModelProperty casesProp) { ModelItemCollection itemsCollection = casesProp.Value.Properties["ItemsCollection"].Collection; ModelItem[] keys = new ModelItem[itemsCollection.Count]; for (int i = 0; i < itemsCollection.Count; i++) { keys[i] = (ModelItem) itemsCollection[i].Properties["Key"].Value; } return keys; } public static void RemoveCase(ModelProperty casesProp, object key) { ModelItemCollection itemsCollection = casesProp.Value.Properties["ItemsCollection"].Collection; if (GenericFlowSwitchHelper.FlowSwitchNullCaseKeyIdentifier.Equals(key)) { key = null; } foreach (ModelItem item in itemsCollection) { object value = item.Properties["Key"].ComputedValue; if (value == key || (value != null && item.Properties["Key"].ComputedValue.Equals(key))) { itemsCollection.Remove(item); return; } } string caseName = GetString(key, itemsCollection.ItemType.GetGenericArguments()[0]); throw FxTrace.Exception.AsError(new KeyNotFoundException(caseName)); } public static void AddCase(ModelProperty casesPropperties, object newKey, object newCase) { Type propertyType = casesPropperties.PropertyType; Fx.Assert(propertyType.IsGenericType && propertyType.GetGenericTypeDefinition() == typeof(IDictionary<,>), "Property type should be IDictonary "); Type keyType = propertyType.GetGenericArguments()[0]; ModelItemCollection itemsCollection = casesPropperties.Value.Properties["ItemsCollection"].Collection; Type caseType = typeof(ModelItemKeyValuePair<,>).MakeGenericType(new Type[] { keyType, typeof(FlowNode) }); object mutableKVPair = Activator.CreateInstance(caseType, new object[] { newKey, newCase }); itemsCollection.Add(mutableKVPair); } public static bool CanBeGeneratedUniquely(Type typeArgument) { return typeArgument.IsEnum || typeof(string).IsAssignableFrom(typeArgument) || GenericFlowSwitchHelper.IsIntegralType(typeArgument) || typeof(bool) == typeArgument; } public static bool CheckEquality(object value, Type targetType) { if (value == null) { return true; } else { string stringValue = GetString(value, targetType); object newValue = GetObject(stringValue, targetType); return value.GetHashCode() == newValue.GetHashCode() && value.Equals(newValue); } } public static bool ValidateCaseKey(object obj, ModelProperty casesProp, Type genericType, out string reason) { reason = string.Empty; string key = GenericFlowSwitchHelper.GetString(obj, genericType); if (GenericFlowSwitchHelper.CheckEquality(obj, genericType)) { if (GenericFlowSwitchHelper.ContainsCaseKey(casesProp, obj)) { reason = string.Format(CultureInfo.CurrentCulture, SR.DuplicateCaseKey, key); return false; } return true; } else { reason = string.Format(CultureInfo.CurrentUICulture, SR.EqualityError, genericType.Name); return false; } } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- Vector3D.cs
- TypeUnloadedException.cs
- Int32Animation.cs
- TimeSpanMinutesOrInfiniteConverter.cs
- TaiwanCalendar.cs
- ReflectEventDescriptor.cs
- SpellerHighlightLayer.cs
- CoTaskMemUnicodeSafeHandle.cs
- HttpChannelHelper.cs
- X509ChainPolicy.cs
- XmlAnyAttributeAttribute.cs
- FileRecordSequenceHelper.cs
- ModelTypeConverter.cs
- Table.cs
- BasicCommandTreeVisitor.cs
- Schema.cs
- BuildManagerHost.cs
- MetafileHeader.cs
- HttpWebRequestElement.cs
- VectorAnimationBase.cs
- SQLBytesStorage.cs
- Label.cs
- ProxyWebPart.cs
- InitializationEventAttribute.cs
- RichTextBoxDesigner.cs
- Int32AnimationUsingKeyFrames.cs
- FragmentQueryProcessor.cs
- WebContext.cs
- ElementProxy.cs
- BoolLiteral.cs
- ExtensionDataReader.cs
- ToolZone.cs
- Int32Storage.cs
- LogRecordSequence.cs
- CharEntityEncoderFallback.cs
- XPathBuilder.cs
- RemotingHelper.cs
- BitmapEffectDrawing.cs
- ACL.cs
- StandardTransformFactory.cs
- UdpUtility.cs
- COM2Properties.cs
- StateMachineWorkflowDesigner.cs
- DataGridView.cs
- RecognizedPhrase.cs
- LayoutEngine.cs
- TypeUnloadedException.cs
- DataGridViewAdvancedBorderStyle.cs
- RelatedPropertyManager.cs
- InternalReceiveMessage.cs
- _NTAuthentication.cs
- CodeDomConfigurationHandler.cs
- DataFormat.cs
- StorageRoot.cs
- PeerDefaultCustomResolverClient.cs
- DataListCommandEventArgs.cs
- AutomationProperty.cs
- XmlNotation.cs
- DesignerAdapterUtil.cs
- NameValuePair.cs
- CodeTypeMemberCollection.cs
- ErrorsHelper.cs
- COM2ExtendedUITypeEditor.cs
- DayRenderEvent.cs
- UInt32.cs
- XPathNavigatorKeyComparer.cs
- SkinBuilder.cs
- DataControlFieldCell.cs
- SHA1CryptoServiceProvider.cs
- AspNetHostingPermission.cs
- ParameterToken.cs
- IImplicitResourceProvider.cs
- FrameworkTemplate.cs
- ArrayListCollectionBase.cs
- StackSpiller.Bindings.cs
- XmlQueryOutput.cs
- LeaseManager.cs
- SafeLibraryHandle.cs
- BasicCommandTreeVisitor.cs
- EncoderReplacementFallback.cs
- HtmlObjectListAdapter.cs
- WindowsScrollBar.cs
- SliderAutomationPeer.cs
- SchemaDeclBase.cs
- SpeakCompletedEventArgs.cs
- HtmlElementCollection.cs
- SqlVersion.cs
- ButtonAutomationPeer.cs
- UseManagedPresentationBindingElementImporter.cs
- HeaderLabel.cs
- InfiniteIntConverter.cs
- NonSerializedAttribute.cs
- PolicyManager.cs
- DnsPermission.cs
- WindowsStatusBar.cs
- StorageEntityContainerMapping.cs
- TabControlAutomationPeer.cs
- ExtendedPropertyDescriptor.cs
- StateDesigner.cs
- EventProviderWriter.cs