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

org.hibernate.hql.ast.spi.SingleEntityQueryBuilder Maven / Gradle / Ivy

There is a newer version: 1.5.0.Final
Show newest version
/*
 * Hibernate, Relational Persistence for Idiomatic Java
 *
 * JBoss, Home of Professional Open Source
 * Copyright 2013 Red Hat Inc. and/or its affiliates and other contributors
 * as indicated by the @authors tag. All rights reserved.
 * See the copyright.txt in the distribution for a
 * full listing of individual contributors.
 *
 * This copyrighted material is made available to anyone wishing to use,
 * modify, copy, or redistribute it subject to the terms and conditions
 * of the GNU Lesser General Public License, v. 2.1.
 * This program is distributed in the hope that it will be useful, but WITHOUT A
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
 * PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.
 * You should have received a copy of the GNU Lesser General Public License,
 * v.2.1 along with this distribution; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 * MA  02110-1301, USA.
 */
package org.hibernate.hql.ast.spi;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Stack;

import org.hibernate.hql.ast.spi.predicate.ComparisonPredicate.Type;
import org.hibernate.hql.ast.spi.predicate.ParentPredicate;
import org.hibernate.hql.ast.spi.predicate.Predicate;
import org.hibernate.hql.ast.spi.predicate.PredicateFactory;
import org.hibernate.hql.ast.spi.predicate.RootPredicate;

/**
 * Builder for the creation of queries targeting a single entity, based on HQL/JPQL queries.
 * 

* Implemented as a stack of {@link Predicate}s which allows to add elements to the constructed query in a uniform * manner while traversing through the original HQL/JPQL query parse tree. * * @param the type of query created by this builder * @author Gunnar Morling */ public final class SingleEntityQueryBuilder { private final PredicateFactory predicateFactory; private final PropertyHelper propertyHelper; /** * The targeted entity type of the built query. */ private String entityType; /** * The root predicate of the {@code WHERE} clause of the built query. */ private RootPredicate rootPredicate; /** * Keeps track of all the parent predicates ({@code AND}, {@code OR} etc.) of the {@code WHERE} clause of the built * query. */ private final Stack> predicates = new Stack>(); private SingleEntityQueryBuilder(PredicateFactory predicateFactory, PropertyHelper propertyHelper) { this.predicateFactory = predicateFactory; this.propertyHelper = propertyHelper; } public static SingleEntityQueryBuilder getInstance(PredicateFactory predicateFactory, PropertyHelper propertyHelper) { return new SingleEntityQueryBuilder( predicateFactory, propertyHelper ); } public SingleEntityQueryBuilder setEntityType(String entityType) { this.entityType = entityType; rootPredicate = predicateFactory.getRootPredicate( entityType ); predicates.push( rootPredicate ); return this; } public SingleEntityQueryBuilder addComparisonPredicate(List propertyPath, Type comparisonType, Object value) { Object typedValue = propertyHelper.convertToBackendType( entityType, propertyPath, value ); pushPredicate( predicateFactory.getComparisonPredicate( entityType, comparisonType, propertyPath, typedValue ) ); return this; } public SingleEntityQueryBuilder addRangePredicate(String property, Object lower, Object upper) { return addRangePredicate( Collections.singletonList( property ), lower, upper ); } public SingleEntityQueryBuilder addRangePredicate(List propertyPath, Object lower, Object upper) { Object lowerValue = propertyHelper.convertToBackendType( entityType, propertyPath, lower ); Object upperValue = propertyHelper.convertToBackendType( entityType, propertyPath, upper ); pushPredicate( predicateFactory.getRangePredicate( entityType, propertyPath, lowerValue, upperValue ) ); return this; } public SingleEntityQueryBuilder addInPredicate(List propertyPath, List elements) { List typedElements = new ArrayList( elements.size() ); for ( Object element : elements ) { typedElements.add( propertyHelper.convertToBackendType( entityType, propertyPath, element ) ); } pushPredicate( predicateFactory.getInPredicate( entityType, propertyPath, typedElements ) ); return this; } public SingleEntityQueryBuilder addLikePredicate(List propertyPath, String patternValue, Character escapeCharacter) { pushPredicate( predicateFactory.getLikePredicate( entityType, propertyPath, patternValue, escapeCharacter ) ); return this; } public SingleEntityQueryBuilder addIsNullPredicate(List propertyPath) { pushPredicate( predicateFactory.getIsNullPredicate( entityType, propertyPath ) ); return this; } public SingleEntityQueryBuilder pushAndPredicate() { pushPredicate( predicateFactory.getConjunctionPredicate() ); return this; } public SingleEntityQueryBuilder pushOrPredicate() { pushPredicate( predicateFactory.getDisjunctionPredicate() ); return this; } public SingleEntityQueryBuilder pushNotPredicate() { pushPredicate( predicateFactory.getNegationPredicate() ); return this; } private void pushPredicate(Predicate predicate) { // Add as sub-predicate to the current top predicate predicates.peek().add( predicate ); // push to parent predicate stack if required if ( predicate.getType().isParent() ) { @SuppressWarnings("unchecked") ParentPredicate parentPredicate = predicate.as( ParentPredicate.class ); predicates.push( parentPredicate ); } } public SingleEntityQueryBuilder popBooleanPredicate() { predicates.pop(); return this; } /** * Returns the query created by this builder. * * @return the query created by this builder */ public Q build() { return rootPredicate.getQuery(); } @Override public String toString() { return "SingleEntityQueryBuilder [entityType=" + entityType + ", rootPredicate=" + rootPredicate + "]"; } }