public AuditSync get(IEventSource session) {
            ITransaction transaction = session.Transaction;

            if( auditSyncs.Keys.Contains(transaction))
                return auditSyncs[transaction];
            else {
                // No worries about registering a transaction twice - a transaction is single thread
                AuditSync verSync = new AuditSync(this, session, revisionInfoGenerator);
                auditSyncs.Add(transaction, verSync);

                transaction.RegisterSynchronization(verSync);

                //ITransactionSynchronization synchro = new EnversTransactionSynchronization(verSync);
                //TransactionSynchronizationManager.RegisterSynchronization(synchro);

                return verSync;
            }
        }
Пример #2
0
        public AuditSync get(IEventSource session)
        {
            ITransaction transaction = session.Transaction;

            if (auditSyncs.Keys.Contains(transaction))
            {
                return(auditSyncs[transaction]);
            }
            else
            {
                // No worries about registering a transaction twice - a transaction is single thread
                AuditSync verSync = new AuditSync(this, session, revisionInfoGenerator);
                auditSyncs.Add(transaction, verSync);

                transaction.RegisterSynchronization(verSync);

                //ITransactionSynchronization synchro = new EnversTransactionSynchronization(verSync);
                //TransactionSynchronizationManager.RegisterSynchronization(synchro);

                return(verSync);
            }
        }
 public EnversTransactionSynchronization(AuditSync _sync)
 {
     sync = _sync;
 }
 public EnversTransactionSynchronization(AuditSync _sync)
 {
     sync = _sync;
 }
        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));
                        }
                    }
                }
            }
        }
        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));
        }
        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));
                }
            }
        }