public IOriCollection Merge(ICUDResult cudResult, IMethodDescription methodDescription) { ParamChecker.AssertParamNotNull(cudResult, "cudResult"); long?startTime = startTimeTL.Value; bool startTimeHasBeenSet = false; if (!startTime.HasValue) { startTime = DateTimeUtil.CurrentTimeMillis(); startTimeTL.Value = startTime; startTimeHasBeenSet = true; } try { if (Transaction == null || Transaction.Active) { return(MergeIntern(cudResult, methodDescription)); } return(Transaction.RunInLazyTransaction(delegate() { return MergeIntern(cudResult, methodDescription); })); } finally { if (startTimeHasBeenSet) { startTimeTL.Value = null; } } }
public String PrintCUDResult(ICUDResult cudResult, IIncrementalMergeState state) { StringBuilder sb = new StringBuilder(); DefaultXmlWriter writer = new DefaultXmlWriter(new AppendableStringBuilder(sb), null); writer.SetBeautifierActive(true); writer.SetBeautifierLinebreak("\n"); WriteCUDResult(cudResult, writer, (IncrementalMergeState)state); return(sb.ToString()); }
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); })); }
public ICUDResult ApplyCUDResultOnEntitiesOfCache(ICUDResult cudResult, bool checkBaseState, IIncrementalMergeState incrementalState) { ICache cache = incrementalState.GetStateCache().CurrentCache; if (cache.CurrentCache == cache) { // given cache is already the current cache return(ApplyIntern(cudResult, checkBaseState, (IncrementalMergeState)incrementalState)); } return(CacheContext.ExecuteWithCache(cache, new IResultingBackgroundWorkerParamDelegate <ICUDResult, ICUDResult>(delegate(ICUDResult state) { return ApplyIntern(state, checkBaseState, (IncrementalMergeState)incrementalState); }), cudResult)); }
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); }
public CUDResultDiff(ICUDResult left, ICUDResult right, bool doFullDiff, ICUDResultHelper cudResultHelper, IEntityMetaDataProvider entityMetaDataProvider) { this.doFullDiff = doFullDiff; this.left = left; this.right = right; this.cudResultHelper = cudResultHelper; this.entityMetaDataProvider = entityMetaDataProvider; if (doFullDiff) { diffChanges = new List <IChangeContainer>(); originalRefs = new List <Object>(); } else { diffChanges = EmptyList.Empty <IChangeContainer>(); originalRefs = EmptyList.Empty <Object>(); } }
public Object ProcessWrite(IPostProcessWriter writer) { ISet <Object> substitutedEntities = writer.SubstitutedEntities; if (substitutedEntities.Count == 0) { return(null); } IDisposableCache childCache = CacheFactory.Create(CacheFactoryDirective.NoDCE, "XmlMerge"); IServiceContext mergeContext = BeanContext.CreateService(delegate(IBeanContextFactory childContextFactory) { childContextFactory.RegisterBean(typeof(MergeHandle)).Autowireable <MergeHandle>().PropertyValue("Cache", childCache); }); try { IDictionary <Object, Int32> mutableToIdMap = writer.MutableToIdMap; IObjRefHelper objRefHelper = ObjRefHelper; MergeHandle mergeHandle = mergeContext.GetService <MergeHandle>(); IList <Object> toMerge = new List <Object>(substitutedEntities.Count); foreach (Object entity in substitutedEntities) { toMerge.Add(entity); IObjRef ori = objRefHelper.EntityToObjRef(entity); mergeHandle.objToOriDict.Add(entity, ori); Int32 id = mutableToIdMap[entity]; mutableToIdMap.Add(ori, id); } ICUDResult cudResult = MergeController.MergeDeep(toMerge, mergeHandle); if (cudResult.AllChanges.Count != 0) { return(cudResult); } else { return(null); } } finally { mergeContext.Dispose(); } }
public void Test_DataChange() { TestEntity newTestEntity = EntityFactory.CreateEntity <TestEntity>(); CountDownLatch latch = new CountDownLatch(1); MergeProcess.Process(newTestEntity, null, null, delegate(bool success) { latch.CountDown(); }); latch.Await(); WaitForUI(); newTestEntity.Relation = EntityFactory.CreateEntity <TestEntity2>(); ICacheWalkerResult cwResult = CacheWalker.WalkEntities(newTestEntity); Log.Info(cwResult.ToString()); ICUDResult mergeResult = MergeController.MergeDeep(newTestEntity, new MergeHandle()); latch = new CountDownLatch(1); RevertChangesHelper.RevertChanges(newTestEntity, delegate(bool success) { latch.CountDown(); }); latch.Await(); WaitForUI(); ((IWritableCache)Cache).Put(newTestEntity); latch = new CountDownLatch(1); ((INotifyPropertyChanged)newTestEntity).PropertyChanged += delegate(Object sender, PropertyChangedEventArgs evnt) { latch.CountDown(); }; MergeService.Merge(mergeResult, null); latch.Await(); WaitForUI(); Assert.AssertNotNull(newTestEntity.Relation); }
protected void WriteCUDResult(ICUDResult cudResult, IWriter writer, IncrementalMergeState state) { IList <IChangeContainer> allChanges = cudResult.AllChanges; List <CreateContainer> creates = new List <CreateContainer>(); List <UpdateContainer> updates = new List <UpdateContainer>(); List <DeleteContainer> deletes = new List <DeleteContainer>(); for (int a = allChanges.Count; a-- > 0;) { IChangeContainer changeContainer = allChanges[a]; if (changeContainer is CreateContainer) { creates.Add((CreateContainer)changeContainer); } else if (changeContainer is UpdateContainer) { updates.Add((UpdateContainer)changeContainer); } else { deletes.Add((DeleteContainer)changeContainer); } } creates.Sort(createContainerComparator); updates.Sort(updateContainerComparator); deletes.Sort(deleteContainerComparator); writer.WriteStartElement("CUDResult"); writer.WriteAttribute("size", allChanges.Count); writer.WriteAttribute("creates", creates.Count); writer.WriteAttribute("updates", updates.Count); writer.WriteAttribute("deletes", deletes.Count); writer.WriteStartElementEnd(); WriteChangeContainers(creates, writer, "Creates", state); WriteChangeContainers(updates, writer, "Updates", state); WriteChangeContainers(deletes, writer, "Deletes", state); writer.WriteCloseElement("CUDResult"); }
protected ICUDResult WhatIfMerged(ICUDResult cudResult, IMethodDescription methodDescription, List <MergeOperation> mergeOperationSequence, IncrementalMergeState incrementalState) { IList <MergeOperation> lastMergeOperationSequence; while (true) { IMap <Type, IList <IChangeContainer> > sortedChanges = BucketSortChanges(cudResult.AllChanges); lastMergeOperationSequence = CreateMergeOperationSequence(sortedChanges); ParamHolder <bool> hasAtLeastOneImplicitChange = new ParamHolder <bool>(false); IList <MergeOperation> fLastMergeOperationSequence = lastMergeOperationSequence; cudResult = CacheContext.ExecuteWithCache(incrementalState.GetStateCache(), delegate(ICUDResult cudResult2) { for (int a = 0, size = fLastMergeOperationSequence.Count; a < size; a++) { MergeOperation mergeOperation = fLastMergeOperationSequence[a]; IMergeServiceExtension mergeServiceExtension = mergeOperation.MergeServiceExtension; ICUDResult explAndImplCudResult = mergeServiceExtension.EvaluateImplicitChanges(cudResult2, incrementalState); cudResult2 = MergeCudResult(cudResult2, explAndImplCudResult, mergeServiceExtension, hasAtLeastOneImplicitChange, incrementalState); } return(cudResult2); }, cudResult); foreach (IMergeListener mergeListener in mergeListeners.GetExtensions()) { ICUDResult explAndImplCudResult = mergeListener.PreMerge(cudResult, incrementalState.GetStateCache()); cudResult = MergeCudResult(cudResult, explAndImplCudResult, mergeListener, hasAtLeastOneImplicitChange, incrementalState); } if (!hasAtLeastOneImplicitChange.Value) { break; } } mergeOperationSequence.AddRange(lastMergeOperationSequence); return(cudResult); }
public ICUDResult DiffCUDResult(ICUDResult left, ICUDResult right) { CUDResultDiff diff = new CUDResultDiff(left, right, true, CudResultHelper, EntityMetaDataProvider); EqualsCUDResult(diff); if (!diff.HasChanges()) { return(null); // null means empty diff } IList <IChangeContainer> diffChanges = diff.diffChanges; for (int a = diffChanges.Count; a-- > 0;) { IChangeContainer changeContainer = diffChanges[a]; if (!(changeContainer is CreateOrUpdateContainerBuild)) { continue; } diffChanges[a] = ((CreateOrUpdateContainerBuild)changeContainer).Build(); } return(new CUDResult(diffChanges, diff.originalRefs)); }
public virtual IOriCollection Merge(ICUDResult cudResult, IMethodDescription methodDescription) { return(MergeServiceWCF.Merge((CUDResult)cudResult, (MethodDescription)methodDescription)); }
protected void ApplyChangesToOriginalsIntern(ICUDResult cudResult, IOriCollection oriCollection, ICache cache) { ICacheModification cacheModification = this.CacheModification; IConversionHelper conversionHelper = this.ConversionHelper; IEntityMetaDataProvider entityMetaDataProvider = this.EntityMetaDataProvider; IList <Object> originalRefs = cudResult.GetOriginalRefs(); IList <IObjRef> allChangeORIs = oriCollection.AllChangeORIs; String[] allChangedBy = oriCollection.AllChangedBy; long[] allChangedOn = oriCollection.AllChangedOn; String singleChangedBy = oriCollection.ChangedBy; long? singleChangedOn = oriCollection.ChangedOn; bool newInstanceOnCall = CacheProvider.IsNewInstanceOnCall; IList <Object> validObjects = new List <Object>(originalRefs.Count); bool oldCacheModificationValue = CacheModification.Active; CacheModification.Active = true; try { for (int a = originalRefs.Count; a-- > 0;) { Object originalRef = originalRefs[a]; IObjRef ori = allChangeORIs[a]; if (originalRef == null) { // Object has been deleted by cascade delete contraints on server merge or simply a "not specified" original ref continue; } if (originalRef is IObjRef) { continue; } long? changedOn = allChangedOn != null ? allChangedOn[a] : singleChangedOn; String changedBy = allChangedBy != null ? allChangedBy[a] : singleChangedBy; IEntityMetaData metaData = ((IEntityMetaDataHolder)originalRef).Get__EntityMetaData(); PrimitiveMember versionMember = metaData.VersionMember; PrimitiveMember keyMember = metaData.IdMember; PrimitiveMember onMember, byMember; if (keyMember.GetValue(originalRef, false) == null) { onMember = metaData.CreatedOnMember; byMember = metaData.CreatedByMember; } else { onMember = metaData.UpdatedOnMember; byMember = metaData.UpdatedByMember; } if (onMember != null && changedOn != null) { Object createdOn = ConversionHelper.ConvertValueToType(onMember.ElementType, changedOn); onMember.SetValue(originalRef, createdOn); } if (byMember != null && changedBy != null) { Object createdBy = ConversionHelper.ConvertValueToType(byMember.ElementType, changedBy); byMember.SetValue(originalRef, createdBy); } if (ori == null) { keyMember.SetValue(originalRef, null); if (versionMember != null) { versionMember.SetValue(originalRef, null); } if (originalRef is IDataObject) { ((IDataObject)originalRef).ToBeUpdated = false; ((IDataObject)originalRef).ToBeDeleted = false; } continue; // Object has been deleted directly } keyMember.SetValue(originalRef, ConversionHelper.ConvertValueToType(keyMember.RealType, ori.Id)); if (versionMember != null) { if (AlwaysUpdateVersionInChangedEntities) { versionMember.SetValue(originalRef, ConversionHelper.ConvertValueToType(versionMember.RealType, ori.Version)); } else { // We INTENTIONALLY do NOT set the version and let it on its old value, to force the following DCE to refresh the cached object with 'real' data // If we set the version here to the ori.getVersion(), the DCE will 'see' a already valid object - but is IS NOT valid // because it may not contain bi-directional information which can only be resolved by reloading the object from persistence layer //versionMember.SetValue(originalRef, null); } } if (originalRef is IDataObject) { ((IDataObject)originalRef).ToBeUpdated = false; ((IDataObject)originalRef).ToBeDeleted = false; } validObjects.Add(originalRef); } PutInstancesToCurrentCache(validObjects, cache); } finally { CacheModification.Active = oldCacheModificationValue; } }
protected void MergePhase3(Object objectToMerge, IList <Object> unpersistedObjectsToDelete, ICUDResult cudResult, ProceedWithMergeHook proceedHook, MergeFinishedCallback mergeFinishedCallback, bool addNewEntitiesToCache) { // Take over callback stored threadlocally from foreign calling thread to current thread bool success = false; try { ProcessCUDResult(objectToMerge, cudResult, unpersistedObjectsToDelete, proceedHook, addNewEntitiesToCache); success = true; } finally { if (mergeFinishedCallback != null) { mergeFinishedCallback.Invoke(success); } } }
protected virtual void ProcessCUDResult(Object objectToMerge, ICUDResult cudResult, IList <Object> unpersistedObjectsToDelete, ProceedWithMergeHook proceedHook, bool addNewEntitiesToCache) { if (cudResult.AllChanges.Count > 0 || (unpersistedObjectsToDelete != null && unpersistedObjectsToDelete.Count > 0)) { if (proceedHook != null) { bool proceed = proceedHook.Invoke(cudResult, unpersistedObjectsToDelete); if (!proceed) { return; } } } if (cudResult.AllChanges.Count == 0) { if (Log.InfoEnabled) { Log.Info("Service call skipped early because there is nothing to merge"); } } else { IOriCollection oriColl; EventDispatcher.EnableEventQueue(); try { EventDispatcher.Pause(Cache); try { bool?oldNewlyPersistedEntities = addNewlyPersistedEntitiesTL.Value; addNewlyPersistedEntitiesTL.Value = addNewEntitiesToCache; try { IResultingBackgroundWorkerDelegate <IOriCollection> runnable = new IResultingBackgroundWorkerDelegate <IOriCollection>(delegate() { IOriCollection oriColl2 = MergeService.Merge(cudResult, null); MergeController.ApplyChangesToOriginals(cudResult, oriColl2, null); return(oriColl2); }); if (Transaction == null || Transaction.Active) { oriColl = runnable(); } else { oriColl = Transaction.RunInLazyTransaction(runnable); } } finally { addNewlyPersistedEntitiesTL.Value = oldNewlyPersistedEntities; } } finally { EventDispatcher.Resume(Cache); } } finally { EventDispatcher.FlushEventQueue(); } DataChangeEvent dataChange = DataChangeEvent.Create(-1, -1, -1); // This is intentionally a remote source dataChange.IsLocalSource = false; if (IsNetworkClientMode) { IList <IChangeContainer> allChanges = cudResult.AllChanges; IList <IObjRef> orisInReturn = oriColl.AllChangeORIs; for (int a = allChanges.Count; a-- > 0;) { IChangeContainer changeContainer = allChanges[a]; IObjRef reference = changeContainer.Reference; IObjRef referenceInReturn = orisInReturn[a]; if (changeContainer is CreateContainer) { if (referenceInReturn.IdNameIndex != ObjRef.PRIMARY_KEY_INDEX) { throw new ArgumentException("Implementation error: Only PK references are allowed in events"); } dataChange.Inserts.Add(new DataChangeEntry(referenceInReturn.RealType, referenceInReturn.IdNameIndex, referenceInReturn.Id, referenceInReturn.Version)); } else if (changeContainer is UpdateContainer) { if (referenceInReturn.IdNameIndex != ObjRef.PRIMARY_KEY_INDEX) { throw new ArgumentException("Implementation error: Only PK references are allowed in events"); } dataChange.Updates.Add(new DataChangeEntry(referenceInReturn.RealType, referenceInReturn.IdNameIndex, referenceInReturn.Id, referenceInReturn.Version)); } else if (changeContainer is DeleteContainer) { if (reference.IdNameIndex != ObjRef.PRIMARY_KEY_INDEX) { throw new ArgumentException("Implementation error: Only PK references are allowed in events"); } dataChange.Deletes.Add(new DataChangeEntry(reference.RealType, reference.IdNameIndex, reference.Id, reference.Version)); } } //EventDispatcher.DispatchEvent(dataChange, DateTime.Now, -1); } } if (unpersistedObjectsToDelete != null && unpersistedObjectsToDelete.Count > 0) { // Create a DCE for all objects without an id but which should be deleted... // This is the case for newly created objects on client side, which should be // "cancelled". The DCE notifies all models which contain identity references to the related // objects to erase their existence in all controls. They are not relevant in the previous // server merge process DataChangeEvent dataChange = DataChangeEvent.Create(0, 0, unpersistedObjectsToDelete.Count); for (int a = unpersistedObjectsToDelete.Count; a-- > 0;) { Object unpersistedObject = unpersistedObjectsToDelete[a]; dataChange.Deletes.Add(new DirectDataChangeEntry(unpersistedObject)); } EventDispatcher.DispatchEvent(dataChange, DateTime.Now, -1); } RevertChangesHelper.RevertChanges(objectToMerge); }
protected IOriCollection Intern(ICUDResult cudResult, IMethodDescription methodDescription, IList <MergeOperation> mergeOperationSequence, IncrementalMergeState state) { IList <IChangeContainer> allChanges = cudResult.AllChanges; IList <Object> originalRefs = cudResult.GetOriginalRefs(); IdentityHashMap <IChangeContainer, int> changeToChangeIndexDict = new IdentityHashMap <IChangeContainer, int>(); for (int a = allChanges.Count; a-- > 0;) { changeToChangeIndexDict.Put(allChanges[a], a); } IObjRef[] objRefs = new IObjRef[allChanges.Count]; long[] allChangedOn = new long[allChanges.Count]; String[] allChangedBy = new String[allChanges.Count]; CHashSet <long> changedOnSet = new CHashSet <long>(); CHashSet <String> changedBySet = new CHashSet <String>(); for (int a = 0, size = mergeOperationSequence.Count; a < size; a++) { MergeOperation mergeOperation = mergeOperationSequence[a]; IMergeServiceExtension mergeServiceExtension = mergeOperation.MergeServiceExtension; IList <IChangeContainer> changesForMergeService = mergeOperation.ChangeContainer; ICUDResult msCudResult = BuildCUDResult(changesForMergeService, changeToChangeIndexDict, originalRefs); IOriCollection msOriCollection = mergeServiceExtension.Merge(msCudResult, methodDescription); MergeController.ApplyChangesToOriginals(msCudResult, msOriCollection, state.GetStateCache()); IList <IObjRef> allChangeORIs = msOriCollection.AllChangeORIs; long? msDefaultChangedOn = msOriCollection.ChangedOn; String msDefaultChangedBy = msOriCollection.ChangedBy; long[] msAllChangedOn = msOriCollection.AllChangedOn; String[] msAllChangedBy = msOriCollection.AllChangedBy; for (int b = changesForMergeService.Count; b-- > 0;) { int index = changeToChangeIndexDict.Get(changesForMergeService[b]); objRefs[index] = allChangeORIs[b]; if (msAllChangedOn != null) { long msChangedOn = msAllChangedOn[b]; allChangedOn[index] = msChangedOn; changedOnSet.Add(msChangedOn); } else { allChangedOn[index] = msDefaultChangedOn.Value; } if (msAllChangedBy != null) { String msChangedBy = msAllChangedBy[b]; allChangedBy[index] = msChangedBy; changedBySet.Add(msChangedBy); } else { allChangedBy[index] = msDefaultChangedBy; } } if (msDefaultChangedOn != null) { changedOnSet.Add(msDefaultChangedOn.Value); } if (msDefaultChangedBy != null) { changedBySet.Add(msDefaultChangedBy); } } OriCollection oriCollection = new OriCollection(); oriCollection.AllChangeORIs = new List <IObjRef>(objRefs); if (changedBySet.Count == 1) { Iterator <String> iter = changedBySet.Iterator(); iter.MoveNext(); oriCollection.ChangedBy = iter.Current; } else { oriCollection.AllChangedBy = allChangedBy; } if (changedOnSet.Count == 1) { Iterator <long> iter = changedOnSet.Iterator(); iter.MoveNext(); oriCollection.ChangedOn = iter.Current; } else { oriCollection.AllChangedOn = allChangedOn; } foreach (IMergeListener mergeListener in mergeListeners.GetExtensions()) { mergeListener.PostMerge(cudResult, objRefs); } if (originalRefs != null) { // Set each original ref to null in order to suppress a post-processing in a potentially calling IMergeProcess for (int a = originalRefs.Count; a-- > 0;) { originalRefs[a] = null; } } // TODO DCE must be fired HERE <--- return(oriCollection); }
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)); } }
public IOriCollection Merge(ICUDResult cudResult, IMethodDescription methodDescription) { int localDcId; IDataChange dataChange; IList <IChangeContainer> allChanges = cudResult.AllChanges; IList <IObjRef> resultOriList = new List <IObjRef>(allChanges.Count); String changedBy = "anonymous"; long changedOn; Lock writeLock = PersistenceMock.GetWriteLock(); writeLock.Lock(); try { localDcId = ++dcId; changedOn = DateTimeUtil.CurrentTimeMillis(); IList <IDataChangeEntry> inserts = new List <IDataChangeEntry>(); IList <IDataChangeEntry> updates = new List <IDataChangeEntry>(); IList <IDataChangeEntry> deletes = new List <IDataChangeEntry>(); for (int a = 0, size = allChanges.Count; a < size; a++) { IChangeContainer changeContainer = allChanges[a]; IObjRef reference = changeContainer.Reference; if (changeContainer is DeleteContainer) { PersistenceMock.RemoveObject(reference); resultOriList.Add(null); deletes.Add(new DataChangeEntry(reference.RealType, reference.IdNameIndex, reference.Id, reference.Version)); } else if (changeContainer is UpdateContainer) { resultOriList.Add(reference); reference.Version = ((int)reference.Version) + 1; PersistenceMock.ChangeObject(reference, ((UpdateContainer)changeContainer).Primitives, ((UpdateContainer)changeContainer).Relations, changedBy, changedOn); updates.Add(new DataChangeEntry(reference.RealType, reference.IdNameIndex, reference.Id, reference.Version)); } else if (changeContainer is CreateContainer) { Object newId = AcquireIdForEntityType(reference.RealType); if (newId == null) { throw new Exception("Id must be valid"); } IEntityMetaData metaData = EntityMetaDataProvider.GetMetaData(reference.RealType); newId = ConversionHelper.ConvertValueToType(metaData.IdMember.ElementType, newId); reference.Id = newId; reference.Version = 1; ((IDirectObjRef)reference).Direct = null; resultOriList.Add(reference); PersistenceMock.AddObject(reference, ((CreateContainer)changeContainer).Primitives, ((CreateContainer)changeContainer).Relations, changedBy, changedOn); inserts.Add(new DataChangeEntry(reference.RealType, ObjRef.PRIMARY_KEY_INDEX, reference.Id, reference.Version)); } } OriCollection oriColl = new OriCollection(resultOriList); oriColl.ChangedBy = changedBy; oriColl.ChangedOn = changedOn; MergeController.ApplyChangesToOriginals(cudResult, oriColl, null); dataChange = new DataChangeEvent(inserts, updates, deletes, DateTimeUtil.ConvertJavaMillisToDateTime(changedOn), false); } finally { writeLock.Unlock(); } EventDispatcher.DispatchEvent(dataChange, dataChange.ChangeTime, localDcId); OriCollection oriCollection = new OriCollection(resultOriList); oriCollection.ChangedBy = changedBy; oriCollection.ChangedOn = changedOn; return(oriCollection); }
public bool EqualsCUDResult(ICUDResult left, ICUDResult right) { CUDResultDiff diff = new CUDResultDiff(left, right, false, CudResultHelper, EntityMetaDataProvider); return(EqualsCUDResult(diff)); }
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); } }
protected ICUDResult ApplyIntern(ICUDResult cudResult, bool checkBaseState, IncrementalMergeState incrementalState) { ICache stateCache = incrementalState.GetStateCache(); IList <IChangeContainer> allChanges = cudResult.AllChanges; IList <Object> originalRefs = cudResult.GetOriginalRefs(); IList <Object> allObjects = GetAllExistingObjectsFromCache(stateCache, allChanges); List <Object> hardRefs = new List <Object>(); hardRefs.Add(allObjects); // add list as item intended. adding each item of the source is NOT needed List <IObjRef> toFetchFromCache = new List <IObjRef>(); List <DirectValueHolderRef> toPrefetch = new List <DirectValueHolderRef>(); List <IBackgroundWorkerDelegate> runnables = new List <IBackgroundWorkerDelegate>(); IEntityFactory entityFactory = this.EntityFactory; IdentityHashMap <IObjRef, StateEntry> newObjRefToStateEntryMap = new IdentityHashMap <IObjRef, StateEntry>(); IdentityHashMap <IChangeContainer, IChangeContainer> alreadyClonedMap = new IdentityHashMap <IChangeContainer, IChangeContainer>(); List <IChangeContainer> newAllChanges = new List <IChangeContainer>(allChanges.Count); for (int a = 0, size = allChanges.Count; a < size; a++) { IChangeContainer changeContainer = allChanges[a]; Object originalEntity = originalRefs[a]; StateEntry stateEntry = incrementalState.entityToStateMap.Get(originalEntity); IChangeContainer newChangeContainer; if (changeContainer is CreateContainer) { newChangeContainer = new CreateContainer(); } else if (changeContainer is UpdateContainer) { newChangeContainer = new UpdateContainer(); } else { newChangeContainer = new DeleteContainer(); } newAllChanges.Add(newChangeContainer); alreadyClonedMap.Put(changeContainer, newChangeContainer); if (!(changeContainer is CreateContainer)) { Object stateCacheEntity2 = allObjects[a]; stateEntry = incrementalState.entityToStateMap.Get(stateCacheEntity2); if (stateEntry == null) { stateEntry = new StateEntry(stateCacheEntity2, changeContainer.Reference, incrementalState.entityToStateMap.Count + 1); incrementalState.entityToStateMap.Put(stateCacheEntity2, stateEntry); incrementalState.objRefToStateMap.Put(stateEntry.objRef, stateEntry); } // delete & update do not need further handling continue; } Type realType = changeContainer.Reference.RealType; Object stateCacheEntity; if (stateEntry == null) { stateCacheEntity = entityFactory.CreateEntity(realType); DirectObjRef directObjRef = new DirectObjRef(realType, stateCacheEntity); directObjRef.CreateContainerIndex = a; stateEntry = new StateEntry(stateCacheEntity, directObjRef, incrementalState.entityToStateMap.Count + 1); incrementalState.entityToStateMap.Put(stateCacheEntity, stateEntry); incrementalState.objRefToStateMap.Put(stateEntry.objRef, stateEntry); newObjRefToStateEntryMap.Put(changeContainer.Reference, stateEntry); } else { stateCacheEntity = stateEntry.entity; } allObjects[a] = stateCacheEntity; } cloneStateTL.Value = new CloneState(newObjRefToStateEntryMap, incrementalState); try { for (int a = allChanges.Count; a-- > 0;) { IChangeContainer changeContainer = allChanges[a]; IObjRefContainer entity = (IObjRefContainer)allObjects[a]; changeContainer = FillClonedChangeContainer(changeContainer, alreadyClonedMap); IPrimitiveUpdateItem[] puis; IRelationUpdateItem[] ruis; if (changeContainer is CreateContainer) { CreateContainer createContainer = (CreateContainer)changeContainer; puis = createContainer.Primitives; ruis = createContainer.Relations; } else if (changeContainer is UpdateContainer) { UpdateContainer updateContainer = (UpdateContainer)changeContainer; puis = updateContainer.Primitives; ruis = updateContainer.Relations; } else { ((IDataObject)entity).ToBeDeleted = true; continue; } IEntityMetaData metaData = ((IEntityMetaDataHolder)entity).Get__EntityMetaData(); ApplyPrimitiveUpdateItems(entity, puis, metaData); if (ruis != null) { bool isUpdate = changeContainer is UpdateContainer; foreach (IRelationUpdateItem rui in ruis) { ApplyRelationUpdateItem(entity, rui, isUpdate, metaData, toPrefetch, toFetchFromCache, checkBaseState, runnables); } } } while (toPrefetch.Count > 0 || toFetchFromCache.Count > 0 || runnables.Count > 0) { if (toPrefetch.Count > 0) { PrefetchHelper.Prefetch(toPrefetch); toPrefetch.Clear(); } if (toFetchFromCache.Count > 0) { IList <Object> fetchedObjects = stateCache.GetObjects(toFetchFromCache, CacheDirective.None); hardRefs.Add(fetchedObjects); // add list as item intended. adding each item of the source is NOT needed toFetchFromCache.Clear(); } IBackgroundWorkerDelegate[] runnableArray = runnables.ToArray(); runnables.Clear(); foreach (IBackgroundWorkerDelegate runnable in runnableArray) { runnable(); } } List <Object> newObjects = new List <Object>(allObjects.Count); List <DirectValueHolderRef> changedRelationRefs = new List <DirectValueHolderRef>(); for (int a = allObjects.Count; a-- > 0;) { IChangeContainer newChange = newAllChanges[a]; IRelationUpdateItem[] ruis = null; Object entity = allObjects[a]; if (newChange is CreateContainer) { newObjects.Add(entity); ruis = ((CreateContainer)newChange).Relations; } else if (newChange is UpdateContainer) { ruis = ((UpdateContainer)newChange).Relations; } if (ruis == null) { continue; } IEntityMetaData metaData = EntityMetaDataProvider.GetMetaData(entity.GetType()); foreach (IRelationUpdateItem rui in ruis) { Member member = metaData.GetMemberByName(rui.MemberName); changedRelationRefs.Add(new DirectValueHolderRef((IObjRefContainer)entity, (RelationMember)member)); } } if (newObjects.Count > 0) { ((IWritableCache)stateCache).Put(newObjects); } if (changedRelationRefs.Count > 0) { PrefetchHelper.Prefetch(changedRelationRefs); } return(new CUDResult(newAllChanges, allObjects)); } finally { cloneStateTL.Value = null; } }
public IOriCollection Merge(ICUDResult cudResult, IMethodDescription methodDescription) { return(null); }
protected bool EqualsCUDResult(CUDResultDiff cudResultDiff) { ICUDResult left = cudResultDiff.left; ICUDResult right = cudResultDiff.right; IList <Object> leftRefs = left.GetOriginalRefs(); IList <Object> rightRefs = right.GetOriginalRefs(); if (leftRefs.Count != rightRefs.Count) { if (!cudResultDiff.doFullDiff) { return(false); } } IList <IChangeContainer> leftChanges = left.AllChanges; IList <IChangeContainer> rightChanges = right.AllChanges; IdentityHashMap <Object, int?> rightMap = IdentityHashMap <Object, int?> .Create(rightRefs.Count); for (int a = rightRefs.Count; a-- > 0;) { rightMap.Put(rightRefs[a], a); } for (int a = leftRefs.Count; a-- > 0;) { Object leftEntity = leftRefs[a]; int? rightIndex = rightMap.Remove(leftEntity); if (!rightIndex.HasValue) { if (!cudResultDiff.doFullDiff) { return(false); } cudResultDiff.diffChanges.Add(leftChanges[a]); cudResultDiff.originalRefs.Add(leftEntity); continue; } if (!EqualsChangeContainer(cudResultDiff, leftChanges[a], rightChanges[rightIndex.Value])) { if (!cudResultDiff.doFullDiff) { if (cudResultDiff.containerBuild != null) { throw new Exception(); } return(false); } cudResultDiff.diffChanges.Add(cudResultDiff.containerBuild); cudResultDiff.originalRefs.Add(rightRefs[rightIndex.Value]); cudResultDiff.containerBuild = null; } else if (cudResultDiff.containerBuild != null) { throw new Exception(); } } if (rightMap.Count == 0) { return(true); } foreach (Entry <Object, int> entry in rightMap) { Object rightRef = entry.Key; int rightIndex = entry.Value; IChangeContainer rightChange = rightChanges[rightIndex]; cudResultDiff.diffChanges.Add(rightChange); cudResultDiff.originalRefs.Add(rightRef); } return(false); }