org.hibernate.query.sqm.tree.domain.SqmPolymorphicRootDescriptor Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of hibernate-core Show documentation
Show all versions of hibernate-core Show documentation
Hibernate's core ORM functionality
/*
* 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.query.sqm.tree.domain;
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 java.util.function.Consumer;
import java.util.stream.Collectors;
import javax.persistence.metamodel.Attribute;
import javax.persistence.metamodel.CollectionAttribute;
import javax.persistence.metamodel.ListAttribute;
import javax.persistence.metamodel.MapAttribute;
import javax.persistence.metamodel.PluralAttribute;
import javax.persistence.metamodel.SetAttribute;
import javax.persistence.metamodel.SingularAttribute;
import org.hibernate.graph.spi.SubGraphImplementor;
import org.hibernate.metamodel.RepresentationMode;
import org.hibernate.metamodel.model.domain.DomainType;
import org.hibernate.metamodel.model.domain.EntityDomainType;
import org.hibernate.metamodel.model.domain.IdentifiableDomainType;
import org.hibernate.metamodel.model.domain.ManagedDomainType;
import org.hibernate.metamodel.model.domain.PersistentAttribute;
import org.hibernate.metamodel.model.domain.PluralPersistentAttribute;
import org.hibernate.metamodel.model.domain.SimpleDomainType;
import org.hibernate.metamodel.model.domain.SingularPersistentAttribute;
import org.hibernate.query.sqm.SqmPathSource;
import org.hibernate.query.hql.spi.SqmCreationState;
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
/**
* Acts as the EntityValuedNavigable for a "polymorphic query" grouping
*
* @author Steve Ebersole
*/
public class SqmPolymorphicRootDescriptor implements EntityDomainType {
private final Set> implementors;
private final Map commonAttributes;
private final JavaTypeDescriptor polymorphicJavaDescriptor;
public SqmPolymorphicRootDescriptor(
JavaTypeDescriptor polymorphicJavaDescriptor,
Set> implementors) {
this.polymorphicJavaDescriptor = polymorphicJavaDescriptor;
this.implementors = implementors;
final Map workMap = new HashMap<>();
final ArrayList> implementorsList = new ArrayList<>( implementors );
final EntityDomainType firstImplementor = implementorsList.get( 0 );
// basically we want to "expose" only the attributes that all the implementors expose...
// - visit all of the attributes defined on the first implementor and check it against
// all of the others
final List> subList = implementorsList.subList( 1, implementors.size() - 1 );
firstImplementor.visitAttributes(
attribute -> {
// for each of its attributes, check whether the other implementors also expose it
for ( EntityDomainType navigable : subList ) {
if ( navigable.findAttribute( attribute.getName() ) == null ) {
// we found an implementor that does not expose that attribute,
// so break-out to the next attribute
break;
}
// if we get here - they all had it. so put it in the workMap
//
// todo (6.0) : Atm We use the attribute from the first implementor directly for each implementor
// need to handle this in QuerySplitter somehow
workMap.put( attribute.getName(), attribute );
}
}
);
this.commonAttributes = Collections.unmodifiableMap( workMap );
}
public Set> getImplementors() {
return new HashSet<>( implementors );
}
@Override
public String getName() {
return polymorphicJavaDescriptor.getJavaType().getName();
}
@Override
public String getHibernateEntityName() {
return getName();
}
@Override
public String getTypeName() {
return getName();
}
@Override
public String getPathName() {
return getName();
}
@Override
public DomainType getSqmPathType() {
return this;
}
@Override
public BindableType getBindableType() {
return BindableType.ENTITY_TYPE;
}
@Override
public Class getBindableJavaType() {
return polymorphicJavaDescriptor.getJavaType();
}
@Override
public PersistenceType getPersistenceType() {
return PersistenceType.ENTITY;
}
@Override
public Class getJavaType() {
return getBindableJavaType();
}
@Override
public JavaTypeDescriptor getExpressableJavaTypeDescriptor() {
return polymorphicJavaDescriptor;
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Attribute handling
@Override
@SuppressWarnings("unchecked")
public PersistentAttribute findAttribute(String name) {
return commonAttributes.get( name );
}
@Override
public void visitAttributes(Consumer> action) {
commonAttributes.values().forEach( (Consumer) action );
}
@Override
public void visitDeclaredAttributes(Consumer> action) {
}
@Override
public PersistentAttribute getAttribute(String name) {
final PersistentAttribute attribute = findAttribute( name );
if ( attribute == null ) {
// per-JPA
throw new IllegalArgumentException();
}
return attribute;
}
@Override
public PersistentAttribute getDeclaredAttribute(String name) {
throw new IllegalArgumentException();
}
@Override
public SingularPersistentAttribute findSingularAttribute(String name) {
//noinspection unchecked
return (SingularPersistentAttribute) findAttribute( name );
}
@Override
public PluralPersistentAttribute findPluralAttribute(String name) {
//noinspection unchecked
return (PluralPersistentAttribute) findAttribute( name );
}
@Override
public PersistentAttribute findDeclaredAttribute(String name) {
return null;
}
@Override
public SingularPersistentAttribute findDeclaredSingularAttribute(String name) {
return null;
}
@Override
public PluralPersistentAttribute findDeclaredPluralAttribute(String name) {
return null;
}
@Override
public Set> getAttributes() {
//noinspection unchecked
return (Set>) commonAttributes;
}
@Override
public Set> getDeclaredAttributes() {
return Collections.emptySet();
}
@Override
public SingularAttribute getSingularAttribute(String name, Class type) {
//noinspection unchecked
return (SingularAttribute) getAttribute( name );
}
@Override
public SingularAttribute getDeclaredSingularAttribute(String name, Class type) {
//noinspection unchecked
return (SingularAttribute) getDeclaredAttribute( name );
}
@Override
public Set> getSingularAttributes() {
//noinspection unchecked
return (Set) commonAttributes.values().stream()
.filter( attribute -> attribute instanceof SingularAttribute )
.collect( Collectors.toSet() );
}
@Override
public Set> getDeclaredSingularAttributes() {
return Collections.emptySet();
}
@Override
public CollectionAttribute getCollection(String name, Class elementType) {
//noinspection unchecked
return (CollectionAttribute) getAttribute( name );
}
@Override
public CollectionAttribute getDeclaredCollection(String name, Class elementType) {
throw new IllegalArgumentException();
}
@Override
public SetAttribute getSet(String name, Class elementType) {
//noinspection unchecked
return (SetAttribute) getAttribute( name );
}
@Override
public SetAttribute getDeclaredSet(String name, Class elementType) {
throw new IllegalArgumentException( );
}
@Override
public ListAttribute getList(String name, Class elementType) {
//noinspection unchecked
return (ListAttribute) getAttribute( name );
}
@Override
public ListAttribute getDeclaredList(String name, Class elementType) {
throw new IllegalArgumentException();
}
@Override
public MapAttribute getMap(String name, Class keyType, Class valueType) {
//noinspection unchecked
return (MapAttribute) getAttribute( name );
}
@Override
public MapAttribute getDeclaredMap(String name, Class keyType, Class valueType) {
throw new IllegalArgumentException();
}
@Override
public Set> getPluralAttributes() {
//noinspection unchecked
return (Set) commonAttributes.values().stream()
.filter( attribute -> attribute instanceof PluralAttribute )
.collect( Collectors.toSet() );
}
@Override
public Set> getDeclaredPluralAttributes() {
return Collections.emptySet();
}
@Override
public SingularAttribute getSingularAttribute(String name) {
//noinspection unchecked
return (SingularAttribute) getAttribute( name );
}
@Override
public SingularAttribute getDeclaredSingularAttribute(String name) {
throw new IllegalArgumentException();
}
@Override
public CollectionAttribute getCollection(String name) {
//noinspection unchecked
return (CollectionAttribute) getAttribute( name );
}
@Override
public CollectionAttribute getDeclaredCollection(String name) {
throw new IllegalArgumentException();
}
@Override
public SetAttribute getSet(String name) {
//noinspection unchecked
return (SetAttribute) getAttribute( name );
}
@Override
public SetAttribute getDeclaredSet(String name) {
throw new IllegalArgumentException();
}
@Override
public ListAttribute getList(String name) {
//noinspection unchecked
return (ListAttribute) getAttribute( name );
}
@Override
public ListAttribute getDeclaredList(String name) {
throw new IllegalArgumentException();
}
@Override
public MapAttribute getMap(String name) {
//noinspection unchecked
return (MapAttribute) getAttribute( name );
}
@Override
public MapAttribute getDeclaredMap(String name) {
throw new IllegalArgumentException();
}
@Override
public SqmPathSource findSubPathSource(String name) {
return (SqmPathSource) findAttribute( name );
}
@Override
public SqmPath createSqmPath(SqmPath lhs, SqmCreationState creationState) {
throw new UnsupportedOperationException();
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Unsupported operations
@Override
public RepresentationMode getRepresentationMode() {
return RepresentationMode.POJO;
}
@Override
public SubGraphImplementor makeSubGraph() {
throw new UnsupportedOperationException( );
}
@Override
public SubGraphImplementor makeSubGraph(Class subType) {
throw new UnsupportedOperationException( );
}
@Override
public ManagedDomainType findSubType(String subTypeName) {
// technically we could support this
throw new UnsupportedOperationException( );
}
@Override
public ManagedDomainType findSubType(Class type) {
// technically we could support this
throw new UnsupportedOperationException( );
}
@Override
public SqmPathSource getIdentifierDescriptor() {
return null;
}
@Override
public SingularPersistentAttribute getId(Class type) {
throw new UnsupportedOperationException( );
}
@Override
public SingularPersistentAttribute getDeclaredId(Class type) {
throw new UnsupportedOperationException( );
}
@Override
public SingularPersistentAttribute getVersion(Class type) {
throw new UnsupportedOperationException( );
}
@Override
public SingularPersistentAttribute getDeclaredVersion(Class type) {
throw new UnsupportedOperationException( );
}
@Override
public Set> getIdClassAttributes() {
throw new UnsupportedOperationException( );
}
@Override
public SimpleDomainType getIdType() {
throw new UnsupportedOperationException( );
}
@Override
public IdentifiableDomainType getSupertype() {
throw new UnsupportedOperationException( );
}
@Override
public boolean hasIdClass() {
throw new UnsupportedOperationException( );
}
@Override
public SingularPersistentAttribute findIdAttribute() {
throw new UnsupportedOperationException( );
}
@Override
public void visitIdClassAttributes(Consumer> action) {
}
@Override
public SingularPersistentAttribute findVersionAttribute() {
throw new UnsupportedOperationException( );
}
@Override
public boolean hasSingleIdAttribute() {
throw new UnsupportedOperationException( );
}
@Override
public boolean hasVersionAttribute() {
throw new UnsupportedOperationException( );
}
@Override
public ManagedDomainType getSuperType() {
throw new UnsupportedOperationException( );
}
}