예제 #1
0
        public Object ProcessServiceResult(Object result, IList <IObjRef> objRefs, IList <Object> entities, Type expectedType, Object[] serviceRequestArgs,
                                           Attribute annotation)
        {
            IPagingResponse pagingResponse = (IPagingResponse)result;

            QueryResultType queryResultType = QueryResultType.REFERENCES;

            if (annotation is FindAttribute)
            {
                queryResultType = ((FindAttribute)annotation).ResultType;
            }
            switch (queryResultType)
            {
            case QueryResultType.BOTH:
                pagingResponse.RefResult = objRefs;
                pagingResponse.Result    = entities;
                break;

            case QueryResultType.ENTITIES:
                pagingResponse.RefResult = null;
                pagingResponse.Result    = entities;
                break;

            case QueryResultType.REFERENCES:
                pagingResponse.RefResult = objRefs;
                pagingResponse.Result    = null;
                break;

            default:
                throw RuntimeExceptionUtil.CreateEnumNotSupportedException(queryResultType);
            }
            return(pagingResponse);
        }
 // After each Find, the paging properties of the viewmodel must be updated:
 public virtual void UpdatePagingInformation(IPagingResponse pagingResponse)
 {
     if (pagingResponse != null)
     {
         Model.ItemCount = pagingResponse.TotalSize;
         Model.PageIndex = pagingResponse.Number;
     }
 }
예제 #3
0
        public virtual IList <T> GetObjectsFromPagingResponse(IPagingResponse pagingResponse)
        {
            IList <T> result = new List <T>();

            foreach (Object obj in pagingResponse.Result)
            {
                result.Add((T)obj);
            }
            return(result);
        }
        protected virtual void PopulateAsync(GenericViewModel <T> model, IFilterDescriptor filterDescriptor, IList <ISortDescriptor> sortDescriptors, IPagingRequest pagingRequest, Object[] contextInformation, ICache cache, Object localRequest)
        {
            lock (currentRequestLock)
            {
                // Early check here, but more important check in the finally-SyncContext.
                // We will not update the ViewModel, if this request is not the current request (hence Populate was recalled
                // since this request was initiated).
                // An example where this is important would be a screen, where the user can enter search criteria and start
                // a corresponding search, while the screen is still loading data from a preceeding request. In this case, the
                // result of the second search could be retrieved before the first one, leading to wrong data in the screen.
                //
                // ToDo: Is there a scenario where the same VMDCC is used with multiple VMs or different Caches?
                //       If so, localRequest and currentRequest must contain the VM and Cache references to compare them!
                if (!Object.ReferenceEquals(localRequest, currentRequest))
                {
                    return;
                }
            }
            IList <T>       initialEntities = null;
            IPagingResponse pagingResponse  = null;

            try
            {
                if (hasPagedViewModel)
                {
                    pagingResponse  = ((IPagingRefresher <T>)Refresher).Populate(filterDescriptor, sortDescriptors, pagingRequest, contextInformation);
                    initialEntities = new List <T>();
                    foreach (Object obj in pagingResponse.Result)
                    {
                        initialEntities.Add((T)obj);
                    }
                }
                else
                {
                    if (filterDescriptor != null || sortDescriptors != null)
                    {
                        contextInformation    = new Object[2];
                        contextInformation[0] = filterDescriptor;
                        contextInformation[1] = sortDescriptors;
                    }
                    initialEntities = ((IRefresher <T>)Refresher).Populate(contextInformation);
                }
            }
            catch (Exception e)
            {
                if (Log.ErrorEnabled)
                {
                    Log.Error(e);
                }
            }
            finally
            {
                GuiThreadHelper.InvokeInGui(delegate()
                {
                    lock (currentRequestLock)
                    {
                        if (!Object.ReferenceEquals(localRequest, currentRequest))
                        {
                            return;
                        }
                    }
                    try
                    {
                        if (IsRefreshedDataValid(contextInformation))
                        {
                            if (initialEntities != null)
                            {
                                if (ToBeCreatedOnTop)
                                {
                                    // ToBeCreated entities are never part of the initialEntities, so no doublette check necessary
                                    foreach (T entity in model.Objects)
                                    {
                                        if ((entity is IDataObject) && ((IDataObject)entity).ToBeCreated)
                                        {
                                            initialEntities.Insert(0, entity);
                                        }
                                    }
                                }
                                model.Clear();
                                for (int a = 0, size = initialEntities.Count; a < size; a++)
                                {
                                    T item = initialEntities[a];
                                    model.InsertAt(a, item);
                                }
                            }

                            // Important to update the sorting states (if the provider disables gridviews own sorting mechanism):
                            if (hasPagedViewModel)
                            {
                                UpdatePagingInformation(pagingResponse);
                            }
                            UpdateAfterDCE();
                        }
                    }
                    catch (Exception ex)
                    {
                        if (Log.ErrorEnabled)
                        {
                            Log.Error(ex);
                        }
                    }
                    finally
                    {
                        model.IsBusy = false;
                    }
                });
            }
        }
        public virtual void DataChanged(IDataChange dataChange, DateTime dispatchTime, long sequenceId)
        {
            dataChange = dataChange.Derive(InterestedEntityTypes);
            if (dataChange.IsEmpty)
            {
                return;
            }
            ISet <Object> directObjectsToDelete = null;

            ISet <Type> requestedTypes = new HashSet <Type>();
            IDictionary <Type, IEntityMetaData> typeToMetaDataDict = new Dictionary <Type, IEntityMetaData>();

            GuiThreadHelper.InvokeInGuiAndWait(delegate()
            {
                IList <T> entities = Model.Objects;

                for (int i = entities.Count; i-- > 0;)
                {
                    Object entity = entities[i];

                    requestedTypes.Add(entity.GetType());
                }
            });

            IList <IDataChangeEntry> dataChangeEntries = dataChange.Inserts;

            for (int a = dataChangeEntries.Count; a-- > 0;)
            {
                requestedTypes.Add(dataChangeEntries[a].EntityType);
            }
            dataChangeEntries = dataChange.Updates;
            for (int a = dataChangeEntries.Count; a-- > 0;)
            {
                requestedTypes.Add(dataChangeEntries[a].EntityType);
            }
            dataChangeEntries = dataChange.Deletes;
            for (int a = dataChangeEntries.Count; a-- > 0;)
            {
                requestedTypes.Add(dataChangeEntries[a].EntityType);
            }

            IList <IEntityMetaData> metaDatas = EntityMetaDataProvider.GetMetaData(ListUtil.ToList(requestedTypes));

            foreach (IEntityMetaData metaData in metaDatas)
            {
                typeToMetaDataDict[metaData.EntityType] = metaData;
            }

            bool consistsOnlyOfDirectDeletes = false;

            if (dataChange.Deletes.Count > 0)
            {
                consistsOnlyOfDirectDeletes = true;
                foreach (IDataChangeEntry deleteEntry in dataChange.Deletes)
                {
                    if (deleteEntry is DirectDataChangeEntry)
                    {
                        if (directObjectsToDelete == null)
                        {
                            directObjectsToDelete = new IdentityHashSet <Object>();
                        }
                        directObjectsToDelete.Add(((DirectDataChangeEntry)deleteEntry).Entry);
                    }
                    else
                    {
                        consistsOnlyOfDirectDeletes = false;
                    }
                }
            }

            IList <T> interestingEntities = null;

            Object[]                contextInformation = GetContextInformation();
            IFilterDescriptor       filterDescriptor   = GetFilterDescriptor();
            IList <ISortDescriptor> sortDescriptors    = GetSortDescriptors();
            IPagingRequest          pagingRequest      = GetPagingRequest();

            IPagingResponse         pagingResponse  = null;
            List <IDataChangeEntry> modifiedEntries = new List <IDataChangeEntry>();

            modifiedEntries.AddRange(dataChange.All);

            if (!consistsOnlyOfDirectDeletes)
            {
                interestingEntities = CacheContext.ExecuteWithCache(CacheProvider.GetCurrentCache(), delegate()
                {
                    ConfigureCacheWithEagerLoads(Cache);
                    if (Refresher is IPagingRefresher <T> )
                    {
                        interestingEntities = new List <T>();
                        pagingResponse      = ((IPagingRefresher <T>)Refresher).Refresh(modifiedEntries, filterDescriptor, sortDescriptors, pagingRequest, contextInformation);
                        foreach (Object obj in pagingResponse.Result)
                        {
                            interestingEntities.Add((T)obj);
                        }
                        return(interestingEntities);
                    }
                    else
                    {
                        if (filterDescriptor != null || sortDescriptors != null)
                        {
                            contextInformation    = new Object[2];
                            contextInformation[0] = filterDescriptor;
                            contextInformation[1] = sortDescriptors;
                        }

                        return(((IRefresher <T>)Refresher).Refresh(modifiedEntries, contextInformation));
                    }
                });
            }
            GuiThreadHelper.InvokeInGuiAndWait(delegate()
            {
                IList <T> entities = Model.Objects;

                ISet <T> entitiesToAdd                           = null;
                ISet <T> entitiesToRemove                        = null;
                IDictionary <T, T> entitiesToReplace             = null;
                IDictionary <IObjRef, T> oldObjRefToOldEntityMap = null;
                bool mergeModel = false;

                if (interestingEntities != null && interestingEntities.Count > 0)
                {
                    entitiesToAdd           = new IdentityHashSet <T>(interestingEntities);
                    entitiesToRemove        = new IdentityHashSet <T>(entities);
                    entitiesToReplace       = new IdentityDictionary <T, T>();
                    oldObjRefToOldEntityMap = new Dictionary <IObjRef, T>();
                    mergeModel = true;
                }
                for (int i = entities.Count; i-- > 0;)
                {
                    T oldEntity = entities[i];
                    if (directObjectsToDelete != null && directObjectsToDelete.Contains(oldEntity))
                    {
                        if (entitiesToRemove != null)
                        {
                            entitiesToRemove.Remove(oldEntity);
                        }
                        Model.RemoveAt(i);
                        continue;
                    }
                    Type oldEntityType       = ProxyHelper.GetRealType(oldEntity.GetType());
                    PrimitiveMember idMember = typeToMetaDataDict[oldEntityType].IdMember;
                    Object oldEntityId       = idMember.GetValue(oldEntity, false);
                    if (oldEntityId == null)
                    {
                        if (entitiesToRemove != null)
                        {
                            entitiesToRemove.Remove(oldEntity);
                        }
                        // Unpersisted object. This object should not be removed
                        // only because of a background DCE
                        continue;
                    }
                    bool entryRemoved = false;
                    foreach (IDataChangeEntry deleteEntry in dataChange.Deletes)
                    {
                        if (deleteEntry is DirectDataChangeEntry)
                        {
                            continue;
                        }
                        Object id = deleteEntry.Id;
                        if (!EqualsItems(oldEntityType, oldEntityId, deleteEntry.EntityType, id))
                        {
                            continue;
                        }
                        if (entitiesToRemove != null)
                        {
                            entitiesToRemove.Remove(oldEntity);
                        }
                        Model.RemoveAt(i);
                        entryRemoved = true;
                        break;
                    }
                    if (entryRemoved)
                    {
                        continue;
                    }
                    if (mergeModel)
                    {
                        IObjRef oldObjRef   = new ObjRef(oldEntityType, ObjRef.PRIMARY_KEY_INDEX, oldEntityId, null);
                        T existingOldEntity = DictionaryExtension.ValueOrDefault(oldObjRefToOldEntityMap, oldObjRef);
                        if (existingOldEntity == null)
                        {
                            oldObjRefToOldEntityMap.Add(oldObjRef, oldEntity);
                        }
                        else if (!Object.ReferenceEquals(existingOldEntity, oldEntity))
                        {
                            // Force duplicate key exception
                            oldObjRefToOldEntityMap.Add(oldObjRef, oldEntity);
                        }
                    }
                }
                if (oldObjRefToOldEntityMap != null && oldObjRefToOldEntityMap.Count > 0)
                {
                    IDictionary <IObjRef, T> newObjRefToNewEntityMap = new Dictionary <IObjRef, T>();
                    for (int a = interestingEntities.Count; a-- > 0;)
                    {
                        T newEntity              = interestingEntities[a];
                        Type newEntityType       = ProxyHelper.GetRealType(newEntity.GetType());
                        PrimitiveMember idMember = typeToMetaDataDict[newEntityType].IdMember;
                        Object newEntityId       = idMember.GetValue(newEntity, false);

                        IObjRef newObjRef = new ObjRef(newEntityType, ObjRef.PRIMARY_KEY_INDEX, newEntityId, null);
                        newObjRefToNewEntityMap.Add(newObjRef, newEntity);
                    }
                    DictionaryExtension.Loop(oldObjRefToOldEntityMap, delegate(IObjRef objRef, T oldEntity)
                    {
                        T newEntity = DictionaryExtension.ValueOrDefault(newObjRefToNewEntityMap, objRef);
                        if (newEntity == null)
                        {
                            // Nothing to do if current oldEntity has no corresponding newEntity
                            return;
                        }
                        entitiesToAdd.Remove(newEntity);
                        if (!Object.ReferenceEquals(oldEntity, newEntity) &&
                            (dataChange.IsLocalSource || !(oldEntity is IDataObject) || !((IDataObject)oldEntity).ToBeUpdated))
                        {
                            entitiesToReplace[oldEntity] = newEntity;
                        }
                        entitiesToRemove.Remove(oldEntity);
                    });
                }

                if (mergeModel)
                {
                    for (int a = entities.Count; a-- > 0;)
                    {
                        T item = entities[a];
                        if (entitiesToRemove.Contains(item))
                        {
                            Model.RemoveAt(a);
                            continue;
                        }
                        T replacingItem = DictionaryExtension.ValueOrDefault(entitiesToReplace, item);
                        if (replacingItem != null)
                        {
                            Model.Replace(a, replacingItem);
                            continue;
                        }
                    }
                    IEnumerator <T> enumerator = entitiesToAdd.GetEnumerator();
                    while (enumerator.MoveNext())
                    {
                        T entityToAdd = enumerator.Current;
                        Model.Add(entityToAdd);
                    }

                    if (hasPagedViewModel)
                    {
                        UpdatePagingInformation(pagingResponse);
                    }
                    UpdateAfterDCE();
                }
            });
        }