OPENJPA-1278,OPENJPA-1276,OPENJPA-1013:

Modify negation of predicate logic
  Promote interfaces from internal implementaion argument to  public interfaces
 Add Fetch Join and logical precedence order to CQL generation

git-svn-id: https://svn.apache.org/repos/asf/openjpa/trunk@810825 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Pinaki Poddar 2009-09-03 08:52:17 +00:00
parent 5d6581bf7f
commit e01390051b
22 changed files with 422 additions and 293 deletions

View File

@ -63,5 +63,23 @@ public class TestCQL extends CriteriaTest {
jpql = "SELECT p FROM Person p WHERE (p.name = 'A' OR (p.name = 'B' AND (p.name = 'C' OR p.name = 'D')))";
assertEquivalence(q, jpql);
assertEquals(jpql, q.toCQL());
// NOT (a OR b)
q.where(cb.or(a, b).negate());
jpql = "SELECT p FROM Person p WHERE NOT (p.name = 'A' OR p.name = 'B')";
assertEquivalence(q, jpql);
assertEquals(jpql, q.toCQL());
// NOT a
q.where(cb.and(a).negate());
jpql = "SELECT p FROM Person p WHERE NOT p.name = 'A'";
assertEquivalence(q, jpql);
assertEquals(jpql, q.toCQL());
// NOT a OR NOT b
q.where(cb.or(cb.not(a), cb.not(b)));
jpql = "SELECT p FROM Person p WHERE (p.name <> 'A' OR p.name <> 'B')";
assertEquivalence(q, jpql);
assertEquals(jpql, q.toCQL());
}
}

View File

@ -1477,7 +1477,6 @@ public class TestEmbeddableCriteria extends EmbeddableDomainTestCase {
assertEquivalence(q, jpql);
}
@AllowFailure(message="JPQL parse exception")
public void testEmbeddableQuery111() {
String jpql = "select i from Item1 i where :image = any(select KEY(e) from i.images e) order by i";
CriteriaQuery<Item1> q = cb.createQuery(Item1.class);

View File

@ -0,0 +1,46 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.openjpa.persistence.criteria;
import javax.persistence.criteria.JoinType;
import javax.persistence.criteria.Root;
public class TestFetchJoin extends CriteriaTest {
public void testFetchJoin() {
String jpql = "SELECT e FROM Employee e INNER JOIN FETCH e.department";
OpenJPACriteriaQuery<Employee> q = cb.createQuery(Employee.class);
Root<Employee> e = q.from(Employee.class);
q.select(e);
e.fetch(Employee_.department);
assertEquivalence(q, jpql);
assertEquals(jpql, q.toCQL());
}
public void testLeftFetchJoin() {
String jpql = "SELECT e FROM Employee e LEFT JOIN FETCH e.department";
OpenJPACriteriaQuery<Employee> q = cb.createQuery(Employee.class);
Root<Employee> e = q.from(Employee.class);
q.select(e);
e.fetch(Employee_.department, JoinType.LEFT);
assertEquivalence(q, jpql);
assertEquals(jpql, q.toCQL());
}
}

View File

@ -112,13 +112,13 @@ public class TestTypeSafeCondExpression extends CriteriaTest {
public void testLike1() {
String jpql = "SELECT o.computerName FROM CompUser o "
+ "WHERE o.name LIKE 'Sha%' AND o.computerName NOT IN ('PC')";
+ "WHERE o.name LIKE 'Sha%' AND o.computerName NOT IN ('PC','Laptop')";
CriteriaQuery<String> cq = cb.createQuery(String.class);
Root<CompUser> o = cq.from(CompUser.class);
cq.where(cb.and(
cb.like(o.get(CompUser_.name),"Sha%"),
cb.in(o.get(CompUser_.computerName)).value("PC").negate()
cb.in(o.get(CompUser_.computerName)).value("PC").value("Laptop").negate()
));
cq.select(o.get(CompUser_.computerName));
@ -128,13 +128,13 @@ public class TestTypeSafeCondExpression extends CriteriaTest {
public void testLike2() {
String jpql = "SELECT o.computerName FROM CompUser o "
+ "WHERE o.name LIKE 'Sha%o_' AND o.computerName NOT IN ('UNIX')";
+ "WHERE o.name LIKE 'Sha%o_' AND o.computerName NOT IN ('UNIX','DOS')";
CriteriaQuery<String> cq = cb.createQuery(String.class);
Root<CompUser> o = cq.from(CompUser.class);
cq.where(cb.and(
cb.like(o.get(CompUser_.name),"Sha%o_"),
cb.in(o.get(CompUser_.computerName)).value("UNIX").negate()
cb.in(o.get(CompUser_.computerName)).value("UNIX").value("DOS").negate()
));
cq.select(o.get(CompUser_.computerName));

View File

@ -1019,7 +1019,7 @@ public class TestTypesafeCriteria extends CriteriaTest {
public void testKeys7() {
String sql = "SELECT t0.name, t2.id, t2.label FROM CR_ITEM t0 "
+ "INNER JOIN CR_ITEM_photos t1 ON t0.id = t1.ITEM_ID "
+ "INNER JOIN CR_PHT t2 ON t1.VALUE_ID = t2.id";
+ "INNER JOIN CR_PHT t2 ON t1.VALUE_ID = t2.id WHERE (NOT (1 <> 1))";
CriteriaQuery<Customer> q = cb.createQuery(Customer.class);
Root<Item> item = q.from(Item.class);
@ -1178,7 +1178,7 @@ public class TestTypesafeCriteria extends CriteriaTest {
public void testValues7() {
String sql = "SELECT t0.name, t2.id, t2.label FROM CR_ITEM t0 "
+ "INNER JOIN CR_ITEM_photos t1 ON t0.id = t1.ITEM_ID "
+ "INNER JOIN CR_PHT t2 ON t1.VALUE_ID = t2.id";
+ "INNER JOIN CR_PHT t2 ON t1.VALUE_ID = t2.id WHERE (NOT (1 <> 1))";
CriteriaQuery<Customer> q = cb.createQuery(Customer.class);
Root<Item> item = q.from(Item.class);

View File

@ -18,6 +18,7 @@
*/
package org.apache.openjpa.persistence.criteria;
import javax.persistence.criteria.Root;
import javax.persistence.criteria.Selection;
import org.apache.openjpa.kernel.exps.Value;
@ -58,6 +59,12 @@ public interface AliasContext {
*/
Value getRegisteredVariable(Selection<?> node);
/**
* Gets the registered root variable for the given node.
* Return null if the node is not registered.
*/
Value getRegisteredRootVariable(Root<?> node);
/**
* Gets the registered path value for the given node.
* Return null if the node is not registered.

View File

@ -97,7 +97,7 @@ public class CompoundSelections {
abstract FillStrategy<X> getFillStrategy();
@Override
public StringBuilder asValue(CriteriaQueryImpl<?> q) {
public StringBuilder asValue(AliasContext q) {
StringBuilder buffer = new StringBuilder();
for (int i = 0; i < _args.size(); i++) {
buffer.append((((CriteriaExpression)_args.get(i)).asValue(q)));
@ -158,7 +158,7 @@ public class CompoundSelections {
}
@Override
public StringBuilder asValue(CriteriaQueryImpl<?> q) {
public StringBuilder asValue(AliasContext q) {
return new StringBuilder("NEW ").append(getJavaType().getName()).append("(")
.append(super.asValue(q)).append(")");
}

View File

@ -392,6 +392,10 @@ public class CriteriaBuilder implements OpenJPACriteriaBuilder, ExpressionParser
}
public <T> Expression<T> literal(T value) {
if (Boolean.TRUE.equals(value))
return (Expression<T>)PredicateImpl.TRUE;
if (Boolean.FALSE.equals(value))
return (Expression<T>)PredicateImpl.FALSE;
return new Expressions.Constant<T>(value);
}
@ -452,15 +456,15 @@ public class CriteriaBuilder implements OpenJPACriteriaBuilder, ExpressionParser
}
public Predicate not(Expression<Boolean> restriction) {
return new Expressions.Not(restriction);
return ((Predicate)restriction).negate();
}
public Predicate notEqual(Expression<?> x, Expression<?> y) {
return equal(x, y).negate();
return new Expressions.NotEqual(x, y);
}
public Predicate notEqual(Expression<?> x, Object y) {
return equal(x, y).negate();
return new Expressions.NotEqual(x, y);
}
public Predicate notLike(Expression<String> x, Expression<String> pattern) {
@ -679,7 +683,7 @@ public class CriteriaBuilder implements OpenJPACriteriaBuilder, ExpressionParser
}
public Predicate isNotNull(Expression<?> x) {
return new Expressions.IsNull((ExpressionImpl<?> )x).negate();
return new Expressions.IsNotNull((ExpressionImpl<?> )x);
}
public Predicate isNull(Expression<?> x) {

View File

@ -36,10 +36,10 @@ public interface CriteriaExpression {
/**
* Get a string representation of this node as a value in the context of the given query.
*/
StringBuilder asValue(CriteriaQueryImpl<?> q);
StringBuilder asValue(AliasContext q);
/**
* Get a string representation of this node as a variable in the context of the given query.
*/
StringBuilder asVariable(CriteriaQueryImpl<?> q);
StringBuilder asVariable(AliasContext q);
}

View File

@ -89,28 +89,21 @@ public class CriteriaExpressionBuilder {
protected void evalAccessPaths(QueryExpressions exps, ExpressionFactory factory, CriteriaQueryImpl<?> q) {
Set<ClassMetaData> metas = new HashSet<ClassMetaData>();
Set<Root<?>> roots = q.getRoots();
if (roots != null) {
MetamodelImpl metamodel = q.getMetamodel();
for (Root<?> root : roots) {
metas.add(((AbstractManagedType<?>)root.getModel()).meta);
if (root.getJoins() != null) {
for (Join<?,?> join : root.getJoins()) {
Class<?> cls = join.getAttribute().getJavaType();
if (join.getAttribute().isAssociation()) {
ClassMetaData meta = metamodel.repos.getMetaData(cls, null, true);
PersistenceType type = MetamodelImpl.getPersistenceType(meta);
if (type == PersistenceType.ENTITY || type == PersistenceType.EMBEDDABLE)
metas.add(meta);
}
}
if (root.getFetches() != null) {
for (Fetch<?,?> fetch : root.getFetches()) {
metas.add(metamodel.repos.getMetaData(fetch.getAttribute().getJavaType(), null, false));
}
}
MetamodelImpl metamodel = q.getMetamodel();
for (Root<?> root : q.getRoots()) {
metas.add(((AbstractManagedType<?>)root.getModel()).meta);
for (Join<?,?> join : root.getJoins()) {
Class<?> cls = join.getAttribute().getJavaType();
if (join.getAttribute().isAssociation()) {
ClassMetaData meta = metamodel.repos.getMetaData(cls, null, true);
PersistenceType type = MetamodelImpl.getPersistenceType(meta);
if (type == PersistenceType.ENTITY || type == PersistenceType.EMBEDDABLE)
metas.add(meta);
}
}
for (Fetch<?,?> fetch : root.getFetches()) {
metas.add(metamodel.repos.getCachedMetaData(fetch.getAttribute().getJavaType()));
}
}
exps.accessPath = metas.toArray(new ClassMetaData[metas.size()]);
}
@ -178,15 +171,9 @@ public class CriteriaExpressionBuilder {
}
protected void evalDistinct(QueryExpressions exps, ExpressionFactory factory, CriteriaQueryImpl<?> q) {
Boolean distinct = q.getDistinct();
if (distinct == null) {
exps.distinct = QueryExpressions.DISTINCT_FALSE;
} else if (distinct) {
exps.distinct = QueryExpressions.DISTINCT_TRUE
| QueryExpressions.DISTINCT_AUTO;
}
//exps.distinct &= ~QueryExpressions.DISTINCT_AUTO;
}
exps.distinct = q.isDistinct() ? QueryExpressions.DISTINCT_TRUE | QueryExpressions.DISTINCT_AUTO
: QueryExpressions.DISTINCT_FALSE;
}
protected void evalCrossJoinRoots(QueryExpressions exps, ExpressionFactory factory, CriteriaQueryImpl<?> q) {
Set<Root<?>> roots = q.getRoots();
@ -197,10 +184,11 @@ public class CriteriaExpressionBuilder {
for (Root<?> root : roots) {
String alias = q.getAlias(root);
Value var = factory.newBoundVariable(alias, AbstractExpressionBuilder.TYPE_OBJECT);
var.setMetaData(((Types.Entity)root.getModel()).meta);
var.setMetaData(((AbstractManagedType<?>)root.getModel()).meta);
q.registerRoot(root, var);
}
} }
}
}
}
protected void evalFilter(QueryExpressions exps, ExpressionFactory factory, CriteriaQueryImpl<?> q) {
@ -212,25 +200,23 @@ public class CriteriaExpressionBuilder {
if (subQuery == null || subQuery.getCorrelatedJoins() == null) {
q.assertRoot();
for (Root<?> root : roots) {
if (root.getJoins() != null) {
for (Join<?, ?> join : root.getJoins()) {
filter = and(factory, ((ExpressionImpl<?>)join).toKernelExpression(factory, model, q), filter);
}
for (Join<?, ?> join : root.getJoins()) {
filter = Expressions.and(factory,
((ExpressionImpl<?>)join).toKernelExpression(factory, model, q), filter);
}
((RootImpl<?>)root).addToContext(factory, model, q);
}
}
if (subQuery != null) {
List<Join<?,?>> corrJoins = subQuery.getCorrelatedJoins();
if (corrJoins != null) {
for (int i = 0; i < corrJoins.size(); i++)
filter = and(factory, ((ExpressionImpl<?>)corrJoins.get(i)).toKernelExpression(factory, model, q),
filter);
for (int i = 0; corrJoins != null && i < corrJoins.size(); i++) {
filter = Expressions.and(factory, ((ExpressionImpl<?>)corrJoins.get(i))
.toKernelExpression(factory, model, q), filter);
}
}
if (where != null) {
filter = and(factory, where.toKernelExpression(factory, model, q), filter);
filter = Expressions.and(factory, where.toKernelExpression(factory, model, q), filter);
}
if (filter == null) {
filter = factory.emptyExpression();
@ -296,51 +282,31 @@ public class CriteriaExpressionBuilder {
}
}
}
// protected boolean isDefaultProjection(List<Selection<?>> selections, CriteriaQueryImpl<?> q) {
// if (selections == null)
// return true;
// if (selections.size() != 1)
// return false;
// Selection<?> sel = selections.get(0);
// if (q.getRoots() != null && sel == q.getRoot())
// return true;
// if ((sel instanceof PathImpl<?,?>) && ((PathImpl<?,?>)sel)._correlatedPath != null)
// return true;
// return false;
// }
protected void evalFetchJoin(QueryExpressions exps, ExpressionFactory factory, CriteriaQueryImpl<?> q) {
List<String> iPaths = new ArrayList<String>();
List<String> oPaths = new ArrayList<String>();
Set<Root<?>> roots = q.getRoots();
if (roots == null)
return;
for (Root root : roots) {
Set<Fetch> fetches = root.getFetches();
if (fetches == null)
continue;
for (Fetch<?,?> fetch : fetches) {
String fPath = ((Members.Member<?, ?>)fetch.getAttribute())
.fmd.getFullName(false);
String fPath = ((Members.Member<?, ?>)fetch.getAttribute()).fmd.getFullName(false);
oPaths.add(fPath);
if (fetch.getJoinType() == JoinType.INNER) {
iPaths.add(fPath);
}
}
}
if (!iPaths.isEmpty())
if (!iPaths.isEmpty()) {
exps.fetchInnerPaths = iPaths.toArray(new String[iPaths.size()]);
if (!oPaths.isEmpty())
}
if (!oPaths.isEmpty()) {
exps.fetchPaths = oPaths.toArray(new String[oPaths.size()]);
}
}
protected static org.apache.openjpa.kernel.exps.Expression and (ExpressionFactory factory,
org.apache.openjpa.kernel.exps.Expression e1, org.apache.openjpa.kernel.exps.Expression e2) {
return e1 == null ? e2 : e2 == null ? e1 : factory.and(e1, e2);
}
// ===================================================================================
// Result Shape processing
// ===================================================================================
@ -358,7 +324,7 @@ public class CriteriaExpressionBuilder {
if (type == null)
type = Object.class;
if (s.isCompoundSelection()) {
CompoundSelection<?> cs = (CompoundSelection)s;
CompoundSelection<?> cs = (CompoundSelection<?>)s;
result = new ResultShape(s.getJavaType(), CompoundSelections.getFillStrategy(cs));
List<Selection<?>> terms = cs.getCompoundSelectionItems();
for (Selection<?> term : terms) {
@ -414,6 +380,4 @@ public class CriteriaExpressionBuilder {
return result;
}
}

View File

@ -28,11 +28,11 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Stack;
import java.util.concurrent.CopyOnWriteArrayList;
import javax.persistence.criteria.AbstractQuery;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Expression;
import javax.persistence.criteria.Fetch;
import javax.persistence.criteria.Join;
import javax.persistence.criteria.Order;
import javax.persistence.criteria.ParameterExpression;
@ -72,13 +72,13 @@ public class CriteriaQueryImpl<T> implements OpenJPACriteriaQuery<T>, AliasConte
private Set<Root<?>> _roots;
private PredicateImpl _where;
private List<Order> _orders;
private LinkedMap/*<ParameterExpression<?>, Class<?>>*/ _params;
private Selection<? extends T> _selection;
private LinkedMap _params; /*<ParameterExpression<?>, Class<?>>*/
private Selection<? extends T> _selection;
private List<Selection<?>> _selections;
private List<Expression<?>> _groups;
private PredicateImpl _having;
private List<Subquery<?>> _subqueries;
private Boolean _distinct;
private boolean _distinct;
private final SubqueryImpl<?> _delegator;
private final Class<T> _resultClass;
private boolean _compiled;
@ -236,18 +236,22 @@ public class CriteriaQueryImpl<T> implements OpenJPACriteriaQuery<T>, AliasConte
}
public CriteriaQuery<T> groupBy(Expression<?>... grouping) {
_groups = new ArrayList<Expression<?>>();
if (grouping == null)
if (grouping == null) {
_groups = null;
return this;
}
_groups = new ArrayList<Expression<?>>();
for (Expression<?> e : grouping)
_groups.add(e);
return this;
}
public CriteriaQuery<T> groupBy(List<Expression<?>> grouping) {
_groups = new ArrayList<Expression<?>>();
if (grouping == null)
if (grouping == null) {
_groups = null;
return this;
}
_groups = new ArrayList<Expression<?>>();
for (Expression<?> e : grouping)
_groups.add(e);
return this;
@ -255,21 +259,27 @@ public class CriteriaQueryImpl<T> implements OpenJPACriteriaQuery<T>, AliasConte
public CriteriaQuery<T> having(Expression<Boolean> restriction) {
_having = new PredicateImpl().add(restriction);
_having = (PredicateImpl)restriction;
return this;
}
public CriteriaQuery<T> having(Predicate... restrictions) {
_having = new PredicateImpl();
if (restrictions == null) {
_having = null;
return this;
}
_having = new PredicateImpl.And();
for (Predicate p : restrictions)
_having.add(p);
return this;
}
public CriteriaQuery<T> orderBy(Order... orders) {
_orders = new ArrayList<Order>();
if (orders == null)
if (orders == null) {
_orders = null;
return this;
}
_orders = new ArrayList<Order>();
for (Order o : orders) {
_orders.add(o);
}
@ -277,9 +287,11 @@ public class CriteriaQueryImpl<T> implements OpenJPACriteriaQuery<T>, AliasConte
}
public CriteriaQuery<T> orderBy(List<Order> orders) {
_orders = new ArrayList<Order>();
if (orders == null)
if (orders == null) {
_orders = null;
return this;
}
_orders = new ArrayList<Order>();
for (Order o : orders) {
_orders.add(o);
}
@ -306,7 +318,7 @@ public class CriteriaQueryImpl<T> implements OpenJPACriteriaQuery<T>, AliasConte
_where = null;
return this;
}
_where = new PredicateImpl().add(restriction);
_where = (PredicateImpl)restriction;
return this;
}
@ -316,9 +328,7 @@ public class CriteriaQueryImpl<T> implements OpenJPACriteriaQuery<T>, AliasConte
_where = null;
return this;
}
_where = new PredicateImpl();
for (Predicate p : restrictions)
_where.add(p);
_where = new PredicateImpl.And(restrictions);
return this;
}
@ -371,11 +381,10 @@ public class CriteriaQueryImpl<T> implements OpenJPACriteriaQuery<T>, AliasConte
_roots.add(root);
}
/**
* Affirms if selection of this query is distinct.
*/
public boolean isDistinct() {
return _distinct == null ? false : _distinct.booleanValue();
}
Boolean getDistinct() {
return _distinct;
}
@ -553,11 +562,8 @@ public class CriteriaQueryImpl<T> implements OpenJPACriteriaQuery<T>, AliasConte
/**
* Gets the registered variable for the given root.
*
* @param root
* @return
*/
Value getRegisteredRootVariable(Root<?> root) {
public Value getRegisteredRootVariable(Root<?> root) {
Value var = _rootVariables.get(root);
if (var != null)
return var;
@ -640,7 +646,7 @@ public class CriteriaQueryImpl<T> implements OpenJPACriteriaQuery<T>, AliasConte
public String toCQL() {
StringBuilder buffer = new StringBuilder();
render(buffer, _roots, null);
return buffer.toString();
return buffer.toString().trim();
}
void render(StringBuilder buffer, Set<Root<?>> roots, List<Join<?,?>> correlatedJoins) {
@ -655,11 +661,20 @@ public class CriteriaQueryImpl<T> implements OpenJPACriteriaQuery<T>, AliasConte
}
if (_orders != null) {
buffer.append(" ORDER BY ");
List<Order> orderBys = getOrderList();
for (int i = 0; i < orderBys.size(); i++) {
buffer.append(((CriteriaExpression)orderBys.get(i)).asValue(this));
for (Order orderBy : getOrderList()) {
buffer.append(((CriteriaExpression)orderBy).asValue(this));
}
}
if (_groups != null) {
buffer.append(" GROUP BY ");
for (Expression<?> groupBy : getGroupList()) {
buffer.append(((CriteriaExpression)groupBy).asValue(this));
}
}
if (_having != null) {
buffer.append(" HAVING ");
buffer.append(_having.asValue(this));
}
}
private void renderJoins(StringBuilder buffer, Collection<Join<?,?>> joins) {
@ -667,6 +682,7 @@ public class CriteriaQueryImpl<T> implements OpenJPACriteriaQuery<T>, AliasConte
for (Join j : joins) {
buffer.append(((ExpressionImpl<?>)j).asVariable(this)).append(" ");
renderJoins(buffer, j.getJoins());
renderFetches(buffer, j.getFetches());
}
}
@ -677,6 +693,13 @@ public class CriteriaQueryImpl<T> implements OpenJPACriteriaQuery<T>, AliasConte
buffer.append(((ExpressionImpl<?>)r).asVariable(this));
if (++i != roots.size()) buffer.append(", ");
renderJoins(buffer, r.getJoins());
renderFetches(buffer, r.getFetches());
}
}
private void renderFetches(StringBuilder buffer, Set<Fetch> fetches) {
if (fetches == null) return;
for (Fetch j : fetches) {
buffer.append(((ExpressionImpl<?>)j).asValue(this)).append(" ");
}
}
}

View File

@ -124,7 +124,7 @@ public class Expressions {
/**
* Renders the given expressions as a list of values separated by the given connector.
*/
static StringBuilder asValue(CriteriaQueryImpl<?> q, Expression<?>[] exps, String connector) {
static StringBuilder asValue(AliasContext q, Expression<?>[] exps, String connector) {
StringBuilder buffer = new StringBuilder();
if (exps == null) return buffer;
for (int i = 0; i < exps.length; i++) {
@ -139,7 +139,7 @@ public class Expressions {
/**
* Renders the given arguments as a list of values separated by the given connector.
*/
static StringBuilder asValue(CriteriaQueryImpl<?> q, Object...params) {
static StringBuilder asValue(AliasContext q, Object...params) {
StringBuilder buffer = new StringBuilder();
if (params == null) return buffer;
for (int i = 0; i < params.length; i++) {
@ -175,6 +175,11 @@ public class Expressions {
return set == null ? new HashSet<X>() : new CopyOnWriteArraySet<X>(set);
}
static org.apache.openjpa.kernel.exps.Expression and(ExpressionFactory factory,
org.apache.openjpa.kernel.exps.Expression e1, org.apache.openjpa.kernel.exps.Expression e2) {
return e1 == null ? e2 : e2 == null ? e1 : factory.and(e1, e2);
}
/**
@ -254,7 +259,7 @@ public class Expressions {
* i.e. an expression whose resultant type is Boolean.
*
*/
public static class BinaryLogicalExpression extends PredicateImpl {
public static abstract class BinaryLogicalExpression extends PredicateImpl {
protected final ExpressionImpl<?> e1;
protected final ExpressionImpl<?> e2;
@ -264,10 +269,10 @@ public class Expressions {
e2 = (ExpressionImpl<?>)y;
}
@Override
public PredicateImpl clone() {
return new BinaryLogicalExpression(e1, e2);
}
// @Override
// public PredicateImpl clone() {
// return new BinaryLogicalExpression(e1, e2);
// }
public void acceptVisit(CriteriaExpressionVisitor visitor) {
Expressions.acceptVisit(visitor, this, e1, e2);
@ -285,7 +290,7 @@ public class Expressions {
return factory.abs(Expressions.toValue(e, factory, model, q));
}
public StringBuilder asValue(CriteriaQueryImpl<?> q) {
public StringBuilder asValue(AliasContext q) {
return Expressions.asValue(q, "ABS", OPEN_BRACE, e, CLOSE_BRACE);
}
}
@ -309,7 +314,7 @@ public class Expressions {
}
@Override
public StringBuilder asValue(CriteriaQueryImpl<?> q) {
public StringBuilder asValue(AliasContext q) {
return Expressions.asValue(q, "COUNT", OPEN_BRACE, _distinct ? "DISTINCT"+OPEN_BRACE : "",
e, _distinct ? CLOSE_BRACE : "", CLOSE_BRACE);
}
@ -326,7 +331,7 @@ public class Expressions {
}
@Override
public StringBuilder asValue(CriteriaQueryImpl<?> q) {
public StringBuilder asValue(AliasContext q) {
return Expressions.asValue(q, "AVG", OPEN_BRACE, e, CLOSE_BRACE);
}
}
@ -341,7 +346,7 @@ public class Expressions {
return factory.sqrt(Expressions.toValue(e, factory, model, q));
}
public StringBuilder asValue(CriteriaQueryImpl<?> q) {
public StringBuilder asValue(AliasContext q) {
return Expressions.asValue(q, "SQRT", OPEN_BRACE, e, CLOSE_BRACE);
}
}
@ -356,7 +361,7 @@ public class Expressions {
return factory.max(Expressions.toValue(e, factory, model, q));
}
public StringBuilder asValue(CriteriaQueryImpl<?> q) {
public StringBuilder asValue(AliasContext q) {
return Expressions.asValue(q, "MAX", OPEN_BRACE, e, CLOSE_BRACE);
}
}
@ -371,7 +376,7 @@ public class Expressions {
return factory.min(Expressions.toValue(e, factory, model, q));
}
public StringBuilder asValue(CriteriaQueryImpl<?> q) {
public StringBuilder asValue(AliasContext q) {
return Expressions.asValue(q, "MIN", OPEN_BRACE, e, CLOSE_BRACE);
}
}
@ -395,7 +400,7 @@ public class Expressions {
return factory.size(val);
}
public StringBuilder asValue(CriteriaQueryImpl<?> q) {
public StringBuilder asValue(AliasContext q) {
return Expressions.asValue(q, "SIZE", OPEN_BRACE, e, CLOSE_BRACE);
}
}
@ -416,7 +421,7 @@ public class Expressions {
new Expressions.ListArgument(resultType, args).toValue(factory, model, q));
}
public StringBuilder asValue(CriteriaQueryImpl<?> q) {
public StringBuilder asValue(AliasContext q) {
return Expressions.asValue(q, functionName, OPEN_BRACE, Expressions.asValue(q, args, COMMA), CLOSE_BRACE);
}
}
@ -433,7 +438,7 @@ public class Expressions {
}
@Override
public StringBuilder asValue(CriteriaQueryImpl<?> q) {
public StringBuilder asValue(AliasContext q) {
return Expressions.asValue(q, "TYPE", OPEN_BRACE, e, CLOSE_BRACE);
}
}
@ -449,7 +454,7 @@ public class Expressions {
}
@Override
public StringBuilder asValue(CriteriaQueryImpl<?> q) {
public StringBuilder asValue(AliasContext q) {
return Expressions.asValue(q, OPEN_BRACE, getJavaType().getSimpleName(), CLOSE_BRACE, e);
}
}
@ -475,7 +480,7 @@ public class Expressions {
}
@Override
public StringBuilder asValue(CriteriaQueryImpl<?> q) {
public StringBuilder asValue(AliasContext q) {
return Expressions.asValue(q, "CONCAT", OPEN_BRACE, e1, COMMA, e2, CLOSE_BRACE);
}
}
@ -520,7 +525,7 @@ public class Expressions {
}
@Override
public StringBuilder asValue(CriteriaQueryImpl<?> q) {
public StringBuilder asValue(AliasContext q) {
return Expressions.asValue(q, "SUBSTRING", OPEN_BRACE, e, COMMA, from, COMMA, len, CLOSE_BRACE);
}
}
@ -572,7 +577,7 @@ public class Expressions {
}
@Override
public StringBuilder asValue(CriteriaQueryImpl<?> q) {
public StringBuilder asValue(AliasContext q) {
return Expressions.asValue(q, "LOCATE", OPEN_BRACE, pattern, COMMA, path, CLOSE_BRACE);
}
}
@ -623,7 +628,7 @@ public class Expressions {
}
@Override
public StringBuilder asValue(CriteriaQueryImpl<?> q) {
public StringBuilder asValue(AliasContext q) {
return Expressions.asValue(q, "TRIM", OPEN_BRACE, e1, COMMA, e2, CLOSE_BRACE);
}
}
@ -655,7 +660,7 @@ public class Expressions {
}
@Override
public StringBuilder asValue(CriteriaQueryImpl<?> q) {
public StringBuilder asValue(AliasContext q) {
return e2 == null
? Expressions.asValue(q, "SUM", OPEN_BRACE, e1, CLOSE_BRACE)
: Expressions.asValue(q, e1, " + ", e2);
@ -683,7 +688,7 @@ public class Expressions {
}
@Override
public StringBuilder asValue(CriteriaQueryImpl<?> q) {
public StringBuilder asValue(AliasContext q) {
return Expressions.asValue(q, e1, " * " ,e2);
}
}
@ -709,7 +714,7 @@ public class Expressions {
}
@Override
public StringBuilder asValue(CriteriaQueryImpl<?> q) {
public StringBuilder asValue(AliasContext q) {
return Expressions.asValue(q, e1, " - " ,e2);
}
}
@ -736,7 +741,7 @@ public class Expressions {
}
@Override
public StringBuilder asValue(CriteriaQueryImpl<?> q) {
public StringBuilder asValue(AliasContext q) {
return Expressions.asValue(q, e1, "%" ,e2);
}
}
@ -760,7 +765,7 @@ public class Expressions {
}
@Override
public StringBuilder asValue(CriteriaQueryImpl<?> q) {
public StringBuilder asValue(AliasContext q) {
return Expressions.asValue(q, "MOD", OPEN_BRACE, e1, COMMA, e2, CLOSE_BRACE);
}
}
@ -776,7 +781,7 @@ public class Expressions {
}
@Override
public StringBuilder asValue(CriteriaQueryImpl<?> q) {
public StringBuilder asValue(AliasContext q) {
return new StringBuilder("CURRENT_DATE");
}
}
@ -792,7 +797,7 @@ public class Expressions {
}
@Override
public StringBuilder asValue(CriteriaQueryImpl<?> q) {
public StringBuilder asValue(AliasContext q) {
return new StringBuilder("CURRENT_TIME");
}
}
@ -808,7 +813,7 @@ public class Expressions {
}
@Override
public StringBuilder asValue(CriteriaQueryImpl<?> q) {
public StringBuilder asValue(AliasContext q) {
return new StringBuilder("CURRENT_TIMESTAMP");
}
}
@ -821,10 +826,10 @@ public class Expressions {
public <X> Equal(Expression<X> x, Object y) {
this(x, new Constant(y));
}
@Override
public PredicateImpl clone() {
return new Equal(e1, e2);
public PredicateImpl negate() {
return new NotEqual(e1, e2).markNegated();
}
@Override
@ -833,15 +838,44 @@ public class Expressions {
Value val1 = Expressions.toValue(e1, factory, model, q);
Value val2 = Expressions.toValue(e2, factory, model, q);
Expressions.setImplicitTypes(val1, val2, e1.getJavaType(), q);
return isNegated() ? factory.notEqual(val1, val2) : factory.equal(val1, val2);
return factory.equal(val1, val2);
}
@Override
public StringBuilder asValue(CriteriaQueryImpl<?> q) {
public StringBuilder asValue(AliasContext q) {
return Expressions.asValue(q, e1, " = ", e2);
}
}
public static class NotEqual extends BinaryLogicalExpression {
public <X,Y> NotEqual(Expression<X> x, Expression<Y> y) {
super(x,y);
}
public <X> NotEqual(Expression<X> x, Object y) {
this(x, new Constant(y));
}
@Override
public PredicateImpl negate() {
return new Equal(e1, e2).markNegated();
}
@Override
org.apache.openjpa.kernel.exps.Expression toKernelExpression(ExpressionFactory factory, MetamodelImpl model,
CriteriaQueryImpl<?> q) {
Value val1 = Expressions.toValue(e1, factory, model, q);
Value val2 = Expressions.toValue(e2, factory, model, q);
Expressions.setImplicitTypes(val1, val2, e1.getJavaType(), q);
return factory.notEqual(val1, val2);
}
@Override
public StringBuilder asValue(AliasContext q) {
return Expressions.asValue(q, e1, " <> ", e2);
}
}
public static class GreaterThan extends BinaryLogicalExpression {
public <X,Y> GreaterThan(Expression<X> x, Expression<Y> y) {
super(x,y);
@ -851,6 +885,11 @@ public class Expressions {
this(x, new Constant(y));
}
@Override
public PredicateImpl negate() {
return new LessThanEqual(e1, e2).markNegated();
}
@Override
org.apache.openjpa.kernel.exps.Expression toKernelExpression(ExpressionFactory factory, MetamodelImpl model,
CriteriaQueryImpl<?> q) {
@ -861,7 +900,7 @@ public class Expressions {
}
@Override
public StringBuilder asValue(CriteriaQueryImpl<?> q) {
public StringBuilder asValue(AliasContext q) {
return Expressions.asValue(q, e1, " > ", e2);
}
}
@ -875,6 +914,11 @@ public class Expressions {
this(x, new Constant(y));
}
@Override
public PredicateImpl negate() {
return new LessThan(e1, e2).markNegated();
}
@Override
org.apache.openjpa.kernel.exps.Expression toKernelExpression(ExpressionFactory factory, MetamodelImpl model,
CriteriaQueryImpl<?> q) {
@ -885,7 +929,7 @@ public class Expressions {
}
@Override
public StringBuilder asValue(CriteriaQueryImpl<?> q) {
public StringBuilder asValue(AliasContext q) {
return Expressions.asValue(q, e1, " >= ", e2);
}
}
@ -899,6 +943,11 @@ public class Expressions {
this(x, new Constant(y));
}
@Override
public PredicateImpl negate() {
return new GreaterThanEqual(e1, e2).markNegated();
}
@Override
org.apache.openjpa.kernel.exps.Expression toKernelExpression(ExpressionFactory factory, MetamodelImpl model,
CriteriaQueryImpl<?> q) {
@ -909,7 +958,7 @@ public class Expressions {
}
@Override
public StringBuilder asValue(CriteriaQueryImpl<?> q) {
public StringBuilder asValue(AliasContext q) {
return Expressions.asValue(q, e1, " < ", e2);
}
}
@ -923,6 +972,11 @@ public class Expressions {
this(x, new Constant(y));
}
@Override
public PredicateImpl negate() {
return new GreaterThan(e1, e2).markNegated();
}
@Override
org.apache.openjpa.kernel.exps.Expression toKernelExpression(ExpressionFactory factory, MetamodelImpl model,
CriteriaQueryImpl<?> q) {
@ -934,7 +988,7 @@ public class Expressions {
@Override
public StringBuilder asValue(CriteriaQueryImpl<?> q) {
public StringBuilder asValue(AliasContext q) {
return Expressions.asValue(q, e1, " <= ", e2);
}
}
@ -956,7 +1010,7 @@ public class Expressions {
}
@Override
public StringBuilder asValue(CriteriaQueryImpl<?> q) {
public StringBuilder asValue(AliasContext q) {
return Expressions.asValue(q, e, " BETWEEN ", v1, " AND ", v2);
}
}
@ -1009,7 +1063,7 @@ public class Expressions {
Expressions.acceptVisit(visitor, this, arg instanceof Expression ? ((Expression)arg) : null);
}
public StringBuilder asValue(CriteriaQueryImpl<?> q) {
public StringBuilder asValue(AliasContext q) {
if (arg == null)
return new StringBuilder("NULL");
Class<?> literalClass = getJavaType();
@ -1040,15 +1094,20 @@ public class Expressions {
}
@Override
public PredicateImpl clone() {
return new IsEmpty(collection);
public PredicateImpl negate() {
return new IsNotEmpty(collection).markNegated();
}
@Override
Value toValue(ExpressionFactory factory, MetamodelImpl model, CriteriaQueryImpl<?> q) {
return Expressions.toValue(collection, factory, model, q);
}
@Override
org.apache.openjpa.kernel.exps.Expression toKernelExpression(ExpressionFactory factory, MetamodelImpl model,
CriteriaQueryImpl<?> q) {
Value val = Expressions.toValue(collection, factory, model, q);
return (isNegated()) ? factory.not(factory.isEmpty(val)) : factory.isEmpty(val);
return factory.isEmpty(val);
}
public void acceptVisit(CriteriaExpressionVisitor visitor) {
@ -1057,7 +1116,7 @@ public class Expressions {
}
@Override
public StringBuilder asValue(CriteriaQueryImpl<?> q) {
public StringBuilder asValue(AliasContext q) {
return Expressions.asValue(q, collection, " IS EMPTY");
}
}
@ -1070,15 +1129,21 @@ public class Expressions {
}
@Override
public PredicateImpl clone() {
return new IsNotEmpty(collection);
public PredicateImpl negate() {
return new IsEmpty(collection).markNegated();
}
@Override
Value toValue(ExpressionFactory factory, MetamodelImpl model, CriteriaQueryImpl<?> q) {
return Expressions.toValue(collection, factory, model, q);
}
@Override
org.apache.openjpa.kernel.exps.Expression toKernelExpression(ExpressionFactory factory, MetamodelImpl model,
CriteriaQueryImpl<?> q) {
Value val = Expressions.toValue(collection, factory, model, q);
return (isNegated()) ? factory.isEmpty(val) : factory.isNotEmpty(val);
// factory.isNotEmpty() not used to match JPQL
return factory.not(factory.isEmpty(val));
}
public void acceptVisit(CriteriaExpressionVisitor visitor) {
@ -1087,7 +1152,7 @@ public class Expressions {
}
@Override
public StringBuilder asValue(CriteriaQueryImpl<?> q) {
public StringBuilder asValue(AliasContext q) {
return Expressions.asValue(q, collection, " IS NOT EMPTY");
}
}
@ -1108,7 +1173,7 @@ public class Expressions {
}
@Override
public StringBuilder asValue(CriteriaQueryImpl<?> q) {
public StringBuilder asValue(AliasContext q) {
return Expressions.asValue(q, "INDEX", OPEN_BRACE, e, CLOSE_BRACE);
}
}
@ -1131,18 +1196,13 @@ public class Expressions {
this((Class<E>)element.getClass(), element, collection);
}
@Override
public PredicateImpl clone() {
return new IsMember<E>(element.getJavaType(), element, collection);
}
@Override
public org.apache.openjpa.kernel.exps.Expression toKernelExpression(
ExpressionFactory factory, MetamodelImpl model, CriteriaQueryImpl<?> q) {
org.apache.openjpa.kernel.exps.Expression contains = factory.contains(
Expressions.toValue(collection, factory, model, q),
Expressions.toValue(element, factory, model, q));
return isNegated() ? factory.not(contains) : contains;
return contains;
}
public void acceptVisit(CriteriaExpressionVisitor visitor) {
@ -1151,8 +1211,8 @@ public class Expressions {
}
@Override
public StringBuilder asValue(CriteriaQueryImpl<?> q) {
return Expressions.asValue(q, element, isNegated() ? "NOT " : "", "MEMBER OF ", collection);
public StringBuilder asValue(AliasContext q) {
return Expressions.asValue(q, element, "MEMBER OF ", collection);
}
}
@ -1192,11 +1252,6 @@ public class Expressions {
this(x, new Constant<String>(pat), new Constant<Character>(esc));
}
@Override
public PredicateImpl clone() {
return new Like(str, pattern, escapeChar);
}
@Override
public org.apache.openjpa.kernel.exps.Expression toKernelExpression(
ExpressionFactory factory, MetamodelImpl model, CriteriaQueryImpl<?> q) {
@ -1215,7 +1270,7 @@ public class Expressions {
}
@Override
public StringBuilder asValue(CriteriaQueryImpl<?> q) {
public StringBuilder asValue(AliasContext q) {
return Expressions.asValue(q, str, " LIKE ", pattern);
}
}
@ -1252,7 +1307,7 @@ public class Expressions {
}
@Override
public StringBuilder asValue(CriteriaQueryImpl<?> q) {
public StringBuilder asValue(AliasContext q) {
return Expressions.asValue(q, "COALESCE", OPEN_BRACE, Expressions.asValue(q, values == null
? null : values.toArray(new Expression<?>[values.size()]), COMMA), CLOSE_BRACE);
}
@ -1285,7 +1340,7 @@ public class Expressions {
}
@Override
public StringBuilder asValue(CriteriaQueryImpl<?> q) {
public StringBuilder asValue(AliasContext q) {
return Expressions.asValue(q, "NULLIF", OPEN_BRACE, val1, COMMA, val2, CLOSE_BRACE);
}
}
@ -1299,8 +1354,8 @@ public class Expressions {
@Override
public PredicateImpl negate() {
return new Expressions.IsNotNull(e);
}
return new IsNotNull(e).markNegated();
}
@Override
org.apache.openjpa.kernel.exps.Expression toKernelExpression(
@ -1316,7 +1371,7 @@ public class Expressions {
}
@Override
public StringBuilder asValue(CriteriaQueryImpl<?> q) {
public StringBuilder asValue(AliasContext q) {
return Expressions.asValue(q, e, " IS NULL");
}
}
@ -1330,9 +1385,9 @@ public class Expressions {
@Override
public PredicateImpl negate() {
return new Expressions.IsNull(e);
}
return new IsNull(e).markNegated();
}
@Override
org.apache.openjpa.kernel.exps.Expression toKernelExpression(
ExpressionFactory factory, MetamodelImpl model, CriteriaQueryImpl<?> q) {
@ -1347,7 +1402,7 @@ public class Expressions {
}
@Override
public StringBuilder asValue(CriteriaQueryImpl<?> q) {
public StringBuilder asValue(AliasContext q) {
return Expressions.asValue(q, e, " IS NOT NULL");
}
}
@ -1355,7 +1410,6 @@ public class Expressions {
public static class In<T> extends PredicateImpl.Or implements QueryBuilder.In<T> {
final ExpressionImpl<T> e;
private boolean negate;
public In(Expression<?> e) {
super();
this.e = (ExpressionImpl<T>)e;
@ -1375,11 +1429,16 @@ public class Expressions {
return this;
}
public In<T> negate() {
this.negate = !negate;
return this;
@Override
public PredicateImpl negate() {
In<T> notIn = new In<T>(e);
notIn.markNegated();
for (Predicate e : _exps) {
notIn.add(e);
}
return notIn;
}
@Override
org.apache.openjpa.kernel.exps.Expression toKernelExpression(
ExpressionFactory factory, MetamodelImpl model, CriteriaQueryImpl<?> q) {
@ -1390,23 +1449,20 @@ public class Expressions {
ExpressionImpl<?> e1 = e.e1;
Value val2 = Expressions.toValue(e2, factory, model, q);
if (!(val2 instanceof Literal)) {
Value val1 = Expressions.toValue(e1, factory, model, q);
Value val1 = Expressions.toValue(e1, factory, model, q);
Expressions.setImplicitTypes(val1, val2, e1.getJavaType(), q);
inExpr = factory.contains(val2, val1);
return negate ? factory.not(inExpr) : inExpr;
return isNegated() ? factory.not(inExpr) : inExpr;
} else if (((Literal)val2).getParseType() == Literal.TYPE_COLLECTION) {
List<Expression<Boolean>> exps = new ArrayList<Expression<Boolean>>();
Collection coll = (Collection)((Literal)val2).getValue();
_exps.clear();
for (Object v : coll) {
exps.add(new Expressions.Equal(e1,v));
add(new Expressions.Equal(e1,v));
}
_exps = exps;
}
}
inExpr = super.toKernelExpression(factory, model, q);
IsNotNull notNull = new Expressions.IsNotNull(e);
if (negate)
inExpr = factory.not(inExpr);
return factory.and(inExpr, notNull.toKernelExpression(factory, model, q));
}
@ -1417,8 +1473,8 @@ public class Expressions {
}
@Override
public StringBuilder asValue(CriteriaQueryImpl<?> q) {
StringBuilder buffer = Expressions.asValue(q, e, negate ? " NOT IN " : " IN ", OPEN_BRACE);
public StringBuilder asValue(AliasContext q) {
StringBuilder buffer = Expressions.asValue(q, e, " IN ", OPEN_BRACE);
for (int i = 0; i < _exps.size(); i++) {
buffer.append(((Equal)_exps.get(i)).e2.asValue(q)).append(i+1 == _exps.size() ? CLOSE_BRACE : COMMA);
}
@ -1481,7 +1537,7 @@ public class Expressions {
}
@Override
public StringBuilder asValue(CriteriaQueryImpl<?> q) {
public StringBuilder asValue(AliasContext q) {
StringBuilder buffer = new StringBuilder("CASE ");
int size = whens.size();
for (int i = 0; i < size; i++) {
@ -1558,7 +1614,7 @@ public class Expressions {
}
@Override
public StringBuilder asValue(CriteriaQueryImpl<?> q) {
public StringBuilder asValue(AliasContext q) {
StringBuilder buffer = new StringBuilder("CASE ");
int size = whens.size();
for (int i = 0; i < size; i++) {
@ -1580,7 +1636,7 @@ public class Expressions {
}
@Override
public StringBuilder asValue(CriteriaQueryImpl<?> q) {
public StringBuilder asValue(AliasContext q) {
return Expressions.asValue(q, "LOWER", OPEN_BRACE, e, CLOSE_BRACE);
}
}
@ -1596,7 +1652,7 @@ public class Expressions {
}
@Override
public StringBuilder asValue(CriteriaQueryImpl<?> q) {
public StringBuilder asValue(AliasContext q) {
return Expressions.asValue(q, "UPPER", OPEN_BRACE, e, CLOSE_BRACE);
}
}
@ -1612,7 +1668,7 @@ public class Expressions {
}
@Override
public StringBuilder asValue(CriteriaQueryImpl<?> q) {
public StringBuilder asValue(AliasContext q) {
return Expressions.asValue(q, "LENGTH", OPEN_BRACE, e, CLOSE_BRACE);
}
}
@ -1648,22 +1704,17 @@ public class Expressions {
super(x);
}
@Override
public PredicateImpl clone() {
return new Exists<X>(e);
}
@Override
org.apache.openjpa.kernel.exps.Expression toKernelExpression(
ExpressionFactory factory, MetamodelImpl model, CriteriaQueryImpl<?> q) {
org.apache.openjpa.kernel.exps.Expression exists =
factory.isNotEmpty(Expressions.toValue(e, factory, model, q));
return isNegated() ? factory.not(exists) : exists;
return exists;
}
@Override
public StringBuilder asValue(CriteriaQueryImpl<?> q) {
return Expressions.asValue(q, isNegated() ? "NOT" : "", " EXISTS", OPEN_BRACE, e, CLOSE_BRACE);
public StringBuilder asValue(AliasContext q) {
return Expressions.asValue(q, " EXISTS", OPEN_BRACE, e, CLOSE_BRACE);
}
}
@ -1679,7 +1730,7 @@ public class Expressions {
}
@Override
public StringBuilder asValue(CriteriaQueryImpl<?> q) {
public StringBuilder asValue(AliasContext q) {
return Expressions.asValue(q, "ALL", OPEN_BRACE, e, CLOSE_BRACE);
}
}
@ -1695,27 +1746,22 @@ public class Expressions {
}
@Override
public StringBuilder asValue(CriteriaQueryImpl<?> q) {
public StringBuilder asValue(AliasContext q) {
return Expressions.asValue(q, "ANY", OPEN_BRACE, e, CLOSE_BRACE);
}
}
public static class Not<X> extends PredicateImpl {
public static class Not extends PredicateImpl {
protected final ExpressionImpl<Boolean> e;
public Not(Expression<Boolean> ne) {
super();
e = (ExpressionImpl<Boolean>)ne;
}
@Override
public PredicateImpl clone() {
return new Not<X>(e);
}
@Override
public org.apache.openjpa.kernel.exps.Expression toKernelExpression(
ExpressionFactory factory, MetamodelImpl model, CriteriaQueryImpl<?> q) {
return factory.not(super.toKernelExpression(factory, model, q));
return factory.not(e.toKernelExpression(factory, model, q));
}
public void acceptVisit(CriteriaExpressionVisitor visitor) {
@ -1723,8 +1769,8 @@ public class Expressions {
}
@Override
public StringBuilder asValue(CriteriaQueryImpl<?> q) {
return Expressions.asValue(q, "NOT", OPEN_BRACE, e, CLOSE_BRACE);
public StringBuilder asValue(AliasContext q) {
return Expressions.asValue(q, "NOT ", e);
}
}
@ -1748,7 +1794,7 @@ public class Expressions {
}
@Override
public StringBuilder asValue(CriteriaQueryImpl<?> q) {
public StringBuilder asValue(AliasContext q) {
return actual.asValue(q);
}
}

View File

@ -110,4 +110,7 @@ public class FetchPathImpl<Z,X> extends PathImpl<Z,X> implements Fetch<Z, X> {
return fetch;
}
public StringBuilder asValue(AliasContext q) {
return super.asValue(q).insert(0, " " + joinType + " JOIN FETCH ");
}
}

View File

@ -148,8 +148,7 @@ public class FromImpl<Z,X> extends PathImpl<Z,X> implements From<Z,X> {
* Join to the given List-valued attribute using the given join type.
*/
public <Y> ListJoin<X,Y> join(ListAttribute<? super X, Y> list, JoinType jt) {
ListJoin<X, Y> join = new Joins.List<X, Y>(this,
(Members.ListAttributeImpl<? super X, Y>)list, jt);
ListJoin<X, Y> join = new Joins.List<X, Y>(this, (Members.ListAttributeImpl<? super X, Y>)list, jt);
addJoin(join);
return join;
}
@ -283,6 +282,6 @@ public class FromImpl<Z,X> extends PathImpl<Z,X> implements From<Z,X> {
public void acceptVisit(CriteriaExpressionVisitor visitor) {
Expressions.acceptVisit(visitor, this,
_joins == null ? null : _joins.toArray(new ExpressionImpl<?>[_joins.size()]));
_joins == null ? null : _joins.toArray(new ExpressionImpl<?>[_joins.size()]));
}
}

View File

@ -175,11 +175,11 @@ public abstract class Joins {
}
if (getJoins() != null) {
for (Join<?, ?> join1 : getJoins()) {
filter = CriteriaExpressionBuilder.and(factory,
((FromImpl<?,?>)join1).toKernelExpression(factory, model, c), filter);
filter = Expressions.and(factory,
((FromImpl<?,?>)join1).toKernelExpression(factory, model, c), filter);
}
}
org.apache.openjpa.kernel.exps.Expression expr = CriteriaExpressionBuilder.and(factory, join, filter);
org.apache.openjpa.kernel.exps.Expression expr = Expressions.and(factory, join, filter);
if (correlatedParentPath == null) {
return expr;
@ -199,7 +199,7 @@ public abstract class Joins {
path.setMetaData(meta);
//filter = bindVariableForKeyPath(path, alias, filter);
filter = factory.equal(parentPath, path);
return CriteriaExpressionBuilder.and(factory, expr, filter);
return Expressions.and(factory, expr, filter);
}
}
@ -249,7 +249,7 @@ public abstract class Joins {
}
@Override
public StringBuilder asVariable(CriteriaQueryImpl<?> q) {
public StringBuilder asVariable(AliasContext q) {
String varName = "?";
Value var = q.getRegisteredVariable(this);
if (var == null) {
@ -257,8 +257,7 @@ public abstract class Joins {
} else {
varName = var.getName();
}
return new StringBuilder(joinType.toString()).append(" JOIN ")
.append(super.asVariable(q)).append(" " + varName);
return new StringBuilder(" " + joinType + " JOIN ").append(super.asVariable(q)).append(" " + varName);
}
}
@ -386,11 +385,11 @@ public abstract class Joins {
}
if (getJoins() != null) {
for (Join<?, ?> join1 : getJoins()) {
filter = CriteriaExpressionBuilder.and(factory,
filter = Expressions.and(factory,
((FromImpl<?,?>)join1).toKernelExpression(factory, model, c), filter);
}
}
org.apache.openjpa.kernel.exps.Expression expr = CriteriaExpressionBuilder.and(factory, join, filter);
org.apache.openjpa.kernel.exps.Expression expr = Expressions.and(factory, join, filter);
if (correlatedParentPath == null) {
return expr;
} else {
@ -417,11 +416,11 @@ public abstract class Joins {
c.registerVariable(this, var, parentPath);
if (_member.fmd.isElementCollection()) {
filter = CriteriaExpressionBuilder.and(factory, join, filter);
filter = Expressions.and(factory, join, filter);
} else {
filter = factory.equal(parentPath, path);
}
return CriteriaExpressionBuilder.and(factory, expr, filter);
return Expressions.and(factory, expr, filter);
}
}
@ -580,7 +579,7 @@ public abstract class Joins {
}
@Override
public StringBuilder asValue(CriteriaQueryImpl<?> q) {
public StringBuilder asValue(AliasContext q) {
StringBuilder buffer = new StringBuilder("KEY(");
Value var = q.getRegisteredVariable(map);
buffer.append(var != null ? var.getName() : map.asValue(q)).append(")");
@ -609,7 +608,7 @@ public abstract class Joins {
}
@Override
public StringBuilder asValue(CriteriaQueryImpl<?> q) {
public StringBuilder asValue(AliasContext q) {
StringBuilder buffer = new StringBuilder("ENTRY(");
Value var = q.getRegisteredVariable(map);
buffer.append(var != null ? var.getName() : map.asValue(q)).append(")");

View File

@ -60,11 +60,11 @@ public class OrderImpl implements Order, CriteriaExpression {
}
}
public StringBuilder asValue(CriteriaQueryImpl<?> q) {
public StringBuilder asValue(AliasContext q) {
return e.asValue(q).append(_ascending ? "" : " DESC");
}
public StringBuilder asVariable(CriteriaQueryImpl<?> q) {
public StringBuilder asVariable(AliasContext q) {
throw new IllegalStateException(this + " can not be rendered as variable");
}
}

View File

@ -98,7 +98,7 @@ public class ParameterExpressionImpl<T> extends ExpressionImpl<T>
}
@Override
public StringBuilder asValue(CriteriaQueryImpl<?> q) {
public StringBuilder asValue(AliasContext q) {
return Expressions.asValue(q, ":", _name == null ? "param" : _name);
}

View File

@ -279,7 +279,7 @@ public class PathImpl<Z,X> extends ExpressionImpl<X> implements Path<X> {
return new Expressions.Type<Class<? extends X>>(this);
}
public StringBuilder asValue(CriteriaQueryImpl<?> q) {
public StringBuilder asValue(AliasContext q) {
StringBuilder buffer = new StringBuilder();
if (_parent != null) {
Value var = q.getRegisteredVariable(_parent);
@ -291,7 +291,7 @@ public class PathImpl<Z,X> extends ExpressionImpl<X> implements Path<X> {
return buffer;
}
public StringBuilder asVariable(CriteriaQueryImpl<?> q) {
public StringBuilder asVariable(AliasContext q) {
Value var = q.getRegisteredVariable(this);
return asValue(q).append(" ").append(var == null ? "?" : var.getName());
}

View File

@ -19,7 +19,6 @@
package org.apache.openjpa.persistence.criteria;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
@ -29,24 +28,37 @@ import javax.persistence.criteria.Predicate;
import org.apache.openjpa.kernel.exps.ExpressionFactory;
import org.apache.openjpa.persistence.meta.MetamodelImpl;
public class PredicateImpl extends ExpressionImpl<Boolean> implements Predicate {
/**
* Predicate is a expression that evaluates to true or false.
* All boolean expressions are implemented as Predicate.
* A predicate can have zero or more predicate arguments.
* Default predicate operator is AND (conjunction).
* Two constant predicates are Predicate.TRUE and Predicate.FALSE.
* AND predicate with no argument evaluates to TRUE.
* OR predicate with no argument evaluates to FALSE.
* Negation of a Predicate creates a new Predicate.
*
* @author Pinaki Poddar
*
*/
public abstract class PredicateImpl extends ExpressionImpl<Boolean> implements Predicate {
private static final ExpressionImpl<Integer> ONE = new Expressions.Constant<Integer>(1);
public static final ExpressionImpl<Boolean> TRUE = new Expressions.Equal(ONE,ONE);
public static final ExpressionImpl<Boolean> FALSE = new Expressions.Equal(ONE,ONE).negate();
public static final Predicate TRUE = new Expressions.Equal(ONE,ONE);
public static final Predicate FALSE = new Expressions.NotEqual(ONE,ONE);
List<Expression<Boolean>> _exps;
protected final List<Predicate> _exps = new ArrayList<Predicate>();
protected final BooleanOperator _op;
private boolean _negated = false;
protected boolean _negated = false;
/**
* A predicate with empty name and AND operator.
* A predicate no arguments representing AND operator.
*/
protected PredicateImpl() {
this(BooleanOperator.AND);
}
/**
* A predicate with given name and given operator.
* A predicate representing given operator.
*/
protected PredicateImpl(BooleanOperator op) {
super(Boolean.class);
@ -54,13 +66,13 @@ public class PredicateImpl extends ExpressionImpl<Boolean> implements Predicate
}
/**
* A predicate with given name, given operator with given arguments.
* A predicate of given operator with given arguments.
*/
protected PredicateImpl(BooleanOperator op, Predicate...restrictions) {
this(op);
if (restrictions != null) {
for (Predicate p : restrictions)
add((PredicateImpl)p);
add(p);
}
}
@ -68,14 +80,16 @@ public class PredicateImpl extends ExpressionImpl<Boolean> implements Predicate
* Adds the given predicate expression.
*/
public PredicateImpl add(Expression<Boolean> s) {
if (_exps == null)
_exps = new ArrayList<Expression<Boolean>>();
_exps.add(s);
_exps.add((Predicate)s); // all boolean expressions are Predicate
return this;
}
public List<Expression<Boolean>> getExpressions() {
return Expressions.returnCopy(_exps);
List<Expression<Boolean>> result = new CopyOnWriteArrayList<Expression<Boolean>>();
if (_exps.isEmpty())
return result;
result.addAll(_exps);
return result;
}
public final BooleanOperator getOperator() {
@ -86,38 +100,38 @@ public class PredicateImpl extends ExpressionImpl<Boolean> implements Predicate
return _negated;
}
/**
* Default negation creates a Not expression with this receiver as delegate.
* Derived predicates can return the inverse expression such as NotEqual
* for Equal or LessThan for GreaterThanEqual etc.
*/
public PredicateImpl negate() {
PredicateImpl not = clone();
not._negated = true;
return not;
return new Expressions.Not(this).markNegated();
}
public PredicateImpl clone() {
PredicateImpl clone = new PredicateImpl(_op);
if (_exps != null)
clone._exps = new ArrayList<Expression<Boolean>>(this._exps);
return clone;
protected PredicateImpl markNegated() {
_negated = true;
return this;
}
@Override
org.apache.openjpa.kernel.exps.Value toValue(ExpressionFactory factory, MetamodelImpl model,
org.apache.openjpa.kernel.exps.Value toValue(ExpressionFactory factory, MetamodelImpl model,
CriteriaQueryImpl<?> q) {
throw new AbstractMethodError();
throw new AbstractMethodError(this.getClass().getName());
}
@Override
org.apache.openjpa.kernel.exps.Expression toKernelExpression(ExpressionFactory factory, MetamodelImpl model,
CriteriaQueryImpl<?> q) {
if (_exps == null || _exps.isEmpty()) {
ExpressionImpl<Boolean> nil = _op == BooleanOperator.AND ? TRUE : FALSE;
return nil.toKernelExpression(factory, model, q);
if (_exps.isEmpty()) {
Predicate nil = _op == BooleanOperator.AND ? TRUE : FALSE;
return ((PredicateImpl)nil).toKernelExpression(factory, model, q);
}
if (_exps.size() == 1) {
ExpressionImpl<Boolean> e0 = (ExpressionImpl<Boolean>)_exps.get(0);
if (e0 instanceof Expressions.Constant && e0.getJavaType() == Boolean.class) {
e0 = Boolean.TRUE.equals(((Expressions.Constant<Boolean>)e0).arg) ? TRUE : FALSE;
}
return e0.toKernelExpression(factory, model, q);
Predicate e0 = _exps.get(0);
if (isNegated())
e0 = e0.negate();
return ((PredicateImpl)e0).toKernelExpression(factory, model, q);
}
ExpressionImpl<?> e1 = (ExpressionImpl<?>)_exps.get(0);
@ -128,27 +142,30 @@ public class PredicateImpl extends ExpressionImpl<Boolean> implements Predicate
? factory.and(ke1,ke2) : factory.or(ke1, ke2);
for (int i = 2; i < _exps.size(); i++) {
ExpressionImpl<?> e = (ExpressionImpl<?>)_exps.get(i);
PredicateImpl p = (PredicateImpl)_exps.get(i);
result = _op == BooleanOperator.AND
? factory.and(result, e.toKernelExpression(factory, model, q))
: factory.or(result, e.toKernelExpression(factory,model,q));
? factory.and(result, p.toKernelExpression(factory, model, q))
: factory.or(result, p.toKernelExpression(factory,model,q));
}
return _negated ? factory.not(result) : result;
}
public void acceptVisit(CriteriaExpressionVisitor visitor) {
Expressions.acceptVisit(visitor, this, _exps == null ? null : _exps.toArray(new Expression<?>[_exps.size()]));
Expressions.acceptVisit(visitor, this, _exps.toArray(new Expression<?>[_exps.size()]));
}
public StringBuilder asValue(CriteriaQueryImpl<?> q) {
boolean braces = _exps != null && _exps.size() > 1;
StringBuilder buffer = Expressions.asValue(q, _exps == null ? null :
_exps.toArray(new Expression<?>[_exps.size()]), " " +_op + " ");
public StringBuilder asValue(AliasContext q) {
boolean braces = _exps.size() > 1;
StringBuilder buffer = Expressions.asValue(q, _exps.toArray(new Expression<?>[_exps.size()]), " " +_op + " ");
if (braces) buffer.insert(0, "(").append(")");
if (isNegated()) buffer.insert(0, "NOT ");
return buffer;
}
/**
* Concrete AND predicate.
*
*/
public static class And extends PredicateImpl {
public And(Expression<Boolean> x, Expression<Boolean> y) {
super(BooleanOperator.AND);
@ -160,6 +177,10 @@ public class PredicateImpl extends ExpressionImpl<Boolean> implements Predicate
}
}
/**
* Concrete OR predicate.
*
*/
public static class Or extends PredicateImpl {
public Or(Expression<Boolean> x, Expression<Boolean> y) {
super(BooleanOperator.OR);

View File

@ -99,7 +99,7 @@ public class RootImpl<X> extends FromImpl<X,X> implements Root<X> {
return factory.bindVariable(var, path);
}
public StringBuilder asValue(CriteriaQueryImpl<?> q) {
public StringBuilder asValue(AliasContext q) {
Value v = q.getRegisteredRootVariable(this);
if (v != null)
return new StringBuilder(v.getAlias());
@ -111,7 +111,7 @@ public class RootImpl<X> extends FromImpl<X,X> implements Root<X> {
return new StringBuilder().append(Character.toLowerCase(_entity.getName().charAt(0)));
}
public StringBuilder asVariable(CriteriaQueryImpl<?> q) {
public StringBuilder asVariable(AliasContext q) {
return new StringBuilder(_entity.getName()).append(" ").append(asValue(q));
}

View File

@ -52,11 +52,11 @@ public class SelectionImpl<X> extends TupleElementImpl<X>
return false;
}
public StringBuilder asValue(CriteriaQueryImpl<?> q) {
public StringBuilder asValue(AliasContext q) {
throw new IllegalStateException(this.getClass().getSimpleName() + " can not be rendered as value");
}
public StringBuilder asVariable(CriteriaQueryImpl<?> q) {
public StringBuilder asVariable(AliasContext q) {
throw new IllegalStateException(this.getClass().getSimpleName() + " can not be rendered as variable");
}

View File

@ -379,13 +379,13 @@ public class SubqueryImpl<T> extends ExpressionImpl<T> implements Subquery<T> {
return getJavaType();
}
public StringBuilder asValue(CriteriaQueryImpl<?> q) {
public StringBuilder asValue(AliasContext q) {
StringBuilder buffer = new StringBuilder();
_delegate.render(buffer, _delegate.getRoots(), _corrJoins);
return buffer;
}
public StringBuilder asVariable(CriteriaQueryImpl<?> q) {
public StringBuilder asVariable(AliasContext q) {
return asValue(q);
}
}