public int GetIdOfObject(Object obj) { bool isImmutableType = ImmutableTypeSet.IsImmutableType(obj.GetType()); IDictionary <Object, int> objectToIdMap = isImmutableType ? immutableToIdMap : mutableToIdMap; return(DictionaryExtension.ValueOrDefault(objectToIdMap, obj)); }
public T Clone <T>(T source) { // Don't clone a null object or immutable objects. Return the identical reference in these cases if (source == null || ImmutableTypeSet.IsImmutableType(source.GetType())) { return(source); } // Try to access current "in-use" ObjectCopierState first ObjectCopierState ocState = usedOcStateTL.Value; if (ocState != null) { // Reuse TL instance. And do not bother with cleanup return(CloneRecursive(source, ocState)); } // No ObjectCopierState "in-use". So we set the TL instance "in-use" and clean it up in the end // because we are responsible for this in this case ocState = AcquireObjectCopierState(); usedOcStateTL.Value = ocState; try { return(CloneRecursive(source, ocState)); } finally { // Clear "in-use" instance usedOcStateTL.Value = null; // Cleanup ObjectCopierState to allow reusage in the same thread later ocState.Clear(); } }
protected void FetchMetaData() { IList <Type> types = new List <Type>(); foreach (Type type in rootElementClasses) { if (type.IsInterface || ImmutableTypeSet.IsImmutableType(type)) { continue; } types.Add(type); } EntityMetaDataProvider.GetMetaData(types); }
public int AcquireIdForObject(Object obj) { bool isImmutableType = ImmutableTypeSet.IsImmutableType(obj.GetType()); IDictionary <Object, int> objectToIdMap = isImmutableType ? immutableToIdMap : mutableToIdMap; if (objectToIdMap.ContainsKey(obj)) { throw new Exception("There is already a id mapped given object (" + obj + ")"); } int id = nextIdMapIndex++; objectToIdMap.Add(obj, id); return(id); }
/// <summary> /// Gets called by the ObjectCopierState on custom / default behavior switches /// </summary> internal T CloneRecursive <T>(T source, ObjectCopierState ocState) { // Don't clone a null object or immutable objects. Return the identical reference in these cases if (source == null || ImmutableTypeSet.IsImmutableType(source.GetType())) { return(source); } Type objType = source.GetType(); IdentityDictionary <Object, Object> objectToCloneDict = ocState.objectToCloneDict; Object clone = DictionaryExtension.ValueOrDefault(ocState.objectToCloneDict, source); if (clone != null) { // Object has already been cloned. Cycle detected - we are finished here return((T)clone); } if (objType.IsArray) { return((T)CloneArray(source, ocState)); } if (source is IEnumerable && !(source is String)) { return((T)CloneCollection(source, ocState)); } // Check whether the object will be copied by custom behavior IObjectCopierExtension extension = extensions.GetExtension(objType); if (extension != null) { clone = extension.DeepClone(source, ocState); objectToCloneDict.Add(source, clone); return((T)clone); } // Copy by default behavior return((T)CloneDefault(source, ocState)); }
protected Object CloneArray(Object source, ObjectCopierState ocState) { Type objType = source.GetType(); Array array = (Array)(Object)source; Type elementType = objType.GetElementType(); int length = array.Length; Array cloneArray = Array.CreateInstance(elementType, length); ocState.objectToCloneDict.Add(source, cloneArray); if (ImmutableTypeSet.IsImmutableType(elementType)) { // Clone native array with native functionality for performance reasons Array.Copy(array, cloneArray, length); } else { for (int a = length; a-- > 0;) { // Clone each item of the array cloneArray.SetValue(CloneRecursive(array.GetValue(a), ocState), a); } } return(cloneArray); }
protected override Object InterceptLoad(IInvocation invocation, Attribute annotation, Boolean?isAsyncBegin) { ServiceDescription serviceDescription; IServiceResult serviceResult; MethodInfo method = invocation.Method; Object[] args = invocation.Arguments; CachedAttribute cached = annotation is CachedAttribute ? (CachedAttribute)annotation : null; if (cached == null && pauseCache.Value) { return(base.InterceptLoad(invocation, annotation, isAsyncBegin)); } Type returnType = method.ReturnType; if (ImmutableTypeSet.IsImmutableType(returnType)) { // No possible result which might been read by cache return(base.InterceptLoad(invocation, annotation, isAsyncBegin)); } if (cached == null) { ISecurityScope[] securityScopes = SecurityScopeProvider.SecurityScopes; serviceDescription = SyncToAsyncUtil.CreateServiceDescription(ServiceName, method, args, securityScopes); serviceResult = CacheService.GetORIsForServiceRequest(serviceDescription); return(CreateResultObject(serviceResult, returnType, args, annotation)); } if (args.Length != 1) { throw new Exception("This annotation is only allowed on methods with exactly 1 argument. Please check your " + typeof(CachedAttribute).FullName + " annotation on method " + method.ToString()); } Type entityType = cached.Type; if (entityType == null || typeof(void).Equals(entityType)) { entityType = TypeInfoItemUtil.GetElementTypeUsingReflection(returnType, null); } if (entityType == null || typeof(void).Equals(entityType)) { throw new Exception("Please specify a valid returnType for the " + typeof(CachedAttribute).FullName + " annotation on method " + method.ToString()); } IEntityMetaData metaData = GetSpecifiedMetaData(method, typeof(CachedAttribute), entityType); Member member = GetSpecifiedMember(method, typeof(CachedAttribute), metaData, cached.AlternateIdName); sbyte idIndex; try { idIndex = metaData.GetIdIndexByMemberName(member.Name); } catch (Exception e) { throw new Exception( "Member " + entityType.FullName + "." + cached.AlternateIdName + " is not configured as an alternate ID member. There must be a single-column unique contraint on the respective table column. Please check your " + typeof(CachedAttribute).FullName + " annotation on method " + method.ToString(), e); } bool returnMisses = cached.ReturnMisses; List <IObjRef> orisToGet = new List <IObjRef>(); FillOrisToGet(orisToGet, args, entityType, idIndex, returnMisses); return(CreateResultObject(orisToGet, returnType, returnMisses, annotation)); }
protected void BackupObjects(Object obj, IDictionary <Object, RevertChangesSavepoint.IBackup> originalToValueBackup) { if (obj == null) { return; } Type objType = ProxyHelper.GetRealType(obj.GetType()); if (ImmutableTypeSet.IsImmutableType(objType) || originalToValueBackup.ContainsKey(obj)) { return; } originalToValueBackup.Add(obj, null); if (obj is Array) { Array sourceArray = (Array)obj; RevertChangesSavepoint.ArrayBackup arrayBackup = new RevertChangesSavepoint.ArrayBackup((Array)sourceArray.Clone()); originalToValueBackup[obj] = arrayBackup; Type elementType = sourceArray.GetType().GetElementType(); if (!ImmutableTypeSet.IsImmutableType(elementType)) { for (int a = sourceArray.Length; a-- > 0;) { Object arrayItem = sourceArray.GetValue(a); BackupObjects(arrayItem, originalToValueBackup); } } return; } if (obj is IList) { IList list = (IList)obj; Object[] array = new Object[list.Count]; list.CopyTo(array, 0); RevertChangesSavepoint.ListBackup listBackup = new RevertChangesSavepoint.ListBackup(array); originalToValueBackup[obj] = listBackup; for (int a = list.Count; a-- > 0;) { Object item = list[a]; BackupObjects(item, originalToValueBackup); } return; } else if (obj is IEnumerable) { foreach (Object item in (IEnumerable)obj) { BackupObjects(item, originalToValueBackup); } return; } ITypeInfo typeInfo = TypeInfoProvider.GetTypeInfo(objType); ITypeInfoItem[] members = typeInfo.Members; Object[] originalValues = new Object[members.Length]; RevertChangesSavepoint.ObjectBackup objBackup = new RevertChangesSavepoint.ObjectBackup(members, originalValues); originalToValueBackup[obj] = objBackup; for (int b = members.Length; b-- > 0;) { ITypeInfoItem member = members[b]; Object originalValue = member.GetValue(obj); originalValues[b] = originalValue; BackupObjects(originalValue, originalToValueBackup); } }
protected void InitializeValueObjectMapping() { Object writeLock = GetWriteLock(); lock (writeLock) { this.businessObjectSaveOrder = null; HashMap <Type, IISet <Type> > boTypeToBeforeBoTypes = new HashMap <Type, IISet <Type> >(); HashMap <Type, IISet <Type> > boTypeToAfterBoTypes = new HashMap <Type, IISet <Type> >(); foreach (Entry <Type, IValueObjectConfig> entry in ValueObjectMap.GetExtensions()) { IValueObjectConfig voConfig = entry.Value; Type entityType = voConfig.EntityType; Type valueType = voConfig.ValueType; IEntityMetaData metaData = GetMetaData(entityType); if (metaData == null) { // Currently no bo metadata found. We can do nothing here return; } IMap <String, ITypeInfoItem> boNameToVoMember = GetTypeInfoMapForVo(valueType); foreach (RelationMember boMember in metaData.RelationMembers) { String boMemberName = boMember.Name; String voMemberName = voConfig.GetValueObjectMemberName(boMemberName); ITypeInfoItem voMember = boNameToVoMember.Get(boMemberName); if (voConfig.IsIgnoredMember(voMemberName) || voMember == null) { continue; } Type voMemberRealType = voMember.RealType; if (voConfig.HoldsListType(voMember.Name)) { IPropertyInfo[] properties = PropertyInfoProvider.GetProperties(voMemberRealType); if (properties.Length != 1) { throw new ArgumentException("ListTypes must have exactly one property"); } voMemberRealType = TypeInfoProvider.GetMember(voMemberRealType, properties[0]).RealType; } if (!ImmutableTypeSet.IsImmutableType(voMemberRealType)) { // vo member is either a list or a single direct relation to another VO // This implies that a potential service can handle both VO types as new objects at once continue; } // vo member only holds a id reference which implies that the related VO has to be persisted first to // contain an id which can be referred to. But we do NOT know the related VO here, but we know // the related BO where ALL potential VOs will be derived from: Type boMemberElementType = boMember.ElementType; if (Object.Equals(entityType, boMemberElementType)) { continue; } AddBoTypeAfter(entityType, boMemberElementType, boTypeToBeforeBoTypes, boTypeToAfterBoTypes); AddBoTypeBefore(entityType, boMemberElementType, boTypeToBeforeBoTypes, boTypeToAfterBoTypes); } } List <Type> businessObjectSaveOrder = new List <Type>(); foreach (Type boType in boTypeToBeforeBoTypes.KeySet()) { // BeforeBoType are types which have to be saved BEFORE saving the boType bool added = false; for (int a = 0, size = businessObjectSaveOrder.Count; a < size; a++) { Type orderedBoType = businessObjectSaveOrder[a]; // OrderedBoType is the type currently inserted at the correct position in the save order - as far as the keyset // has been traversed, yet ISet <Type> typesBeforeOrderedType = boTypeToBeforeBoTypes.Get(orderedBoType); // typesBeforeOrderedType are types which have to be bool orderedHasToBeAfterCurrent = typesBeforeOrderedType != null && typesBeforeOrderedType.Contains(boType); if (!orderedHasToBeAfterCurrent) { // our boType has nothing to do with the orderedBoType. So we let is be at it is continue; } businessObjectSaveOrder.Insert(a, boType); added = true; break; } if (!added) { businessObjectSaveOrder.Add(boType); } } foreach (Type boType in boTypeToAfterBoTypes.KeySet()) { if (boTypeToBeforeBoTypes.ContainsKey(boType)) { // already handled in the previous loop continue; } bool added = false; for (int a = businessObjectSaveOrder.Count; a-- > 0;) { Type orderedBoType = businessObjectSaveOrder[a]; // OrderedBoType is the type currently inserted at the correct position in the save order - as far as the keyset // has been traversed, yet ISet <Type> typesBeforeOrderedType = boTypeToBeforeBoTypes.Get(orderedBoType); bool orderedHasToBeAfterCurrent = typesBeforeOrderedType != null && typesBeforeOrderedType.Contains(boType); if (!orderedHasToBeAfterCurrent) { // our boType has nothing to do with the orderedBoType. So we let it be as it is continue; } businessObjectSaveOrder.Insert(a, boType); added = true; break; } if (!added) { businessObjectSaveOrder.Add(boType); } } this.businessObjectSaveOrder = businessObjectSaveOrder.ToArray(); } }
public static bool IsLowLevelSerializationType(Type type) { if (typeof(Type).IsAssignableFrom(type) || typeof(IEnumerable).IsAssignableFrom(type) || type.IsArray || type.IsValueType || type.IsEnum || type.IsPrimitive || ImmutableTypeSet.IsImmutableType(type)) { return(true); } return(lowLevelSerializationTypes.Contains(type)); }