com.mysema.query.DefaultQueryMetadata Maven / Gradle / Ivy
/*
* Copyright 2015, The Querydsl Team (http://www.querydsl.com/team)
*
* Licensed 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 com.mysema.query;
import javax.annotation.Nullable;
import java.util.List;
import java.util.Map;
import java.util.Set;
import com.google.common.base.Objects;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.mysema.query.types.*;
import static com.mysema.query.util.CollectionUtils.*;
/**
* DefaultQueryMetadata is the default implementation of the {@link QueryMetadata} interface
*
* @author tiwe
*/
public class DefaultQueryMetadata implements QueryMetadata, Cloneable {
private static final long serialVersionUID = 317736313966701232L;
private boolean distinct;
private Set> exprInJoins = ImmutableSet.of();
private List> groupBy = ImmutableList.of();
@Nullable
private Predicate having;
private List joins = ImmutableList.of();
private Expression> joinTarget;
private JoinType joinType;
@Nullable
private Predicate joinCondition;
private Set joinFlags = ImmutableSet.of();
@Nullable
private QueryModifiers modifiers = QueryModifiers.EMPTY;
private List> orderBy = ImmutableList.of();
private List> projection = ImmutableList.of();
// NOTE : this is not necessarily serializable
private Map,Object> params = ImmutableMap., Object>of();
private boolean unique;
@Nullable
private Predicate where;
private Set flags = ImmutableSet.of();
private boolean extractParams = true;
private boolean validate = true;
private ValidatingVisitor validatingVisitor = ValidatingVisitor.DEFAULT;
private static Predicate and(Predicate lhs, Predicate rhs) {
if (lhs == null) {
return rhs;
} else {
return ExpressionUtils.and(lhs, rhs);
}
}
/**
* Create an empty DefaultQueryMetadata instance
*/
public DefaultQueryMetadata() {}
/**
* Disable validation
*
* @return
*/
public DefaultQueryMetadata noValidate() {
validate = false;
return this;
}
@Override
public void addFlag(QueryFlag flag) {
flags = addSorted(flags, flag);
}
@Override
public void addJoinFlag(JoinFlag flag) {
joinFlags = addSorted(joinFlags, flag);
}
@Override
public void addGroupBy(Expression> o) {
addLastJoin();
// group by elements can't be validated, since they can refer to projection elements
// that are declared later
groupBy = add(groupBy, o);
}
@Override
public void addHaving(Predicate e) {
addLastJoin();
if (e == null) {
return;
}
e = (Predicate)ExpressionUtils.extract(e);
if (e != null) {
// having elements can't be validated, since they can refer to projection elements
// that are declared later
having = and(having, e);
}
}
private void addLastJoin() {
if (joinTarget == null) {
return;
}
joins = add(joins, new JoinExpression(joinType, joinTarget, joinCondition, joinFlags));
joinType = null;
joinTarget = null;
joinCondition = null;
joinFlags = ImmutableSet.of();
}
@Override
public void addJoin(JoinType joinType, Expression> expr) {
addLastJoin();
if (!exprInJoins.contains(expr)) {
if (expr instanceof Path && ((Path>)expr).getMetadata().isRoot()) {
exprInJoins = add(exprInJoins, expr);
} else {
validate(expr);
}
this.joinType = joinType;
this.joinTarget = expr;
} else if (validate) {
throw new IllegalStateException(expr + " is already used");
}
}
@Override
public void addJoinCondition(Predicate o) {
validate(o);
joinCondition = and(joinCondition, o);
}
@Override
public void addOrderBy(OrderSpecifier> o) {
addLastJoin();
// order specifiers can't be validated, since they can refer to projection elements
// that are declared later
orderBy = add(orderBy, o);
}
@Override
public void addProjection(Expression> o) {
addLastJoin();
validate(o);
projection = add(projection, o);
}
@Override
public void addWhere(Predicate e) {
if (e == null) {
return;
}
addLastJoin();
e = (Predicate)ExpressionUtils.extract(e);
if (e != null) {
validate(e);
where = and(where, e);
}
}
@Override
public void clearOrderBy() {
orderBy = ImmutableList.of();
}
@Override
public void clearProjection() {
projection = ImmutableList.of();
}
@Override
public void clearWhere() {
where = new BooleanBuilder();
}
@Override
public QueryMetadata clone() {
try {
addLastJoin();
DefaultQueryMetadata clone = (DefaultQueryMetadata) super.clone();
clone.exprInJoins = copyOf(exprInJoins);
clone.groupBy = copyOf(groupBy);
clone.having = having;
clone.joins = copyOf(joins);
clone.modifiers = modifiers;
clone.orderBy = copyOf(orderBy);
clone.projection = copyOf(projection);
clone.params = copyOf(params);
clone.where = where;
clone.flags = copyOfSorted(flags);
return clone;
} catch (CloneNotSupportedException e) {
throw new QueryException(e);
}
}
@Override
public List> getGroupBy() {
return groupBy;
}
@Override
public Predicate getHaving() {
return having;
}
@Override
public List getJoins() {
addLastJoin();
return joins;
}
@Override
@Nullable
public QueryModifiers getModifiers() {
return modifiers;
}
@Override
public Map,Object> getParams() {
return params;
}
@Override
public List> getOrderBy() {
return orderBy;
}
@Override
public List> getProjection() {
return projection;
}
@Override
public Predicate getWhere() {
return where;
}
@Override
public boolean isDistinct() {
return distinct;
}
@Override
public boolean isUnique() {
return unique;
}
@Override
public void reset() {
clearProjection();
params = ImmutableMap.of();
modifiers = QueryModifiers.EMPTY;
}
@Override
public void setDistinct(boolean distinct) {
this.distinct = distinct;
}
@Override
public void setLimit(Long limit) {
if (modifiers == null || modifiers.getOffset() == null) {
modifiers = QueryModifiers.limit(limit);
} else {
modifiers = new QueryModifiers(limit, modifiers.getOffset());
}
}
@Override
public void setModifiers(@Nullable QueryModifiers restriction) {
this.modifiers = restriction;
}
@Override
public void setOffset(Long offset) {
if (modifiers == null || modifiers.getLimit() == null) {
modifiers = QueryModifiers.offset(offset);
} else {
modifiers = new QueryModifiers(modifiers.getLimit(), offset);
}
}
@Override
public void setUnique(boolean unique) {
this.unique = unique;
}
@Override
public void setParam(ParamExpression param, T value) {
params = put(params, param, value);
}
@Override
public Set getFlags() {
return flags;
}
@Override
public boolean hasFlag(QueryFlag flag) {
return flags.contains(flag);
}
@Override
public void removeFlag(QueryFlag flag) {
flags = removeSorted(flags, flag);
}
private void validate(Expression> expr) {
if (extractParams) {
expr.accept(ParamsVisitor.DEFAULT, this);
}
if (validate) {
exprInJoins = expr.accept(validatingVisitor, exprInJoins);
}
}
@Override
public void setValidate(boolean v) {
this.validate = v;
}
public void setValidatingVisitor(ValidatingVisitor visitor) {
this.validatingVisitor = visitor;
}
@Override
public boolean equals(Object o) {
if (o instanceof QueryMetadata) {
addLastJoin();
QueryMetadata q = (QueryMetadata)o;
return q.getFlags().equals(flags)
&& q.getGroupBy().equals(groupBy)
&& Objects.equal(q.getHaving(), having)
&& q.isDistinct() == distinct
&& q.isUnique() == unique
&& q.getJoins().equals(joins)
&& Objects.equal(q.getModifiers(), modifiers)
&& q.getOrderBy().equals(orderBy)
&& q.getParams().equals(params)
&& q.getProjection().equals(projection)
&& Objects.equal(q.getWhere(), where);
} else {
return false;
}
}
@Override
public int hashCode() {
addLastJoin();
return Objects.hashCode(flags, groupBy, having, joins, modifiers,
orderBy, params, projection, unique, where);
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy