/* * 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.produce.internal; import org.hibernate.persister.collection.spi.CollectionElement; import org.hibernate.persister.collection.spi.CollectionIndex; import org.hibernate.persister.common.internal.SingularPersistentAttributeBasic; import org.hibernate.persister.common.internal.SingularPersistentAttributeEmbedded; import org.hibernate.persister.common.internal.SingularPersistentAttributeEntity; import org.hibernate.persister.common.spi.Navigable; import org.hibernate.persister.common.spi.PluralPersistentAttribute; import org.hibernate.persister.common.spi.SingularPersistentAttribute; import org.hibernate.persister.entity.spi.IdentifierDescriptor; import org.hibernate.persister.entity.spi.IdentifierDescriptorComposite; import org.hibernate.persister.entity.spi.IdentifierDescriptorSimple; import org.hibernate.persister.queryable.spi.EntityValuedExpressableType; import org.hibernate.query.sqm.NotYetImplementedException; import org.hibernate.query.sqm.ParsingException; import org.hibernate.query.sqm.domain.SqmPluralAttributeIndex; import org.hibernate.query.sqm.tree.expression.SqmExpression; import org.hibernate.query.sqm.tree.expression.domain.SqmCollectionElementReference; import org.hibernate.query.sqm.tree.expression.domain.SqmCollectionElementReferenceBasic; import org.hibernate.query.sqm.tree.expression.domain.SqmCollectionElementReferenceEmbedded; import org.hibernate.query.sqm.tree.expression.domain.SqmCollectionElementReferenceEntity; import org.hibernate.query.sqm.tree.expression.domain.SqmCollectionIndexReference; import org.hibernate.query.sqm.tree.expression.domain.SqmCollectionIndexReferenceBasic; import org.hibernate.query.sqm.tree.expression.domain.SqmCollectionIndexReferenceEmbedded; import org.hibernate.query.sqm.tree.expression.domain.SqmCollectionIndexReferenceEntity; import org.hibernate.query.sqm.tree.expression.domain.SqmEntityIdentifierReference; import org.hibernate.query.sqm.tree.expression.domain.SqmEntityIdentifierReferenceComposite; import org.hibernate.query.sqm.tree.expression.domain.SqmEntityIdentifierReferenceSimple; import org.hibernate.query.sqm.tree.expression.domain.SqmEntityReference; import org.hibernate.query.sqm.tree.expression.domain.SqmEntityTypedReference; import org.hibernate.query.sqm.tree.expression.domain.SqmIndexedElementReferenceBasic; import org.hibernate.query.sqm.tree.expression.domain.SqmIndexedElementReferenceEmbedded; import org.hibernate.query.sqm.tree.expression.domain.SqmIndexedElementReferenceEntity; import org.hibernate.query.sqm.tree.expression.domain.SqmMaxElementReferenceBasic; import org.hibernate.query.sqm.tree.expression.domain.SqmMaxElementReferenceEmbedded; import org.hibernate.query.sqm.tree.expression.domain.SqmMaxElementReferenceEntity; import org.hibernate.query.sqm.tree.expression.domain.SqmMaxIndexReferenceBasic; import org.hibernate.query.sqm.tree.expression.domain.SqmMaxIndexReferenceEmbedded; import org.hibernate.query.sqm.tree.expression.domain.SqmMaxIndexReferenceEntity; import org.hibernate.query.sqm.tree.expression.domain.SqmMinElementReferenceBasic; import org.hibernate.query.sqm.tree.expression.domain.SqmMinElementReferenceEmbedded; import org.hibernate.query.sqm.tree.expression.domain.SqmMinElementReferenceEntity; import org.hibernate.query.sqm.tree.expression.domain.SqmMinIndexReferenceBasic; import org.hibernate.query.sqm.tree.expression.domain.SqmMinIndexReferenceEmbeddable; import org.hibernate.query.sqm.tree.expression.domain.SqmMinIndexReferenceEntity; import org.hibernate.query.sqm.tree.expression.domain.SqmNavigableReference; import org.hibernate.query.sqm.tree.expression.domain.SqmNavigableSourceReference; import org.hibernate.query.sqm.tree.expression.domain.SqmPluralAttributeReference; import org.hibernate.query.sqm.tree.expression.domain.SqmRestrictedCollectionElementReference; import org.hibernate.query.sqm.tree.expression.domain.SqmSingularAttributeReference; import org.hibernate.query.sqm.tree.expression.domain.SqmSingularAttributeReferenceBasic; import org.hibernate.query.sqm.tree.expression.domain.SqmSingularAttributeReferenceEmbedded; import org.hibernate.query.sqm.tree.expression.domain.SqmSingularAttributeReferenceEntity; import org.hibernate.query.sqm.tree.from.SqmFrom; import org.hibernate.query.sqm.tree.from.SqmFromElementSpace; import org.hibernate.query.sqm.tree.from.SqmFromExporter; /** * @author Steve Ebersole */ public class NavigableBindingHelper { public static SqmFrom resolveExportedFromElement(SqmNavigableReference binding) { if ( binding instanceof SqmFromExporter ) { return ( (SqmFromExporter) binding ).getExportedFromElement(); } if ( binding.getSourceReference() != null ) { return resolveExportedFromElement( binding.getSourceReference() ); } throw new ParsingException( "Could not resolve SqmFrom element from NavigableBinding : " + binding ); } public static SqmFromElementSpace extractSpace(SqmFromExporter exporter) { return exporter.getExportedFromElement() == null ? null : exporter.getExportedFromElement() .getContainingSpace(); } public static SqmNavigableReference createNavigableBinding(SqmNavigableSourceReference source, Navigable navigable) { if ( navigable instanceof IdentifierDescriptor ) { assert source instanceof SqmEntityTypedReference; return createEntityIdentiferBinding( (SqmEntityTypedReference) source, (IdentifierDescriptor) navigable ); } else if ( navigable instanceof SingularPersistentAttribute ) { return createSingularAttributeBinding( source, (SingularPersistentAttribute) navigable ); } else if ( navigable instanceof PluralPersistentAttribute ) { return createPluralAttributeBinding( source, (PluralPersistentAttribute) navigable ); } else if ( navigable instanceof CollectionElement ) { return createCollectionElementBinding( source, (CollectionElement) navigable ); } else if ( navigable instanceof CollectionIndex ) { return createCollectionIndexBinding( source, (CollectionIndex) navigable ); } else if ( navigable instanceof EntityValuedExpressableType ) { // for anything else source should be null assert source == null; return createEntityBinding( (EntityValuedExpressableType) navigable ); } throw new ParsingException( "Unexpected SqmNavigable for creation of NavigableBinding : " + navigable ); } private static SqmEntityIdentifierReference createEntityIdentiferBinding( SqmEntityTypedReference sourceBinding, IdentifierDescriptor navigable) { if ( navigable instanceof IdentifierDescriptorSimple ) { return new SqmEntityIdentifierReferenceSimple( sourceBinding, (IdentifierDescriptorSimple) navigable ); } else { return new SqmEntityIdentifierReferenceComposite( sourceBinding, (IdentifierDescriptorComposite) navigable ); } } private static SqmPluralAttributeReference createPluralAttributeBinding( SqmNavigableSourceReference lhs, PluralPersistentAttribute pluralAttribute) { return new SqmPluralAttributeReference( lhs, pluralAttribute ); } public static SqmSingularAttributeReference createSingularAttributeBinding( SqmNavigableSourceReference sourceBinding, SingularPersistentAttribute attribute) { switch ( attribute.getAttributeTypeClassification() ) { case BASIC: { return new SqmSingularAttributeReferenceBasic( sourceBinding, (SingularPersistentAttributeBasic) attribute ); } case EMBEDDED: { return new SqmSingularAttributeReferenceEmbedded( sourceBinding, (SingularPersistentAttributeEmbedded) attribute ); } case ONE_TO_ONE: case MANY_TO_ONE: { return new SqmSingularAttributeReferenceEntity( sourceBinding, (SingularPersistentAttributeEntity) attribute ); } default: { throw new NotYetImplementedException(); } } } public static SqmCollectionElementReference createCollectionElementBinding( SqmNavigableSourceReference source, CollectionElement elementDescriptor) { assert source instanceof SqmPluralAttributeReference; final SqmPluralAttributeReference pluralAttributeBinding = (SqmPluralAttributeReference) source; switch ( elementDescriptor.getClassification() ) { case BASIC: { return new SqmCollectionElementReferenceBasic( pluralAttributeBinding ); } case EMBEDDABLE: { return new SqmCollectionElementReferenceEmbedded( pluralAttributeBinding ); } case ONE_TO_MANY: case MANY_TO_MANY: { return new SqmCollectionElementReferenceEntity( pluralAttributeBinding ); } default: { throw new NotYetImplementedException(); } } } enum CollectionPartBindingType { NORMAL, MIN, MAX } public static SqmCollectionElementReference createCollectionElementBinding( CollectionPartBindingType bindingType, SqmNavigableSourceReference source, CollectionElement elementDescriptor) { assert source instanceof SqmPluralAttributeReference; final SqmPluralAttributeReference pluralAttributeBinding = (SqmPluralAttributeReference) source; switch ( elementDescriptor.getClassification() ) { case BASIC: { switch ( bindingType ) { case MAX: { return new SqmMaxElementReferenceBasic( pluralAttributeBinding ); } case MIN: { return new SqmMinElementReferenceBasic( pluralAttributeBinding ); } default: { return new SqmCollectionElementReferenceBasic( pluralAttributeBinding ); } } } case EMBEDDABLE: { switch ( bindingType ) { case MAX: { return new SqmMaxElementReferenceEmbedded( pluralAttributeBinding ); } case MIN: { return new SqmMinElementReferenceEmbedded( pluralAttributeBinding ); } default: { return new SqmCollectionElementReferenceEmbedded( pluralAttributeBinding ); } } } case ONE_TO_MANY: case MANY_TO_MANY: { switch ( bindingType ) { case MAX: { return new SqmMaxElementReferenceEntity( pluralAttributeBinding ); } case MIN: { return new SqmMinElementReferenceEntity( pluralAttributeBinding ); } default: { return new SqmCollectionElementReferenceEntity( pluralAttributeBinding ); } } } default: { throw new NotYetImplementedException(); } } } public static SqmCollectionIndexReference createCollectionIndexBinding( SqmNavigableSourceReference source, CollectionIndex indexDescriptor) { assert source instanceof SqmPluralAttributeReference; final SqmPluralAttributeReference pluralAttributeBinding = (SqmPluralAttributeReference) source; switch ( indexDescriptor.getClassification() ) { case BASIC: { return new SqmCollectionIndexReferenceBasic( pluralAttributeBinding ); } case EMBEDDABLE: { return new SqmCollectionIndexReferenceEmbedded( pluralAttributeBinding ); } case ONE_TO_MANY: case MANY_TO_MANY: { return new SqmCollectionIndexReferenceEntity( pluralAttributeBinding ); } default: { throw new NotYetImplementedException( ); } } } public static SqmCollectionIndexReference createCollectionIndexBinding( CollectionPartBindingType bindingType, SqmNavigableSourceReference source, SqmPluralAttributeIndex indexDescriptor) { assert source instanceof SqmPluralAttributeReference; final SqmPluralAttributeReference pluralAttributeBinding = (SqmPluralAttributeReference) source; switch ( indexDescriptor.getClassification() ) { case BASIC: { switch ( bindingType ) { case MAX: { return new SqmMaxIndexReferenceBasic( pluralAttributeBinding ); } case MIN: { return new SqmMinIndexReferenceBasic( pluralAttributeBinding ); } default: { return new SqmCollectionIndexReferenceBasic( pluralAttributeBinding ); } } } case EMBEDDABLE: { switch ( bindingType ) { case MAX: { return new SqmMaxIndexReferenceEmbedded( pluralAttributeBinding ); } case MIN: { return new SqmMinIndexReferenceEmbeddable( pluralAttributeBinding ); } default: { return new SqmCollectionIndexReferenceEmbedded( pluralAttributeBinding ); } } } case ONE_TO_MANY: case MANY_TO_MANY: { switch ( bindingType ) { case MAX: { return new SqmMaxIndexReferenceEntity( pluralAttributeBinding ); } case MIN: { return new SqmMinIndexReferenceEntity( pluralAttributeBinding ); } default: { return new SqmCollectionIndexReferenceEntity( pluralAttributeBinding ); } } } default: { throw new NotYetImplementedException( ); } } } public static SqmRestrictedCollectionElementReference createIndexedCollectionElementBinding( SqmPluralAttributeReference pluralAttributeBinding, CollectionElement elementDescriptor, SqmExpression selectorExpression) { switch ( elementDescriptor.getClassification() ) { case BASIC: { return new SqmIndexedElementReferenceBasic( pluralAttributeBinding, selectorExpression ); } case EMBEDDABLE: { return new SqmIndexedElementReferenceEmbedded( pluralAttributeBinding, selectorExpression ); } case ONE_TO_MANY: case MANY_TO_MANY: { return new SqmIndexedElementReferenceEntity( pluralAttributeBinding, selectorExpression ); } default: { throw new NotYetImplementedException(); } } } public static SqmEntityTypedReference createEntityBinding(EntityValuedExpressableType entityReference) { return new SqmEntityReference( entityReference ); } private NavigableBindingHelper() { } }