All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.hibernate.envers.internal.reader.CrossTypeRevisionChangesReaderImpl Maven / Gradle / Ivy

There is a newer version: 7.0.0.Alpha3
Show newest version
/*
 * 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 .
 */
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.AuditService;
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;
import static org.hibernate.envers.tools.Pair.make;

/**
 * @author Lukasz Antoniak (lukasz dot antoniak at gmail dot com)
 * @author Chris Cranford
 */
public class CrossTypeRevisionChangesReaderImpl implements CrossTypeRevisionChangesReader {
	private final AuditReaderImplementor auditReaderImplementor;

	public CrossTypeRevisionChangesReaderImpl(AuditReaderImplementor auditReaderImplementor) {
		this.auditReaderImplementor = auditReaderImplementor;
	}

	@Override
	@SuppressWarnings({"unchecked"})
	public List findEntities(Number revision) throws IllegalStateException, IllegalArgumentException {
		final Set> entityTypes = findEntityTypes( revision );
		final List result = new ArrayList<>();
		for ( Pair type : entityTypes ) {
			result.addAll(
					auditReaderImplementor.createQuery()
							.forEntitiesModifiedAtRevision( type.getSecond(), type.getFirst(), revision )
							.getResultList()
			);
		}
		return result;
	}

	@Override
	@SuppressWarnings({"unchecked"})
	public List findEntities(Number revision, RevisionType revisionType)
	throws IllegalStateException, IllegalArgumentException {
		final Set> entityTypes = findEntityTypes( revision );
		final List result = new ArrayList<>();
		for ( Pair 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> findEntitiesGroupByRevisionType(Number revision)
	throws IllegalStateException, IllegalArgumentException {
		final Set> entityTypes = findEntityTypes( revision );
		final Map> result = new HashMap<>();
		for ( RevisionType revisionType : RevisionType.values() ) {
			result.put( revisionType, new ArrayList<>() );
			for ( Pair type : entityTypes ) {
				final List 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> 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 AuditService auditService = auditReaderImplementor.getAuditService();

		final Set revisions = new HashSet<>( 1 );
		revisions.add( revision );
		final Query query = auditService.getRevisionInfoQueryCreator().getRevisionsQuery( session, revisions );
		final Object revisionInfo = query.uniqueResult();

		if ( revisionInfo != null ) {
			// If revision exists.
			final Set entityNames = auditService.getModifiedEntityNamesReader()
					.getModifiedEntityNames( revisionInfo );
			if ( entityNames != null ) {
				// Generate result that contains entity names and corresponding Java classes.
				final Set> result = new HashSet<>();
				for ( String entityName : entityNames ) {
					result.add( 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!" );
		}
	}

}