From df96cc61297a92ceb7d045ff0b7598d85ef68b7b Mon Sep 17 00:00:00 2001 From: Fay Wang Date: Thu, 14 May 2009 17:13:44 +0000 Subject: [PATCH] OPENJPA-1013: simple case and case expression support in Criteria Query git-svn-id: https://svn.apache.org/repos/asf/openjpa/trunk@774848 13f79535-47bb-0310-9956-ffa450edef68 --- .../persistence/criteria/CriteriaBuilder.java | 5 +- .../persistence/criteria/Expressions.java | 140 ++++++++++++++++++ 2 files changed, 142 insertions(+), 3 deletions(-) diff --git a/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/CriteriaBuilder.java b/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/CriteriaBuilder.java index f67152f76..d2d7af485 100644 --- a/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/CriteriaBuilder.java +++ b/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/CriteriaBuilder.java @@ -544,13 +544,12 @@ public class CriteriaBuilder implements QueryBuilder, ExpressionParser { } public Case selectCase() { - throw new AbstractMethodError(); - + return new Expressions.Case(); } public SimpleCase selectCase( Expression expression) { - throw new AbstractMethodError(); + return new Expressions.SimpleCase(expression); } public > Expression size(C collection) { diff --git a/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/Expressions.java b/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/Expressions.java index bba278004..3e34790f1 100644 --- a/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/Expressions.java +++ b/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/Expressions.java @@ -29,6 +29,7 @@ import javax.persistence.criteria.QueryBuilder; import javax.persistence.criteria.QueryBuilder.Trimspec; import org.apache.openjpa.kernel.exps.ExpressionFactory; +import org.apache.openjpa.kernel.exps.Literal; import org.apache.openjpa.kernel.exps.Value; import org.apache.openjpa.kernel.jpql.JPQLExpressionBuilder; import org.apache.openjpa.persistence.meta.MetamodelImpl; @@ -765,4 +766,143 @@ public class Expressions { notNull.toKernelExpression(factory, model)); } } + + public static class Case extends ExpressionImpl + implements QueryBuilder.Case { + private List> thens = + new ArrayList>(); + + private List> whens = + new ArrayList>(); + + private Expression otherwise; + + public Case() { + super(null); + } + + public Case(Class cls) { + super(cls); + } + + public Case when(Expression when, + Expression then) { + whens.add(when); + thens.add(then); + return this; + } + + public Case when(Expression when, T then) { + whens.add(when); + Expression thenExpr = + new Expressions.Constant(then); + thens.add(thenExpr); + return this; + } + + public Case otherwise(Expression otherwise) { + this.otherwise = otherwise; + return this; + } + + public Case otherwise(T otherwise) { + this.otherwise = new Expressions.Constant(otherwise); + return this; + } + + @Override + public org.apache.openjpa.kernel.exps.Value toValue( + ExpressionFactory factory, MetamodelImpl model) { + int size = whens.size(); + org.apache.openjpa.kernel.exps.Expression[] exps = + new org.apache.openjpa.kernel.exps.Expression[size]; + for (int i = 0; i < size; i++) { + org.apache.openjpa.kernel.exps.Expression expr = + ((Expressions.BinaryLogicalExpression)whens.get(i)). + toKernelExpression(factory, model); + Value action = ((ExpressionImpl)thens.get(i)). + toValue(factory, model); + exps[i] = factory.whenCondition(expr, action); + } + + Value other = ((ExpressionImpl)otherwise). + toValue(factory, model); + + return factory.generalCaseExpression(exps, other); + } + } + + public static class SimpleCase extends ExpressionImpl + implements QueryBuilder.SimpleCase { + private List> thens = + new ArrayList>(); + + private List whens = new ArrayList(); + + private Expression otherwise; + + private Expression caseOperand; + + public SimpleCase() { + super(null); + } + + public SimpleCase(Class cls) { + super(cls); + } + + public SimpleCase(Expression expr) { + super(null); + this.caseOperand = expr; + } + public Expression getExpression() { + return caseOperand; + } + + public SimpleCase when(C when, Expression then) { + whens.add(when); + thens.add(then); + return this; + } + + public SimpleCase when(C when, R then) { + whens.add(when); + Expression thenExpr = + new Expressions.Constant(then); + thens.add(thenExpr); + return this; + } + + public SimpleCase otherwise(Expression otherwise) { + this.otherwise = otherwise; + return this; + } + + public SimpleCase otherwise(R otherwise) { + this.otherwise = new Expressions.Constant(otherwise); + return this; + } + + @Override + public org.apache.openjpa.kernel.exps.Value toValue( + ExpressionFactory factory, MetamodelImpl model) { + Value caseOperandExpr = Expressions.toValue( + (ExpressionImpl)caseOperand, factory, model); + int size = whens.size(); + org.apache.openjpa.kernel.exps.Expression[] exps = + new org.apache.openjpa.kernel.exps.Expression[size]; + for (int i = 0; i < size; i++) { + org.apache.openjpa.kernel.exps.Literal val = null; + //TODO: Boolean literal, String literal + val = factory.newLiteral(whens.get(i), Literal.TYPE_NUMBER); + Value action = ((ExpressionImpl)thens.get(i)). + toValue(factory, model); + exps[i] = factory.whenScalar(val, action); + } + + Value other = ((ExpressionImpl)otherwise). + toValue(factory, model); + return factory.simpleCaseExpression(caseOperandExpr, exps, other); + } + } }