Example #1
0
        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));
                }
            }
        }
Example #2
0
        public void OnPostInsert(PostInsertEvent evt)
        {
            String entityName = evt.Persister.EntityName;

            if (verCfg.EntCfg.IsVersioned(entityName))
            {
                AuditSync verSync = verCfg.AuditSyncManager.get(evt.Session);

                IAuditWorkUnit workUnit = new AddWorkUnit(evt.Session, evt.Persister.EntityName, verCfg,
                                                          evt.Id, evt.Persister, evt.State);
                verSync.AddWorkUnit(workUnit);

                if (workUnit.ContainsWork())
                {
                    GenerateBidirectionalCollectionChangeWorkUnits(verSync, evt.Persister, entityName, evt.State,
                                                                   null, evt.Session);
                }

                //Simon - TODO - Correct/clarify this:
                // it appears that the AuditSyncManager's transaction.RegisterSynchronization(verSync);
                // does not lead to calling the verSync's synchronization methods (Before and AfterCompletion
                // so I will call this manually. The problem that I found is that AdoTransaction's Commit method
                // is not called at all. Could this be because of Spring.NET?
                // When corrected, change also in AuditSync the Flush in BeforeCompletion.
                //verSync.BeforeCompletion();
            }
        }
Example #3
0
        public T GetCurrentRevision <T>(System.Type revisionEntityClass, bool persist)
        {
            if (!(Session is IEventSource))
            {
                throw new NotSupportedException("The provided session is not an EventSource!");// ORIG IllegalArgumentException
            }

            // Obtaining the current audit sync
            AuditSync auditSync = verCfg.AuditSyncManager.get((IEventSource)Session);

            // And getting the current revision data
            return((T)auditSync.GetCurrentRevisionData(Session, persist));
        }
Example #4
0
        public void OnPostDelete(PostDeleteEvent evt)
        {
            String entityName = evt.Persister.EntityName;

            if (verCfg.EntCfg.IsVersioned(entityName))
            {
                AuditSync verSync = verCfg.AuditSyncManager.get(evt.Session);

                IAuditWorkUnit workUnit = new DelWorkUnit(evt.Session, evt.Persister.EntityName, verCfg,
                                                          evt.Id, evt.Persister, evt.DeletedState);
                verSync.AddWorkUnit(workUnit);

                if (workUnit.ContainsWork())
                {
                    GenerateBidirectionalCollectionChangeWorkUnits(verSync, evt.Persister, entityName, null,
                                                                   evt.DeletedState, evt.Session);
                }
            }
        }
Example #5
0
        public void OnPostUpdate(PostUpdateEvent evt)
        {
            String entityName = evt.Persister.EntityName;

            if (verCfg.EntCfg.IsVersioned(entityName))
            {
                AuditSync verSync = verCfg.AuditSyncManager.get(evt.Session);

                IAuditWorkUnit workUnit = new ModWorkUnit(evt.Session, evt.Persister.EntityName, verCfg,
                                                          evt.Id, evt.Persister, evt.State, evt.OldState);
                verSync.AddWorkUnit(workUnit);

                if (workUnit.ContainsWork())
                {
                    GenerateBidirectionalCollectionChangeWorkUnits(verSync, evt.Persister, entityName, evt.State,
                                                                   evt.OldState, evt.Session);
                }
                //Simon - TODO - same as above
                //verSync.BeforeCompletion();
            }
        }
Example #6
0
        private void OnCollectionAction(AbstractCollectionEvent evt, IPersistentCollection newColl, object oldColl,
                                        CollectionEntry collectionEntry)
        {
            String entityName = evt.GetAffectedOwnerEntityName();

            if (verCfg.EntCfg.IsVersioned(entityName))
            {
                AuditSync verSync = verCfg.AuditSyncManager.get(evt.Session);

                String ownerEntityName         = ((AbstractCollectionPersister)collectionEntry.LoadedPersister).OwnerEntityName;
                String 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.
                RelationDescription rd = verCfg.EntCfg[entityName].GetRelationDescription(referencingPropertyName);
                if (rd != null && rd.MappedByPropertyName != null)
                {
                    GenerateFakeBidirecationalRelationWorkUnits(verSync, newColl, oldColl, entityName,
                                                                referencingPropertyName, evt, rd);
                }
                else
                {
                    PersistentCollectionChangeWorkUnit 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);
                    }
                }
            }
        }
Example #7
0
        private void GenerateFakeBidirecationalRelationWorkUnits(AuditSync verSync, IPersistentCollection newColl, object oldColl,
                                                                 String collectionEntityName, String referencingPropertyName,
                                                                 AbstractCollectionEvent evt,
                                                                 RelationDescription rd)
        {
            // First computing the relation changes
            IList <PersistentCollectionChangeData> collectionChanges = verCfg.EntCfg[collectionEntityName].PropertyMapper
                                                                       .MapCollectionChanges(referencingPropertyName, newColl, oldColl, evt.AffectedOwnerIdOrNull);

            // Getting the id mapper for the related entity, as the work units generated will corrspond to the related
            // entities.
            String    relatedEntityName = rd.ToEntityName;
            IIdMapper relatedIdMapper   = verCfg.EntCfg[relatedEntityName].GetIdMapper();

            // For each collection change, generating the bidirectional work unit.
            foreach (PersistentCollectionChangeData changeData in collectionChanges)
            {
                Object       relatedObj = changeData.GetChangedElement();
                object       relatedId  = relatedIdMapper.MapToIdFromEntity(relatedObj);
                RevisionType revType    = (RevisionType)changeData.getData()[verCfg.AuditEntCfg.RevisionTypePropName];

                // This can be different from relatedEntityName, in case of inheritance (the real entity may be a subclass
                // of relatedEntityName).
                String realRelatedEntityName = evt.Session.BestGuessEntityName(relatedObj);

                // By default, the nested work unit is a collection change work unit.
                IAuditWorkUnit nestedWorkUnit = new CollectionChangeWorkUnit(evt.Session, realRelatedEntityName, verCfg,
                                                                             relatedId, relatedObj);

                verSync.AddWorkUnit(new FakeBidirectionalRelationWorkUnit(evt.Session, realRelatedEntityName, verCfg,
                                                                          relatedId, referencingPropertyName, evt.AffectedOwnerOrNull, rd, revType,
                                                                          changeData.GetChangedElementIndex(), nestedWorkUnit));
            }

            // We also have to generate a collection change work unit for the owning entity.
            verSync.AddWorkUnit(new CollectionChangeWorkUnit(evt.Session, collectionEntityName, verCfg,
                                                             evt.AffectedOwnerIdOrNull, evt.AffectedOwnerOrNull));
        }
Example #8
0
        private void GenerateBidirectionalCollectionChangeWorkUnits(AuditSync verSync, IEntityPersister entityPersister,
                                                                    String entityName, Object[] newState, Object[] oldState,
                                                                    ISessionImplementor session)
        {
            // Checking if this is enabled in configuration ...
            if (!verCfg.GlobalCfg.isGenerateRevisionsForCollections())
            {
                return;
            }

            // Checks every property of the entity, if it is an "owned" to-one relation to another entity.
            // If the value of that property changed, and the relation is bi-directional, a new revision
            // for the related entity is generated.
            String[] propertyNames = entityPersister.PropertyNames;

            for (int i = 0; i < propertyNames.GetLength(0); i++)
            {
                String propertyName         = propertyNames[i];
                RelationDescription relDesc = verCfg.EntCfg.GetRelationDescription(entityName, propertyName);
                if (relDesc != null && relDesc.Bidirectional && relDesc.RelationType == RelationType.TO_ONE &&
                    relDesc.Insertable)
                {
                    // Checking for changes
                    Object oldValue = oldState == null ? null : oldState[i];
                    Object newValue = newState == null ? null : newState[i];

                    if (!Toolz.EntitiesEqual(session, oldValue, newValue))
                    {
                        // We have to generate changes both in the old collection (size decreses) and new collection
                        // (size increases).

                        //<TODO Simon: doua if-uri cu cod duplicat, refact.
                        if (newValue != null)
                        {
                            // relDesc.getToEntityName() doesn't always return the entity name of the value - in case
                            // of subclasses, this will be root class, no the actual class. So it can't be used here.
                            String toEntityName;

                            // Java: Serializable id
                            object id;

                            if (newValue is INHibernateProxy)
                            {
                                INHibernateProxy hibernateProxy = (INHibernateProxy)newValue;
                                toEntityName = session.BestGuessEntityName(newValue);
                                id           = hibernateProxy.HibernateLazyInitializer.Identifier;
                                // We've got to initialize the object from the proxy to later read its state.
                                newValue = NHibernate.Envers.Tools.Toolz.GetTargetFromProxy(session.Factory, hibernateProxy);
                            }
                            else
                            {
                                toEntityName = session.GuessEntityName(newValue);

                                IIdMapper idMapper = verCfg.EntCfg[toEntityName].GetIdMapper();
                                id = idMapper.MapToIdFromEntity(newValue);
                            }

                            verSync.AddWorkUnit(new CollectionChangeWorkUnit(session, toEntityName, verCfg, id, newValue));
                        }

                        if (oldValue != null)
                        {
                            String toEntityName;
                            object id;

                            if (oldValue is INHibernateProxy)
                            {
                                INHibernateProxy hibernateProxy = (INHibernateProxy)oldValue;
                                toEntityName = session.BestGuessEntityName(oldValue);
                                id           = hibernateProxy.HibernateLazyInitializer.Identifier;
                                // We've got to initialize the object as we'll read it's state anyway.
                                oldValue = Toolz.GetTargetFromProxy(session.Factory, hibernateProxy);
                            }
                            else
                            {
                                toEntityName = session.GuessEntityName(oldValue);

                                IIdMapper idMapper = verCfg.EntCfg[toEntityName].GetIdMapper();
                                id = idMapper.MapToIdFromEntity(oldValue);
                            }

                            verSync.AddWorkUnit(new CollectionChangeWorkUnit(session, toEntityName, verCfg, id, oldValue));
                        }
                    }
                }
            }
        }