All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.querydsl.core.DefaultQueryMetadata Maven / Gradle / Ivy

The newest version!
/*
 * 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.querydsl.core;

import static com.querydsl.core.util.CollectionUtils.addSorted;
import static com.querydsl.core.util.CollectionUtils.copyOf;
import static com.querydsl.core.util.CollectionUtils.copyOfSorted;
import static com.querydsl.core.util.CollectionUtils.put;
import static com.querydsl.core.util.CollectionUtils.removeSorted;

import com.querydsl.core.types.Expression;
import com.querydsl.core.types.ExpressionUtils;
import com.querydsl.core.types.OrderSpecifier;
import com.querydsl.core.types.ParamExpression;
import com.querydsl.core.types.ParamsVisitor;
import com.querydsl.core.types.Path;
import com.querydsl.core.types.Predicate;
import com.querydsl.core.types.ValidatingVisitor;
import com.querydsl.core.util.CollectionUtils;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import org.jetbrains.annotations.Nullable;

/**
 * {@code DefaultQueryMetadata} is the default implementation of the {@link QueryMetadata}
 * interface.
 *
 * 

{@code DefaultQueryMetadata} is mutable, but {@link DefaultQueryMetadata#clone()} can be used * to created deep copies to refine the state without modifying the initial instance. * * @author tiwe */ public class DefaultQueryMetadata implements QueryMetadata, Cloneable { private static final long serialVersionUID = 317736313966701232L; private boolean distinct; private Set> exprInJoins = new LinkedHashSet<>(); private List> groupBy = new ArrayList<>(); @Nullable private Predicate having; private List joins = new ArrayList<>(); private Expression joinTarget; private JoinType joinType; @Nullable private Predicate joinCondition; private Set joinFlags = new LinkedHashSet<>(); private QueryModifiers modifiers = QueryModifiers.EMPTY; private List> orderBy = new ArrayList<>(); @Nullable private Expression projection; // NOTE : this is not necessarily serializable private Map, Object> params = new LinkedHashMap<>(); private boolean unique; @Nullable private Predicate where; private Set flags = new LinkedHashSet<>(); private boolean extractParams = true; private boolean validate = false; 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 the current object */ public DefaultQueryMetadata noValidate() { validate = false; return this; } @Override public void addFlag(QueryFlag flag) { flags = addSorted(flags, flag); } @Override public void addJoinFlag(JoinFlag flag) { joinFlags.add(flag); } @Override public void addGroupBy(Expression o) { // group by elements can't be validated, since they can refer to projection elements // that are declared later groupBy.add(o); } @Override public void addHaving(Predicate e) { 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) { joins.add( new JoinExpression( joinType, joinTarget, joinCondition, CollectionUtils.unmodifiableSet(joinFlags))); joinType = null; joinTarget = null; joinCondition = null; joinFlags.clear(); } } @Override public void addJoin(JoinType joinType, Expression expr) { addLastJoin(); if (!exprInJoins.contains(expr)) { if (expr instanceof Path && ((Path) expr).getMetadata().isRoot()) { exprInJoins.add(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) { // order specifiers can't be validated, since they can refer to projection elements // that are declared later orderBy.add(o); } @Override public void setProjection(Expression o) { validate(o); projection = o; } @Override public void addWhere(Predicate e) { if (e == null) { return; } e = (Predicate) ExpressionUtils.extract(e); if (e != null) { validate(e); where = and(where, e); } } @Override public void clearOrderBy() { orderBy.clear(); } @Override public void clearWhere() { where = new BooleanBuilder(); } @Override public QueryMetadata clone() { try { var clone = (DefaultQueryMetadata) super.clone(); clone.exprInJoins = copyOf(exprInJoins); clone.groupBy = copyOf(groupBy); clone.having = having; clone.joins = copyOf(joins); clone.joinTarget = joinTarget; clone.joinCondition = joinCondition; clone.joinFlags = copyOf(joinFlags); clone.joinType = joinType; clone.modifiers = modifiers; clone.orderBy = copyOf(orderBy); clone.projection = 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 Collections.unmodifiableList(groupBy); } @Override public Predicate getHaving() { return having; } @Override public List getJoins() { if (joinTarget == null) { return Collections.unmodifiableList(joins); } else { List j = new ArrayList<>(joins); j.add( new JoinExpression( joinType, joinTarget, joinCondition, Collections.unmodifiableSet(new HashSet<>(joinFlags)))); return j; } } @Override public QueryModifiers getModifiers() { return modifiers; } @Override public Map, Object> getParams() { return Collections.unmodifiableMap(params); } @Override public List> getOrderBy() { return Collections.unmodifiableList(orderBy); } @Override public Expression 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() { params = new LinkedHashMap<>(); 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(QueryModifiers restriction) { if (restriction == null) { throw new NullPointerException(); } 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) { var q = (QueryMetadata) o; return q.getFlags().equals(flags) && q.getGroupBy().equals(groupBy) && Objects.equals(q.getHaving(), having) && q.isDistinct() == distinct && q.isUnique() == unique && q.getJoins().equals(getJoins()) && q.getModifiers().equals(modifiers) && q.getOrderBy().equals(orderBy) && q.getParams().equals(params) && Objects.equals(q.getProjection(), projection) && Objects.equals(q.getWhere(), where); } else { return false; } } @Override public int hashCode() { return Objects.hash( flags, groupBy, having, getJoins(), modifiers, orderBy, params, projection, unique, where); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy