mirror of
https://github.com/apache/openjpa.git
synced 2025-02-21 01:15:30 +00:00
OPENJPA-1013: Visitor pattern for collecting declared parameters. Editing with parameters. Search within result usage.
git-svn-id: https://svn.apache.org/repos/asf/openjpa/trunk@809036 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
fe44661dc2
commit
0795778d3d
@ -118,6 +118,7 @@ public abstract class AbstractPersistenceTestCase extends TestCase {
|
||||
|
||||
protected Map<String, Object> getPropertiesMap(Object... props) {
|
||||
Map<String, Object> map = new HashMap<String, Object>();
|
||||
map.put("openjpa.DynamicEnhancementAgent", "false");
|
||||
List<Class<?>> types = new ArrayList<Class<?>>();
|
||||
boolean prop = false;
|
||||
|
||||
|
@ -174,7 +174,7 @@ public class CriteriaExpressionBuilder {
|
||||
exps.grouping[i] = Expressions.toValue((ExpressionImpl<?>)groupBy, factory, model, q);;
|
||||
}
|
||||
|
||||
exps.having = having == null ? factory.emptyExpression() : having.toKernelExpression(factory, model, q);
|
||||
exps.having = having == null ? null : having.toKernelExpression(factory, model, q);
|
||||
}
|
||||
|
||||
protected void evalDistinct(QueryExpressions exps, ExpressionFactory factory, CriteriaQueryImpl<?> q) {
|
||||
|
@ -28,7 +28,6 @@ import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.Stack;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
import java.util.concurrent.CopyOnWriteArraySet;
|
||||
|
||||
import javax.persistence.criteria.AbstractQuery;
|
||||
import javax.persistence.criteria.CriteriaQuery;
|
||||
@ -80,7 +79,7 @@ public class CriteriaQueryImpl<T> implements CriteriaQuery<T>, AliasContext {
|
||||
private Boolean _distinct;
|
||||
private SubqueryImpl<?> _delegator;
|
||||
private final Class<T> _resultClass;
|
||||
|
||||
private boolean _compiled;
|
||||
|
||||
// AliasContext
|
||||
private int aliasCount = 0;
|
||||
@ -190,21 +189,8 @@ public class CriteriaQueryImpl<T> implements CriteriaQuery<T>, AliasContext {
|
||||
|
||||
/**
|
||||
* Registers the given parameter.
|
||||
* On registration, an unnamed parameter is assigned an auto-generated
|
||||
* name.
|
||||
*
|
||||
*/
|
||||
public void registerParameter(ParameterExpressionImpl<?> p) {
|
||||
if (_delegator != null) {
|
||||
CriteriaQueryImpl<?> owner = _delegator.getInnermostParent();
|
||||
if (owner != this) {
|
||||
owner.registerParameter(p);
|
||||
}
|
||||
}
|
||||
registerParameterInternal(p);
|
||||
}
|
||||
|
||||
private void registerParameterInternal(ParameterExpressionImpl<?> p) {
|
||||
void registerParameter(ParameterExpressionImpl<?> p) {
|
||||
if (_params == null)
|
||||
_params = new LinkedMap/*<ParameterExpression<?>, Class<?>*/();
|
||||
if (!_params.containsKey(p)) {
|
||||
@ -214,6 +200,7 @@ public class CriteriaQueryImpl<T> implements CriteriaQuery<T>, AliasContext {
|
||||
}
|
||||
|
||||
public Set<ParameterExpression<?>> getParameters() {
|
||||
collectParameters(new CriteriaExpressionVisitor.ParameterVisitor(this));
|
||||
return _params == null ? Collections.EMPTY_SET : _params.keySet();
|
||||
}
|
||||
|
||||
@ -266,11 +253,21 @@ public class CriteriaQueryImpl<T> implements CriteriaQuery<T>, AliasContext {
|
||||
}
|
||||
|
||||
public CriteriaQuery<T> where(Expression<Boolean> restriction) {
|
||||
invalidateCompilation();
|
||||
if (restriction == null) {
|
||||
_where = null;
|
||||
return this;
|
||||
}
|
||||
_where = new PredicateImpl().add(restriction);
|
||||
return this;
|
||||
}
|
||||
|
||||
public CriteriaQuery<T> where(Predicate... restrictions) {
|
||||
invalidateCompilation();
|
||||
if (restrictions == null) {
|
||||
_where = null;
|
||||
return this;
|
||||
}
|
||||
_where = new PredicateImpl();
|
||||
for (Predicate p : restrictions)
|
||||
_where.add(p);
|
||||
@ -340,6 +337,7 @@ public class CriteriaQueryImpl<T> implements CriteriaQuery<T>, AliasContext {
|
||||
* Empty map if no parameter has been declared.
|
||||
*/
|
||||
public LinkedMap getParameterTypes() {
|
||||
collectParameters(new CriteriaExpressionVisitor.ParameterVisitor(this));
|
||||
return _params == null ? StoreQuery.EMPTY_PARAMS : _params;
|
||||
}
|
||||
|
||||
@ -562,5 +560,37 @@ public class CriteriaQueryImpl<T> implements CriteriaQuery<T>, AliasContext {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void invalidateCompilation() {
|
||||
_compiled = false;
|
||||
_params = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compiles to verify that at least one root is defined, a selection term is present
|
||||
* and, most importantly, collects all the parameters so that they can be bound to
|
||||
* the executable query.
|
||||
*/
|
||||
public void compile() {
|
||||
if (_compiled)
|
||||
return;
|
||||
assertRoot();
|
||||
assertSelection();
|
||||
collectParameters(new CriteriaExpressionVisitor.ParameterVisitor(this));
|
||||
_compiled = true;
|
||||
}
|
||||
|
||||
private void collectParameters(CriteriaExpressionVisitor visitor) {
|
||||
if (_compiled)
|
||||
return;
|
||||
if (_where != null) {
|
||||
_where.acceptVisit(visitor);
|
||||
}
|
||||
if (_subqueries != null) {
|
||||
for (Subquery<?> subq : _subqueries) {
|
||||
((SubqueryImpl<?>)subq).getDelegate().collectParameters(visitor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -37,15 +37,22 @@ import org.apache.openjpa.persistence.meta.MetamodelImpl;
|
||||
* @param <X> the type of the value this expression represents.
|
||||
*/
|
||||
public abstract class ExpressionImpl<X> extends SelectionImpl<X>
|
||||
implements Expression<X> {
|
||||
|
||||
abstract Value toValue(ExpressionFactory factory, MetamodelImpl model, CriteriaQueryImpl<?> q);
|
||||
implements CriteriaExpression<X> {
|
||||
abstract org.apache.openjpa.kernel.exps.Value toValue(ExpressionFactory factory, MetamodelImpl model,
|
||||
CriteriaQueryImpl<?> q);
|
||||
|
||||
org.apache.openjpa.kernel.exps.Expression toKernelExpression(ExpressionFactory factory, MetamodelImpl model,
|
||||
CriteriaQueryImpl<?> q) {
|
||||
return factory.asExpression(toValue(factory, model, q));
|
||||
}
|
||||
|
||||
public void acceptVisit(CriteriaExpressionVisitor visitor) {
|
||||
if (!visitor.isVisited(this)) {
|
||||
visitor.enter(this);
|
||||
visitor.exit(this);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param cls the type of the evaluated result of the expression
|
||||
|
@ -63,6 +63,15 @@ public class Expressions {
|
||||
JPQLExpressionBuilder.setImplicitTypes(v1, v2, expected, q.getMetamodel(),
|
||||
q.getParameterTypes(), q.toString());
|
||||
}
|
||||
|
||||
static void acceptVisit(CriteriaExpressionVisitor visitor, Expression<?>...exprs) {
|
||||
if (exprs == null)
|
||||
return;
|
||||
for (Expression<?> e : exprs) {
|
||||
if (e != null)
|
||||
((ExpressionImpl<?>)e).acceptVisit(visitor);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Unary Functional Expression applies a unary function on a input operand Expression.
|
||||
@ -82,6 +91,11 @@ public class Expressions {
|
||||
public UnaryFunctionalExpression(Expression<X> e) {
|
||||
this(e.getJavaType(), e);
|
||||
}
|
||||
|
||||
public void acceptVisit(CriteriaExpressionVisitor visitor) {
|
||||
super.acceptVisit(visitor);
|
||||
Expressions.acceptVisit(visitor, e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -101,6 +115,11 @@ public class Expressions {
|
||||
e1 = (ExpressionImpl<?>)x;
|
||||
e2 = (ExpressionImpl<?>)y;
|
||||
}
|
||||
|
||||
public void acceptVisit(CriteriaExpressionVisitor visitor) {
|
||||
super.acceptVisit(visitor);
|
||||
Expressions.acceptVisit(visitor, e1, e2);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -122,6 +141,11 @@ public class Expressions {
|
||||
this.args[i] = (ExpressionImpl<?>)args[i];
|
||||
}
|
||||
}
|
||||
|
||||
public void acceptVisit(CriteriaExpressionVisitor visitor) {
|
||||
super.acceptVisit(visitor);
|
||||
Expressions.acceptVisit(visitor, args);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -143,6 +167,11 @@ public class Expressions {
|
||||
public PredicateImpl clone() {
|
||||
return new BinaryLogicalExpression(e1, e2);
|
||||
}
|
||||
|
||||
public void acceptVisit(CriteriaExpressionVisitor visitor) {
|
||||
super.acceptVisit(visitor);
|
||||
Expressions.acceptVisit(visitor, e1, e2);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -333,6 +362,11 @@ public class Expressions {
|
||||
from == null ? null : from.toValue(factory, model, q),
|
||||
len == null ? null : len.toValue(factory, model, q));
|
||||
}
|
||||
|
||||
public void acceptVisit(CriteriaExpressionVisitor visitor) {
|
||||
super.acceptVisit(visitor);
|
||||
Expressions.acceptVisit(visitor, from, len);
|
||||
}
|
||||
}
|
||||
|
||||
public static class Locate extends ExpressionImpl<Integer> {
|
||||
@ -376,6 +410,11 @@ public class Expressions {
|
||||
factory.newLiteral(Integer.valueOf(1), Literal.TYPE_NUMBER)))),
|
||||
factory.newLiteral(Integer.valueOf(1), Literal.TYPE_NUMBER));
|
||||
}
|
||||
|
||||
public void acceptVisit(CriteriaExpressionVisitor visitor) {
|
||||
super.acceptVisit(visitor);
|
||||
Expressions.acceptVisit(visitor, pattern, from, path);
|
||||
}
|
||||
}
|
||||
|
||||
public static class Trim extends BinarayFunctionalExpression<String> {
|
||||
@ -721,19 +760,15 @@ public class Expressions {
|
||||
}
|
||||
return factory.newLiteral(value, literalType);
|
||||
}
|
||||
|
||||
public void acceptVisit(CriteriaExpressionVisitor visitor) {
|
||||
super.acceptVisit(visitor);
|
||||
if (arg instanceof CriteriaExpression) {
|
||||
((CriteriaExpression<?>)arg).acceptVisit(visitor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// public static class TypeConstant<X> extends Constant<X> {
|
||||
// public TypeConstant(X x) {
|
||||
// super((Class<X>)x.getClass(),x);
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public Value toValue(ExpressionFactory factory, MetamodelImpl model, CriteriaQueryImpl<?> q) {
|
||||
// return factory.newTypeLiteral(arg, Literal.TYPE_CLASS);
|
||||
// }
|
||||
// }
|
||||
|
||||
public static class IsEmpty extends PredicateImpl {
|
||||
final ExpressionImpl<?> collection;
|
||||
public IsEmpty(Expression<?> collection) {
|
||||
@ -752,6 +787,11 @@ public class Expressions {
|
||||
Value val = Expressions.toValue(collection, factory, model, q);
|
||||
return (isNegated()) ? factory.not(factory.isEmpty(val)) : factory.isEmpty(val);
|
||||
}
|
||||
|
||||
public void acceptVisit(CriteriaExpressionVisitor visitor) {
|
||||
super.acceptVisit(visitor);
|
||||
Expressions.acceptVisit(visitor, collection);
|
||||
}
|
||||
}
|
||||
|
||||
public static class IsNotEmpty extends PredicateImpl {
|
||||
@ -772,6 +812,11 @@ public class Expressions {
|
||||
Value val = Expressions.toValue(collection, factory, model, q);
|
||||
return (isNegated()) ? factory.isEmpty(val) : factory.isNotEmpty(val);
|
||||
}
|
||||
|
||||
public void acceptVisit(CriteriaExpressionVisitor visitor) {
|
||||
super.acceptVisit(visitor);
|
||||
Expressions.acceptVisit(visitor, collection);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -820,6 +865,11 @@ public class Expressions {
|
||||
Expressions.toValue(element, factory, model, q));
|
||||
return _negated ? factory.not(contains) : contains;
|
||||
}
|
||||
|
||||
public void acceptVisit(CriteriaExpressionVisitor visitor) {
|
||||
super.acceptVisit(visitor);
|
||||
Expressions.acceptVisit(visitor, collection, element);
|
||||
}
|
||||
}
|
||||
|
||||
public static class Like extends PredicateImpl {
|
||||
@ -875,6 +925,11 @@ public class Expressions {
|
||||
Expressions.toValue(pattern, factory, model, q),
|
||||
MATCH_SINGLECHAR, MATCH_MULTICHAR, escapeStr);
|
||||
}
|
||||
|
||||
public void acceptVisit(CriteriaExpressionVisitor visitor) {
|
||||
super.acceptVisit(visitor);
|
||||
Expressions.acceptVisit(visitor, str, pattern, escapeChar);
|
||||
}
|
||||
}
|
||||
|
||||
public static class Coalesce<T> extends ExpressionImpl<T> implements QueryBuilder.Coalesce<T> {
|
||||
@ -903,6 +958,11 @@ public class Expressions {
|
||||
vs[i++] = Expressions.toValue((ExpressionImpl<?>)e, factory, model, q);
|
||||
return factory.coalesceExpression(vs);
|
||||
}
|
||||
|
||||
public void acceptVisit(CriteriaExpressionVisitor visitor) {
|
||||
super.acceptVisit(visitor);
|
||||
Expressions.acceptVisit(visitor, values.toArray(new ExpressionImpl[values.size()]));
|
||||
}
|
||||
}
|
||||
|
||||
public static class Nullif<T> extends ExpressionImpl<T> {
|
||||
@ -928,6 +988,11 @@ public class Expressions {
|
||||
Value value2 = Expressions.toValue((ExpressionImpl<?>)val2, factory, model, q);
|
||||
return factory.nullIfExpression(value1, value2);
|
||||
}
|
||||
|
||||
public void acceptVisit(CriteriaExpressionVisitor visitor) {
|
||||
super.acceptVisit(visitor);
|
||||
Expressions.acceptVisit(visitor, val1, val2);
|
||||
}
|
||||
}
|
||||
|
||||
public static class IsNull extends PredicateImpl {
|
||||
@ -949,6 +1014,11 @@ public class Expressions {
|
||||
Expressions.toValue(e, factory, model, q),
|
||||
factory.getNull());
|
||||
}
|
||||
|
||||
public void acceptVisit(CriteriaExpressionVisitor visitor) {
|
||||
super.acceptVisit(visitor);
|
||||
Expressions.acceptVisit(visitor, e);
|
||||
}
|
||||
}
|
||||
|
||||
public static class IsNotNull extends PredicateImpl {
|
||||
@ -970,6 +1040,11 @@ public class Expressions {
|
||||
Expressions.toValue(e, factory, model, q),
|
||||
factory.getNull());
|
||||
}
|
||||
|
||||
public void acceptVisit(CriteriaExpressionVisitor visitor) {
|
||||
super.acceptVisit(visitor);
|
||||
Expressions.acceptVisit(visitor, e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1030,6 +1105,11 @@ public class Expressions {
|
||||
|
||||
return factory.and(inExpr, notNull.toKernelExpression(factory, model, q));
|
||||
}
|
||||
|
||||
public void acceptVisit(CriteriaExpressionVisitor visitor) {
|
||||
super.acceptVisit(visitor);
|
||||
Expressions.acceptVisit(visitor, e);
|
||||
}
|
||||
}
|
||||
|
||||
public static class Case<T> extends ExpressionImpl<T> implements QueryBuilder.Case<T> {
|
||||
@ -1075,6 +1155,13 @@ public class Expressions {
|
||||
Value other = Expressions.toValue((ExpressionImpl<?>)otherwise, factory, model, q);
|
||||
return factory.generalCaseExpression(exps, other);
|
||||
}
|
||||
|
||||
public void acceptVisit(CriteriaExpressionVisitor visitor) {
|
||||
super.acceptVisit(visitor);
|
||||
Expressions.acceptVisit(visitor, thens.toArray(new ExpressionImpl[thens.size()]));
|
||||
Expressions.acceptVisit(visitor, whens.toArray(new ExpressionImpl[whens.size()]));
|
||||
Expressions.acceptVisit(visitor, otherwise);
|
||||
}
|
||||
}
|
||||
|
||||
public static class SimpleCase<C,R> extends ExpressionImpl<R> implements QueryBuilder.SimpleCase<C,R> {
|
||||
@ -1130,6 +1217,13 @@ public class Expressions {
|
||||
Value other = Expressions.toValue((ExpressionImpl<?>)otherwise, factory, model, q);
|
||||
return factory.simpleCaseExpression(caseOperandExpr, exps, other);
|
||||
}
|
||||
|
||||
public void acceptVisit(CriteriaExpressionVisitor visitor) {
|
||||
super.acceptVisit(visitor);
|
||||
Expressions.acceptVisit(visitor, thens.toArray(new ExpressionImpl[thens.size()]));
|
||||
Expressions.acceptVisit(visitor, whens.toArray(new ExpressionImpl[whens.size()]));
|
||||
Expressions.acceptVisit(visitor, otherwise, caseOperand);
|
||||
}
|
||||
}
|
||||
|
||||
public static class Lower extends UnaryFunctionalExpression<String> {
|
||||
@ -1167,13 +1261,39 @@ public class Expressions {
|
||||
return factory.stringLength(Expressions.toValue(e, factory, model, q));
|
||||
}
|
||||
}
|
||||
|
||||
public static class Exists<X> extends PredicateImpl {
|
||||
|
||||
public static abstract class SubqueryPredicate<X> extends PredicateImpl {
|
||||
final SubqueryImpl<X> e;
|
||||
public Exists(Subquery<X> x) {
|
||||
|
||||
public SubqueryPredicate(Subquery<X> x) {
|
||||
super();
|
||||
e = (SubqueryImpl<X>)x;
|
||||
}
|
||||
|
||||
public void acceptVisit(CriteriaExpressionVisitor visitor) {
|
||||
super.acceptVisit(visitor);
|
||||
Expressions.acceptVisit(visitor, e);
|
||||
}
|
||||
}
|
||||
|
||||
public static abstract class SubqueryExpression<X> extends ExpressionImpl<X> {
|
||||
final SubqueryImpl<X> e;
|
||||
|
||||
public SubqueryExpression(Subquery<X> x) {
|
||||
super(x.getJavaType());
|
||||
e = (SubqueryImpl<X>)x;
|
||||
}
|
||||
|
||||
public void acceptVisit(CriteriaExpressionVisitor visitor) {
|
||||
super.acceptVisit(visitor);
|
||||
if (e != null) e.acceptVisit(visitor);
|
||||
}
|
||||
}
|
||||
|
||||
public static class Exists<X> extends SubqueryPredicate<X> {
|
||||
public Exists(Subquery<X> x) {
|
||||
super(x);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PredicateImpl clone() {
|
||||
@ -1189,11 +1309,9 @@ public class Expressions {
|
||||
}
|
||||
}
|
||||
|
||||
public static class All<X> extends ExpressionImpl<X> {
|
||||
final SubqueryImpl<X> e;
|
||||
public static class All<X> extends SubqueryExpression<X> {
|
||||
public All(Subquery<X> x) {
|
||||
super(x.getJavaType());
|
||||
e = (SubqueryImpl<X>)x;
|
||||
super(x);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -1203,11 +1321,9 @@ public class Expressions {
|
||||
}
|
||||
}
|
||||
|
||||
public static class Any<X> extends ExpressionImpl<X> {
|
||||
final SubqueryImpl<X> e;
|
||||
public static class Any<X> extends SubqueryExpression<X> {
|
||||
public Any(Subquery<X> x) {
|
||||
super(x.getJavaType());
|
||||
e = (SubqueryImpl<X>)x;
|
||||
super(x);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -1233,6 +1349,11 @@ public class Expressions {
|
||||
ExpressionFactory factory, MetamodelImpl model, CriteriaQueryImpl<?> q) {
|
||||
return factory.not(super.toKernelExpression(factory, model, q));
|
||||
}
|
||||
|
||||
public void acceptVisit(CriteriaExpressionVisitor visitor) {
|
||||
super.acceptVisit(visitor);
|
||||
Expressions.acceptVisit(visitor, e);
|
||||
}
|
||||
}
|
||||
|
||||
public static class CastAs<Y> extends ExpressionImpl<Y> {
|
||||
@ -1249,6 +1370,11 @@ public class Expressions {
|
||||
e.setImplicitType(getJavaType());
|
||||
return e;
|
||||
}
|
||||
|
||||
public void acceptVisit(CriteriaExpressionVisitor visitor) {
|
||||
super.acceptVisit(visitor);
|
||||
Expressions.acceptVisit(visitor, actual);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1275,6 +1401,11 @@ public class Expressions {
|
||||
e.setImplicitType(getJavaType());
|
||||
return e;
|
||||
}
|
||||
|
||||
public void acceptVisit(CriteriaExpressionVisitor visitor) {
|
||||
super.acceptVisit(visitor);
|
||||
Expressions.acceptVisit(visitor, _args);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -124,6 +124,14 @@ public class PredicateImpl extends ExpressionImpl<Boolean> implements Predicate
|
||||
return _negated ? factory.not(result) : result;
|
||||
}
|
||||
|
||||
public void acceptVisit(CriteriaExpressionVisitor visitor) {
|
||||
if (_exps == null)
|
||||
return;
|
||||
for (Expression<?> e : _exps) {
|
||||
((ExpressionImpl<?>)e).acceptVisit(visitor);
|
||||
}
|
||||
}
|
||||
|
||||
public static class And extends PredicateImpl {
|
||||
public And(Expression<Boolean> x, Expression<Boolean> y) {
|
||||
super(BooleanOperator.AND);
|
||||
|
Loading…
x
Reference in New Issue
Block a user