protected ICUDResult MergeCudResult(ICUDResult cudResult, ICUDResult explAndImplCudResult, Object implyingHandle, ParamHolder <Boolean> hasAtLeastOneImplicitChange, IncrementalMergeState state) { if (explAndImplCudResult == null || Object.ReferenceEquals(cudResult, explAndImplCudResult)) { return(cudResult); } ICUDResult diffCUDResult = CudResultComparer.DiffCUDResult(cudResult, explAndImplCudResult); if (diffCUDResult == null) { return(cudResult); } hasAtLeastOneImplicitChange.Value = true; CudResultApplier.ApplyCUDResultOnEntitiesOfCache(diffCUDResult, false, state); if (Log.DebugEnabled) { Object currHandle = implyingHandle; if (currHandle is IProxyTargetAccessor) { IInterceptor interceptor = ((IProxyTargetAccessor)currHandle).GetInterceptors()[0]; while (interceptor is CascadedInterceptor) { Object target = ((CascadedInterceptor)interceptor).Target; if (target is IInterceptor) { interceptor = ((IInterceptor)target); continue; } currHandle = target; break; } } if (currHandle == null) { currHandle = implyingHandle; } if (CudResultPrinter != null) { Log.Debug("Incremental merge [" + RuntimeHelpers.GetHashCode(state) + "] (" + currHandle.GetType().Name + "):\n" + CudResultPrinter.PrintCUDResult(diffCUDResult, state)); } else { Log.Debug("Incremental merge [" + RuntimeHelpers.GetHashCode(state) + "] (" + currHandle.GetType().Name + "). No Details printable"); } } return(explAndImplCudResult); }
protected IOriCollection MergeIntern(ICUDResult cudResultOriginal, IMethodDescription methodDescription) { IResultingBackgroundWorkerDelegate <IOriCollection> runnable = new IResultingBackgroundWorkerDelegate <IOriCollection>(delegate() { IDisposableCache childCache = CacheFactory.CreatePrivileged(CacheFactoryDirective.SubscribeTransactionalDCE, false, false, "MergeServiceRegistry.STATE"); try { IncrementalMergeState state = null; ICUDResult cudResultOfCache; if (MergeProcess.IsAddNewlyPersistedEntities() || (Log.DebugEnabled && CudResultPrinter != null)) { childCache = CacheFactory.CreatePrivileged(CacheFactoryDirective.SubscribeTransactionalDCE, false, false, "MergeServiceRegistry.STATE"); state = (IncrementalMergeState)CudResultApplier.AcquireNewState(childCache); cudResultOfCache = CudResultApplier.ApplyCUDResultOnEntitiesOfCache(cudResultOriginal, true, state); } else { cudResultOfCache = cudResultOriginal; } if (Log.DebugEnabled) { if (CudResultPrinter != null) { Log.Debug("Initial merge [" + RuntimeHelpers.GetHashCode(state) + "]:\n" + CudResultPrinter.PrintCUDResult(cudResultOfCache, state)); } else { Log.Debug("Initial merge [" + RuntimeHelpers.GetHashCode(state) + "]. No Details available"); } } List <MergeOperation> mergeOperationSequence = new List <MergeOperation>(); ICUDResult extendedCudResult = WhatIfMerged(cudResultOfCache, methodDescription, mergeOperationSequence, state); if (Log.DebugEnabled) { Log.Debug("Merge finished [" + RuntimeHelpers.GetHashCode(state) + "]"); } if (MergeSecurityManager != null) { SecurityActive.ExecuteWithSecurityDirective(SecurityDirective.ENABLE_ENTITY_CHECK, delegate() { MergeSecurityManager.CheckMergeAccess(extendedCudResult, methodDescription); }); } List <Object> originalRefsOfCache = new List <Object>(cudResultOfCache.GetOriginalRefs()); List <Object> originalRefsExtended = new List <Object>(extendedCudResult.GetOriginalRefs()); IOriCollection oriCollExtended = Intern(extendedCudResult, methodDescription, mergeOperationSequence, state); IList <IChangeContainer> allChangesOriginal = cudResultOriginal.AllChanges; IList <IObjRef> allChangedObjRefsExtended = oriCollExtended.AllChangeORIs; IObjRef[] allChangedObjRefsResult = new IObjRef[allChangesOriginal.Count]; IdentityHashMap <Object, int?> originalRefOfCacheToIndexMap = new IdentityHashMap <Object, int?>(); for (int a = originalRefsOfCache.Count; a-- > 0;) { originalRefOfCacheToIndexMap.Put(originalRefsOfCache[a], a); } for (int a = originalRefsExtended.Count; a-- > 0;) { int?indexOfCache = originalRefOfCacheToIndexMap.Get(originalRefsExtended[a]); if (indexOfCache == null) { // this is a change implied by a rule or an persistence-implicit change // we do not know about it in the outer original CUDResult continue; } IObjRef objRefExtended = allChangedObjRefsExtended[a]; IObjRef objRefOriginal = allChangesOriginal[indexOfCache.Value].Reference; if (objRefExtended == null) { // entity has been deleted objRefOriginal.Id = null; objRefOriginal.Version = null; } else { objRefOriginal.Id = objRefExtended.Id; objRefOriginal.Version = objRefExtended.Version; } if (objRefOriginal is IDirectObjRef) { ((IDirectObjRef)objRefOriginal).Direct = null; } allChangedObjRefsResult[indexOfCache.Value] = objRefOriginal; } OriCollection oriCollection = new OriCollection(new List <IObjRef>(allChangedObjRefsResult)); return(oriCollection); } finally { childCache.Dispose(); } }); if (SecurityActive == null || !SecurityActive.FilterActivated) { return(runnable()); } else { return(SecurityActive.ExecuteWithoutFiltering(runnable)); } }