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

com.blazebit.persistence.impl.builder.predicate.AbstractQuantifiablePredicateBuilder Maven / Gradle / Ivy

/*
 * Copyright 2014 - 2020 Blazebit.
 *
 * 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.blazebit.persistence.impl.builder.predicate;

import com.blazebit.persistence.CaseWhenAndThenBuilder;
import com.blazebit.persistence.CaseWhenBuilder;
import com.blazebit.persistence.CaseWhenOrThenBuilder;
import com.blazebit.persistence.CaseWhenThenBuilder;
import com.blazebit.persistence.CommonQueryBuilder;
import com.blazebit.persistence.FullQueryBuilder;
import com.blazebit.persistence.FullSelectCTECriteriaBuilder;
import com.blazebit.persistence.LeafOngoingFinalSetOperationSubqueryBuilder;
import com.blazebit.persistence.MultipleSubqueryInitiator;
import com.blazebit.persistence.QuantifiableBinaryPredicateBuilder;
import com.blazebit.persistence.RestrictionBuilder;
import com.blazebit.persistence.SimpleCaseWhenBuilder;
import com.blazebit.persistence.StartOngoingSetOperationSubqueryBuilder;
import com.blazebit.persistence.SubqueryBuilder;
import com.blazebit.persistence.SubqueryInitiator;
import com.blazebit.persistence.impl.ClauseType;
import com.blazebit.persistence.impl.MultipleSubqueryInitiatorImpl;
import com.blazebit.persistence.impl.ParameterManager;
import com.blazebit.persistence.impl.SubqueryAndExpressionBuilderListener;
import com.blazebit.persistence.impl.SubqueryInitiatorFactory;
import com.blazebit.persistence.impl.SubqueryInternalBuilder;
import com.blazebit.persistence.impl.builder.expression.CaseWhenBuilderImpl;
import com.blazebit.persistence.impl.builder.expression.ExpressionBuilder;
import com.blazebit.persistence.impl.builder.expression.ExpressionBuilderEndedListener;
import com.blazebit.persistence.impl.builder.expression.SimpleCaseWhenBuilderImpl;
import com.blazebit.persistence.parser.expression.Expression;
import com.blazebit.persistence.parser.expression.ExpressionFactory;
import com.blazebit.persistence.parser.expression.SubqueryExpression;
import com.blazebit.persistence.parser.predicate.BinaryExpressionPredicate;
import com.blazebit.persistence.parser.predicate.Predicate;
import com.blazebit.persistence.parser.predicate.PredicateBuilder;
import com.blazebit.persistence.parser.predicate.PredicateQuantifier;
import com.blazebit.persistence.parser.predicate.QuantifiableBinaryExpressionPredicate;
import com.blazebit.persistence.parser.util.TypeUtils;

import javax.persistence.metamodel.EntityType;
import java.util.Collection;

/**
 *
 * @author Christian Beikov
 * @author Moritz Becker
 * @since 1.0.0
 */
public abstract class AbstractQuantifiablePredicateBuilder extends SubqueryAndExpressionBuilderListener implements QuantifiableBinaryPredicateBuilder, PredicateBuilder {

    protected final Expression leftExpression;
    protected final SubqueryInitiatorFactory subqueryInitFactory;
    protected final ExpressionFactory expressionFactory;

    private final T result;
    private final PredicateBuilderEndedListener listener;
    private final boolean wrapNot;
    private Predicate predicate;
    private final ParameterManager parameterManager;
    private final ClauseType clauseType;
    private SubqueryInitiator subqueryInitiator;

    public AbstractQuantifiablePredicateBuilder(T result, PredicateBuilderEndedListener listener, Expression leftExpression, boolean wrapNot, SubqueryInitiatorFactory subqueryInitFactory, ExpressionFactory expressionFactory, ParameterManager parameterManager, ClauseType clauseType) {
        this.result = result;
        this.listener = listener;
        this.wrapNot = wrapNot;
        this.leftExpression = leftExpression;
        this.subqueryInitFactory = subqueryInitFactory;
        this.expressionFactory = expressionFactory;
        this.parameterManager = parameterManager;
        this.clauseType = clauseType;
    }

    protected abstract QuantifiableBinaryExpressionPredicate createPredicate(Expression left, Expression right, PredicateQuantifier quantifier);

    protected T chain(Predicate predicate) {
        verifyBuilderEnded();
        if (wrapNot) {
            predicate.negate();
        }
        this.predicate = predicate;
        listener.onBuilderEnded(this);
        return result;
    }

    protected void chainSubbuilder(Predicate predicate) {
        verifyBuilderEnded();
        if (wrapNot) {
            predicate.negate();
        }
        this.predicate = predicate;
    }

    @Override
    public CommonQueryBuilder getParentQueryBuilder() {
        return (CommonQueryBuilder) subqueryInitFactory.getQueryBuilder();
    }

    @Override
    public T value(Object value) {
        return chain(createPredicate(leftExpression, parameterManager.addParameterExpression(value, clauseType, subqueryInitFactory.getQueryBuilder()), PredicateQuantifier.ONE));
    }

    @Override
    public T literal(Object value) {
        String literal = TypeUtils.asLiteral(value, subqueryInitFactory.getQueryBuilder().getMetamodel().getEnumTypes().keySet());
        if (literal == null) {
            return value(value);
        }
        return chain(createPredicate(leftExpression, expressionFactory.createInItemExpression(literal), PredicateQuantifier.ONE));
    }

    @Override
    public T expression(String expression) {
        return chain(createPredicate(leftExpression, expressionFactory.createSimpleExpression(expression, false), PredicateQuantifier.ONE));
    }

    @Override
    public MultipleSubqueryInitiator subqueries(String expression) {
        return new MultipleSubqueryInitiatorImpl(result, expressionFactory.createSimpleExpression(expression, true), new ExpressionBuilderEndedListener() {
            
            @Override
            public void onBuilderEnded(ExpressionBuilder builder) {
                chain(createPredicate(leftExpression, builder.getExpression(), PredicateQuantifier.ONE));
            }
            
        }, subqueryInitFactory, clauseType);
    }

    /* case when functions */
    @Override
    public RestrictionBuilder>> caseWhen(String expression) {
        chainSubbuilder(createPredicate(leftExpression, null, PredicateQuantifier.ONE));
        return startBuilder(new CaseWhenBuilderImpl(result, this, subqueryInitFactory, expressionFactory, parameterManager, clauseType)).when(expression);
    }

    @Override
    public CaseWhenAndThenBuilder> caseWhenAnd() {
        chainSubbuilder(createPredicate(leftExpression, null, PredicateQuantifier.ONE));
        return startBuilder(new CaseWhenBuilderImpl(result, this, subqueryInitFactory, expressionFactory, parameterManager, clauseType)).whenAnd();
    }

    @Override
    public SubqueryInitiator>> caseWhenExists() {
        chainSubbuilder(createPredicate(leftExpression, null, PredicateQuantifier.ONE));
        return startBuilder(new CaseWhenBuilderImpl(result, this, subqueryInitFactory, expressionFactory, parameterManager, clauseType)).whenExists();
    }

    @Override
    public SubqueryInitiator>> caseWhenNotExists() {
        chainSubbuilder(createPredicate(leftExpression, null, PredicateQuantifier.ONE));
        return startBuilder(new CaseWhenBuilderImpl(result, this, subqueryInitFactory, expressionFactory, parameterManager, clauseType)).whenNotExists();
    }

    @Override
    public SubqueryBuilder>> caseWhenExists(FullQueryBuilder criteriaBuilder) {
        chainSubbuilder(createPredicate(leftExpression, null, PredicateQuantifier.ONE));
        return startBuilder(new CaseWhenBuilderImpl(result, this, subqueryInitFactory, expressionFactory, parameterManager, clauseType)).whenExists(criteriaBuilder);
    }

    @Override
    public SubqueryBuilder>> caseWhenNotExists(FullQueryBuilder criteriaBuilder) {
        chainSubbuilder(createPredicate(leftExpression, null, PredicateQuantifier.ONE));
        return startBuilder(new CaseWhenBuilderImpl(result, this, subqueryInitFactory, expressionFactory, parameterManager, clauseType)).whenNotExists(criteriaBuilder);
    }

    @Override
    public SubqueryInitiator>>> caseWhenSubquery() {
        chainSubbuilder(createPredicate(leftExpression, null, PredicateQuantifier.ONE));
        return startBuilder(new CaseWhenBuilderImpl(result, this, subqueryInitFactory, expressionFactory, parameterManager, clauseType)).whenSubquery();
    }

    @Override
    public SubqueryInitiator>>> caseWhenSubquery(String subqueryAlias, String expression) {
        chainSubbuilder(createPredicate(leftExpression, null, PredicateQuantifier.ONE));
        return startBuilder(new CaseWhenBuilderImpl(result, this, subqueryInitFactory, expressionFactory, parameterManager, clauseType)).whenSubquery(subqueryAlias, expression);
    }

    @Override
    public MultipleSubqueryInitiator>>> caseWhenSubqueries(String expression) {
        chainSubbuilder(createPredicate(leftExpression, null, PredicateQuantifier.ONE));
        return startBuilder(new CaseWhenBuilderImpl(result, this, subqueryInitFactory, expressionFactory, parameterManager, clauseType)).whenSubqueries(expression);
    }

    @Override
    public SubqueryBuilder>>> caseWhenSubquery(FullQueryBuilder criteriaBuilder) {
        chainSubbuilder(createPredicate(leftExpression, null, PredicateQuantifier.ONE));
        return startBuilder(new CaseWhenBuilderImpl(result, this, subqueryInitFactory, expressionFactory, parameterManager, clauseType)).whenSubquery(criteriaBuilder);
    }

    @Override
    public SubqueryBuilder>>> caseWhenSubquery(String subqueryAlias, String expression, FullQueryBuilder criteriaBuilder) {
        chainSubbuilder(createPredicate(leftExpression, null, PredicateQuantifier.ONE));
        return startBuilder(new CaseWhenBuilderImpl(result, this, subqueryInitFactory, expressionFactory, parameterManager, clauseType)).whenSubquery(subqueryAlias, expression, criteriaBuilder);
    }

    @Override
    public CaseWhenOrThenBuilder> caseWhenOr() {
        chainSubbuilder(createPredicate(leftExpression, null, PredicateQuantifier.ONE));
        return startBuilder(new CaseWhenBuilderImpl(result, this, subqueryInitFactory, expressionFactory, parameterManager, clauseType)).whenOr();
    }

    @Override
    public SimpleCaseWhenBuilder simpleCase(String caseOperand) {
        chainSubbuilder(createPredicate(leftExpression, null, PredicateQuantifier.ONE));
        return startBuilder(new SimpleCaseWhenBuilderImpl(result, this, expressionFactory, expressionFactory.createSimpleExpression(caseOperand, false), subqueryInitFactory, parameterManager, clauseType));
    }

    /* quantification functions */
    @Override
    public SubqueryInitiator all() {
        chainSubbuilder(createPredicate(leftExpression, null, PredicateQuantifier.ALL));
        return subqueryInitFactory.createSubqueryInitiator(result, this, false, clauseType);
    }

    @Override
    public SubqueryInitiator any() {
        chainSubbuilder(createPredicate(leftExpression, null, PredicateQuantifier.ANY));
        return subqueryInitFactory.createSubqueryInitiator(result, this, false, clauseType);
    }

    @Override
    public SubqueryBuilder all(FullQueryBuilder criteriaBuilder) {
        chainSubbuilder(createPredicate(leftExpression, null, PredicateQuantifier.ALL));
        return subqueryInitFactory.createSubqueryBuilder(result, this, false, criteriaBuilder, clauseType);
    }

    @Override
    public SubqueryBuilder any(FullQueryBuilder criteriaBuilder) {
        chainSubbuilder(createPredicate(leftExpression, null, PredicateQuantifier.ANY));
        return subqueryInitFactory.createSubqueryBuilder(result, this, false, criteriaBuilder, clauseType);
    }

    public SubqueryBuilder one(FullQueryBuilder criteriaBuilder) {
        chainSubbuilder(createPredicate(leftExpression, null, PredicateQuantifier.ONE));
        return subqueryInitFactory.createSubqueryBuilder(result, this, false, criteriaBuilder, clauseType);
    }

    @Override
    public SubqueryBuilder from(Class clazz) {
        chainSubbuilder(createPredicate(leftExpression, null, PredicateQuantifier.ONE));
        return getSubqueryInitiator().from(clazz);
    }

    @Override
    public SubqueryBuilder from(Class clazz, String alias) {
        chainSubbuilder(createPredicate(leftExpression, null, PredicateQuantifier.ONE));
        return getSubqueryInitiator().from(clazz, alias);
    }

    @Override
    public SubqueryBuilder from(EntityType entityType) {
        chainSubbuilder(createPredicate(leftExpression, null, PredicateQuantifier.ONE));
        return getSubqueryInitiator().from(entityType);
    }

    @Override
    public SubqueryBuilder from(EntityType entityType, String alias) {
        chainSubbuilder(createPredicate(leftExpression, null, PredicateQuantifier.ONE));
        return getSubqueryInitiator().from(entityType, alias);
    }

    @Override
    public SubqueryBuilder from(String correlationPath) {
        chainSubbuilder(createPredicate(leftExpression, null, PredicateQuantifier.ONE));
        return getSubqueryInitiator().from(correlationPath);
    }

    @Override
    public SubqueryBuilder from(String correlationPath, String alias) {
        chainSubbuilder(createPredicate(leftExpression, null, PredicateQuantifier.ONE));
        return getSubqueryInitiator().from(correlationPath, alias);
    }

    @Override
    public StartOngoingSetOperationSubqueryBuilder> startSet() {
        return getSubqueryInitiator().startSet();
    }

    @Override
    public SubqueryBuilder fromOld(Class entityClass) {
        chainSubbuilder(createPredicate(leftExpression, null, PredicateQuantifier.ONE));
        return getSubqueryInitiator().fromOld(entityClass);
    }

    @Override
    public SubqueryBuilder fromOld(Class entityClass, String alias) {
        chainSubbuilder(createPredicate(leftExpression, null, PredicateQuantifier.ONE));
        return getSubqueryInitiator().fromOld(entityClass, alias);
    }

    @Override
    public SubqueryBuilder fromNew(Class entityClass) {
        chainSubbuilder(createPredicate(leftExpression, null, PredicateQuantifier.ONE));
        return getSubqueryInitiator().fromNew(entityClass);
    }

    @Override
    public SubqueryBuilder fromNew(Class entityClass, String alias) {
        chainSubbuilder(createPredicate(leftExpression, null, PredicateQuantifier.ONE));
        return getSubqueryInitiator().fromNew(entityClass, alias);
    }

    @Override
    public SubqueryBuilder fromValues(Class valueClass, String alias, int valueCount) {
        chainSubbuilder(createPredicate(leftExpression, null, PredicateQuantifier.ONE));
        return getSubqueryInitiator().fromValues(valueClass, alias, valueCount);
    }

    @Override
    public SubqueryBuilder fromValues(Class entityBaseClass, String attributeName, String alias, int valueCount) {
        chainSubbuilder(createPredicate(leftExpression, null, PredicateQuantifier.ONE));
        return getSubqueryInitiator().fromValues(entityBaseClass, attributeName, alias, valueCount);
    }

    @Override
    public SubqueryBuilder fromIdentifiableValues(Class valueClass, String alias, int valueCount) {
        chainSubbuilder(createPredicate(leftExpression, null, PredicateQuantifier.ONE));
        return getSubqueryInitiator().fromIdentifiableValues(valueClass, alias, valueCount);
    }

    @Override
    public SubqueryBuilder fromIdentifiableValues(Class valueClass, String identifierAttribute, String alias, int valueCount) {
        chainSubbuilder(createPredicate(leftExpression, null, PredicateQuantifier.ONE));
        return getSubqueryInitiator().fromIdentifiableValues(valueClass, identifierAttribute, alias, valueCount);
    }

    @Override
    public  SubqueryBuilder fromValues(Class valueClass, String alias, Collection values) {
        chainSubbuilder(createPredicate(leftExpression, null, PredicateQuantifier.ONE));
        return getSubqueryInitiator().fromValues(valueClass, alias, values);
    }

    @Override
    public SubqueryBuilder fromValues(Class entityBaseClass, String attributeName, String alias, Collection values) {
        chainSubbuilder(createPredicate(leftExpression, null, PredicateQuantifier.ONE));
        return getSubqueryInitiator().fromValues(entityBaseClass, attributeName, alias, values);
    }

    @Override
    public  SubqueryBuilder fromIdentifiableValues(Class valueClass, String alias, Collection values) {
        chainSubbuilder(createPredicate(leftExpression, null, PredicateQuantifier.ONE));
        return getSubqueryInitiator().fromIdentifiableValues(valueClass, alias, values);
    }

    @Override
    public  SubqueryBuilder fromIdentifiableValues(Class valueClass, String identifierAttribute, String alias, Collection values) {
        chainSubbuilder(createPredicate(leftExpression, null, PredicateQuantifier.ONE));
        return getSubqueryInitiator().fromIdentifiableValues(valueClass, identifierAttribute, alias, values);
    }

    @Override
    public FullSelectCTECriteriaBuilder> fromSubquery(Class cteClass) {
        chainSubbuilder(createPredicate(leftExpression, null, PredicateQuantifier.ONE));
        return getSubqueryInitiator().fromSubquery(cteClass);
    }

    @Override
    public FullSelectCTECriteriaBuilder> fromSubquery(Class cteClass, String alias) {
        chainSubbuilder(createPredicate(leftExpression, null, PredicateQuantifier.ONE));
        return getSubqueryInitiator().fromSubquery(cteClass, alias);
    }

    @Override
    public FullSelectCTECriteriaBuilder> fromEntitySubquery(Class cteClass) {
        chainSubbuilder(createPredicate(leftExpression, null, PredicateQuantifier.ONE));
        return getSubqueryInitiator().fromEntitySubquery(cteClass);
    }

    @Override
    public FullSelectCTECriteriaBuilder> fromEntitySubquery(Class cteClass, String alias) {
        chainSubbuilder(createPredicate(leftExpression, null, PredicateQuantifier.ONE));
        return getSubqueryInitiator().fromEntitySubquery(cteClass, alias);
    }

    @Override
    public FullSelectCTECriteriaBuilder> fromEntitySubquery(Class cteClass, String alias, String subqueryAlias) {
        chainSubbuilder(createPredicate(leftExpression, null, PredicateQuantifier.ONE));
        return getSubqueryInitiator().fromEntitySubquery(cteClass, alias, subqueryAlias);
    }

    @Override
    public void onBuilderEnded(SubqueryInternalBuilder builder) {
        super.onBuilderEnded(builder);
        // set the finished subquery builder on the previously created predicate
        if (predicate instanceof BinaryExpressionPredicate) {
            ((BinaryExpressionPredicate) predicate).setRight(new SubqueryExpression(builder));
        } else {
            throw new IllegalStateException("SubqueryBuilder ended but predicate type was unexpected");
        }

        listener.onBuilderEnded(this);
    }

    @Override
    public Predicate getPredicate() {
        return predicate;
    }

    protected SubqueryInitiator getSubqueryInitiator() {
        if (subqueryInitiator == null) {
            subqueryInitiator = subqueryInitFactory.createSubqueryInitiator(result, this, false, clauseType);
        }
        return subqueryInitiator;
    }

    @Override
    public void onBuilderEnded(ExpressionBuilder builder) {
        super.onBuilderEnded(builder);
        if (predicate instanceof BinaryExpressionPredicate) {
            ((BinaryExpressionPredicate) predicate).setRight(builder.getExpression());
        } else {
            throw new IllegalStateException("ExpressionBuilder ended but predicate type was unexpected");
        }

        listener.onBuilderEnded(AbstractQuantifiablePredicateBuilder.this);
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy