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 override Object InterceptDeleteIntern(MethodInfo method, Object[] arguments, Attribute annotation, Boolean?isAsyncBegin) { if (arguments == null || (arguments.Length != 1 && arguments.Length != 3)) { throw new Exception("Arguments currently must be only 1 or 3: " + method.ToString()); } ProceedWithMergeHook proceedHook = GetProceedHook(arguments); MergeFinishedCallback finishedCallback = GetFinishedCallback(arguments); RemoveAttribute remove = (RemoveAttribute)annotation; if (remove != null) { String idName = remove.IdName; Type entityType = remove.EntityType; if (idName != null && idName.Length > 0) { if (entityType == null) { throw new Exception("Annotation invalid: " + remove + " on method " + method.ToString()); } DeleteById(method, entityType, idName, arguments[0], proceedHook, finishedCallback); return(null); } } Object argumentToDelete = arguments[0]; MergeProcess.Process(null, argumentToDelete, proceedHook, finishedCallback); if (!typeof(void).Equals(method.ReturnType)) { return(argumentToDelete); } return(null); }
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 Execute(Object parameter, INextCommandDelegate commandFinishedCallback) { if (parameter == null) { if (commandFinishedCallback != null) { commandFinishedCallback.Invoke(true); } return; } IList <Object> businessObjects = ExtractBusinessObjects(parameter); if (businessObjects.Count < 1) { if (commandFinishedCallback != null) { commandFinishedCallback.Invoke(true); } return; } ProceedWithMergeHook proceedWithMergeHook = null; if (CUDResultPreprocessor != null) { proceedWithMergeHook = CUDResultPreprocessor.GetProceedWithMergeHook(); } MergeFinishedCallback mergeFinishedCallback = new MergeFinishedCallback(delegate(bool success) { bool result = success; if (proceedWithMergeHook != null) { if (CUDResultPreprocessor.GetPreprocessSuccess(proceedWithMergeHook) != true) { result = false; } CUDResultPreprocessor.CleanUp(proceedWithMergeHook); } if (commandFinishedCallback != null) { commandFinishedCallback.Invoke(result); } }); MergeProcess.Process(businessObjects, null, proceedWithMergeHook, mergeFinishedCallback); }
protected override Object InterceptMergeIntern(MethodInfo method, Object[] arguments, Attribute annotation, Boolean?isAsyncBegin) { if (arguments == null || (arguments.Length != 1 && arguments.Length != 2 && arguments.Length != 3)) { throw new Exception("Arguments currently must be only 1, 2 or 3: " + method.ToString()); } Object argumentToMerge = arguments[0]; Object argumentToDelete = GetArgumentToDelete(arguments, method.GetParameters()); ProceedWithMergeHook proceedHook = GetProceedHook(arguments); MergeFinishedCallback finishedCallback = GetFinishedCallback(arguments); MergeProcess.Process(argumentToMerge, argumentToDelete, proceedHook, finishedCallback); if (!typeof(void).Equals(method.ReturnType)) { return(argumentToMerge); } return(null); }
protected void DeleteById(MethodInfo method, Type entityType, String idName, Object ids, ProceedWithMergeHook proceedHook, MergeFinishedCallback finishedCallback) { IEntityMetaData metaData = GetSpecifiedMetaData(method, typeof(RemoveAttribute), entityType); Member idMember = GetSpecifiedMember(method, typeof(RemoveAttribute), metaData, idName); sbyte idIndex = metaData.GetIdIndexByMemberName(idName); Type idType = idMember.RealType; List <IObjRef> objRefs = new List <IObjRef>(); BuildObjRefs(entityType, idIndex, idType, ids, objRefs); MergeProcess.Process(null, objRefs, proceedHook, finishedCallback); }
public void Process(Object objectToMerge, Object objectToDelete, ProceedWithMergeHook proceedHook, MergeFinishedCallback mergeFinishedCallback) { Process(objectToMerge, objectToDelete, proceedHook, mergeFinishedCallback, true); }
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 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 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); } }