示例#1
0
        public int GetIdOfObject(Object obj)
        {
            bool isImmutableType = ImmutableTypeSet.IsImmutableType(obj.GetType());
            IDictionary <Object, int> objectToIdMap = isImmutableType ? immutableToIdMap : mutableToIdMap;

            return(DictionaryExtension.ValueOrDefault(objectToIdMap, obj));
        }
示例#2
0
        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();
            }
        }
示例#3
0
        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);
        }
示例#4
0
        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);
        }
示例#5
0
        /// <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));
        }
示例#6
0
        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);
        }
示例#7
0
        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));
        }
示例#8
0
        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);
            }
        }
示例#9
0
        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();
            }
        }
示例#10
0
 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));
 }