/* * Hibernate, Relational Persistence for Idiomatic Java * * License: GNU Lesser General Public License (LGPL), version 2.1 or later. * See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>. */ package org.hibernate.envers.internal.reader; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import org.hibernate.Session; import org.hibernate.engine.spi.SessionImplementor; import org.hibernate.envers.CrossTypeRevisionChangesReader; import org.hibernate.envers.RevisionType; import org.hibernate.envers.boot.internal.EnversService; import org.hibernate.envers.internal.tools.EntityTools; import org.hibernate.envers.query.criteria.internal.RevisionTypeAuditExpression; import org.hibernate.envers.tools.Pair; import org.hibernate.query.Query; import static org.hibernate.envers.internal.tools.ArgumentsTools.checkNotNull; import static org.hibernate.envers.internal.tools.ArgumentsTools.checkPositive; /** * @author Lukasz Antoniak (lukasz dot antoniak at gmail dot com) */ public class CrossTypeRevisionChangesReaderImpl implements CrossTypeRevisionChangesReader { private final AuditReaderImplementor auditReaderImplementor; private final EnversService enversService; public CrossTypeRevisionChangesReaderImpl( AuditReaderImplementor auditReaderImplementor, EnversService enversService) { this.auditReaderImplementor = auditReaderImplementor; this.enversService = enversService; } @Override @SuppressWarnings({"unchecked"}) public List<Object> findEntities(Number revision) throws IllegalStateException, IllegalArgumentException { final Set<Pair<String, Class>> entityTypes = findEntityTypes( revision ); final List<Object> result = new ArrayList<>(); for ( Pair<String, Class> type : entityTypes ) { result.addAll( auditReaderImplementor.createQuery().forEntitiesModifiedAtRevision( type.getSecond(), type.getFirst(), revision ) .getResultList() ); } return result; } @Override @SuppressWarnings({"unchecked"}) public List<Object> findEntities(Number revision, RevisionType revisionType) throws IllegalStateException, IllegalArgumentException { final Set<Pair<String, Class>> entityTypes = findEntityTypes( revision ); final List<Object> result = new ArrayList<>(); for ( Pair<String, Class> type : entityTypes ) { result.addAll( auditReaderImplementor.createQuery().forEntitiesModifiedAtRevision( type.getSecond(), type.getFirst(), revision ) .add( new RevisionTypeAuditExpression( null, revisionType, "=" ) ).getResultList() ); } return result; } @Override @SuppressWarnings({"unchecked"}) public Map<RevisionType, List<Object>> findEntitiesGroupByRevisionType(Number revision) throws IllegalStateException, IllegalArgumentException { final Set<Pair<String, Class>> entityTypes = findEntityTypes( revision ); final Map<RevisionType, List<Object>> result = new HashMap<>(); for ( RevisionType revisionType : RevisionType.values() ) { result.put( revisionType, new ArrayList<>() ); for ( Pair<String, Class> type : entityTypes ) { final List<Object> list = auditReaderImplementor.createQuery() .forEntitiesModifiedAtRevision( type.getSecond(), type.getFirst(), revision ) .add( new RevisionTypeAuditExpression( null, revisionType, "=" ) ) .getResultList(); result.get( revisionType ).addAll( list ); } } return result; } @Override @SuppressWarnings({"unchecked"}) public Set<Pair<String, Class>> findEntityTypes(Number revision) throws IllegalStateException, IllegalArgumentException { checkNotNull( revision, "Entity revision" ); checkPositive( revision, "Entity revision" ); checkSession(); final Session session = auditReaderImplementor.getSession(); final SessionImplementor sessionImplementor = auditReaderImplementor.getSessionImplementor(); final Set<Number> revisions = new HashSet<>( 1 ); revisions.add( revision ); final Query<?> query = enversService.getRevisionInfoQueryCreator().getRevisionsQuery( session, revisions ); final Object revisionInfo = query.uniqueResult(); if ( revisionInfo != null ) { // If revision exists. final Set<String> entityNames = enversService.getModifiedEntityNamesReader().getModifiedEntityNames( revisionInfo ); if ( entityNames != null ) { // Generate result that contains entity names and corresponding Java classes. final Set<Pair<String, Class>> result = new HashSet<>(); for ( String entityName : entityNames ) { result.add( Pair.make( entityName, EntityTools.getEntityClass( sessionImplementor, entityName ) ) ); } return result; } } return Collections.EMPTY_SET; } private void checkSession() { if ( !auditReaderImplementor.getSession().isOpen() ) { throw new IllegalStateException( "The associated entity manager is closed!" ); } } }