Beispiel #1
0
        //static int count = 10000000;

        ////[TestInitialize]
        //public void InitManually()
        //{
        //    base.InitManually(GetType());
        //}

        //static Object[] objects;

        //static ValueHolderContainerTest()
        //{
        //     objects = new Object[count];
        //        for (int a = count; a-- > 0; )
        //        {
        //            objects[a] = new Object();
        //        }
        //}

        //[TestMethod]
        //public void test_Dictionary()
        //{
        //    Dictionary<Object, Object> dict = new Dictionary<Object, Object>(count, new IdentityEqualityComparer<Object>());

        //    //for (int a = count; a-- > 0; )
        //    //{
        //    //    dict.Add(a, objects[a]);
        //    //    dict.Remove(a);
        //    //    dict.Add(a, objects[a]);
        //    //    dict.Remove(a);
        //    //    dict.Add(a, objects[a]);
        //    //    dict.Remove(a);
        //    //    dict.Add(a, objects[a]);
        //    //    dict.Remove(a);
        //    //    dict.Add(a, objects[a]);
        //    //    dict.Remove(a);
        //    //}
        //    for (int a = count; a-- > 0; )
        //    {
        //        dict.Add(a, objects[a]);
        //    }
        //    for (int a = 10; a-- > 0; )
        //    {
        //        foreach (KeyValuePair<Object, Object> entry in dict)
        //        {
        //            Object key = entry.Key;
        //            Object value = entry.Value;
        //            if (!Object.ReferenceEquals(objects[(int)key], value))
        //            {
        //                throw new Exception();
        //            }
        //        }
        //    }
        //}

        //[TestMethod]
        //public void test_HashMap()
        //{
        //    IdentityLinkedMap<Object, Object> dict = IdentityLinkedMap<Object, Object>.Create(count);

        //    //for (int a = count; a-- > 0; )
        //    //{
        //    //    dict.Put(a, objects[a]);
        //    //    dict.Remove(a);
        //    //    dict.Put(a, objects[a]);
        //    //    dict.Remove(a);
        //    //    dict.Put(a, objects[a]);
        //    //    dict.Remove(a);
        //    //    dict.Put(a, objects[a]);
        //    //    dict.Remove(a);
        //    //    dict.Put(a, objects[a]);
        //    //    dict.Remove(a);
        //    //}
        //    for (int a = count; a-- > 0; )
        //    {
        //        dict.Put(a, objects[a]);
        //    }
        //    for (int a = 10; a-- > 0; )
        //    {
        //        foreach (Entry<Object, Object> entry in dict)
        //        {
        //            Object key = entry.Key;
        //            Object value = entry.Value;
        //            if (!Object.ReferenceEquals(objects[(int)key], value))
        //            {
        //                throw new Exception();
        //            }
        //        }
        //    }
        //}

        //[TestMethod]
        //public void test_PropertyInfo()
        //{
        //    Material mat = new Material();

        //    PropertyInfo pi = mat.GetType().GetProperty("Name");

        //    DateTime prePi = DateTime.Now;
        //    for (int a = count; a-- > 0; )
        //    {
        //        Object piValue = pi.GetValue(mat, null);
        //        piValue = pi.GetValue(mat, null);
        //        piValue = pi.GetValue(mat, null);
        //        piValue = pi.GetValue(mat, null);
        //        piValue = pi.GetValue(mat, null);
        //        piValue = pi.GetValue(mat, null);
        //        piValue = pi.GetValue(mat, null);
        //        piValue = pi.GetValue(mat, null);
        //        piValue = pi.GetValue(mat, null);
        //        piValue = pi.GetValue(mat, null);
        //        piValue = pi.GetValue(mat, null);
        //        piValue = pi.GetValue(mat, null);
        //        piValue = pi.GetValue(mat, null);
        //        piValue = pi.GetValue(mat, null);
        //        piValue = pi.GetValue(mat, null);
        //        piValue = pi.GetValue(mat, null);
        //        piValue = pi.GetValue(mat, null);
        //        piValue = pi.GetValue(mat, null);
        //        piValue = pi.GetValue(mat, null);
        //        piValue = pi.GetValue(mat, null);
        //    }
        //    DateTime postPi = DateTime.Now;
        //    long piTime = postPi.Ticks - prePi.Ticks;
        //    Console.WriteLine(piTime);
        //}

        //[TestMethod]
        //public void test_GetDelegate()
        //{
        //    Material mat = new Material();

        //    MemberGetDelegate del = TypeUtility.GetMemberGetDelegate(mat.GetType(), "Name");

        //    MemberSetDelegate setDel = TypeUtility.GetMemberSetDelegate(mat.GetType(), "Id");

        //    setDel(mat, 5);

        //    DateTime preDel = DateTime.Now;
        //    for (int a = count; a-- > 0; )
        //    {
        //        Object delValue = del(mat);
        //        delValue = del(mat);
        //        delValue = del(mat);
        //        delValue = del(mat);
        //        delValue = del(mat);
        //        delValue = del(mat);
        //        delValue = del(mat);
        //        delValue = del(mat);
        //        delValue = del(mat);
        //        delValue = del(mat);
        //        delValue = del(mat);
        //        delValue = del(mat);
        //        delValue = del(mat);
        //        delValue = del(mat);
        //        delValue = del(mat);
        //        delValue = del(mat);
        //        delValue = del(mat);
        //        delValue = del(mat);
        //        delValue = del(mat);
        //        delValue = del(mat);
        //    }
        //    DateTime postDel = DateTime.Now;

        //    long delTime = postDel.Ticks - preDel.Ticks;
        //    Console.WriteLine(delTime);
        //}

        protected void WaitForUI()
        {
            GuiThreadHelper.InvokeInGuiAndWait(delegate()
            {
                // Intended blank
            });
        }
        protected void ChangeFirstLevelCaches(CacheDependencyNode node, ISet <IObjRef> intermediateDeletes)
        {
            List <IDataChangeEntry> deletes           = new List <IDataChangeEntry>();
            ICacheModification      cacheModification = this.CacheModification;

            bool oldCacheModificationValue = cacheModification.Active;

            if (!oldCacheModificationValue)
            {
                cacheModification.Active = true;
            }
            try
            {
                ChangeFirstLevelCachesIntern(node, intermediateDeletes);
            }
            finally
            {
                if (!oldCacheModificationValue)
                {
                    cacheModification.Active = oldCacheModificationValue;
                }
            }
            if (deletes.Count > 0)
            {
                IDataChange dce = DataChangeEvent.Create(0, 0, deletes.Count);
                ListUtil.AddAll(dce.Deletes, dce.Deletes.Count, deletes);
                GuiThreadHelper.InvokeOutOfGui(delegate()
                {
                    EventDispatcher.DispatchEvent(dce);
                });
            }
        }
Beispiel #3
0
        protected void MergePhase2(Object objectToMerge, Object objectToDelete, MergeHandle mergeHandle, ICUDResult cudResult, ProceedWithMergeHook proceedHook, MergeFinishedCallback mergeFinishedCallback, bool addNewEntitiesToCache)
        {
            List <Object> unpersistedObjectsToDelete = new List <Object>();

            RemoveUnpersistedDeletedObjectsFromCudResult(cudResult.AllChanges, cudResult.GetOriginalRefs(), unpersistedObjectsToDelete);
            if (objectToDelete != null)
            {
                IList <IObjRef> oriList = OriHelper.ExtractObjRefList(objectToDelete, mergeHandle);

                AppendDeleteContainers(objectToDelete, oriList, cudResult.AllChanges, cudResult.GetOriginalRefs(), unpersistedObjectsToDelete);
            }

            // Store the MergeFinishedCallback from this thread on the stack and set the property null (for following calls):
            if (GuiThreadHelper.IsInGuiThread())
            {
                GuiThreadHelper.InvokeOutOfGui(delegate()
                {
                    MergePhase3(objectToMerge, unpersistedObjectsToDelete, cudResult, proceedHook, mergeFinishedCallback, addNewEntitiesToCache);
                });
            }
            else
            {
                MergePhase3(objectToMerge, unpersistedObjectsToDelete, cudResult, proceedHook, mergeFinishedCallback, addNewEntitiesToCache);
            }
        }
Beispiel #4
0
        protected void FireQueuedPropertyChangeEvents()
        {
            List <IBackgroundWorkerDelegate> queuedEvents = queuedEventsTL.Value;

            if (queuedEvents == null)
            {
                return;
            }
            queuedEventsTL.Value = null;
            Log.Info("ICacheModification.FlushInGui()");
            GuiThreadHelper.InvokeInGui(delegate()
            {
                Log.Info("ICacheModification.FlushWithinGui()");
                try
                {
                    for (int a = 0, size = queuedEvents.Count; a < size; a++)
                    {
                        IBackgroundWorkerDelegate queuedEvent = queuedEvents[a];
                        queuedEvent();
                    }
                }
                catch (Exception e)
                {
                    Log.Error(e);
                    throw;
                }
                Log.Info("ICacheModification.FlushWithinGui finished");
            });
        }
Beispiel #5
0
        protected void MergePhase1(Object objectToMerge, Object objectToDelete, ProceedWithMergeHook proceedHook, MergeFinishedCallback mergeFinishedCallback, bool addNewEntitiesToCache)
        {
            ICUDResult       cudResult;
            MergeHandle      mergeHandle;
            IDisposableCache childCache = CacheFactory.Create(CacheFactoryDirective.NoDCE, false, false, "MergeProcess.ORIGINAL");

            try
            {
                mergeHandle = BeanContext.RegisterBean <MergeHandle>() //
                              .PropertyValue("Cache", childCache)      //
                              .Finish();
                cudResult         = MergeController.MergeDeep(objectToMerge, mergeHandle);
                mergeHandle.Cache = null;
            }
            finally
            {
                childCache.Dispose();
                childCache = null;
            }
            if (GuiThreadHelper.IsInGuiThread())
            {
                MergePhase2(objectToMerge, objectToDelete, mergeHandle, cudResult, proceedHook, mergeFinishedCallback, addNewEntitiesToCache);
            }
            else
            {
                GuiThreadHelper.InvokeInGui(delegate()
                {
                    MergePhase2(objectToMerge, objectToDelete, mergeHandle, cudResult, proceedHook, mergeFinishedCallback, addNewEntitiesToCache);
                });
            }
        }
 protected virtual void RaisePropertyChanged(String propertyName)
 {
     GuiThreadHelper.InvokeInGui(delegate()
     {
         var localEventHandler = PropertyChanged;
         if (localEventHandler != null)
         {
             localEventHandler.Invoke(this, new PropertyChangedEventArgs(propertyName));
         }
     });
 }
Beispiel #7
0
 public void ApplyChangesToOriginals(ICUDResult cudResult, IOriCollection oriCollection, ICache cache)
 {
     if (GuiThreadHelper.IsInGuiThread())
     {
         ApplyChangesToOriginalsIntern(cudResult, oriCollection, cache);
         return;
     }
     GuiThreadHelper.InvokeInGuiAndWait(new IBackgroundWorkerDelegate(delegate()
     {
         ApplyChangesToOriginalsIntern(cudResult, oriCollection, cache);
     }));
 }
Beispiel #8
0
 public void Process(Object objectToMerge, Object objectToDelete, ProceedWithMergeHook proceedHook, MergeFinishedCallback mergeFinishedCallback, bool addNewEntitiesToCache)
 {
     if (GuiThreadHelper.IsInGuiThread())
     {
         GuiThreadHelper.InvokeOutOfGui(delegate()
         {
             MergePhase1(objectToMerge, objectToDelete, proceedHook, mergeFinishedCallback, addNewEntitiesToCache);
         });
     }
     else
     {
         MergePhase1(objectToMerge, objectToDelete, proceedHook, mergeFinishedCallback, addNewEntitiesToCache);
     }
 }
        public virtual void Populate()
        {
            var localRequest = new Object();

            lock (currentRequestLock)
            {
                currentRequest = localRequest;
            }
            if (GuiThreadHelper.IsInGuiThread())
            {
                IFilterDescriptor       filterDescriptor = GetFilterDescriptor();
                IList <ISortDescriptor> sortDescriptors  = GetSortDescriptors();
                IPagingRequest          pagingRequest    = GetPagingRequest();
                Object[] contextInformation = GetContextInformation();

                Model.IsBusy = true;
                ThreadPool.Queue((GenericViewModel <T> model) =>
                {
                    CacheContext.ExecuteWithCache <Object>(CacheProvider.GetCurrentCache(), delegate()
                    {
                        ConfigureCacheWithEagerLoads(Cache);
                        PopulateAsync(model, filterDescriptor, sortDescriptors, pagingRequest, contextInformation, Cache, localRequest);
                        return(null);
                    });
                }, Model);
            }
            else
            {
                IFilterDescriptor       filterDescriptor = null;
                IList <ISortDescriptor> sortDescriptors  = null;
                IPagingRequest          pagingRequest    = null;
                Object[] contextInformation = null;
                GuiThreadHelper.InvokeInGuiAndWait(delegate()
                {
                    filterDescriptor = GetFilterDescriptor();
                    sortDescriptors  = GetSortDescriptors();
                    pagingRequest    = GetPagingRequest();

                    contextInformation = GetContextInformation();

                    Model.IsBusy = true;
                });
                CacheContext.ExecuteWithCache <Object>(CacheProvider.GetCurrentCache(), delegate()
                {
                    ConfigureCacheWithEagerLoads(Cache);
                    PopulateAsync(Model, filterDescriptor, sortDescriptors, pagingRequest, contextInformation, Cache, localRequest);
                    return(null);
                });
            }
        }
Beispiel #10
0
 protected void ExecuteFirePropertyChange(PropertyChangeSupport propertyChangeSupport, IList <IPropertyChangeExtension> extensions, Object obj, PropertyChangedEventArgs[] evnts, String[] propertyNames, Object[] oldValues, Object[] currentValues)
 {
     if (AsyncPropertyChangeActive)
     {
         GuiThreadHelper.InvokeInGui(delegate()
         {
             ExecuteFirePropertyChangeIntern(propertyChangeSupport, extensions, obj, evnts, propertyNames, oldValues, currentValues);
         });
     }
     else
     {
         ExecuteFirePropertyChangeIntern(propertyChangeSupport, extensions, obj, evnts, propertyNames, oldValues, currentValues);
     }
 }
Beispiel #11
0
 public virtual void OnCanExecuteChanged(Object sender, EventArgs e)
 {
     if (CanExecuteChanged != null)
     {
         if (GuiThreadHelper.IsInGuiThread())
         {
             CanExecuteChanged.Invoke(this, EventArgs.Empty);
         }
         else
         {
             SyncContext.Send((object state) =>
             {
                 CanExecuteChanged.Invoke(this, EventArgs.Empty);
             }, null);
         }
     }
 }
Beispiel #12
0
        public IBusyToken AcquireBusyToken()
        {
            BusyToken token = new BusyToken(this);
            bool      changed;

            lock (pendingTokens)
            {
                pendingTokens.Add(token);
                changed = (pendingTokens.Count == 1);
            }
            GuiThreadHelper.InvokeInGui(delegate()
            {
                PropertyChanged(this, busyCountPCE);
                // Busy flag might evaluate to true
                if (changed)
                {
                    PropertyChanged(this, isBusyPCE);
                }
            });
            return(token);
        }
Beispiel #13
0
        protected override void InterceptIntern(IInvocation invocation)
        {
            Attribute annotation = GetMethodLevelBehavior(invocation.Method);

            if (annotation is NoProxyAttribute)
            {
                InvokeTarget(invocation);
                return;
            }
            String  methodName   = invocation.Method.Name.ToLower();
            Boolean?isAsyncBegin = null;

            if (methodName.StartsWith("begin"))
            {
                isAsyncBegin = true;
                methodName   = methodName.Substring(5);
            }
            else if (methodName.StartsWith("end"))
            {
                isAsyncBegin = false;
                methodName   = methodName.Substring(3);
            }
            if (GuiThreadHelper.IsInGuiThread())
            {
                if (!typeof(void).Equals(invocation.Method.ReturnType))
                {
                    throw new Exception("It is not allowed to call synchronuous methods from GUI thread. Please use '" + typeof(IThreadPool).FullName
                                        + "' to make this synchronuous call from a background thread");
                }
                ThreadPool.Queue(delegate()
                {
                    Intercept(invocation, methodName, annotation, isAsyncBegin);
                });
                return;
            }
            Object result = Intercept(invocation, methodName, annotation, isAsyncBegin);

            invocation.ReturnValue = result;
        }
Beispiel #14
0
        public void Finished(IBusyToken busyToken)
        {
            bool changed;

            lock (pendingTokens)
            {
                if (!pendingTokens.Remove(busyToken))
                {
                    throw new ArgumentException("Token not known");
                }
                changed = (pendingTokens.Count == 0);
            }
            GuiThreadHelper.InvokeInGui(delegate()
            {
                PropertyChanged(this, busyCountPCE);
                // Busy flag might evaluate to false
                if (changed)
                {
                    PropertyChanged(this, isBusyPCE);
                }
            });
        }
Beispiel #15
0
        public void test_PropertyChange_OutOfGuiThread()
        {
            HashMap <String, IMap <Thread, int> > counter = new HashMap <String, IMap <Thread, int> >();
            PropertyChangedEventHandler           handler = GetPropertyChangeHandlerForUI(counter);

            Thread         workerThread = null;
            CountDownLatch latch        = new CountDownLatch(1);

            ThreadPool.Queue(delegate()
            {
                workerThread = Thread.CurrentThread;
                Log.Info("Test()");
                try
                {
                    Material obj = EntityFactory.CreateEntity <Material>();
                    ((INotifyPropertyChanged)obj).PropertyChanged += handler;

                    Log.Info("ICacheModification.set_Active(true)");
                    CacheModification.Active = true;
                    try
                    {
                        Log.Info("set_Id");
                        obj.Id = 1;
                        Log.Info("set_Id finished");
                        Assert.AssertEquals(0, counter.Count);
                    }
                    finally
                    {
                        Log.Info("ICacheModification.set_Active(false)");
                        CacheModification.Active = false;
                        Log.Info("ICacheModification.set_Active(false) finished");
                    }
                    WaitForUI();
                    Assert.AssertEquals(3, counter.Count);
                    Log.Info(" set_Name");
                    obj.Name = "hallo";
                    WaitForUI();
                    Log.Info("set_Name finished");
                    Assert.AssertEquals(5, counter.Count);
                }
                finally
                {
                    latch.CountDown();
                }
            });
            Log.Info("Await()");
            latch.Await();
            // Wait till the current ui queue has been processed completely
            GuiThreadHelper.InvokeInGuiAndWait(delegate()
            {
                // just an empty blocking delegate
            });
            Assert.AssertEquals(5, counter.Count);

            Thread guiThread = ValueHolderContainerTestModule.dispatcherThread;

            IMap <Thread, int> toBeCreatedMap = counter.Get("ToBeCreated");

            Assert.AssertNotNull(toBeCreatedMap);
            Assert.AssertEquals(1, toBeCreatedMap.Count);
            Assert.AssertTrue(toBeCreatedMap.ContainsKey(guiThread));
            Assert.AssertEquals(1, toBeCreatedMap.Get(guiThread));

            IMap <Thread, int> idMap = counter.Get("Id");

            Assert.AssertNotNull(idMap);
            Assert.AssertEquals(1, idMap.Count);
            Assert.AssertTrue(idMap.ContainsKey(guiThread));
            Assert.AssertEquals(1, idMap.Get(guiThread));

            // uiThread is intended for Name in the case where asynchronous PCEs are allowed
            // but dispatched transparently in the UI
            IMap <Thread, int> nameMap = counter.Get("Name");

            Assert.AssertNotNull(nameMap);
            Assert.AssertEquals(1, nameMap.Count);
            Assert.AssertTrue(idMap.ContainsKey(guiThread));
            Assert.AssertEquals(1, nameMap.Get(guiThread));

            IMap <Thread, int> toBeUpdatedMap = counter.Get("ToBeUpdated");

            Assert.AssertNotNull(toBeUpdatedMap);
            Assert.AssertEquals(1, toBeUpdatedMap.Count);
            Assert.AssertTrue(toBeUpdatedMap.ContainsKey(guiThread));
            Assert.AssertEquals(1, toBeUpdatedMap.Get(guiThread));

            IMap <Thread, int> hasPendingChangesMap = counter.Get("HasPendingChanges");

            Assert.AssertNotNull(hasPendingChangesMap);
            Assert.AssertEquals(1, hasPendingChangesMap.Count);
            Assert.AssertTrue(hasPendingChangesMap.ContainsKey(guiThread));
            Assert.AssertEquals(2, hasPendingChangesMap.Get(guiThread));
        }
Beispiel #16
0
        protected void ProcessPendingOrelsAndObjRefs(ILinkedMap <Type, PrefetchPath[]> entityTypeToPrefetchPath,
                                                     AlreadyHandledSet alreadyHandledSet, IdentityLinkedMap <ICacheIntern, IISet <IObjRef> > cacheToOrisLoadedHistory,
                                                     IdentityLinkedMap <ICacheIntern, IISet <IObjRelation> > cacheToOrelsLoadedHistory, IdentityLinkedMap <ICacheIntern, IISet <IObjRef> > cacheToOrisToLoad,
                                                     IdentityLinkedMap <ICacheIntern, IMap <IObjRelation, bool> > cacheToOrelsToLoad, List <PrefetchCommand> pendingPrefetchCommands,
                                                     List <Object> hardRefList)
        {
            // all relation members where at least one instance of the owning entity type needs a prefetch on this member in the immediate next step
            MergePrefetchPathsCache mergePrefetchPathsCache = new MergePrefetchPathsCache(EntityMetaDataProvider);

            IdentityLinkedSet <Member> prioMembers = PrioMembersProvider.GetPrioMembers(entityTypeToPrefetchPath, pendingPrefetchCommands, mergePrefetchPathsCache);

            LoadAndAddOrels(cacheToOrelsToLoad, hardRefList, cacheToOrelsLoadedHistory, cacheToOrisToLoad, prioMembers);
            LoadAndAddOris(cacheToOrisToLoad, hardRefList, cacheToOrisLoadedHistory);

            while (pendingPrefetchCommands.Count > 0)
            {
                PrefetchCommand[] currentPrefetchCommands = pendingPrefetchCommands.ToArray();
                // Clear the items to be ready for cascaded items in new batch recursion step
                pendingPrefetchCommands.Clear();
                if (prioMembers.Count > 0)
                {
                    for (int a = 0, size = currentPrefetchCommands.Length; a < size; a++)
                    {
                        PrefetchCommand      prefetchCommand = currentPrefetchCommands[a];
                        DirectValueHolderRef valueHolder     = prefetchCommand.valueHolder;
                        if (!prioMembers.Contains(valueHolder.Member))
                        {
                            currentPrefetchCommands[a] = null;
                            pendingPrefetchCommands.Add(prefetchCommand);
                        }
                    }
                }
                GuiThreadHelper.InvokeInGuiAndWait(delegate()
                {
                    ICacheModification cacheModification = CacheModification;
                    ValueHolderContainerMixin valueHolderContainerMixin = ValueHolderContainerMixin;
                    bool oldActive = cacheModification.Active;
                    if (!oldActive)
                    {
                        cacheModification.Active = true;
                    }
                    try
                    {
                        foreach (PrefetchCommand prefetchCommand in currentPrefetchCommands)
                        {
                            if (prefetchCommand == null)
                            {
                                continue;
                            }
                            DirectValueHolderRef valueHolder = prefetchCommand.valueHolder;
                            PrefetchPath[] cachePaths        = prefetchCommand.prefetchPaths;

                            RelationMember member = valueHolder.Member;
                            // Merge the root prefetch path with the relative prefetch path
                            cachePaths = mergePrefetchPathsCache.MergePrefetchPaths(member.ElementType, cachePaths, entityTypeToPrefetchPath);

                            IObjRefContainer vhc = valueHolder.Vhc;
                            ICacheIntern targetCache;
                            bool doSetValue = false;
                            if (valueHolder is IndirectValueHolderRef)
                            {
                                IndirectValueHolderRef valueHolderKey = (IndirectValueHolderRef)valueHolder;
                                targetCache = valueHolderKey.RootCache;
                            }
                            else
                            {
                                targetCache = ((IValueHolderContainer)vhc).__TargetCache;
                                doSetValue  = true;
                            }
                            int relationIndex = vhc.Get__EntityMetaData().GetIndexByRelation(member);
                            IObjRef[] objRefs = vhc.Get__ObjRefs(relationIndex);
                            Object obj        = valueHolderContainerMixin.GetValue(vhc, relationIndex, member, targetCache, objRefs, CacheDirective.FailEarly);
                            if (doSetValue && obj != null)
                            {
                                member.SetValue(vhc, obj);
                            }
                            EnsureInitializedRelationsIntern3(obj, cachePaths, entityTypeToPrefetchPath, cacheToOrisToLoad, cacheToOrelsToLoad, cacheToOrisLoadedHistory,
                                                              cacheToOrelsLoadedHistory, alreadyHandledSet, pendingPrefetchCommands);
                        }
                    }
                    finally
                    {
                        if (!oldActive)
                        {
                            cacheModification.Active = false;
                        }
                    }
                });
                // Remove all oris which have already been tried to load before
                if (cacheToOrisToLoad.Count == 0 && cacheToOrelsToLoad.Count == 0 && pendingPrefetchCommands.Count == 0)
                {
                    return;
                }
                prioMembers = PrioMembersProvider.GetPrioMembers(entityTypeToPrefetchPath, pendingPrefetchCommands, mergePrefetchPathsCache);
                LoadAndAddOrels(cacheToOrelsToLoad, hardRefList, cacheToOrelsLoadedHistory, cacheToOrisToLoad, prioMembers);
                LoadAndAddOris(cacheToOrisToLoad, hardRefList, cacheToOrisLoadedHistory);
            }
        }
        public void FilterValues()
        {
            if (DataSource == null)
            {
                return;
            }
            IList <T> readonlyDataSourceContext;

            if (DataSource is IModelMultiContainer <T> )
            {
                readonlyDataSourceContext = ((IModelMultiContainer <T>)DataSource).Values;
            }
            else if (DataSource is IModelSingleContainer <T> )
            {
                readonlyDataSourceContext = new List <T>(1);
                T value = ((IModelSingleContainer <T>)DataSource).Value;
                if (value != null)
                {
                    readonlyDataSourceContext.Add(value);
                }
            }
            else
            {
                throw new NotSupportedException(typeof(IModelContainer).Name + " of type '" + DataSource.GetType() + "' not supported");
            }
            SetBusy();
            if (GuiThreadHelper.IsInGuiThread())
            {
                // Create a 'safe copy' of the datasource from within gui thread
                IList <T> clonedDataSourceContext = new List <T>(readonlyDataSourceContext);
                ThreadPool.Queue(delegate()
                {
                    try
                    {
                        IList <T> values = ClientFilter.Filter(clonedDataSourceContext);

                        // This will not set the Values-IList<T> Pointer but will clear and reinit its content
                        // This assumption is important because our unmodifiableValues-Property depends on it
                        SyncContext.Send((object state) =>
                        {
                            base.Values = values;
                        }, null);
                    }
                    finally
                    {
                        SetUnbusy();
                    }
                });
            }
            else
            {
                try
                {
                    IList <T> clonedDataSourceContext = null;
                    SyncContext.Send((object state) =>
                    {
                        // Create a 'safe copy' of the datasource from within gui thread
                        clonedDataSourceContext = new List <T>(readonlyDataSourceContext);
                    }, null);

                    IList <T> values = ClientFilter.Filter(clonedDataSourceContext);

                    // This will not set the Values-IList<T> Pointer but will clear and reinit its content
                    // This assumption is important because our unmodifiableValues-Property depends on it
                    SyncContext.Send((object state) =>
                    {
                        base.Values = values;
                    }, null);
                }
                finally
                {
                    SetUnbusy();
                }
            }
        }
        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();
                }
            });
        }
        protected void DataChangedIntern(IDataChange dataChange, IList <Object> pausedEventTargets, IProcessResumeItem processResumeItem, CacheDependencyNode rootNode)
        {
            try
            {
                bool isLocalSource = dataChange.IsLocalSource;
                IList <IDataChangeEntry> deletes = dataChange.Deletes;
                IList <IDataChangeEntry> updates = dataChange.Updates;
                IList <IDataChangeEntry> inserts = dataChange.Inserts;

                CHashSet <Type>    occuringTypes       = new CHashSet <Type>();
                CHashSet <IObjRef> deletesSet          = new CHashSet <IObjRef>();
                CHashSet <Type>    directRelatingTypes = new CHashSet <Type>();
                bool acquirementSuccessful             = rootNode.rootCache.AcquireHardRefTLIfNotAlready();
                try
                {
                    for (int a = deletes.Count; a-- > 0;)
                    {
                        IDataChangeEntry deleteEntry = deletes[a];
                        Type             entityType  = deleteEntry.EntityType;
                        occuringTypes.Add(entityType);
                        if (deleteEntry is DirectDataChangeEntry)
                        {
                            // Ignore delete entries of unpersisted objects here
                            continue;
                        }
                        ObjRef tempORI = new ObjRef(entityType, deleteEntry.IdNameIndex, deleteEntry.Id, deleteEntry.Version);
                        deletesSet.Add(tempORI);
                    }
                    // Remove items from the cache only if they are really deleted/updates by a remote event
                    // And not 'simulated' by a local source
                    bool cleanupSecondLevelCaches = false;
                    if (pausedEventTargets != null && (deletes.Count > 0 || updates.Count > 0) && !isLocalSource)
                    {
                        cleanupSecondLevelCaches = true;
                    }
                    else if (updates.Count > 0)
                    {
                        for (int a = updates.Count; a-- > 0;)
                        {
                            IDataChangeEntry updateEntry = updates[a];
                            Type             entityType  = updateEntry.EntityType;
                            occuringTypes.Add(entityType);
                        }
                    }
                    for (int a = inserts.Count; a-- > 0;)
                    {
                        IDataChangeEntry insertEntry = inserts[a];
                        Type             entityType  = insertEntry.EntityType;
                        occuringTypes.Add(entityType);
                    }
                    EnsureMetaDataIsLoaded(occuringTypes, directRelatingTypes);

                    if (cleanupSecondLevelCaches)
                    {
                        CleanupSecondLevelCaches(rootNode, deletesSet.ToList(), updates, occuringTypes);
                    }

                    BuildCacheChangeItems(rootNode, dataChange);

                    rootNode.AggregateAllCascadedObjRefs();

                    ISet <IObjRef> intermediateDeletes = rootNode.lookForIntermediateDeletes();

                    ChangeSecondLevelCache(rootNode);

                    if (rootNode.IsPendingChangeOnAnyChildCache())
                    {
                        GuiThreadHelper.InvokeInGuiAndWait(delegate()
                        {
                            bool oldFailEarlyModeActive = AbstractCache.FailInCacheHierarchyModeActive;
                            AbstractCache.FailInCacheHierarchyModeActive = true;
                            try
                            {
                                ChangeFirstLevelCaches(rootNode, intermediateDeletes);
                            }
                            finally
                            {
                                AbstractCache.FailInCacheHierarchyModeActive = oldFailEarlyModeActive;
                            }
                        });
                    }
                }
                finally
                {
                    rootNode.rootCache.ClearHardRefs(acquirementSuccessful);
                }
            }
            finally
            {
                if (processResumeItem != null)
                {
                    processResumeItem.ResumeProcessingFinished();
                }
            }
        }
        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;
                    }
                });
            }
        }
Beispiel #21
0
        protected virtual void RevertChangesIntern(IRevertChangesSavepoint savepoint, IList <Object> objectsToRevert, bool globally,
                                                   RevertChangesFinishedCallback revertChangesFinishedCallback)
        {
            // Store the RevertChangesFinishedCallback from this thread on the stack and set the property null (for following calls):
            if (objectsToRevert == null || objectsToRevert.Count == 0)
            {
                if (revertChangesFinishedCallback != null)
                {
                    revertChangesFinishedCallback.Invoke(true);
                }
                return;
            }
            if (globally)
            {
                GuiThreadHelper.InvokeOutOfGui(delegate()
                {
                    bool success = false;
                    try
                    {
                        DataChangeEvent dataChange = new DataChangeEvent();
                        dataChange.IsLocalSource   = true;
                        dataChange.Inserts         = new List <IDataChangeEntry>(0);
                        dataChange.Updates         = new List <IDataChangeEntry>();
                        dataChange.Deletes         = new List <IDataChangeEntry>();

                        for (int a = objectsToRevert.Count; a-- > 0;)
                        {
                            Object objectToRevert    = objectsToRevert[a];
                            IEntityMetaData metaData = ((IEntityMetaDataHolder)objectToRevert).Get__EntityMetaData();
                            Object id = metaData.IdMember.GetValue(objectToRevert, false);

                            if (id == null)
                            {
                                dataChange.Deletes.Add(new DirectDataChangeEntry(objectToRevert));
                                continue;
                            }
                            dataChange.Updates.Add(new DataChangeEntry(metaData.EntityType, ObjRef.PRIMARY_KEY_INDEX, id, null));
                        }

                        EventDispatcher.DispatchEvent(dataChange, DateTime.Now, -1);
                        success = true;
                    }
                    finally
                    {
                        if (revertChangesFinishedCallback != null)
                        {
                            revertChangesFinishedCallback.Invoke(success);
                        }
                    }
                });
            }
            else
            {
                // Commented the following part from Ambeth 0.130 and use the part from Ambeth 0.129 due to a deadlock in the merge process:
                //GuiThreadHelper.InvokeOutOfGui(delegate()
                //{
                //    bool success1 = false;
                //    try
                //    {
                //        IList<IDataChangeEntry> directObjectDeletes = new List<IDataChangeEntry>();
                //        IList<Object> initializedObjects = MergeController.ScanForInitializedObjects(objectsToRevert, true, null);

                //        IList<IObjRef> orisToRevert = new List<IObjRef>();
                //        ISet<Object> persistedObjectsToRevert = new IdentityHashSet<Object>();
                //        for (int a = initializedObjects.Count; a-- > 0; )
                //        {
                //            Object objectToRevert = initializedObjects[a];
                //            IEntityMetaData metaData = EntityMetaDataProvider.GetMetaData(objectToRevert.GetType());
                //            Object id = metaData.IdMember.GetValue(objectToRevert, false);

                //            if (id == null)
                //            {
                //                directObjectDeletes.Add(new DirectDataChangeEntry(objectToRevert));
                //                continue;
                //            }
                //            persistedObjectsToRevert.Add(objectToRevert);
                //            orisToRevert.Add(new ObjRef(metaData.EntityType, ObjRef.PRIMARY_KEY_INDEX, id, null));
                //        }
                //        IList<Object> hardRefsToRootCacheValues = RootCache.GetObjects(orisToRevert, CacheDirective.CacheValueResult | CacheDirective.ReturnMisses);

                //        for (int a = orisToRevert.Count; a-- > 0; )
                //        {
                //            if (hardRefsToRootCacheValues[a] == null)
                //            {
                //                // Object could not be loaded/retrieved any more. So the ori refers to an invalid object
                //                // We can not revert invalid objects and currently ignore them. They will raise exceptions if they will
                //                // be tried to persist in a merge process any time in the future
                //                orisToRevert.RemoveAt(a);
                //            }
                //        }
                //        // We do nothing with the hardRef-list from the RootCache. It is only necessary to keep track of the instance reference on the stack
                //        // To prohibit GC any potential WeakReferences in the meantime....
                //        GuiThreadHelper.InvokeInGuiAndWait(delegate()
                //        {
                //            IProcessResumeItem processResumeItem = WaitEventToResume();
                //            try
                //            {
                //                bool oldCacheModificationValue = CacheModification.IsActive;
                //                CacheModification.IsActive = true;
                //                bool oldFailEarlyModeActive = AbstractCache<Object>.FailEarlyModeActive;
                //                AbstractCache<Object>.FailEarlyModeActive = true;
                //                try
                //                {
                //                    IList<IWritableCache> firstLevelCaches = FirstLevelCacheManager.SelectFirstLevelCaches();
                //                    IList<Object> hardRefsToRootCacheValuesHere = hardRefsToRootCacheValues;

                //                    foreach (IWritableCache firstLevelCache in firstLevelCaches)
                //                    {
                //                        IList<Object> persistedObjectsInThisCache = firstLevelCache.GetObjects(orisToRevert, CacheDirective.FailEarly);

                //                        for (int a = persistedObjectsInThisCache.Count; a-- > 0; )
                //                        {
                //                            Object persistedObjectInThisCache = persistedObjectsInThisCache[a];
                //                            if (!persistedObjectsToRevert.Contains(persistedObjectInThisCache))
                //                            {
                //                                continue;
                //                            }
                //                            RootCache.ApplyValues(persistedObjectInThisCache, (ICacheIntern)firstLevelCache);
                //                        }
                //                    }
                //                    for (int a = objectsToRevert.Count; a-- > 0; )
                //                    {
                //                        Object objectToRevert = objectsToRevert[a];
                //                        if (objectToRevert is IDataObject)
                //                        {
                //                            // Objects which are specified to be reverted loose their delete flag
                //                            ((IDataObject)objectToRevert).ToBeDeleted = false;
                //                        }
                //                    }
                //                }
                //                finally
                //                {
                //                    AbstractCache<Object>.FailEarlyModeActive = oldFailEarlyModeActive;
                //                    CacheModification.IsActive = oldCacheModificationValue;
                //                }
                //            }
                //            finally
                //            {
                //                if (processResumeItem != null)
                //                {
                //                    processResumeItem.ResumeProcessingFinished();
                //                    processResumeItem = null;
                //                }
                //            }
                //        });
                //        if (directObjectDeletes.Count > 0)
                //        {
                //            DataChangeEvent dataChange = DataChangeEvent.Create(0, 0, 0);
                //            dataChange.Deletes = directObjectDeletes;

                //            EventDispatcher.DispatchEvent(dataChange, DateTime.Now, -1);
                //        }
                //        success1 = true;
                //    }
                //    finally
                //    {
                //        if (revertChangesFinishedCallback != null)
                //        {
                //            revertChangesFinishedCallback.Invoke(success1);
                //        }
                //    }
                //});

                // Here comes the part from Ambeth 0.129:
                GuiThreadHelper.InvokeOutOfGui(delegate()
                {
                    bool success1 = false;
                    bool?success2 = null;
                    bool?success3 = null;
                    try
                    {
                        IList <IDataChangeEntry> directObjectDeletes = new List <IDataChangeEntry>();
                        List <IObjRef> objRefs = new List <IObjRef>();
                        List <ValueHolderRef> valueHolderKeys = new List <ValueHolderRef>();
                        IList <Object> initializedObjects     = MergeController.ScanForInitializedObjects(objectsToRevert, true, null, objRefs, valueHolderKeys);

                        IList <IObjRef> orisToRevert           = new List <IObjRef>();
                        ISet <Object> persistedObjectsToRevert = new IdentityHashSet <Object>();
                        for (int a = initializedObjects.Count; a-- > 0;)
                        {
                            Object objectToRevert    = initializedObjects[a];
                            IEntityMetaData metaData = ((IEntityMetaDataHolder)objectToRevert).Get__EntityMetaData();
                            Object id = metaData.IdMember.GetValue(objectToRevert, false);

                            if (id == null)
                            {
                                directObjectDeletes.Add(new DirectDataChangeEntry(objectToRevert));
                                continue;
                            }
                            persistedObjectsToRevert.Add(objectToRevert);
                            orisToRevert.Add(new ObjRef(metaData.EntityType, ObjRef.PRIMARY_KEY_INDEX, id, null));
                        }
                        IList <Object> hardRefsToRootCacheValues = RootCache.GetObjects(orisToRevert, CacheDirective.CacheValueResult | CacheDirective.ReturnMisses);

                        for (int a = orisToRevert.Count; a-- > 0;)
                        {
                            if (hardRefsToRootCacheValues[a] == null)
                            {
                                // Object could not be loaded/retrieved any more. So the ori refers to an invalid object
                                // We can not revert invalid objects and currently ignore them. They will raise exceptions if they will
                                // be tried to persist in a merge process any time in the future
                                orisToRevert.RemoveAt(a);
                            }
                        }
                        // We do nothing with the hardRef-list from the RootCache. It is only necessary to keep track of the instance reference on the stack
                        // To prohibit GC any potential WeakReferences in the meantime....
                        success2 = false;
                        GuiThreadHelper.InvokeInGui(delegate(Object state)
                        {
                            WaitEventToResume(delegate(IProcessResumeItem processResumeItem)
                            {
                                try
                                {
                                    bool oldCacheModificationValue = CacheModification.Active;
                                    CacheModification.Active       = true;
                                    bool oldFailEarlyModeActive    = AbstractCache.FailInCacheHierarchyModeActive;
                                    AbstractCache.FailInCacheHierarchyModeActive = true;
                                    try
                                    {
                                        IList <IWritableCache> firstLevelCaches      = FirstLevelCacheManager.SelectFirstLevelCaches();
                                        IList <Object> hardRefsToRootCacheValuesHere = hardRefsToRootCacheValues;

                                        foreach (IWritableCache firstLevelCache in firstLevelCaches)
                                        {
                                            IList <Object> persistedObjectsInThisCache = firstLevelCache.GetObjects(orisToRevert, CacheDirective.FailEarly);

                                            for (int a = persistedObjectsInThisCache.Count; a-- > 0;)
                                            {
                                                Object persistedObjectInThisCache = persistedObjectsInThisCache[a];
                                                if (!persistedObjectsToRevert.Contains(persistedObjectInThisCache))
                                                {
                                                    continue;
                                                }
                                                RootCache.ApplyValues(persistedObjectInThisCache, (ICacheIntern)firstLevelCache, null);
                                            }
                                        }
                                        for (int a = objectsToRevert.Count; a-- > 0;)
                                        {
                                            Object objectToRevert = objectsToRevert[a];
                                            if (objectToRevert is IDataObject)
                                            {
                                                // Objects which are specified to be reverted loose their flags
                                                ((IDataObject)objectToRevert).ToBeDeleted = false;
                                            }
                                        }
                                        if (directObjectDeletes.Count == 0)
                                        {
                                            success2 = true;
                                            return;
                                        }
                                    }
                                    finally
                                    {
                                        AbstractCache.FailInCacheHierarchyModeActive = oldFailEarlyModeActive;
                                        CacheModification.Active = oldCacheModificationValue;
                                    }
                                }
                                finally
                                {
                                    if (processResumeItem != null)
                                    {
                                        processResumeItem.ResumeProcessingFinished();
                                    }
                                }
                                success3 = false;
                                GuiThreadHelper.InvokeOutOfGui(delegate()
                                {
                                    try
                                    {
                                        DataChangeEvent dataChange = DataChangeEvent.Create(0, 0, 0);
                                        dataChange.Deletes         = directObjectDeletes;

                                        EventDispatcher.DispatchEvent(dataChange, DateTime.Now, -1);
                                        success3 = true;
                                    }
                                    finally
                                    {
                                        if (revertChangesFinishedCallback != null)
                                        {
                                            revertChangesFinishedCallback.Invoke(success3.Value);
                                        }
                                    }
                                });
                                success2 = true;
                            }, delegate(Exception e)
                            {
                                if (revertChangesFinishedCallback != null && success3 == null)
                                {
                                    revertChangesFinishedCallback.Invoke(success2.Value);
                                }
                            });
                        }, null);
                        success1 = true;
                    }
                    finally
                    {
                        if (revertChangesFinishedCallback != null && success2 == null && success3 == null)
                        {
                            revertChangesFinishedCallback.Invoke(success1);
                        }
                    }
                });
            }
        }
Beispiel #22
0
        protected override void InterceptIntern(IInvocation invocation)
        {
            if (GuiThreadHelper != null && GuiThreadHelper.IsInGuiThread())
            {
                throw new Exception("It is not allowed to call this interceptor from GUI thread");
            }
            lock (clientLock)
            {
                if (connectionChangePending)
                {
                    // Wait till the connection change finished
                    Monitor.Wait(clientLock);
                }
            }
            DateTime   m1     = DateTime.Now;
            MethodInfo method = invocation.Method;
            String     url    = ServiceBaseUrl + "/" + ServiceName + "/" + method.Name;

            HttpWebRequest webRequest;

#if SILVERLIGHT
            if (HttpUseClient)
            {
                webRequest = (HttpWebRequest)WebRequestCreator.ClientHttp.Create(new Uri(url));
            }
            else
            {
                webRequest = WebRequest.CreateHttp(url);
            }
#else
            webRequest           = (HttpWebRequest)WebRequest.Create(url);
            webRequest.Proxy     = null;
            webRequest.KeepAlive = true;
#endif
            Object    result    = null;
            bool      hasResult = false;
            Exception ex        = null;

            lock (webRequest)
            {
                webRequest.Accept = "text/plain";
                if (HttpAcceptEncodingZipped)
                {
                    TryToSetHeader(HttpRequestHeader.AcceptEncoding, webRequest, "gzip");
                    webRequest.Headers["Accept-Encoding-Workaround"] = "gzip";
                }
                SetAuthorization(webRequest);

                if (invocation.Arguments.Length == 0)
                {
                    webRequest.Method = "GET";
                    webRequest.BeginGetResponse(delegate(IAsyncResult asyncResult2)
                    {
                        try
                        {
                            HttpWebResponse response = (HttpWebResponse)webRequest.EndGetResponse(asyncResult2);
                            using (Stream responseStream = response.GetResponseStream())
                                using (Stream memoryStream = new MemoryStream())
                                {
                                    int b;
                                    while ((b = responseStream.ReadByte()) != -1)
                                    {
                                        memoryStream.WriteByte((byte)b);
                                    }
                                    memoryStream.Position = 0;
                                    try
                                    {
                                        Stream deflateStream = GetResponseStream(response, memoryStream);
                                        result = CyclicXmlHandler.ReadFromStream(deflateStream);
                                    }
                                    catch (XmlTypeNotFoundException)
                                    {
                                        throw;
                                    }
                                    catch (Exception)
                                    {
                                        memoryStream.Position = 0;
                                        result = CyclicXmlHandler.ReadFromStream(memoryStream);
                                    }
                                }
                            hasResult = true;
                        }
                        catch (WebException e)
                        {
                            ex = ParseWebException(e);
                            using (HttpWebResponse response = (HttpWebResponse)e.Response)
                            {
                                HandleException(e, response);
                            }
                        }
                        catch (Exception e)
                        {
                            Log.Error(e);
                            ex = e;
                        }
                        finally
                        {
                            lock (webRequest)
                            {
                                Monitor.PulseAll(webRequest);
                            }
                        }
                    }, null);
                }
                else
                {
                    webRequest.Method      = "POST";
                    webRequest.ContentType = "text/plain";
                    if (HttpContentEncodingZipped)
                    {
                        TryToSetHeader(HttpRequestHeader.ContentEncoding, webRequest, "gzip");
                        webRequest.Headers["Content-Encoding-Workaround"] = "gzip";
                    }
                    webRequest.BeginGetRequestStream(delegate(IAsyncResult asyncResult)
                    {
                        try
                        {
                            using (Stream stream = webRequest.EndGetRequestStream(asyncResult))
#if SILVERLIGHT
                                using (Stream deflateStream = HttpContentEncodingZipped ? new GZipStream(stream, CompressionMode.Compress, CompressionLevel.BestCompression, false) : stream)
#else
                                using (Stream deflateStream = HttpContentEncodingZipped ? new GZipStream(stream, CompressionMode.Compress, false) : stream)
#endif
                                {
                                    CyclicXmlHandler.WriteToStream(deflateStream, invocation.Arguments);
                                }
                            webRequest.BeginGetResponse(delegate(IAsyncResult asyncResult2)
                            {
                                DateTime m4 = DateTime.Now;
                                try
                                {
                                    HttpWebResponse response = (HttpWebResponse)webRequest.EndGetResponse(asyncResult2);
                                    DateTime m5 = DateTime.Now;
                                    using (Stream responseStream = response.GetResponseStream())
                                        using (Stream memoryStream = new MemoryStream())
                                        {
                                            int b;
                                            while ((b = responseStream.ReadByte()) != -1)
                                            {
                                                memoryStream.WriteByte((byte)b);
                                            }
                                            memoryStream.Position = 0;
                                            try
                                            {
                                                Stream deflateStream = GetResponseStream(response, memoryStream);
                                                result = CyclicXmlHandler.ReadFromStream(deflateStream);
                                            }
                                            catch (XmlTypeNotFoundException)
                                            {
                                                throw;
                                            }
                                            catch (Exception)
                                            {
                                                memoryStream.Position = 0;
                                                result = CyclicXmlHandler.ReadFromStream(memoryStream);
                                            }
                                        }
                                    hasResult = true;
                                }
                                catch (WebException e)
                                {
                                    ex = ParseWebException(e);
                                    using (HttpWebResponse response = (HttpWebResponse)e.Response)
                                    {
                                        HandleException(e, response);
                                    }
                                }
                                catch (Exception e)
                                {
                                    ex = e;
                                }
                                finally
                                {
                                    lock (webRequest)
                                    {
                                        Monitor.PulseAll(webRequest);
                                    }
                                }
                            }, null);
                        }
                        catch (Exception e)
                        {
                            ex = e;
                            lock (webRequest)
                            {
                                Monitor.PulseAll(webRequest);
                            }
                        }
                    }, null);
                }
                while (!hasResult && ex == null)
                {
                    Monitor.Wait(webRequest);
                }
            }
            if (result is AmbethServiceException)
            {
                ex = ParseServiceException((AmbethServiceException)result);
                throw new Exception("Error occured while calling " + webRequest.Method + " " + webRequest.RequestUri, ex);
            }
            if (ex != null)
            {
                if (ex is WebException)
                {
                    throw new Exception(ex.Message + "\r\rError occured while calling " + webRequest.Method + " " + webRequest.RequestUri + ". " + CyclicXmlHandler.Write(invocation.Arguments), ex);
                }
                throw new Exception("Error occured while calling " + webRequest.Method + " " + webRequest.RequestUri + ". " + CyclicXmlHandler.Write(invocation.Arguments), ex);
            }
            if (!hasResult)
            {
                throw new Exception("This must never happen");
            }
            invocation.ReturnValue = ConvertToExpectedType(method.ReturnType, result);
        }