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

org.apache.openjpa.persistence.criteria.PredicateImpl Maven / Gradle / Ivy

There is a newer version: 4.0.1
Show newest version
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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 org.apache.openjpa.persistence.criteria;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;

import javax.persistence.criteria.Expression;
import javax.persistence.criteria.Predicate;

import org.apache.openjpa.kernel.exps.ExpressionFactory;
import org.apache.openjpa.kernel.exps.Literal;

/**
 * Predicate is a expression that evaluates to true or false.
 * All boolean expressions are implemented as Predicate.
 * A predicate can have zero or more predicate arguments.
 * Default predicate operator is AND (conjunction).
 * Two constant predicates are Predicate.TRUE and Predicate.FALSE.
 * AND predicate with no argument evaluates to TRUE.
 * OR predicate with no argument evaluates to FALSE.
 * Negation of a Predicate creates a new Predicate.
 *
 * @author Pinaki Poddar
 * @author Fay Wang
 *
 * @since 2.0.0
 */
abstract class PredicateImpl extends ExpressionImpl implements Predicate {
    static final Expression TRUE_CONSTANT = new Expressions.Constant<>(true);
    static final Expression FALSE_CONSTANT = new Expressions.Constant<>(false);

    private static Predicate TRUE;
    private static Predicate FALSE;

    protected final List _exps = Collections.synchronizedList(new ArrayList<>());
    private final BooleanOperator _op;
    private boolean _negated = false;

    /**
     * An AND predicate with no arguments.
     */
    protected PredicateImpl() {
        this(BooleanOperator.AND);
    }

    /**
     * A predicate with the given operator.
     */
    protected PredicateImpl(BooleanOperator op) {
        super(Boolean.class);
        _op = op;
    }

    /**
     * A predicate of given operator with given arguments.
     */
    protected PredicateImpl(BooleanOperator op, Predicate...restrictions) {
        this(op);
        if (restrictions == null || restrictions.length == 0) return;

    	for (Predicate p : restrictions) {
   			add(p);
    	}
    }

    /**
     * Adds the given predicate expression.
     */
    public PredicateImpl add(Expression s) {
    	synchronized (_exps) {
        	_exps.add((Predicate)s); // all boolean expressions are Predicate
		}
        return this;
    }

    @Override
    public List> getExpressions() {
        List> result = new CopyOnWriteArrayList<>();
        if (_exps.isEmpty())
            return result;
        result.addAll(_exps);
        return result;
    }

    @Override
    public final BooleanOperator getOperator() {
        return _op;
    }

    public final boolean isEmpty() {
        return _exps.isEmpty();
    }

    /**
     * Is this predicate created by negating another predicate?
     */
    @Override
    public final boolean isNegated() {
        return _negated;
    }

    /**
     * Returns a new predicate as the negation of this predicate.
     * 
* Note: * Default negation creates a Not expression with this receiver as delegate. * Derived predicates can return the inverse expression, if exists. * For example, NotEqual for Equal or LessThan for GreaterThanEqual etc. */ @Override public PredicateImpl not() { return new Expressions.Not(this).markNegated(); } protected PredicateImpl markNegated() { _negated = true; return this; } public static Predicate TRUE() { if (TRUE == null) { ExpressionImpl ONE = new Expressions.Constant<>(1); TRUE = new Expressions.Equal(ONE, ONE); } return TRUE; } public static Predicate FALSE() { if (FALSE == null) { ExpressionImpl ONE = new Expressions.Constant<>(1); FALSE = new Expressions.NotEqual(ONE, ONE); } return FALSE; } @Override org.apache.openjpa.kernel.exps.Value toValue(ExpressionFactory factory, CriteriaQueryImpl q) { if (_exps.isEmpty()) { return factory.newLiteral(_op == BooleanOperator.AND, Literal.TYPE_BOOLEAN); } throw new AbstractMethodError(this.getClass().getName()); } @Override org.apache.openjpa.kernel.exps.Expression toKernelExpression(ExpressionFactory factory, CriteriaQueryImpl q) { if (_exps.isEmpty()) { Predicate nil = _op == BooleanOperator.AND ? TRUE() : FALSE(); return ((PredicateImpl)nil).toKernelExpression(factory, q); } if (_exps.size() == 1) { Predicate e0 = _exps.get(0); if (isNegated()) e0 = e0.not(); return ((PredicateImpl)e0).toKernelExpression(factory, q); } ExpressionImpl e1 = (ExpressionImpl)_exps.get(0); ExpressionImpl e2 = (ExpressionImpl)_exps.get(1); org.apache.openjpa.kernel.exps.Expression ke1 = e1.toKernelExpression(factory, q); org.apache.openjpa.kernel.exps.Expression ke2 = e2.toKernelExpression(factory, q); org.apache.openjpa.kernel.exps.Expression result = _op == BooleanOperator.AND ? factory.and(ke1,ke2) : factory.or(ke1, ke2); for (int i = 2; i < _exps.size(); i++) { PredicateImpl p = (PredicateImpl)_exps.get(i); result = _op == BooleanOperator.AND ? factory.and(result, p.toKernelExpression(factory, q)) : factory.or(result, p.toKernelExpression(factory,q)); } return _negated ? factory.not(result) : result; } @Override public void acceptVisit(CriteriaExpressionVisitor visitor) { Expressions.acceptVisit(visitor, this, _exps.toArray(new Expression[_exps.size()])); } @Override public StringBuilder asValue(AliasContext q) { boolean braces = _exps.size() > 1; StringBuilder buffer = Expressions.asValue(q, _exps.toArray(new Expression[_exps.size()]), " " +_op + " "); if (braces) buffer.insert(0, "(").append(")"); if (isNegated()) buffer.insert(0, "NOT "); return buffer; } /** * Concrete AND predicate. * */ static class And extends PredicateImpl { public And(Expression x, Expression y) { super(BooleanOperator.AND); add(x).add(y); } public And(Predicate...restrictions) { super(BooleanOperator.AND, restrictions); } } /** * Concrete OR predicate. * */ static class Or extends PredicateImpl { public Or(Expression x, Expression y) { super(BooleanOperator.OR); add(x).add(y); } public Or(Predicate...restrictions) { super(BooleanOperator.OR, restrictions); } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy