org.hibernate.query.criteria.internal.expression.SimpleCaseExpression Maven / Gradle / Ivy
/*
* 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 .
*/
package org.hibernate.query.criteria.internal.expression;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.function.BiFunction;
import javax.persistence.criteria.CriteriaBuilder.SimpleCase;
import javax.persistence.criteria.Expression;
import org.hibernate.query.criteria.internal.CriteriaBuilderImpl;
import org.hibernate.query.criteria.internal.ParameterRegistry;
import org.hibernate.query.criteria.internal.Renderable;
import org.hibernate.query.criteria.internal.compile.RenderingContext;
/**
* Models what ANSI SQL terms a simple case statement. This is a CASE expression in the form
* CASE [expression]
* WHEN [firstCondition] THEN [firstResult]
* WHEN [secondCondition] THEN [secondResult]
* ELSE [defaultResult]
* END
*
*
* @author Steve Ebersole
*/
public class SimpleCaseExpression
extends ExpressionImpl
implements SimpleCase, Serializable {
private final Expression expression;
private List whenClauses = new ArrayList();
private Expression otherwiseResult;
public class WhenClause {
private final LiteralExpression condition;
private final Expression result;
public WhenClause(LiteralExpression condition, Expression result) {
this.condition = condition;
this.result = result;
}
public LiteralExpression getCondition() {
return condition;
}
public Expression getResult() {
return result;
}
}
public SimpleCaseExpression(
CriteriaBuilderImpl criteriaBuilder,
Class javaType,
Expression expression) {
super( criteriaBuilder, javaType);
this.expression = expression;
}
@SuppressWarnings({ "unchecked" })
public Expression getExpression() {
return (Expression) expression;
}
public SimpleCase when(C condition, R result) {
return when( condition, buildLiteral(result) );
}
@SuppressWarnings({ "unchecked" })
private LiteralExpression buildLiteral(R result) {
final Class type = result != null
? (Class) result.getClass()
: getJavaType();
return new LiteralExpression( criteriaBuilder(), type, result );
}
public SimpleCase when(C condition, Expression result) {
WhenClause whenClause = new WhenClause(
new LiteralExpression( criteriaBuilder(), condition ),
result
);
whenClauses.add( whenClause );
resetJavaType( result.getJavaType() );
return this;
}
public Expression otherwise(R result) {
return otherwise( buildLiteral(result) );
}
public Expression otherwise(Expression result) {
this.otherwiseResult = result;
resetJavaType( result.getJavaType() );
return this;
}
public Expression getOtherwiseResult() {
return otherwiseResult;
}
public List getWhenClauses() {
return whenClauses;
}
public void registerParameters(ParameterRegistry registry) {
Helper.possibleParameter( getExpression(), registry );
for ( WhenClause whenClause : getWhenClauses() ) {
Helper.possibleParameter( whenClause.getResult(), registry );
}
Helper.possibleParameter( getOtherwiseResult(), registry );
}
public String render(RenderingContext renderingContext) {
return render(
renderingContext,
(Renderable expression, RenderingContext context) -> expression.render( context )
);
}
public String renderProjection(RenderingContext renderingContext) {
return render(
renderingContext,
(Renderable expression, RenderingContext context) -> expression.renderProjection( context )
);
}
private String render(
RenderingContext renderingContext,
BiFunction formatter) {
StringBuilder caseExpr = new StringBuilder();
caseExpr.append( "case " )
.append( formatter.apply( (Renderable) getExpression(), renderingContext ) );
for ( WhenClause whenClause : getWhenClauses() ) {
caseExpr.append( " when " )
.append( formatter.apply( whenClause.getCondition(), renderingContext ) )
.append( " then " )
.append( formatter.apply( (Renderable) whenClause.getResult(), renderingContext ) );
}
caseExpr.append( " else " )
.append( formatter.apply( (Renderable) getOtherwiseResult(), renderingContext ) )
.append( " end" );
return caseExpr.toString();
}
}