public override IAuditWorkUnit Dispatch(IWorkUnitMergeVisitor first)
        {
            if (first is PersistentCollectionChangeWorkUnit)
            {
                PersistentCollectionChangeWorkUnit original = (PersistentCollectionChangeWorkUnit)first;

                // Merging the collection changes in both work units.

                // First building a map from the ids of the collection-entry-entities from the "second" collection changes,
                // to the PCCD objects. That way, we will be later able to check if an "original" collection change
                // should be added, or if it is overshadowed by a new one.
                IDictionary <Object, PersistentCollectionChangeData> newChangesIdMap = new Dictionary <Object, PersistentCollectionChangeData>();
                foreach (PersistentCollectionChangeData persistentCollectionChangeData in getCollectionChanges())
                {
                    newChangesIdMap.Add(
                        getOriginalId(persistentCollectionChangeData),
                        persistentCollectionChangeData);
                }

                // This will be the list with the resulting (merged) changes.
                List <PersistentCollectionChangeData> mergedChanges = new List <PersistentCollectionChangeData>();

                // Including only those original changes, which are not overshadowed by new ones.
                foreach (PersistentCollectionChangeData originalCollectionChangeData in original.getCollectionChanges())
                {
                    if (!newChangesIdMap.ContainsKey(getOriginalId(originalCollectionChangeData)))
                    {
                        mergedChanges.Add(originalCollectionChangeData);
                    }
                }

                // Finally adding all of the new changes to the end of the list
                mergedChanges = (List <PersistentCollectionChangeData>)mergedChanges.Concat(getCollectionChanges());

                return(new PersistentCollectionChangeWorkUnit(sessionImplementor, EntityName, verCfg, EntityId, mergedChanges,
                                                              ReferencingPropertyName));
            }
            else
            {
                throw new Exception("Trying to merge a " + first + " with a PersitentCollectionChangeWorkUnit. " +
                                    "This is not really possible.");
            }
        }
Пример #2
0
        private void OnCollectionAction(AbstractCollectionEvent evt,
										IPersistentCollection newColl,
										object oldColl,
										CollectionEntry collectionEntry)
        {
            if (!VerCfg.GlobalCfg.GenerateRevisionsForCollections)
                return;
            var entityName = evt.GetAffectedOwnerEntityName();
            if (!VerCfg.EntCfg.IsVersioned(entityName)) return;

            var verSync = VerCfg.AuditProcessManager.Get(evt.Session);
            var ownerEntityName = ((AbstractCollectionPersister)collectionEntry.LoadedPersister).OwnerEntityName;
            var referencingPropertyName = collectionEntry.Role.Substring(ownerEntityName.Length + 1);

            // Checking if this is not a "fake" many-to-one bidirectional relation. The relation description may be
            // null in case of collections of non-entities.
            var rd = VerCfg.EntCfg[entityName].GetRelationDescription(referencingPropertyName);
            if (rd != null && rd.MappedByPropertyName != null)
            {
                GenerateFakeBidirecationalRelationWorkUnits(verSync, newColl, oldColl, entityName,
                                                            referencingPropertyName, evt, rd);
            }
            else
            {
                var workUnit = new PersistentCollectionChangeWorkUnit(evt.Session, entityName, VerCfg, newColl,
                                                                collectionEntry, oldColl, evt.AffectedOwnerIdOrNull,
                                                                referencingPropertyName);
                verSync.AddWorkUnit(workUnit);

                if (workUnit.ContainsWork())
                {
                    // There are some changes: a revision needs also be generated for the collection owner
                    verSync.AddWorkUnit(new CollectionChangeWorkUnit(evt.Session, evt.GetAffectedOwnerEntityName(),
                                                                VerCfg, evt.AffectedOwnerIdOrNull, evt.AffectedOwnerOrNull));

                    GenerateBidirectionalCollectionChangeWorkUnits(verSync, evt, workUnit, rd);
                }
            }
        }
Пример #3
0
        private void GenerateBidirectionalCollectionChangeWorkUnits(AuditProcess auditProcess,
																	IDatabaseEventArgs evt,
																	PersistentCollectionChangeWorkUnit workUnit,
																	RelationDescription rd)
        {
            // Checking if this is enabled in configuration ...
            if (!VerCfg.GlobalCfg.GenerateRevisionsForCollections)
                return;

            // Checking if this is not a bidirectional relation - then, a revision needs also be generated for
            // the other side of the relation.
            // relDesc can be null if this is a collection of simple values (not a relation).
            if (rd != null && rd.Bidirectional)
            {
                var relatedEntityName = rd.ToEntityName;
                var relatedIdMapper = VerCfg.EntCfg[relatedEntityName].IdMapper;

                foreach (var changeData in workUnit.CollectionChanges)
                {
                    var relatedObj = changeData.GetChangedElement();
                    var relatedId = relatedIdMapper.MapToIdFromEntity(relatedObj);

                    auditProcess.AddWorkUnit(new CollectionChangeWorkUnit(evt.Session,
                                                                                            evt.Session.BestGuessEntityName(relatedObj),
                                                                                            VerCfg,
                                                                                            relatedId,
                                                                                            relatedObj));
                }
            }
        }
        private void GenerateBidirectionalCollectionChangeWorkUnits(AuditSync verSync, AbstractCollectionEvent evt,
                                                                    PersistentCollectionChangeWorkUnit workUnit,
                                                                    RelationDescription rd) {
            // Checking if this is enabled in configuration ...
            if (!verCfg.GlobalCfg.isGenerateRevisionsForCollections()) {
                return;
            }

            // Checking if this is not a bidirectional relation - then, a revision needs also be generated for
            // the other side of the relation.
            // relDesc can be null if this is a collection of simple values (not a relation).
            if (rd != null && rd.Bidirectional) {
                String relatedEntityName = rd.ToEntityName;
                IIdMapper relatedIdMapper = verCfg.EntCfg[relatedEntityName].GetIdMapper();
                
                foreach (PersistentCollectionChangeData changeData in workUnit.getCollectionChanges()) 
                {
                    Object relatedObj = changeData.GetChangedElement();
                    object relatedId = relatedIdMapper.MapToIdFromEntity(relatedObj);

                    verSync.AddWorkUnit(new CollectionChangeWorkUnit(evt.Session, relatedEntityName, verCfg,
						    relatedId, relatedObj));
                }
            }
        }