Package org.eclipse.persistence.internal.jpa.querydef

Source Code of org.eclipse.persistence.internal.jpa.querydef.CommonAbstractCriteriaImpl

/*******************************************************************************
* Copyright (c) 2011, 2012 Oracle and/or its affiliates. All rights reserved.
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
* which accompanies this distribution.
* The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
* and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* Contributors:
*     10/26/2012-2.5 Chris Delahunt
*       - 350469: JPA 2.1 Criteria Query framework Bulk Update/Delete support
******************************************************************************/
package org.eclipse.persistence.internal.jpa.querydef;

import java.util.HashSet;
import java.util.Set;

import javax.persistence.criteria.CommonAbstractCriteria;
import javax.persistence.criteria.Expression;
import javax.persistence.criteria.ParameterExpression;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import javax.persistence.criteria.Subquery;
import javax.persistence.criteria.Predicate.BooleanOperator;
import javax.persistence.metamodel.EntityType;
import javax.persistence.metamodel.Metamodel;

import org.eclipse.persistence.expressions.ExpressionBuilder;
import org.eclipse.persistence.internal.expressions.ConstantExpression;
import org.eclipse.persistence.queries.DatabaseQuery;

/**
* <p>
* <b>Purpose</b>: Contains the implementation of the CommonAbstractCriteria interface of
* the JPA criteria API.
* <p>
* <b>Description</b>: This is the container class for the components that
* define a query. This is the superclass of CriteriaQuery, SubQuery, CriteriaDelete
* and CriteriaUpdate.
* <p>
*
* @see javax.persistence.criteria CommonAbstractCriteria
*
* @author Chris Delahunt
* @since EclipseLink 2.5
*/
public abstract class CommonAbstractCriteriaImpl<T> implements CommonAbstractCriteria {

    protected Metamodel metamodel;
    protected Expression<Boolean> where;
    protected CriteriaBuilderImpl queryBuilder;
    protected Class queryType;
   
    protected Set<ParameterExpression<?>> parameters;

    public CommonAbstractCriteriaImpl(Metamodel metamodel, CriteriaBuilderImpl queryBuilder, Class<T> resultType){
        this.metamodel = metamodel;
        this.queryBuilder = queryBuilder;
        this.queryType = resultType;
    }

    /**
     * Return the predicate that corresponds to the where clause restriction(s).
     *
     * @return where clause predicate
     */
    public Predicate getRestriction(){
        if (this.where == null) {
            return null;
        }
        if (((ExpressionImpl)this.where).isPredicate()) {
            return (Predicate)this.where;
        }
        return this.queryBuilder.isTrue(this.where);
    }
   
    /**
     * Return the result type of the query.
     * If a result type was specified as an argument to the
     * createQuery method, that type will be returned.
     * If the query was created using the createTupleQuery
     * method, the result type is Tuple.
     * Otherwise, the result type is Object.
     * @return result type
     */
    public Class<T> getResultType(){
        return this.queryType;
    }

    /**
     * Add a query root corresponding to the given entity, forming a Cartesian
     * product with any existing roots.
     *
     * @param entity
     *            metamodel entity representing the entity of type X
     * @return query root corresponding to the given entity
     */
    public Root internalFrom(EntityType entity) {
        RootImpl root = new RootImpl(entity, this.metamodel, entity.getBindableJavaType(), new ExpressionBuilder(entity.getBindableJavaType()), entity);
        integrateRoot(root);
        return root;
    }

    /**
     * Add a query root corresponding to the given entity, forming a Cartesian
     * product with any existing roots.
     *
     * @param entityClass
     *            the entity class
     * @return query root corresponding to the given entity
     */
    public Root internalFrom(Class entityClass) {
        EntityType entity = this.metamodel.entity(entityClass);
        return this.internalFrom(entity);
    }

    /**
     * Modify the query to restrict the query results according to the specified
     * boolean expression. Replaces the previously added restriction(s), if any.
     *
     * @param restriction
     *            a simple or compound boolean expression
     * @return the modified query
     */
    public CommonAbstractCriteria where(Expression<Boolean> restriction) {
        findRootAndParameters(restriction);
        this.where = restriction;
        return this;
    }

    /**
     * Modify the query to restrict the query results according to the
     * conjunction of the specified restriction predicates. Replaces the
     * previously added restriction(s), if any. If no restrictions are
     * specified, any previously added restrictions are simply removed.
     *
     * @param restrictions
     *            zero or more restriction predicates
     * @return the modified query
     */
    public CommonAbstractCriteria where(Predicate... restrictions) {
        if (restrictions == null || restrictions.length == 0){
            this.where = null;
        }
        Predicate predicate = this.queryBuilder.and(restrictions);
        findRootAndParameters(predicate);
        this.where = predicate;
        return this;
    }

    /**
     * Specify that the query is to be used as a subquery having the specified
     * return type.
     *
     * @return subquery corresponding to the query
     */
    public <U> Subquery<U> subquery(Class<U> type) {
        return new SubQueryImpl<U>(metamodel, type, queryBuilder, this);
    }

    /**
     *  Used to use a root from a different query.
     */
    protected abstract void integrateRoot(RootImpl root);

    protected void findRootAndParameters(Expression<?> predicate) {
        ((InternalSelection) predicate).findRootAndParameters(this);
    }

    protected abstract org.eclipse.persistence.expressions.Expression getBaseExpression();

    public void addParameter(ParameterExpression<?> parameter) {
        if (this.parameters == null) {
            this.parameters = new HashSet<ParameterExpression<?>>();
        }
        this.parameters.add(parameter);
    }
   
    protected abstract DatabaseQuery getDatabaseQuery();
   
    /**
     * Return the parameters of the query
     *
     * @return the query parameters
     */
    public Set<ParameterExpression<?>> getParameters() {
        if (this.parameters == null) {
            this.parameters = new HashSet<ParameterExpression<?>>();
        }
        return this.parameters;
    }
   
   
    /**
     * Translates from the criteria query to a EclipseLink Database Query.
     */
    public DatabaseQuery translate() {
      DatabaseQuery query = getDatabaseQuery();
      for (ParameterExpression<?> parameter : getParameters()) {
            query.addArgument(parameter.getName(), parameter.getJavaType());
        }
        if (this.where != null) {
            if (((InternalExpression) this.where).isPredicate() && ((InternalSelection) this.where).getCurrentNode() == null) {
                if (((PredicateImpl) this.where).getOperator() == BooleanOperator.OR) {
                    query.setSelectionCriteria(new ConstantExpression(1, getBaseExpression()).equal(0));
                }
            } else {
                query.setSelectionCriteria(((InternalSelection) this.where).getCurrentNode());
            }
        }

        return query;
    }

}
TOP

Related Classes of org.eclipse.persistence.internal.jpa.querydef.CommonAbstractCriteriaImpl

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.