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(); } }
protected void ApplyRelationUpdateItem(IObjRefContainer entity, IRelationUpdateItem rui, bool isUpdate, IEntityMetaData metaData, IList <DirectValueHolderRef> toPrefetch, List <IObjRef> toFetchFromCache, bool checkBaseState, IList <IBackgroundWorkerDelegate> runnables) { IObjRefHelper objRefHelper = this.ObjRefHelper; String memberName = rui.MemberName; int relationIndex = metaData.GetIndexByRelationName(memberName); RelationMember relationMember = metaData.RelationMembers[relationIndex]; IObjRef[] existingORIs; if (entity.Is__Initialized(relationIndex)) { existingORIs = ListUtil.ToArray(ObjRefHelper.ExtractObjRefList(relationMember.GetValue(entity), null)); } else { existingORIs = entity.Get__ObjRefs(relationIndex); if (existingORIs == null) { toPrefetch.Add(new DirectValueHolderRef(entity, relationMember, true)); runnables.Add(new IBackgroundWorkerDelegate(delegate() { ApplyRelationUpdateItem(entity, rui, isUpdate, metaData, toPrefetch, toFetchFromCache, checkBaseState, runnables); })); return; } } IObjRef[] addedORIs = rui.AddedORIs; IObjRef[] removedORIs = rui.RemovedORIs; IObjRef[] newORIs; if (existingORIs.Length == 0) { if (checkBaseState && removedORIs != null) { throw new Exception("Removing from empty member"); } newORIs = addedORIs != null ? (IObjRef[])addedORIs.Clone() : ObjRef.EMPTY_ARRAY; for (int a = newORIs.Length; a-- > 0;) { newORIs[a] = CloneObjRef(newORIs[a], false); } } else { // Set to efficiently remove entries LinkedHashSet <IObjRef> existingORIsSet = new LinkedHashSet <IObjRef>(existingORIs); if (removedORIs != null) { foreach (IObjRef removedORI in removedORIs) { IObjRef clonedObjRef = CloneObjRef(removedORI, false); if (existingORIsSet.Remove(clonedObjRef) || !checkBaseState) { continue; } throw OptimisticLockUtil.ThrowModified(objRefHelper.EntityToObjRef(entity), null, entity); } } if (addedORIs != null) { foreach (IObjRef addedORI in addedORIs) { IObjRef clonedObjRef = CloneObjRef(addedORI, false); if (existingORIsSet.Add(clonedObjRef) || !checkBaseState) { continue; } throw OptimisticLockUtil.ThrowModified(objRefHelper.EntityToObjRef(entity), null, entity); } } if (existingORIsSet.Count == 0) { newORIs = ObjRef.EMPTY_ARRAY; } else { newORIs = existingORIsSet.ToArray(); } } if (!entity.Is__Initialized(relationIndex)) { entity.Set__ObjRefs(relationIndex, newORIs); return; } toFetchFromCache.AddRange(newORIs); runnables.Add(new IBackgroundWorkerDelegate(delegate() { ICache stateCache = cloneStateTL.Value.incrementalState.GetStateCache(); IList <Object> objects = stateCache.GetObjects(newORIs, CacheDirective.FailEarly); Object value; if (relationMember.IsToMany) { // To-many relation Object coll = ListUtil.CreateObservableCollectionOfType(relationMember.RealType, objects.Count); ListUtil.FillList(coll, objects); value = coll; } else { // To-one relation value = objects.Count > 0 ? objects[0] : null; } relationMember.SetValue(entity, value); })); }