/*
* 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.expression.domain;
import org.hibernate.persister.common.spi.PersistentAttribute;
import org.hibernate.persister.queryable.spi.ExpressableType;
import org.hibernate.query.spi.NavigablePath;
import org.hibernate.query.sqm.consume.spi.SemanticQueryWalker;
import org.hibernate.query.sqm.tree.from.SqmAttributeJoin;
import org.hibernate.query.sqm.tree.from.SqmFrom;
import org.hibernate.query.sqm.tree.from.SqmFromExporter;
/**
* @author Steve Ebersole
*/
public abstract class AbstractSqmAttributeReference<A extends PersistentAttribute>
extends AbstractSqmNavigableReference
implements SqmAttributeReference, SqmFromExporter {
private final SqmNavigableSourceReference sourceBinding;
private final A attribute;
private final NavigablePath propertyPath;
private SqmAttributeJoin join;
public AbstractSqmAttributeReference(SqmNavigableSourceReference sourceBinding, A attribute) {
if ( sourceBinding == null ) {
throw new IllegalArgumentException( "Source for AttributeBinding cannot be null" );
}
if ( attribute == null ) {
throw new IllegalArgumentException( "Attribute for AttributeBinding cannot be null" );
}
this.sourceBinding = sourceBinding;
this.attribute = attribute;
this.propertyPath = sourceBinding.getNavigablePath().append( attribute.getAttributeName() );
}
@SuppressWarnings("unchecked")
public AbstractSqmAttributeReference(SqmAttributeJoin join) {
this(
join.getBinding().getSourceReference(),
(A) join.getAttributeBinding().getReferencedNavigable()
);
injectExportedFromElement( join );
}
@Override
public void injectExportedFromElement(SqmFrom attributeJoin) {
if ( this.join != null && this.join != attributeJoin ) {
throw new IllegalArgumentException( "Attempting to create multiple SqmFrom references for a single AttributeBinding" );
}
this.join = (SqmAttributeJoin) attributeJoin;
}
@Override
public SqmNavigableSourceReference getSourceReference() {
// attribute binding must have a source
return sourceBinding;
}
@Override
public A getReferencedNavigable() {
return attribute;
}
@Override
public SqmFrom getExportedFromElement() {
return join;
}
@Override
public ExpressableType getExpressionType() {
return getReferencedNavigable();
}
@Override
public ExpressableType getInferableType() {
return getExpressionType();
}
@Override
public <T> T accept(SemanticQueryWalker<T> walker) {
return walker.visitAttributeReferenceExpression( this );
}
@Override
public NavigablePath getNavigablePath() {
return propertyPath;
}
@Override
public String asLoggableText() {
if ( join == null || join.getIdentificationVariable() == null ) {
return getClass().getSimpleName() + '(' + sourceBinding.asLoggableText() + '.' + attribute.getAttributeName() + ")";
}
else {
return getClass().getSimpleName() + '(' + sourceBinding.asLoggableText() + '.' + attribute.getAttributeName() + " : " + join.getIdentificationVariable() + ")";
}
}
}