package org.hibernate.loader.plan.build.internal.spaces;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.internal.CoreLogging;
import org.hibernate.loader.plan.build.spi.ExpandingCollectionQuerySpace;
import org.hibernate.loader.plan.build.spi.ExpandingCompositeQuerySpace;
import org.hibernate.loader.plan.build.spi.ExpandingEntityQuerySpace;
import org.hibernate.loader.plan.build.spi.ExpandingQuerySpaces;
import org.hibernate.loader.plan.spi.QuerySpace;
import org.hibernate.loader.plan.spi.QuerySpaceUidNotRegisteredException;
import org.hibernate.persister.collection.CollectionPersister;
import org.hibernate.persister.entity.EntityPersister;
import org.jboss.logging.Logger;
public class QuerySpacesImpl implements ExpandingQuerySpaces {
private static final Logger log = CoreLogging.logger( QuerySpacesImpl.class );
private final SessionFactoryImplementor sessionFactory;
private final List<QuerySpace> roots = new ArrayList<QuerySpace>();
private final Map<String,QuerySpace> querySpaceByUid = new ConcurrentHashMap<String, QuerySpace>();
public QuerySpacesImpl(SessionFactoryImplementor sessionFactory) {
this.sessionFactory = sessionFactory;
}
@Override
public List<QuerySpace> getRootQuerySpaces() {
return roots;
}
@Override
public QuerySpace findQuerySpaceByUid(String uid) {
return querySpaceByUid.get( uid );
}
@Override
public QuerySpace getQuerySpaceByUid(String uid) {
final QuerySpace space = findQuerySpaceByUid( uid );
if ( space == null ) {
throw new QuerySpaceUidNotRegisteredException( uid );
}
return space;
}
private int implicitUidBase;
@Override
public String generateImplicitUid() {
return "<gen:" + implicitUidBase++ + ">";
}
@Override
public ExpandingEntityQuerySpace makeRootEntityQuerySpace(String uid, EntityPersister entityPersister) {
final ExpandingEntityQuerySpace space = makeEntityQuerySpace( uid, entityPersister, true );
roots.add( space );
return space;
}
@Override
public ExpandingEntityQuerySpace makeEntityQuerySpace(
String uid,
EntityPersister entityPersister,
boolean canJoinsBeRequired) {
checkQuerySpaceDoesNotExist( uid );
final EntityQuerySpaceImpl space = new EntityQuerySpaceImpl(
entityPersister,
uid,
this,
canJoinsBeRequired && !entityPersister.getEntityMetamodel().hasSubclasses()
);
registerQuerySpace( space );
return space;
}
@Override
public ExpandingCollectionQuerySpace makeRootCollectionQuerySpace(String uid, CollectionPersister collectionPersister) {
final ExpandingCollectionQuerySpace space = makeCollectionQuerySpace( uid, collectionPersister, true );
roots.add( space );
return space;
}
@Override
public ExpandingCollectionQuerySpace makeCollectionQuerySpace(
String uid,
CollectionPersister collectionPersister,
boolean canJoinsBeRequired) {
checkQuerySpaceDoesNotExist( uid );
final ExpandingCollectionQuerySpace space = new CollectionQuerySpaceImpl(
collectionPersister,
uid,
this,
canJoinsBeRequired
);
registerQuerySpace( space );
return space;
}
@Override
public ExpandingCompositeQuerySpace makeCompositeQuerySpace(
String uid,
CompositePropertyMapping compositePropertyMapping,
boolean canJoinsBeRequired) {
checkQuerySpaceDoesNotExist( uid );
final ExpandingCompositeQuerySpace space = new CompositeQuerySpaceImpl(
compositePropertyMapping,
uid,
this,
canJoinsBeRequired
);
registerQuerySpace( space );
return space;
}
@Override
public SessionFactoryImplementor getSessionFactory() {
return sessionFactory;
}
private void checkQuerySpaceDoesNotExist(String uid) {
if ( querySpaceByUid.containsKey( uid ) ) {
throw new IllegalStateException( "Encountered duplicate QuerySpace uid : " + uid );
}
}
private void registerQuerySpace(QuerySpace querySpace) {
log.debugf(
"Adding QuerySpace : uid = %s -> %s]",
querySpace.getUid(),
querySpace
);
final QuerySpace previous = querySpaceByUid.put( querySpace.getUid(), querySpace );
if ( previous != null ) {
throw new IllegalStateException( "Encountered duplicate QuerySpace uid : " + querySpace.getUid() );
}
}
}