/* * 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; import org.hibernate.query.sqm.tree.predicate.SqmPredicate; /** * @author Steve Ebersole */ public class CaseSearchedSqmExpression implements SqmExpression, ImpliedTypeSqmExpression { private List<WhenFragment> whenFragments = new ArrayList<>(); private SqmExpression otherwise; private SqmExpressableType expressableType; private SqmExpressableType impliedType; public List<WhenFragment> getWhenFragments() { return whenFragments; } public SqmExpression getOtherwise() { return otherwise; } public void when(SqmPredicate predicate, SqmExpression result) { whenFragments.add( new WhenFragment( predicate, result ) ); } public void otherwise(SqmExpression otherwiseExpression) { this.otherwise = otherwiseExpression; // todo : inject implied type? } @Override public void impliedType(SqmExpressableType type) { this.impliedType = type; // todo : visit whenFragments and otherwise } @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.visitSearchedCaseExpression( this ); } @Override public String asLoggableText() { return "<searched-case>"; } public static class WhenFragment { private final SqmPredicate predicate; private final SqmExpression result; public WhenFragment(SqmPredicate predicate, SqmExpression result) { this.predicate = predicate; this.result = result; } public SqmPredicate getPredicate() { return predicate; } public SqmExpression getResult() { return result; } } }