/*
* 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;
import java.util.ArrayList;
import java.util.List;
import org.hibernate.query.sqm.consume.spi.SemanticQueryWalker;
import org.hibernate.query.sqm.domain.type.SqmDomainType;
import org.hibernate.query.sqm.domain.SqmExpressableType;
/**
* @author Steve Ebersole
*/
public class CaseSimpleSqmExpression implements SqmExpression, ImpliedTypeSqmExpression {
private final SqmExpression fixture;
private List<WhenFragment> whenFragments = new ArrayList<>();
private SqmExpression otherwise;
private SqmExpressableType expressableType;
private SqmExpressableType impliedType;
public CaseSimpleSqmExpression(SqmExpression fixture) {
this.fixture = fixture;
}
public SqmExpression getFixture() {
return fixture;
}
public List<WhenFragment> getWhenFragments() {
return whenFragments;
}
public SqmExpression getOtherwise() {
return otherwise;
}
public void otherwise(SqmExpression otherwiseExpression) {
this.otherwise = otherwiseExpression;
// todo : inject implied expressableType?
}
public void when(SqmExpression test, SqmExpression result) {
whenFragments.add( new WhenFragment( test, result ) );
// todo : inject implied expressableType?
}
@Override
public void impliedType(SqmExpressableType type) {
this.impliedType = type;
// todo : visit whenFragments and elseExpression
}
@Override
public SqmDomainType getExportedDomainType() {
if ( impliedType != null ) {
return impliedType.getExportedDomainType();
}
if ( otherwise != null ) {
return otherwise.getExpressionType().getExportedDomainType();
}
for ( WhenFragment whenFragment : whenFragments ) {
if ( whenFragment.result.getExpressionType() != null ) {
return whenFragment.result.getExpressionType().getExportedDomainType();
}
}
return null;
}
@Override
public SqmExpressableType getExpressionType() {
return expressableType;
}
@Override
public SqmExpressableType getInferableType() {
if ( otherwise != null ) {
return otherwise.getInferableType();
}
for ( WhenFragment whenFragment : whenFragments ) {
if ( whenFragment.result.getExpressionType() != null ) {
return whenFragment.result.getInferableType();
}
}
return expressableType;
}
@Override
public <T> T accept(SemanticQueryWalker<T> walker) {
return walker.visitSimpleCaseExpression( this );
}
@Override
public String asLoggableText() {
return "<simple-case>";
}
public static class WhenFragment {
private final SqmExpression checkValue;
private final SqmExpression result;
public WhenFragment(SqmExpression checkValue, SqmExpression result) {
this.checkValue = checkValue;
this.result = result;
}
public SqmExpression getCheckValue() {
return checkValue;
}
public SqmExpression getResult() {
return result;
}
}
}