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

org.ibatis.persist.impl.predicate.CompoundPredicate Maven / Gradle / Ivy

Go to download

The jBATIS persistence framework will help you to significantly reduce the amount of Java code that you normally need to access a relational database. iBATIS simply maps JavaBeans to SQL statements using a very simple XML descriptor.

The newest version!
package org.ibatis.persist.impl.predicate;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.ibatis.persist.criteria.Expression;
import org.ibatis.persist.criteria.Predicate;

import org.ibatis.persist.impl.CriteriaBuilderImpl;
import org.ibatis.persist.impl.Renderable;
import org.ibatis.persist.impl.RenderingContext;

/**
 * A compound {@link Predicate predicate} is a grouping of other {@link Predicate predicates} in order to convert
 * either a conjunction (logical AND) or a disjunction (logical OR).
 */
@SuppressWarnings("unchecked")
public class CompoundPredicate
		extends AbstractPredicateImpl {
	private BooleanOperator operator;
	private final List> expressions = new ArrayList>();

	/**
	 * Constructs an empty conjunction or disjunction.
	 *
	 * @param criteriaBuilder The query builder from which this originates.
	 * @param operator Indicates whether this predicate will function
	 * as a conjunction or disjunction.
	 */
	public CompoundPredicate(CriteriaBuilderImpl criteriaBuilder, BooleanOperator operator) {
		super( criteriaBuilder );
		this.operator = operator;
	}

	/**
	 * Constructs a conjunction or disjunction over the given expressions.
	 *
	 * @param criteriaBuilder The query builder from which this originates.
	 * @param operator Indicates whether this predicate will function
	 * as a conjunction or disjunction.
	 * @param expressions The expressions to be grouped.
	 */
	public CompoundPredicate(
			CriteriaBuilderImpl criteriaBuilder,
			BooleanOperator operator,
			Expression... expressions) {
		this( criteriaBuilder, operator );
		applyExpressions( expressions );
	}

	/**
	 * Constructs a conjunction or disjunction over the given expressions.
	 *
	 * @param criteriaBuilder The query builder from which this originates.
	 * @param operator Indicates whether this predicate will function
	 * as a conjunction or disjunction.
	 * @param expressions The expressions to be grouped.
	 */
	public CompoundPredicate(
			CriteriaBuilderImpl criteriaBuilder,
			BooleanOperator operator,
			List> expressions) {
		this( criteriaBuilder, operator );
		applyExpressions( expressions );
	}

	private void applyExpressions(Expression... expressions) {
		applyExpressions( Arrays.asList( expressions ) );
	}

	private void applyExpressions(List> expressions) {
		this.expressions.clear();
		this.expressions.addAll( expressions );
	}

	@Override
	public BooleanOperator getOperator() {
		return operator;
	}

	@Override
	public List> getExpressions() {
		return expressions;
	}

	@Override
    public void render(RenderingContext rc) {
        render(isNegated(), rc);
    }

	@Override
	public boolean isJunction() {
		return true;
	}

	@Override
    public void render(boolean isNegated, RenderingContext rc) {
        render(this, rc);
    }

	@Override
    public void renderProjection(RenderingContext rc) {
        render(rc);
    }

	/**
	 * Create negation of compound predicate by using logic rules:
	 * 1. not (x || y) is (not x && not y)
	 * 2. not (x && y) is (not x || not y)
	 */
	@Override
	public Predicate not() {
		return new NegatedPredicateWrapper( this );
	}

	public static BooleanOperator reverseOperator(BooleanOperator operator) {
		return operator == BooleanOperator.AND
				? BooleanOperator.OR
				: BooleanOperator.AND;
	}

    public static void render(PredicateImplementor predicate, RenderingContext rc) {
        if (!predicate.isJunction()) {
            throw new IllegalStateException("CompoundPredicate.render should only be used to render junctions");
        }

        // for junctions, the negation is already cooked into the expressions and operator; we just need to render
        // them as is

        if (predicate.getExpressions().isEmpty()) {
            boolean implicitTrue = predicate.getOperator() == BooleanOperator.AND;
            // AND is always true for empty; OR is always false
            rc.append(implicitTrue ? "1=1" : "0=1");
            return;
        }

        // single valued junction ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        if (predicate.getExpressions().size() == 1) {
            ((Renderable) predicate.getExpressions().get(0)).render(rc);
            return;
        }

        String sep = "";
        for (Expression expression : predicate.getExpressions()) {
            rc.append(sep).append("( ");
            ((Renderable) expression).render(rc);
            rc.append(" )");
            sep = operatorTextWithSeparator(predicate.getOperator());
        }
    }

	private static String operatorTextWithSeparator(BooleanOperator operator) {
		return operator == BooleanOperator.AND
				? " and "
				: " or ";
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy