blob: 03dec367d175dc505d9f928e344cee9ea1a50f90 [file] [log] [blame]
/*
* Copyright (c) 2009, 2022 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2020, 2021 IBM Corporation. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0,
* or the Eclipse Distribution License v. 1.0 which is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
*/
// Contributors:
// Gordon Yorke - Initial development
//
package org.eclipse.persistence.internal.jpa.querydef;
import java.io.Serializable;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
import jakarta.persistence.Tuple;
import jakarta.persistence.criteria.CollectionJoin;
import jakarta.persistence.criteria.CompoundSelection;
import jakarta.persistence.criteria.CriteriaDelete;
import jakarta.persistence.criteria.CriteriaQuery;
import jakarta.persistence.criteria.CriteriaUpdate;
import jakarta.persistence.criteria.Expression;
import jakarta.persistence.criteria.Join;
import jakarta.persistence.criteria.ListJoin;
import jakarta.persistence.criteria.MapJoin;
import jakarta.persistence.criteria.Order;
import jakarta.persistence.criteria.ParameterExpression;
import jakarta.persistence.criteria.Path;
import jakarta.persistence.criteria.Predicate;
import jakarta.persistence.criteria.Predicate.BooleanOperator;
import jakarta.persistence.criteria.Root;
import jakarta.persistence.criteria.Selection;
import jakarta.persistence.criteria.SetJoin;
import jakarta.persistence.criteria.Subquery;
import jakarta.persistence.metamodel.EntityType;
import jakarta.persistence.metamodel.Metamodel;
import jakarta.persistence.metamodel.Type.PersistenceType;
import org.eclipse.persistence.expressions.ExpressionBuilder;
import org.eclipse.persistence.expressions.ExpressionMath;
import org.eclipse.persistence.expressions.ExpressionOperator;
import org.eclipse.persistence.internal.expressions.ArgumentListFunctionExpression;
import org.eclipse.persistence.internal.expressions.ConstantExpression;
import org.eclipse.persistence.internal.expressions.FunctionExpression;
import org.eclipse.persistence.internal.expressions.SubSelectExpression;
import org.eclipse.persistence.internal.helper.BasicTypeHelperImpl;
import org.eclipse.persistence.internal.helper.ClassConstants;
import org.eclipse.persistence.internal.jpa.metamodel.MetamodelImpl;
import org.eclipse.persistence.internal.jpa.metamodel.TypeImpl;
import org.eclipse.persistence.internal.jpa.querydef.AbstractQueryImpl.ResultType;
import org.eclipse.persistence.internal.localization.ExceptionLocalization;
import org.eclipse.persistence.jpa.JpaCriteriaBuilder;
import org.eclipse.persistence.queries.ReportQuery;
public class CriteriaBuilderImpl implements JpaCriteriaBuilder, Serializable {
public static final String CONCAT = "concat";
public static final String SIZE = "size";
protected Metamodel metamodel;
public CriteriaBuilderImpl(Metamodel metamodel){
this.metamodel = metamodel;
}
/**
* Create a Criteria query object.
* @return query object
*/
@Override
public CriteriaQuery<Object> createQuery(){
return new CriteriaQueryImpl(this.metamodel, ResultType.UNKNOWN, ClassConstants.OBJECT, this);
}
/**
* Create a Criteria query object.
* @return query object
*/
@Override
public <T> CriteriaQuery<T> createQuery(Class<T> resultClass) {
if (resultClass == null) {
return (CriteriaQuery<T>) this.createQuery();
}
if (resultClass.equals(Tuple.class)) {
return new CriteriaQueryImpl(this.metamodel, ResultType.TUPLE, resultClass, this);
} else if (resultClass.equals(ClassConstants.AOBJECT)) {
return new CriteriaQueryImpl<T>(this.metamodel, ResultType.OBJECT_ARRAY, resultClass, this);
} else if (resultClass.isArray()) {
return new CriteriaQueryImpl<T>(this.metamodel, ResultType.OBJECT_ARRAY, resultClass, this);
} else {
if (resultClass.equals(ClassConstants.OBJECT)) {
return (CriteriaQuery<T>) this.createQuery();
} else {
if (resultClass.isPrimitive() || resultClass.equals(ClassConstants.STRING)|| BasicTypeHelperImpl.getInstance().isWrapperClass(resultClass) || BasicTypeHelperImpl.getInstance().isDateClass(resultClass)) {
return new CriteriaQueryImpl<T>(metamodel, ResultType.OTHER, resultClass, this);
} else {
TypeImpl<T> type = ((MetamodelImpl)this.metamodel).getType(resultClass);
if (type != null && type.getPersistenceType().equals(PersistenceType.ENTITY)) {
return new CriteriaQueryImpl(this.metamodel, ResultType.ENTITY, resultClass, this);
} else {
return new CriteriaQueryImpl(this.metamodel, ResultType.CONSTRUCTOR, resultClass, this);
}
}
}
}
}
/**
* Create a Criteria query object that returns a tuple of
* objects as its result.
* @return query object
*/
@Override
public CriteriaQuery<Tuple> createTupleQuery(){
return new CriteriaQueryImpl(this.metamodel, ResultType.TUPLE, Tuple.class, this);
}
/**
* Define a select list item corresponding to a constructor.
*
* @param result
* class whose instance is to be constructed
* @param selections
* arguments to the constructor
* @return selection item
*/
@Override
public <Y> CompoundSelection<Y> construct(Class<Y> result, Selection<?>... selections){
return new ConstructorSelectionImpl(result, selections);
}
@Override
public CompoundSelection<Tuple> tuple(Selection<?>... selections){
return new CompoundSelectionImpl(Tuple.class, selections, true);
}
/**
* Create an array-valued selection item
* @param selections selection items
* @return array-valued compound selection
* @throws IllegalArgumentException if an argument is a tuple- or
* array-valued selection item
*/
@Override
public CompoundSelection<Object[]> array(Selection<?>... selections){
return new CompoundSelectionImpl(ClassConstants.AOBJECT, selections, true);
}
/**
* Create an ordering by the ascending value of the expression.
*
* @param x
* expression used to define the ordering
* @return ascending ordering corresponding to the expression
*/
@Override
public Order asc(Expression<?> x){
if (((InternalSelection)x).getCurrentNode() == null){
throw new IllegalArgumentException(ExceptionLocalization.buildMessage("OPERATOR_EXPRESSION_IS_CONJUNCTION"));
}
return new OrderImpl(x);
}
/**
* Create an ordering by the descending value of the expression.
*
* @param x
* expression used to define the ordering
* @return descending ordering corresponding to the expression
*/
@Override
public Order desc(Expression<?> x){
if (((InternalSelection)x).getCurrentNode() == null){
throw new IllegalArgumentException(ExceptionLocalization.buildMessage("OPERATOR_EXPRESSION_IS_CONJUNCTION"));
}
OrderImpl order = new OrderImpl(x, false);
return order;
}
// aggregate functions:
/**
* Create an expression applying the avg operation.
*
* @param x
* expression representing input value to avg operation
* @return avg expression
*/
@Override
public <N extends Number> Expression<Double> avg(Expression<N> x){
return new FunctionExpressionImpl<Double>(this.metamodel, ClassConstants.DOUBLE,((InternalSelection)x).getCurrentNode().average(), buildList(x),"AVG");
}
/**
* Create an expression applying the sum operation.
*
* @param x
* expression representing input value to sum operation
* @return sum expression
*/
@Override
public <N extends Number> Expression<N> sum(Expression<N> x){
return new FunctionExpressionImpl<N>(this.metamodel, (Class<N>) x.getJavaType(), ((InternalSelection)x).getCurrentNode().sum(), buildList(x),"SUM");
}
/**
* Create an expression applying the numerical max operation.
*
* @param x
* expression representing input value to max operation
* @return max expression
*/
@Override
public <N extends Number> Expression<N> max(Expression<N> x){
return new FunctionExpressionImpl<N>(this.metamodel, (Class<N>) x.getJavaType(), ((InternalSelection)x).getCurrentNode().maximum(), buildList(x),"MAX");
}
/**
* Create an expression applying the numerical min operation.
*
* @param x
* expression representing input value to min operation
* @return min expression
*/
@Override
public <N extends Number> Expression<N> min(Expression<N> x){
return new FunctionExpressionImpl<N>(this.metamodel, (Class<N>) x.getJavaType(), ((InternalSelection)x).getCurrentNode().minimum(), buildList(x),"MIN");
}
/**
* Create an aggregate expression for finding the greatest of the values
* (strings, dates, etc).
*
* @param x
* expression representing input value to greatest operation
* @return greatest expression
*/
@Override
public <X extends Comparable<? super X>> Expression<X> greatest(Expression<X> x){
if (((InternalSelection)x).getCurrentNode() == null){
throw new IllegalArgumentException(ExceptionLocalization.buildMessage("OPERATOR_EXPRESSION_IS_CONJUNCTION"));
}
return new ExpressionImpl(this.metamodel, x.getJavaType(),((InternalSelection)x).getCurrentNode().maximum());
}
/**
* Create an aggregate expression for finding the least of the values
* (strings, dates, etc).
*
* @param x
* expression representing input value to least operation
* @return least expression
*/
@Override
public <X extends Comparable<? super X>> Expression<X> least(Expression<X> x){
if (((InternalSelection)x).getCurrentNode() == null){
throw new IllegalArgumentException(ExceptionLocalization.buildMessage("OPERATOR_EXPRESSION_IS_CONJUNCTION"));
}
return new ExpressionImpl(this.metamodel, x.getJavaType(),((InternalSelection)x).getCurrentNode().minimum());
}
/**
* Create an expression applying the count operation.
*
* @param x
* expression representing input value to count operation
* @return count expression
*/
@Override
public Expression<Long> count(Expression<?> x){
if (((InternalSelection)x).getCurrentNode() == null){
throw new IllegalArgumentException(ExceptionLocalization.buildMessage("OPERATOR_EXPRESSION_IS_CONJUNCTION"));
}
return new FunctionExpressionImpl(this.metamodel, ClassConstants.LONG, ((InternalSelection)x).getCurrentNode().count(), buildList(x),"COUNT");
}
/**
* Create an expression applying the count distinct operation.
*
* @param x
* expression representing input value to count distinct
* operation
* @return count distinct expression
*/
@Override
public Expression<Long> countDistinct(Expression<?> x){
if (((InternalSelection)x).getCurrentNode() == null){
throw new IllegalArgumentException(ExceptionLocalization.buildMessage("OPERATOR_EXPRESSION_IS_CONJUNCTION"));
}
return new FunctionExpressionImpl(this.metamodel, ClassConstants.LONG, ((InternalSelection)x).getCurrentNode().distinct().count(), buildList(x),"COUNT");
}
// subqueries:
/**
* Create a predicate testing the existence of a subquery result.
*
* @param subquery
* subquery whose result is to be tested
* @return exists predicate
*/
@Override
public Predicate exists(Subquery<?> subquery){
// Setting SubQuery's SubSelectExpression as a base for the expression created by operator allows setting a new ExpressionBuilder later in the SubSelectExpression (see integrateRoot method in SubQueryImpl).
return new CompoundExpressionImpl(metamodel, ExpressionOperator.getOperator(ExpressionOperator.Exists).expressionFor(((SubQueryImpl)subquery).getCurrentNode()), buildList(subquery), "exists");
}
/**
* Create a predicate corresponding to an all expression over the subquery
* results.
*
* @return all expression
*/
@Override
public <Y> Expression<Y> all(Subquery<Y> subquery){
return new FunctionExpressionImpl<Y>(metamodel, (Class<Y>) subquery.getJavaType(), new ExpressionBuilder().all(((InternalSelection)subquery).getCurrentNode()), buildList(subquery), "all");
}
/**
* Create a predicate corresponding to a some expression over the subquery
* results. This is equivalent to an any expression.
*
* @return all expression
*/
@Override
public <Y> Expression<Y> some(Subquery<Y> subquery){
return new FunctionExpressionImpl<Y>(metamodel, (Class<Y>) subquery.getJavaType(), new ExpressionBuilder().some(((InternalSelection)subquery).getCurrentNode()), buildList(subquery), "some");
}
/**
* Create a predicate corresponding to an any expression over the subquery
* results. This is equivalent to a some expression.
*
* @return any expression
*/
@Override
public <Y> Expression<Y> any(Subquery<Y> subquery){
return new FunctionExpressionImpl<Y>(metamodel, (Class<Y>) subquery.getJavaType(), new ExpressionBuilder().any(((InternalSelection)subquery).getCurrentNode()), buildList(subquery), "any");
}
// boolean functions:
/**
* Create a conjunction of the given boolean expressions.
*
* @param x
* boolean expression
* @param y
* boolean expression
* @return and predicate
*/
@Override
public Predicate and(Expression<Boolean> x, Expression<Boolean> y){
CompoundExpressionImpl xp = null;
CompoundExpressionImpl yp = null;
if (((InternalExpression)x).isExpression()){
xp = (CompoundExpressionImpl)this.isTrue(x);
}else{
xp = (CompoundExpressionImpl)x;
}
if (((InternalExpression)y).isExpression()){
yp = (CompoundExpressionImpl)this.isTrue(y);
}else{
yp = (CompoundExpressionImpl)y;
}
//bug 413084
if (yp.isJunction()){
if ( ((PredicateImpl)yp).getJunctionValue()){
return xp;//yp is true and so can be ignored/extracted
}else{
return yp;//yp is false so the statement is false
}
}
if (xp.isJunction()){
if (((PredicateImpl)xp).getJunctionValue()){
return yp;
}else{
return xp;
}
}
org.eclipse.persistence.expressions.Expression currentNode = xp.getCurrentNode().and(yp.getCurrentNode());
xp.setParentNode(currentNode);
yp.setParentNode(currentNode);
return new PredicateImpl(this.metamodel, currentNode, buildList(xp,yp), BooleanOperator.AND);
}
/**
* Create a disjunction of the given boolean expressions.
*
* @param x
* boolean expression
* @param y
* boolean expression
* @return or predicate
*/
@Override
public Predicate or(Expression<Boolean> x, Expression<Boolean> y){
CompoundExpressionImpl xp = null;
CompoundExpressionImpl yp = null;
if (((InternalExpression)x).isExpression()){
xp = (CompoundExpressionImpl)this.isTrue(x);
}else{
xp = (CompoundExpressionImpl)x;
}
if (((InternalExpression)y).isExpression()){
yp = (CompoundExpressionImpl)this.isTrue(y);
}else{
yp = (CompoundExpressionImpl)y;
}
//bug 413084
if (yp.isJunction()){
if (((PredicateImpl)yp).getJunctionValue()){
return yp;//yp is true so the statement is true
}
return xp;//yp is false so can be extracted.
}
if (xp.isJunction()){
if (((PredicateImpl)xp).getJunctionValue()){
return xp;
}
return yp;
}
org.eclipse.persistence.expressions.Expression parentNode = xp.getCurrentNode().or(yp.getCurrentNode());
xp.setParentNode(parentNode);
yp.setParentNode(parentNode);
return new PredicateImpl(this.metamodel, parentNode, buildList(xp,yp), BooleanOperator.OR);
}
/**
* Create a conjunction of the given restriction predicates. A conjunction
* of zero predicates is true.
*
* @param restrictions
* zero or more restriction predicates
* @return and predicate
*/
@Override
public Predicate and(Predicate... restrictions){
int max = restrictions.length;
if (max == 0){
return this.conjunction();
}
Predicate a = restrictions[0];
for (int i = 1; i < max; ++i){
a = this.and(a, restrictions[i]);
}
return a;
}
/**
* Create a disjunction of the given restriction predicates. A disjunction
* of zero predicates is false.
*
* @param restrictions
* zero or more restriction predicates
* @return and predicate
*/
@Override
public Predicate or(Predicate... restrictions){
int max = restrictions.length;
if (max == 0){
return this.disjunction();
}
Predicate a = restrictions[0];
for (int i = 1; i < max; ++i){
a = this.or(a, restrictions[i]);
}
return a;
}
/**
* Create a negation of the given restriction.
*
* @param restriction
* restriction expression
* @return not predicate
*/
@Override
public Predicate not(Expression<Boolean> restriction){
if (((InternalExpression)restriction).isPredicate()){
return ((Predicate)restriction).not();
}
org.eclipse.persistence.expressions.Expression parentNode = null;
List<Expression<?>> compoundExpressions = null;
String name = "not";
if (((InternalExpression)restriction).isCompoundExpression() && ((CompoundExpressionImpl)restriction).getOperation().equals("exists")){
FunctionExpression exp = (FunctionExpression) ((InternalSelection)restriction).getCurrentNode();
SubSelectExpression sub = (SubSelectExpression) exp.getChildren().get(0);
parentNode = ExpressionOperator.getOperator(ExpressionOperator.NotExists).expressionFor(sub);
name = "notExists";
compoundExpressions = ((CompoundExpressionImpl)restriction).getChildExpressions();
}else{
parentNode = ((InternalSelection)restriction).getCurrentNode().not();
compoundExpressions = buildList(restriction);
}
CompoundExpressionImpl expr = new CompoundExpressionImpl(this.metamodel, parentNode, compoundExpressions, name);
expr.setIsNegated(true);
return expr;
}
/**
* Create a conjunction (with zero conjuncts). A conjunction with zero
* conjuncts is true.
*
* @return and predicate
*/
@Override
public Predicate conjunction(){
return new PredicateImpl(this.metamodel, null, null, BooleanOperator.AND);
}
/**
* Create a disjunction (with zero disjuncts). A disjunction with zero
* disjuncts is false.
*
* @return or predicate
*/
@Override
public Predicate disjunction(){
return new PredicateImpl(this.metamodel, null, null, BooleanOperator.OR);
}
// turn Expression<Boolean> into a Predicate
// useful for use with varargs methods
/**
* Create a predicate testing for a true value.
*
* @param x
* expression to be tested if true
* @return predicate
*/
@Override
public Predicate isTrue(Expression<Boolean> x){
if (((InternalExpression)x).isPredicate()){
if (((InternalSelection)x).getCurrentNode() == null){
return (Predicate)x;
}else{
throw new IllegalArgumentException(ExceptionLocalization.buildMessage("PREDICATE_PASSED_TO_EVALUATION"));
}
}
List<Expression<?>> list = new ArrayList<>();
list.add(x);
return new CompoundExpressionImpl(this.metamodel, ((InternalSelection)x).getCurrentNode().equal(true), list, "equals");
}
/**
* Create a predicate testing for a false value.
*
* @param x
* expression to be tested if false
* @return predicate
*/
@Override
public Predicate isFalse(Expression<Boolean> x){
if (((InternalExpression)x).isPredicate()){
if (((InternalSelection)x).getCurrentNode() == null){
if (((Predicate)x).getOperator() == BooleanOperator.AND){
return (Predicate)x;
}else{
return this.conjunction();
}
}else{
throw new IllegalArgumentException(ExceptionLocalization.buildMessage("PREDICATE_PASSED_TO_EVALUATION"));
}
}
return new CompoundExpressionImpl(this.metamodel, ((InternalSelection)x).getCurrentNode().equal(false), buildList(x), "equals");
}
//null tests:
/**
* Create a predicate to test whether the expression is null.
* @param x expression
* @return predicate
*/
@Override
public Predicate isNull(Expression<?> x){
return new PredicateImpl(this.metamodel, ((InternalSelection)x).getCurrentNode().isNull(), new ArrayList<>(), BooleanOperator.AND);
}
/**
* Create a predicate to test whether the expression is not null.
* @param x expression
* @return predicate
*/
@Override
public Predicate isNotNull(Expression<?> x){
return new PredicateImpl(this.metamodel, ((InternalSelection)x).getCurrentNode().notNull(),new ArrayList<>(), BooleanOperator.AND);
}
// equality:
/**
* Create a predicate for testing the arguments for equality.
*
* @param x
* expression
* @param y
* expression
* @return equality predicate
*/
@Override
public Predicate equal(Expression<?> x, Expression<?> y){
List<Expression<?>> list = new ArrayList<>();
list.add(x);
list.add(y);
return new CompoundExpressionImpl(this.metamodel, ((InternalSelection)x).getCurrentNode().equal(((InternalSelection)y).getCurrentNode()), list, "equals");
}
/**
* Create a predicate for testing the arguments for inequality.
*
* @param x
* expression
* @param y
* expression
* @return inequality predicate
*/
@Override
public Predicate notEqual(Expression<?> x, Expression<?> y){
if (((InternalSelection)x).getCurrentNode() == null || ((InternalSelection)y).getCurrentNode() == null){
throw new IllegalArgumentException(ExceptionLocalization.buildMessage("OPERATOR_EXPRESSION_IS_CONJUNCTION"));
}
List<Expression<?>> list = new ArrayList<>();
list.add(x);
list.add(y);
return new CompoundExpressionImpl(this.metamodel, ((InternalSelection)x).getCurrentNode().notEqual(((InternalSelection)y).getCurrentNode()), list, "not equal");
}
/**
* Create a predicate for testing the arguments for equality.
*
* @param x
* expression
* @param y
* object
* @return equality predicate
*/
@Override
public Predicate equal(Expression<?> x, Object y){
//parameter is not an expression.
if (((InternalSelection)x).getCurrentNode() == null){
throw new IllegalArgumentException(ExceptionLocalization.buildMessage("OPERATOR_EXPRESSION_IS_CONJUNCTION"));
}
if (y instanceof ParameterExpression) return this.equal(x, (ParameterExpression)y);
List<Expression<?>> list = new ArrayList<>();
list.add(x);
list.add(this.internalLiteral(y));
return new CompoundExpressionImpl(this.metamodel, ((InternalSelection)x).getCurrentNode().equal(y), list, "equal");
}
/**
* Create a predicate for testing the arguments for inequality.
*
* @param x
* expression
* @param y
* object
* @return inequality predicate
*/
@Override
public Predicate notEqual(Expression<?> x, Object y){
if (((InternalSelection)x).getCurrentNode() == null){
throw new IllegalArgumentException(ExceptionLocalization.buildMessage("OPERATOR_EXPRESSION_IS_CONJUNCTION"));
}
if (y instanceof ParameterExpression) return this.notEqual(x, (ParameterExpression)y);
List<Expression<?>> list = new ArrayList<>();
list.add(x);
list.add(this.internalLiteral(y));
return new CompoundExpressionImpl(this.metamodel, ((InternalSelection)x).getCurrentNode().notEqual(y), list, "not equal");
}
// comparisons for generic (non-numeric) operands:
/**
* Create a predicate for testing whether the first argument is greater than
* the second.
*
* @param x
* expression
* @param y
* expression
* @return greater-than predicate
*/
@Override
public <Y extends Comparable<? super Y>> Predicate greaterThan(Expression<? extends Y> x, Expression<? extends Y> y){
if (((InternalSelection)x).getCurrentNode() == null || ((InternalSelection)y).getCurrentNode() == null){
throw new IllegalArgumentException(ExceptionLocalization.buildMessage("OPERATOR_EXPRESSION_IS_CONJUNCTION"));
}
List<Expression<?>> list = new ArrayList<>();
list.add(x);
list.add(y);
return new CompoundExpressionImpl(this.metamodel, ((InternalSelection)x).getCurrentNode().greaterThan(((InternalSelection)y).getCurrentNode()), list, "greaterThan");
}
/**
* Create a predicate for testing whether the first argument is less than
* the second.
*
* @param x
* expression
* @param y
* expression
* @return less-than predicate
*/
@Override
public <Y extends Comparable<? super Y>> Predicate lessThan(Expression<? extends Y> x, Expression<? extends Y> y){
if (((InternalSelection)x).getCurrentNode() == null || ((InternalSelection)y).getCurrentNode() == null){
throw new IllegalArgumentException(ExceptionLocalization.buildMessage("OPERATOR_EXPRESSION_IS_CONJUNCTION"));
}
return new CompoundExpressionImpl(this.metamodel, ((InternalSelection)x).getCurrentNode().lessThan(((InternalSelection)y).getCurrentNode()), buildList(x,y), "lessThan");
}
/**
* Create a predicate for testing whether the first argument is greater than
* or equal to the second.
*
* @param x
* expression
* @param y
* expression
* @return greater-than-or-equal predicate
*/
@Override
public <Y extends Comparable<? super Y>> Predicate greaterThanOrEqualTo(Expression<? extends Y> x, Expression<? extends Y> y){
if (((ExpressionImpl)x).getCurrentNode() == null || ((ExpressionImpl)y).getCurrentNode() == null){
throw new IllegalArgumentException(ExceptionLocalization.buildMessage("OPERATOR_EXPRESSION_IS_CONJUNCTION"));
}
List<Expression<?>> list = new ArrayList<>();
list.add(x);
list.add(y);
return new CompoundExpressionImpl(this.metamodel, ((ExpressionImpl)x).getCurrentNode().greaterThanEqual(((ExpressionImpl)y).getCurrentNode()), list, "greaterThanEqual");
}
/**
* Create a predicate for testing whether the first argument is less than or
* equal to the second.
*
* @param x
* expression
* @param y
* expression
* @return less-than-or-equal predicate
*/
@Override
public <Y extends Comparable<? super Y>> Predicate lessThanOrEqualTo(Expression<? extends Y> x, Expression<? extends Y> y){
if (((ExpressionImpl)x).getCurrentNode() == null || ((ExpressionImpl)y).getCurrentNode() == null){
throw new IllegalArgumentException(ExceptionLocalization.buildMessage("OPERATOR_EXPRESSION_IS_CONJUNCTION"));
}
List<Expression<?>> list = new ArrayList<>();
list.add(x);
list.add(y);
return new CompoundExpressionImpl(this.metamodel, ((ExpressionImpl)x).getCurrentNode().lessThanEqual(((ExpressionImpl)y).getCurrentNode()), list, "lessThanEqual");
}
/**
* Create a predicate for testing whether the first argument is between the
* second and third arguments in value.
*
* @param v
* expression
* @param x
* expression
* @param y
* expression
* @return between predicate
*/
@Override
public <Y extends Comparable<? super Y>> Predicate between(Expression<? extends Y> v, Expression<? extends Y> x, Expression<? extends Y> y){
List<Expression<?>> list = new ArrayList<>();
list.add(v);
list.add(x);
list.add(y);
return new CompoundExpressionImpl(this.metamodel, ((ExpressionImpl)v).getCurrentNode().between(((ExpressionImpl)x).getCurrentNode(), ((ExpressionImpl)y).getCurrentNode()), list, "between");
}
/**
* Create a predicate for testing whether the first argument is greater than
* the second.
*
* @param x
* expression
* @param y
* value
* @return greater-than predicate
*/
@Override
public <Y extends Comparable<? super Y>> Predicate greaterThan(Expression<? extends Y> x, Y y){
Expression<Y> expressionY = this.internalLiteral(y);
if (((ExpressionImpl)x).getCurrentNode() == null ){
throw new IllegalArgumentException(ExceptionLocalization.buildMessage("OPERATOR_EXPRESSION_IS_CONJUNCTION"));
}
List<Expression<?>> list = new ArrayList<>();
list.add(x);
list.add(expressionY);
return new CompoundExpressionImpl(this.metamodel, ((ExpressionImpl)x).getCurrentNode().greaterThan(((ExpressionImpl)expressionY).getCurrentNode()), list, "greaterThan");
}
/**
* Create a predicate for testing whether the first argument is less than
* the second.
*
* @param x
* expression
* @param y
* value
* @return less-than predicate
*/
@Override
public <Y extends Comparable<? super Y>> Predicate lessThan(Expression<? extends Y> x, Y y){
Expression<Y> expressionY = this.internalLiteral(y);
if (((ExpressionImpl)x).getCurrentNode() == null ){
throw new IllegalArgumentException(ExceptionLocalization.buildMessage("OPERATOR_EXPRESSION_IS_CONJUNCTION"));
}
List<Expression<?>> list = new ArrayList<>();
list.add(x);
list.add(expressionY);
return new CompoundExpressionImpl(this.metamodel, ((ExpressionImpl)x).getCurrentNode().lessThan(((ExpressionImpl)expressionY).getCurrentNode()), list, "lessThan");
}
/**
* Create a predicate for testing whether the first argument is greater than
* or equal to the second.
*
* @param x
* expression
* @param y
* value
* @return greater-than-or-equal predicate
*/
@Override
public <Y extends Comparable<? super Y>> Predicate greaterThanOrEqualTo(Expression<? extends Y> x, Y y){
Expression<Y> expressionY = this.internalLiteral(y);
if (((ExpressionImpl)x).getCurrentNode() == null ){
throw new IllegalArgumentException(ExceptionLocalization.buildMessage("OPERATOR_EXPRESSION_IS_CONJUNCTION"));
}
List<Expression<?>> list = new ArrayList<>();
list.add(x);
list.add(expressionY);
return new CompoundExpressionImpl(this.metamodel, ((ExpressionImpl)x).getCurrentNode().greaterThanEqual(((ExpressionImpl)expressionY).getCurrentNode()), list, "greaterThanEqual");
}
/**
* Create a predicate for testing whether the first argument is less than or
* equal to the second.
*
* @param x
* expression
* @param y
* value
* @return less-than-or-equal predicate
*/
@Override
public <Y extends Comparable<? super Y>> Predicate lessThanOrEqualTo(Expression<? extends Y> x, Y y){
Expression<Y> expressionY = this.internalLiteral(y);
if (((ExpressionImpl)x).getCurrentNode() == null ){
throw new IllegalArgumentException(ExceptionLocalization.buildMessage("OPERATOR_EXPRESSION_IS_CONJUNCTION"));
}
List<Expression<?>> list = new ArrayList<>();
list.add(x);
list.add(expressionY);
return new CompoundExpressionImpl(this.metamodel, ((ExpressionImpl)x).getCurrentNode().lessThanEqual(((ExpressionImpl)expressionY).getCurrentNode()), list, "lessThanEqual");
}
/**
* Create a predicate for testing whether the first argument is between the
* second and third arguments in value.
*
* @param v
* expression
* @param x
* value
* @param y
* value
* @return between predicate
*/
@Override
public <Y extends Comparable<? super Y>> Predicate between(Expression<? extends Y> v, Y x, Y y){
List<Expression<?>> list = new ArrayList<>();
list.add(v);
list.add(this.internalLiteral(x));
list.add(this.internalLiteral(y));
return new CompoundExpressionImpl(this.metamodel, ((ExpressionImpl)v).getCurrentNode().between(x, y), list, "between");
}
protected List<Expression<?>> buildList(Expression<?>... expressions){
List<Expression<?>> list = new ArrayList<>();
for(Expression<?> exp : expressions){
list.add(exp);
}
return list;
}
// comparisons for numeric operands:
/**
* Create a predicate for testing whether the first argument is greater than
* the second.
*
* @param x
* expression
* @param y
* expression
* @return greater-than predicate
*/
@Override
public Predicate gt(Expression<? extends Number> x, Expression<? extends Number> y){
List<Expression<?>> list = new ArrayList<>();
list.add(x);
list.add(y);
return new CompoundExpressionImpl(this.metamodel, ((InternalSelection)x).getCurrentNode().greaterThan(((InternalSelection)y).getCurrentNode()), list, "gt");
}
/**
* Create a predicate for testing whether the first argument is less than
* the second.
*
* @param x
* expression
* @param y
* expression
* @return less-than predicate
*/
@Override
public Predicate lt(Expression<? extends Number> x, Expression<? extends Number> y){
return new CompoundExpressionImpl(this.metamodel, ((InternalSelection)x).getCurrentNode().lessThan(((InternalSelection)y).getCurrentNode()), buildList(x,y), "lessThan");
}
/**
* Create a predicate for testing whether the first argument is greater than
* or equal to the second.
*
* @param x
* expression
* @param y
* expression
* @return greater-than-or-equal predicate
*/
@Override
public Predicate ge(Expression<? extends Number> x, Expression<? extends Number> y){
List<Expression<?>> list = new ArrayList<>();
list.add(x);
list.add(y);
return new CompoundExpressionImpl(this.metamodel, ((InternalSelection)x).getCurrentNode().greaterThanEqual(((InternalSelection)y).getCurrentNode()), list, "ge");
}
/**
* Create a predicate for testing whether the first argument is less than or
* equal to the second.
*
* @param x
* expression
* @param y
* expression
* @return less-than-or-equal predicate
*/
@Override
public Predicate le(Expression<? extends Number> x, Expression<? extends Number> y){
List<Expression<?>> list = new ArrayList<>();
list.add(x);
list.add(y);
return new CompoundExpressionImpl(this.metamodel, ((InternalSelection)x).getCurrentNode().lessThanEqual(((InternalSelection)y).getCurrentNode()), list, "le");
}
/**
* Create a predicate for testing whether the first argument is greater than
* the second.
*
* @param x
* expression
* @param y
* value
* @return greater-than predicate
*/
@Override
public Predicate gt(Expression<? extends Number> x, Number y){
List<Expression<?>> list = new ArrayList<>();
list.add(x);
list.add(internalLiteral(y));
return new CompoundExpressionImpl(this.metamodel, ((InternalSelection)x).getCurrentNode().greaterThan(y), list, "gt");
}
/**
* Create a predicate for testing whether the first argument is less than
* the second.
*
* @param x
* expression
* @param y
* value
* @return less-than predicate
*/
@Override
public Predicate lt(Expression<? extends Number> x, Number y){
return new CompoundExpressionImpl(this.metamodel, ((InternalSelection)x).getCurrentNode().lessThan(y), buildList(x,internalLiteral(y)), "lt");
}
/**
* Create a predicate for testing whether the first argument is greater than
* or equal to the second.
*
* @param x
* expression
* @param y
* value
* @return greater-than-or-equal predicate
*/
@Override
public Predicate ge(Expression<? extends Number> x, Number y){
List<Expression<?>> list = new ArrayList<>();
list.add(x);
list.add(internalLiteral(y));
return new CompoundExpressionImpl(this.metamodel, ((InternalSelection)x).getCurrentNode().greaterThanEqual(y), list, "ge");
}
/**
* Create a predicate for testing whether the first argument is less than or
* equal to the second.
*
* @param x
* expression
* @param y
* value
* @return less-than-or-equal predicate
*/
@Override
public Predicate le(Expression<? extends Number> x, Number y){
return new CompoundExpressionImpl(this.metamodel, ((InternalSelection)x).getCurrentNode().lessThanEqual(y), buildList(x, internalLiteral(y)), "le");
}
// numerical operations:
/**
* Create an expression that returns the arithmetic negation of its
* argument.
*
* @param x
* expression
* @return negated expression
*/
@Override
public <N extends Number> Expression<N> neg(Expression<N> x){
return new FunctionExpressionImpl(this.metamodel, ClassConstants.INTEGER, ExpressionMath.negate(((InternalSelection)x).getCurrentNode()), buildList(x), "neg");
}
/**
* Create an expression that returns the absolute value of its argument.
*
* @param x
* expression
* @return absolute value
*/
@Override
public <N extends Number> Expression<N> abs(Expression<N> x){
return new FunctionExpressionImpl<N>(metamodel, (Class<N>) x.getJavaType(), ExpressionMath.abs(((InternalSelection)x).getCurrentNode()), buildList(x),"ABS");
}
/**
* Create an expression that returns the sum of its arguments.
*
* @param x
* expression
* @param y
* expression
* @return sum
*/
@Override
public <N extends Number> Expression<N> sum(Expression<? extends N> x, Expression<? extends N> y){
return new FunctionExpressionImpl(this.metamodel, (Class<N>)BasicTypeHelperImpl.getInstance().extendedBinaryNumericPromotion(x.getJavaType(), y.getJavaType()), ExpressionMath.add(((InternalSelection)x).getCurrentNode(),((InternalSelection)y).getCurrentNode()), buildList(x,y), "sum");
}
/**
* Create an aggregate expression applying the sum operation to an
* Integer-valued expression, returning a Long result.
* @param x expression representing input value to sum operation
* @return sum expression
*/
@Override
public Expression<Long> sumAsLong(Expression<Integer> x) {
return new FunctionExpressionImpl(this.metamodel, ClassConstants.LONG, ((InternalSelection)x).getCurrentNode().sum(), buildList(x),"SUM");
}
/**
* Create an aggregate expression applying the sum operation to a
* Float-valued expression, returning a Double result.
* @param x expression representing input value to sum operation
* @return sum expression
*/
@Override
public Expression<Double> sumAsDouble(Expression<Float> x){
return new FunctionExpressionImpl(this.metamodel, ClassConstants.DOUBLE, ((InternalSelection)x).getCurrentNode().sum(), buildList(x),"SUM");
}
/**
* Create an expression that returns the product of its arguments.
*
* @param x
* expression
* @param y
* expression
* @return product
*/
@Override
public <N extends Number> Expression<N> prod(Expression<? extends N> x, Expression<? extends N> y){
return new FunctionExpressionImpl(this.metamodel, (Class<N>)BasicTypeHelperImpl.getInstance().extendedBinaryNumericPromotion(x.getJavaType(), y.getJavaType()), ExpressionMath.multiply(((InternalSelection)x).getCurrentNode(),((InternalSelection)y).getCurrentNode()), buildList(x,y), "prod");
}
/**
* Create an expression that returns the difference between its arguments.
*
* @param x
* expression
* @param y
* expression
* @return difference
*/
@Override
public <N extends Number> Expression<N> diff(Expression<? extends N> x, Expression<? extends N> y){
List<Expression<?>> list = new ArrayList<>();
list.add(x);
list.add(y);
return new FunctionExpressionImpl(this.metamodel, x.getJavaType(), ExpressionMath.subtract(((InternalSelection)x).getCurrentNode(), ((InternalSelection)y).getCurrentNode()), list, "diff");
}
/**
* Create an expression that returns the sum of its arguments.
*
* @param x
* expression
* @param y
* value
* @return sum
*/
@Override
public <N extends Number> Expression<N> sum(Expression<? extends N> x, N y){
return new FunctionExpressionImpl(this.metamodel, (Class<N>)BasicTypeHelperImpl.getInstance().extendedBinaryNumericPromotion(x.getJavaType(), y.getClass()), ExpressionMath.add(((InternalSelection)x).getCurrentNode(),y), buildList(x,internalLiteral(y)), "sum");
}
/**
* Create an expression that returns the product of its arguments.
*
* @param x
* expression
* @param y
* value
* @return product
*/
@Override
public <N extends Number> Expression<N> prod(Expression<? extends N> x, N y){
return new FunctionExpressionImpl(this.metamodel, (Class<N>)BasicTypeHelperImpl.getInstance().extendedBinaryNumericPromotion(x.getJavaType(), y.getClass()), ExpressionMath.multiply(((InternalSelection)x).getCurrentNode(),y), buildList(x,internalLiteral(y)), "prod");
}
/**
* Create an expression that returns the difference between its arguments.
*
* @param x
* expression
* @param y
* value
* @return difference
*/
@Override
public <N extends Number> Expression<N> diff(Expression<? extends N> x, N y){
List<Expression<?>> list = new ArrayList<>();
list.add(x);
list.add(this.internalLiteral(y));
return new FunctionExpressionImpl(this.metamodel, y.getClass(), ExpressionMath.subtract(((InternalSelection)x).getCurrentNode(), y), list, "diff");
}
/**
* Create an expression that returns the sum of its arguments.
*
* @param x
* value
* @param y
* expression
* @return sum
*/
@Override
public <N extends Number> Expression<N> sum(N x, Expression<? extends N> y){
return new FunctionExpressionImpl(this.metamodel, (Class<N>)BasicTypeHelperImpl.getInstance().extendedBinaryNumericPromotion(x.getClass(), y.getJavaType()), ExpressionMath.add(new ConstantExpression(x, ((InternalSelection)y).getCurrentNode()),((InternalSelection)y).getCurrentNode()), buildList(internalLiteral(x),y), "sum");
}
/**
* Create an expression that returns the product of its arguments.
*
* @param x
* value
* @param y
* expression
* @return product
*/
@Override
public <N extends Number> Expression<N> prod(N x, Expression<? extends N> y){
return new FunctionExpressionImpl(this.metamodel, (Class<N>)BasicTypeHelperImpl.getInstance().extendedBinaryNumericPromotion(x.getClass(), y.getJavaType()), ExpressionMath.multiply(new ConstantExpression(x, ((InternalSelection)y).getCurrentNode()),((InternalSelection)y).getCurrentNode()), buildList(internalLiteral(x),y), "prod");
}
/**
* Create an expression that returns the difference between its arguments.
*
* @param x
* value
* @param y
* expression
* @return difference
*/
@Override
public <N extends Number> Expression<N> diff(N x, Expression<? extends N> y){
List<Expression<?>> list = new ArrayList<>();
ExpressionImpl literal = (ExpressionImpl) this.internalLiteral(x);
list.add(literal);
list.add(y);
return new FunctionExpressionImpl(this.metamodel, literal.getJavaType(), ExpressionMath.subtract(((InternalSelection)literal).getCurrentNode(), ((InternalSelection)y).getCurrentNode()), list, "diff");
}
/**
* Create an expression that returns the quotient of its arguments.
*
* @param x
* expression
* @param y
* expression
* @return quotient
*/
@Override
public Expression<Number> quot(Expression<? extends Number> x, Expression<? extends Number> y){
return new FunctionExpressionImpl(this.metamodel, (Class)BasicTypeHelperImpl.getInstance().extendedBinaryNumericPromotion(x.getJavaType(), y.getClass()), ExpressionMath.divide(((InternalSelection)x).getCurrentNode(),((InternalSelection)y).getCurrentNode()), buildList(x,y), "quot");
}
/**
* Create an expression that returns the quotient of its arguments.
*
* @param x
* expression
* @param y
* value
* @return quotient
*/
@Override
public Expression<Number> quot(Expression<? extends Number> x, Number y){
return new FunctionExpressionImpl(this.metamodel, (Class)BasicTypeHelperImpl.getInstance().extendedBinaryNumericPromotion(x.getJavaType(), y.getClass()), ExpressionMath.divide(((InternalSelection)x).getCurrentNode(),y), buildList(x,internalLiteral(y)), "quot");
}
/**
* Create an expression that returns the quotient of its arguments.
*
* @param x
* value
* @param y
* expression
* @return quotient
*/
@Override
public Expression<Number> quot(Number x, Expression<? extends Number> y){
return new FunctionExpressionImpl(this.metamodel, ClassConstants.NUMBER, ExpressionMath.divide(new ConstantExpression(x, ((InternalSelection)y).getCurrentNode()),((InternalSelection)y).getCurrentNode()), buildList(internalLiteral(x),y), "quot");
}
/**
* Create an expression that returns the modulus of its arguments.
*
* @param x
* expression
* @param y
* expression
* @return modulus
*/
@Override
public Expression<Integer> mod(Expression<Integer> x, Expression<Integer> y){
return new FunctionExpressionImpl(this.metamodel, ClassConstants.INTEGER, ExpressionMath.mod(((InternalSelection)x).getCurrentNode(),((InternalSelection)y).getCurrentNode()), buildList(x,y), "mod");
}
/**
* Create an expression that returns the modulus of its arguments.
*
* @param x
* expression
* @param y
* value
* @return modulus
*/
@Override
public Expression<Integer> mod(Expression<Integer> x, Integer y){
return new FunctionExpressionImpl(this.metamodel, ClassConstants.INTEGER, ExpressionMath.mod(((InternalSelection)x).getCurrentNode(),y), buildList(x,internalLiteral(y)), "mod");
}
/**
* Create an expression that returns the modulus of its arguments.
*
* @param x
* value
* @param y
* expression
* @return modulus
*/
@Override
public Expression<Integer> mod(Integer x, Expression<Integer> y){
Expression<Integer> xExp = internalLiteral(x);
return new FunctionExpressionImpl(this.metamodel, ClassConstants.INTEGER, ExpressionMath.mod(((InternalSelection)xExp).getCurrentNode(),((InternalSelection)y).getCurrentNode()), buildList(xExp,y), "mod");
}
/**
* Create an expression that returns the square root of its argument.
*
* @param x
* expression
* @return modulus
*/
@Override
public Expression<Double> sqrt(Expression<? extends Number> x){
return new FunctionExpressionImpl(this.metamodel, ClassConstants.DOUBLE, ExpressionMath.sqrt(((InternalSelection)x).getCurrentNode()), buildList(x), "sqrt");
}
/**
* Create an expression that returns the sign of its argument, that is, {@code 1} if its argument is
* positive, {@code -1} if its argument is negative, or {@code 0} if its argument is exactly zero.
*
* @param x expression
* @return sign
*/
@Override
public Expression<Integer> sign(Expression<? extends Number> x) {
return new FunctionExpressionImpl(this.metamodel, ClassConstants.INTEGER,
ExpressionMath.sign(((InternalSelection)x).getCurrentNode()), buildList(x), "sign");
}
/**
* Create an expression that returns the ceiling of its argument, that is, the smallest integer greater than
* or equal to its argument.
*
* @param x expression
* @return ceiling
*/
@Override
public <N extends Number> Expression<N> ceiling(Expression<N> x) {
return new FunctionExpressionImpl(this.metamodel, ClassConstants.NUMBER,
ExpressionMath.ceil(((InternalSelection)x).getCurrentNode()), buildList(x), "ceiling");
}
/**
* Create an expression that returns the floor of its argument, that is, the largest integer smaller than
* or equal to its argument.
*
* @param x expression
* @return floor
*/
@Override
public <N extends Number> Expression<N> floor(Expression<N> x) {
return new FunctionExpressionImpl(this.metamodel, ClassConstants.NUMBER,
ExpressionMath.floor(((InternalSelection)x).getCurrentNode()), buildList(x), "floor");
}
/**
* Create an expression that returns the exponential of its argument, that is, Euler's number <i>e</i>
* raised to the power of its argument.
*
* @param x expression
* @return exponential
*/
@Override
public Expression<Double> exp(Expression<? extends Number> x) {
return new FunctionExpressionImpl(this.metamodel, ClassConstants.DOUBLE,
ExpressionMath.exp(((InternalSelection)x).getCurrentNode()), buildList(x), "exp");
}
/**
* Create an expression that returns the natural logarithm of its argument.
*
* @param x expression
* @return natural logarithm
*/
@Override
public Expression<Double> ln(Expression<? extends Number> x) {
return new FunctionExpressionImpl(this.metamodel, ClassConstants.DOUBLE,
ExpressionMath.ln(((InternalSelection)x).getCurrentNode()), buildList(x), "ln");
}
/**
* Create an expression that returns the first argument raised to the power of its second argument.
*
* @param x base
* @param y exponent
* @return the base raised to the power of the exponent
*/
@Override
public Expression<Double> power(Expression<? extends Number> x, Expression<? extends Number> y) {
return new FunctionExpressionImpl(this.metamodel, ClassConstants.DOUBLE,
ExpressionMath.power(((InternalSelection)x).getCurrentNode(),
((InternalSelection)y).getCurrentNode()), buildList(x,y), "power");
}
/**
* Create an expression that returns the first argument raised to the power of its second argument.
*
* @param x base
* @param y exponent
* @return the base raised to the power of the exponent
*/
@Override
public Expression<Double> power(Expression<? extends Number> x, Number y) {
return new FunctionExpressionImpl(this.metamodel, ClassConstants.DOUBLE,
ExpressionMath.power(((InternalSelection)x).getCurrentNode(), y),
buildList(x, internalLiteral(y)), "power");
}
/**
* Create an expression that returns the first argument rounded to the number of decimal places given by the
* second argument.
*
* @param x base
* @param n number of decimal places
* @return the rounded value
*/
@Override
public <T extends Number> Expression<T> round(Expression<T> x, Integer n) {
return new FunctionExpressionImpl(this.metamodel, ClassConstants.NUMBER,
ExpressionMath.round(((InternalSelection)x).getCurrentNode(), n),
buildList(x, internalLiteral(n)), "round");
}
// typecasts:
/**
* Typecast.
*
* @param number
* numeric expression
* @return Expression&lt;Long&gt;
*/
@Override
public Expression<Long> toLong(Expression<? extends Number> number){
return (Expression<Long>) number;
}
/**
* Typecast.
*
* @param number
* numeric expression
* @return Expression&lt;Integer&gt;
*/
@Override
public Expression<Integer> toInteger(Expression<? extends Number> number){
return (Expression<Integer>) number;
}
/**
* Typecast.
*
* @param number
* numeric expression
* @return Expression&lt;Float&gt;
*/
@Override
public Expression<Float> toFloat(Expression<? extends Number> number){
return (Expression<Float>) number;
}
/**
* Typecast.
*
* @param number
* numeric expression
* @return Expression&lt;Double&gt;
*/
@Override
public Expression<Double> toDouble(Expression<? extends Number> number){
return (Expression<Double>) number;
}
/**
* Typecast.
*
* @param number
* numeric expression
* @return Expression&lt;BigDecimal&gt;
*/
@Override
public Expression<BigDecimal> toBigDecimal(Expression<? extends Number> number){
return (Expression<BigDecimal>) number;
}
/**
* Typecast.
*
* @param number
* numeric expression
* @return Expression&lt;BigInteger&gt;
*/
@Override
public Expression<BigInteger> toBigInteger(Expression<? extends Number> number){
return (Expression<BigInteger>) number;
}
/**
* Typecast.
*
* @param character
* expression
* @return Expression&lt;String&gt;
*/
@Override
public Expression<String> toString(Expression<Character> character){
ExpressionImpl impl = (ExpressionImpl) character;
return impl;
}
// literals:
/**
* Create an expression literal.
*
* @return expression literal
*/
@Override
public <T> Expression<T> literal(T value){
if (value == null) {
throw new IllegalArgumentException( ExceptionLocalization.buildMessage("jpa_criteriaapi_null_literal_value", new Object[]{}));
}
return new ExpressionImpl<T>(metamodel, (Class<T>) (value.getClass()), new ConstantExpression(value, new ExpressionBuilder()), value);
}
/**
* Create an expression for a null literal with the given type.
*
* @param resultClass type of the null literal
* @return null expression literal
*/
@Override
public <T> Expression<T> nullLiteral(Class<T> resultClass){
return new ExpressionImpl<T>(metamodel, resultClass, new ConstantExpression(null, new ExpressionBuilder()), null);
}
/**
* Create an expression literal but without null validation.
*
* @return expression literal
*/
protected <T> Expression<T> internalLiteral(T value){
return new ExpressionImpl<T>(metamodel, (Class<T>) (value == null? null: value.getClass()), new ConstantExpression(value, new ExpressionBuilder()), value);
}
// parameters:
/**
* Create a parameter.
*
* Create a parameter expression.
* @param paramClass parameter class
* @return parameter expression
*/
@Override
public <T> ParameterExpression<T> parameter(Class<T> paramClass){
return new ParameterExpressionImpl<T>(metamodel, paramClass);
}
/**
* Create a parameter expression with the given name.
*
* @param paramClass
* parameter class
* @return parameter
*/
@Override
public <T> ParameterExpression<T> parameter(Class<T> paramClass, String name){
return new ParameterExpressionImpl<T>(metamodel, paramClass, name);
}
// collection operations:
/**
* Create a predicate that tests whether a collection is empty.
*
* @param collection
* expression
* @return predicate
*/
@Override
public <C extends Collection<?>> Predicate isEmpty(Expression<C> collection){
if (((InternalExpression)collection).isLiteral()){
if (((Collection)((ConstantExpression)((InternalSelection)collection).getCurrentNode()).getValue()).isEmpty()){
return conjunction();
}else{
return disjunction();
}
}
return new CompoundExpressionImpl(metamodel, ((InternalSelection)collection).getCurrentNode().size(ClassConstants.INTEGER).equal(0), buildList(collection), "isEmpty");
}
/**
* Create a predicate that tests whether a collection is not empty.
*
* @param collection
* expression
* @return predicate
*/
@Override
public <C extends Collection<?>> Predicate isNotEmpty(Expression<C> collection){
return new CompoundExpressionImpl(metamodel, ((InternalSelection)collection).getCurrentNode().size(ClassConstants.INTEGER).equal(0).not(), buildList(collection), "isNotEmpty");
}
/**
* Create an expression that tests the size of a collection.
*
* @return size expression
*/
@Override
public <C extends Collection<?>> Expression<Integer> size(C collection){
return internalLiteral(collection.size());
}
/**
* Create an expression that tests the size of a collection.
*
* @param collection
* expression
* @return size expression
*/
@Override
public <C extends java.util.Collection<?>> Expression<Integer> size(Expression<C> collection){
return new FunctionExpressionImpl(metamodel, ClassConstants.INTEGER, ((InternalSelection)collection).getCurrentNode().size(ClassConstants.INTEGER), buildList(collection), SIZE);
}
/**
* Create a predicate that tests whether an element is a member of a
* collection.
*
* @param elem
* element
* @param collection
* expression
* @return predicate
*/
@Override
public <E, C extends Collection<E>> Predicate isMember(E elem, Expression<C> collection){
return new CompoundExpressionImpl(metamodel, ((InternalSelection)collection).getCurrentNode().equal(elem), buildList(collection, internalLiteral(elem)), "isMember");
}
/**
* Create a predicate that tests whether an element is not a member of a
* collection.
*
* @param elem
* element
* @param collection
* expression
* @return predicate
*/
@Override
public <E, C extends Collection<E>> Predicate isNotMember(E elem, Expression<C> collection){
return new CompoundExpressionImpl(metamodel, ((InternalSelection)collection).getCurrentNode().notEqual(elem), buildList(collection, internalLiteral(elem)), "isMember");
}
/**
* Create a predicate that tests whether an element is a member of a
* collection.
*
* @param elem
* element expression
* @param collection
* expression
* @return predicate
*/
@Override
public <E, C extends Collection<E>> Predicate isMember(Expression<E> elem, Expression<C> collection){
return new CompoundExpressionImpl(metamodel, ((InternalSelection)collection).getCurrentNode().equal(((InternalSelection)elem).getCurrentNode()), buildList(collection, elem), "isMember");
}
/**
* Create a predicate that tests whether an element is not a member of a
* collection.
*
* @param elem
* element expression
* @param collection
* expression
* @return predicate
*/
@Override
public <E, C extends Collection<E>> Predicate isNotMember(Expression<E> elem, Expression<C> collection){
ReportQuery subQuery = new ReportQuery();
subQuery.setReferenceClass(((ExpressionImpl)elem).getJavaType());
org.eclipse.persistence.expressions.ExpressionBuilder elemBuilder = new org.eclipse.persistence.expressions.ExpressionBuilder();
org.eclipse.persistence.expressions.Expression collectionExp =((InternalSelection)collection).getCurrentNode();
org.eclipse.persistence.expressions.Expression elemExp =((InternalSelection)elem).getCurrentNode();
subQuery.setExpressionBuilder(elemBuilder);
subQuery.setShouldRetrieveFirstPrimaryKey(true);
subQuery.setSelectionCriteria(elemBuilder.equal(collectionExp).and(collectionExp.equal(elemExp)));
return new CompoundExpressionImpl(metamodel, ((InternalSelection)elem).getCurrentNode().notExists(subQuery), buildList(elem, collection), "isNotMemeber");
}
// get the values and keys collections of the Map, which may then
// be passed to size(), isMember(), isEmpty(), etc
/**
* Create an expression that returns the values of a map.
*
* @return collection expression
*/
@Override
public <V, M extends Map<?, V>> Expression<Collection<V>> values(M map){
return internalLiteral(map.values());
}
/**
* Create an expression that returns the keys of a map.
*
* @return set expression
*/
@Override
public <K, M extends Map<K, ?>> Expression<Set<K>> keys(M map){
return internalLiteral(map.keySet());
}
// string functions:
/**
* Create a predicate for testing whether the expression satisfies the given
* pattern.
*
* @param x
* string expression
* @param pattern
* string expression
* @return like predicate
*/
@Override
public Predicate like(Expression<String> x, Expression<String> pattern){
List<Expression<?>> list = this.buildList(x, pattern);
return new CompoundExpressionImpl(this.metamodel,
((InternalSelection)x).getCurrentNode().like(((InternalSelection)pattern).getCurrentNode()), list, "like");
}
/**
* Create a predicate for testing whether the expression satisfies the given
* pattern.
*
* @param x
* string expression
* @param pattern
* string expression
* @param escapeChar
* escape character expression
* @return like predicate
*/
@Override
public Predicate like(Expression<String> x, Expression<String> pattern, Expression<Character> escapeChar){
List<Expression<?>> list = this.buildList(x, pattern, escapeChar);
return new CompoundExpressionImpl(this.metamodel,
((InternalSelection)x).getCurrentNode().like(((InternalSelection)pattern).getCurrentNode(), ((InternalSelection)escapeChar).getCurrentNode()), list, "like");
}
/**
* Create a predicate for testing whether the expression satisfies the given
* pattern.
*
* @param x
* string expression
* @param pattern
* string expression
* @param escapeChar
* escape character
* @return like predicate
*/
@Override
public Predicate like(Expression<String> x, Expression<String> pattern, char escapeChar){
return this.like(x, pattern, this.internalLiteral(escapeChar));
}
/**
* Create a predicate for testing whether the expression satisfies the given
* pattern.
*
* @param x
* string expression
* @param pattern
* string
* @return like predicate
*/
@Override
public Predicate like(Expression<String> x, String pattern){
List<Expression<?>> list = this.buildList(x, this.internalLiteral(pattern));
return new CompoundExpressionImpl(this.metamodel, ((InternalSelection)x).getCurrentNode().like(pattern), list, "like");
}
/**
* Create a predicate for testing whether the expression satisfies the given
* pattern.
*
* @param x
* string expression
* @param pattern
* string
* @param escapeChar
* escape character expression
* @return like predicate
*/
@Override
public Predicate like(Expression<String> x, String pattern, Expression<Character> escapeChar){
return this.like(x, this.internalLiteral(pattern), escapeChar);
}
/**
* Create a predicate for testing whether the expression satisfies the given
* pattern.
*
* @param x
* string expression
* @param pattern
* string
* @param escapeChar
* escape character
* @return like predicate
*/
@Override
public Predicate like(Expression<String> x, String pattern, char escapeChar){
List<Expression<?>> list = this.buildList(x, this.internalLiteral(pattern), this.internalLiteral(escapeChar));
String escapeString = String.valueOf(escapeChar);
return new CompoundExpressionImpl(this.metamodel,
((InternalSelection)x).getCurrentNode().like(pattern, escapeString), list, "like");
}
/**
* Create a predicate for testing whether the expression does not satisfy
* the given pattern.
*
* @param x
* string expression
* @param pattern
* string expression
* @return like predicate
*/
@Override
public Predicate notLike(Expression<String> x, Expression<String> pattern){
List<Expression<?>> list = this.buildList(x, pattern);
return new CompoundExpressionImpl(this.metamodel,
((InternalSelection)x).getCurrentNode().notLike(((InternalSelection)pattern).getCurrentNode()), list, "notLike");
}
/**
* Create a predicate for testing whether the expression does not satisfy
* the given pattern.
*
* @param x
* string expression
* @param pattern
* string expression
* @param escapeChar
* escape character expression
* @return like predicate
*/
@Override
public Predicate notLike(Expression<String> x, Expression<String> pattern, Expression<Character> escapeChar){
List<Expression<?>> list = this.buildList(x, pattern, escapeChar);
return new CompoundExpressionImpl(this.metamodel,
((InternalSelection)x).getCurrentNode().notLike(((InternalSelection)pattern).getCurrentNode(),
((InternalSelection)escapeChar).getCurrentNode()), list, "like");
}
/**
* Create a predicate for testing whether the expression does not satisfy
* the given pattern.
*
* @param x
* string expression
* @param pattern
* string expression
* @param escapeChar
* escape character
* @return like predicate
*/
@Override
public Predicate notLike(Expression<String> x, Expression<String> pattern, char escapeChar){
return this.notLike(x, pattern, this.internalLiteral(escapeChar));
}
/**
* Create a predicate for testing whether the expression does not satisfy
* the given pattern.
*
* @param x
* string expression
* @param pattern
* string
* @return like predicate
*/
@Override
public Predicate notLike(Expression<String> x, String pattern){
List<Expression<?>> list = new ArrayList<>();
list.add(x);
list.add(this.internalLiteral(pattern));
return new CompoundExpressionImpl(this.metamodel,
((InternalSelection)x).getCurrentNode().notLike(pattern), list, "notLike");
}
/**
* Create a predicate for testing whether the expression does not satisfy
* the given pattern.
*
* @param x
* string expression
* @param pattern
* string
* @param escapeChar
* escape character expression
* @return like predicate
*/
@Override
public Predicate notLike(Expression<String> x, String pattern, Expression<Character> escapeChar){
return this.notLike(x, this.internalLiteral(pattern), escapeChar);
}
/**
* Create a predicate for testing whether the expression does not satisfy
* the given pattern.
*
* @param x
* string expression
* @param pattern
* string
* @param escapeChar
* escape character
* @return like predicate
*/
@Override
public Predicate notLike(Expression<String> x, String pattern, char escapeChar){
return this.notLike(x, this.internalLiteral(pattern), this.internalLiteral(escapeChar));
}
/**
* String concatenation operation.
*
* @param x
* string expression
* @param y
* string expression
* @return expression corresponding to concatenation
*/
@Override
public Expression<String> concat(Expression<String> x, Expression<String> y){
List<Expression<?>> list = new ArrayList<>();
list.add(x);
list.add(y);
org.eclipse.persistence.expressions.Expression xNode = ((InternalSelection)x).getCurrentNode();
org.eclipse.persistence.expressions.Expression yNode = ((InternalSelection)y).getCurrentNode();
if (xNode.isParameterExpression() && yNode.isParameterExpression()) {
//some database require the type when concatting two parameters.
((org.eclipse.persistence.internal.expressions.ParameterExpression)xNode).setType(ClassConstants.STRING);
}
return new FunctionExpressionImpl(this.metamodel, ClassConstants.STRING, xNode.concat(yNode), list, CONCAT);
}
/**
* String concatenation operation.
*
* @param x
* string expression
* @param y
* string
* @return expression corresponding to concatenation
*/
@Override
public Expression<String> concat(Expression<String> x, String y){
List<Expression<?>> list = new ArrayList<>();
list.add(x);
list.add(this.internalLiteral(y));
return new FunctionExpressionImpl(this.metamodel, ClassConstants.STRING, ((InternalSelection)x).getCurrentNode().concat(y), list, CONCAT);
}
/**
* String concatenation operation.
*
* @param x
* string
* @param y
* string expression
* @return expression corresponding to concatenation
*/
@Override
public Expression<String> concat(String x, Expression<String> y){
List<Expression<?>> list = new ArrayList<>();
ExpressionImpl literal = (ExpressionImpl) this.internalLiteral(x);
list.add(literal);
list.add(y);
return new FunctionExpressionImpl(this.metamodel, ClassConstants.STRING, ((InternalSelection)literal).getCurrentNode().concat(((InternalSelection)y).getCurrentNode()), list, CONCAT);
}
/**
* Substring extraction operation. Extracts a substring starting at
* specified position through to end of the string. First position is 1.
*
* @param x
* string expression
* @param from
* start position expression
* @return expression corresponding to substring extraction
*/
@Override
public Expression<String> substring(Expression<String> x, Expression<Integer> from) {
return new FunctionExpressionImpl<String>(metamodel, ClassConstants.STRING, ((InternalSelection) x).getCurrentNode().substring(((InternalSelection) from).getCurrentNode()), buildList(x, from), "subString");
}
/**
* Substring extraction operation. Extracts a substring starting at
* specified position through to end of the string. First position is 1.
*
* @param x
* string expression
* @param from
* start position
* @return expression corresponding to substring extraction
*/
@Override
public Expression<String> substring(Expression<String> x, int from){
return substring(x, this.internalLiteral(from));
}
/**
* Substring extraction operation. Extracts a substring of given length
* starting at specified position. First position is 1.
*
* @param x
* string expression
* @param from
* start position expression
* @param len
* length expression
* @return expression corresponding to substring extraction
*/
@Override
public Expression<String> substring(Expression<String> x, Expression<Integer> from, Expression<Integer> len){
return new FunctionExpressionImpl<String>(metamodel, ClassConstants.STRING, ((InternalSelection) x).getCurrentNode().substring(((InternalSelection) from).getCurrentNode(), ((InternalSelection) len).getCurrentNode()), buildList(x, from, len), "subString");
}
/**
* Substring extraction operation. Extracts a substring of given length
* starting at specified position. First position is 1.
*
* @param x
* string expression
* @param from
* start position
* @param len
* length
* @return expression corresponding to substring extraction
*/
@Override
public Expression<String> substring(Expression<String> x, int from, int len){
return new FunctionExpressionImpl<String>(metamodel, ClassConstants.STRING, ((InternalSelection) x).getCurrentNode().substring(from, len), buildList(x, internalLiteral(from), internalLiteral(len)), "subString");
}
/**
* Create expression to trim blanks from both ends of a string.
*
* @param x
* expression for string to trim
* @return trim expression
*/
@Override
public Expression<String> trim(Expression<String> x){
List<Expression<?>> list = this.buildList(x);
return new FunctionExpressionImpl(this.metamodel, ClassConstants.STRING, ((InternalSelection)x).getCurrentNode().trim(), list, "trim");
}
/**
* Create expression to trim blanks from a string.
*
* @param ts
* trim specification
* @param x
* expression for string to trim
* @return trim expression
*/
@Override
public Expression<String> trim(Trimspec ts, Expression<String> x){
List<Expression<?>> list = this.buildList(x);
if(ts == Trimspec.LEADING) {
return new FunctionExpressionImpl(this.metamodel, ClassConstants.STRING, ((InternalSelection)x).getCurrentNode().leftTrim(), list, "leftTrim");
} else if(ts == Trimspec.TRAILING) {
return new FunctionExpressionImpl(this.metamodel, ClassConstants.STRING, ((InternalSelection)x).getCurrentNode().rightTrim(), list, "rightTrim");
}
return new FunctionExpressionImpl(this.metamodel, ClassConstants.STRING, ((InternalSelection)x).getCurrentNode().rightTrim().leftTrim(), list, "bothTrim");
}
/**
* Create expression to trim character from both ends of a string.
*
* @param t
* expression for character to be trimmed
* @param x
* expression for string to trim
* @return trim expression
*/
@Override
public Expression<String> trim(Expression<Character> t, Expression<String> x){
List<Expression<?>> list = this.buildList(x, t);
return new FunctionExpressionImpl(this.metamodel, ClassConstants.STRING, ((InternalSelection)x).getCurrentNode().trim(((InternalSelection)t).getCurrentNode()), list, "trim");
}
/**
* Create expression to trim character from a string.
*
* @param ts
* trim specification
* @param t
* expression for character to be trimmed
* @param x
* expression for string to trim
* @return trim expression
*/
@Override
public Expression<String> trim(Trimspec ts, Expression<Character> t, Expression<String> x){
List<Expression<?>> list = this.buildList(x, t);
if(ts == Trimspec.LEADING) {
return new FunctionExpressionImpl(this.metamodel, ClassConstants.STRING,
((InternalSelection)x).getCurrentNode().leftTrim(((InternalSelection)t).getCurrentNode()), list, "leftTrim");
} else if(ts == Trimspec.TRAILING) {
return new FunctionExpressionImpl(this.metamodel, ClassConstants.STRING,
((InternalSelection)x).getCurrentNode().rightTrim(((InternalSelection)t).getCurrentNode()), list, "rightTrim");
}
return new FunctionExpressionImpl(this.metamodel, ClassConstants.STRING,
((InternalSelection)x).getCurrentNode().rightTrim(((InternalSelection)t).getCurrentNode()).leftTrim(((InternalSelection)t).getCurrentNode()), list, "bothTrim");
}
/**
* Create expression to trim character from both ends of a string.
*
* @param t
* character to be trimmed
* @param x
* expression for string to trim
* @return trim expression
*/
@Override
public Expression<String> trim(char t, Expression<String> x){
return trim(this.internalLiteral(t), x);
}
/**
* Create expression to trim character from a string.
*
* @param ts
* trim specification
* @param t
* character to be trimmed
* @param x
* expression for string to trim
* @return trim expression
*/
@Override
public Expression<String> trim(Trimspec ts, char t, Expression<String> x){
return trim(ts, this.internalLiteral(t), x);
}
/**
* Create expression for converting a string to lowercase.
*
* @param x
* string expression
* @return expression to convert to lowercase
*/
@Override
public Expression<String> lower(Expression<String> x){
List<Expression<?>> list = this.buildList(x);
return new FunctionExpressionImpl(this.metamodel, ClassConstants.STRING, ((InternalSelection)x).getCurrentNode().toLowerCase(), list, "lower");
}
/**
* Create expression for converting a string to uppercase.
*
* @param x
* string expression
* @return expression to convert to uppercase
*/
@Override
public Expression<String> upper(Expression<String> x){
List<Expression<?>> list = this.buildList(x);
return new FunctionExpressionImpl(this.metamodel, ClassConstants.STRING, ((InternalSelection)x).getCurrentNode().toUpperCase(), list, "upper");
}
/**
* Create expression to return length of a string.
*
* @param x
* string expression
* @return length expression
*/
@Override
public Expression<Integer> length(Expression<String> x){
return new FunctionExpressionImpl(metamodel, ClassConstants.INTEGER, ((InternalSelection)x).getCurrentNode().length(), buildList(x), "length");
}
/**
* Create expression to locate the position of one string within another,
* returning position of first character if found. The first position in a
* string is denoted by 1. If the string to be located is not found, 0 is
* returned.
*
* @param x
* expression for string to be searched
* @param pattern
* expression for string to be located
* @return expression corresponding to position
*/
@Override
public Expression<Integer> locate(Expression<String> x, Expression<String> pattern){
return new FunctionExpressionImpl<Integer>(metamodel, ClassConstants.INTEGER, ((InternalSelection)x).getCurrentNode().locate(((InternalSelection)pattern).getCurrentNode()), buildList(x, pattern),"locate");
}
/**
* Create expression to locate the position of one string within another,
* returning position of first character if found. The first position in a
* string is denoted by 1. If the string to be located is not found, 0 is
* returned.
*
* @param x
* expression for string to be searched
* @param pattern
* expression for string to be located
* @param from
* expression for position at which to start search
* @return expression corresponding to position
*/
@Override
public Expression<Integer> locate(Expression<String> x, Expression<String> pattern, Expression<Integer> from){
return new FunctionExpressionImpl<Integer>(metamodel, ClassConstants.INTEGER, ((InternalSelection)x).getCurrentNode().locate(((InternalSelection)pattern).getCurrentNode(), ((InternalSelection)from).getCurrentNode()), buildList(x, pattern, from),"locate");
}
/**
* Create expression to locate the position of one string within another,
* returning position of first character if found. The first position in a
* string is denoted by 1. If the string to be located is not found, 0 is
* returned.
*
* @param x
* expression for string to be searched
* @param pattern
* string to be located
* @return expression corresponding to position
*/
@Override
public Expression<Integer> locate(Expression<String> x, String pattern){
return new FunctionExpressionImpl<Integer>(metamodel, ClassConstants.INTEGER, ((InternalSelection)x).getCurrentNode().locate(pattern), buildList(x, internalLiteral(pattern)),"locate");
}
/**
* Create expression to locate the position of one string within another,
* returning position of first character if found. The first position in a
* string is denoted by 1. If the string to be located is not found, 0 is
* returned.
*
* @param x
* expression for string to be searched
* @param pattern
* string to be located
* @param from
* position at which to start search
* @return expression corresponding to position
*/
@Override
public Expression<Integer> locate(Expression<String> x, String pattern, int from){
return new FunctionExpressionImpl<Integer>(metamodel, ClassConstants.INTEGER, ((InternalSelection)x).getCurrentNode().locate(pattern, from), buildList(x, internalLiteral(pattern), internalLiteral(from)),"locate");
}
// Date/time/timestamp functions:
/**
* Create expression to return current date.
*
* @return expression for current date
*/
@Override
public Expression<java.sql.Date> currentDate(){
return new ExpressionImpl(metamodel, ClassConstants.SQLDATE, new ExpressionBuilder().currentDateDate());
}
/**
* Create expression to return current timestamp.
*
* @return expression for current timestamp
*/
@Override
public Expression<java.sql.Timestamp> currentTimestamp(){
return new ExpressionImpl(metamodel, ClassConstants.TIMESTAMP, new ExpressionBuilder().currentTimeStamp());
}
/**
* Create expression to return current time.
*
* @return expression for current time
*/
@Override
public Expression<java.sql.Time> currentTime(){
return new ExpressionImpl(metamodel, ClassConstants.TIME, new ExpressionBuilder().currentTime());
}
/**
* Create expression to return current local date.
*
* @return expression for current date
*/
@Override
public Expression<java.time.LocalDate> localDate() {
// TODO: Implement
throw new UnsupportedOperationException("Local date expression is not implemented yet");
}
/**
* Create expression to return current local datetime.
*
* @return expression for current timestamp
*/
@Override
public Expression<java.time.LocalDateTime> localDateTime() {
// TODO: Implement
throw new UnsupportedOperationException("Local datetime expression is not implemented yet");
}
/**
* Create expression to return current local time.
*
* @return expression for current time
*/
@Override
public Expression<java.time.LocalTime> localTime() {
// TODO: Implement
throw new UnsupportedOperationException("Local time expression is not implemented yet");
}
/**
* Create predicate to test whether given expression is contained in a list
* of values.
*
* @param expression
* to be tested against list of values
* @return in predicate
*/
@Override
public <T> In<T> in(Expression<? extends T> expression){
List<Expression<?>> list = new ArrayList<>();
list.add(expression);
return new InImpl(metamodel, (ExpressionImpl) expression, new ArrayList<>(), list);
}
// coalesce, nullif:
/**
* Create an expression that returns null if all its arguments evaluate to
* null, and the value of the first non-null argument otherwise.
*
* @param x
* expression
* @param y
* expression
* @return expression corresponding to the given coalesce expression
*/
@Override
public <Y> Expression<Y> coalesce(Expression<? extends Y> x, Expression<? extends Y> y) {
ArgumentListFunctionExpression coalesce = ((InternalSelection)x).getCurrentNode().coalesce();
org.eclipse.persistence.expressions.Expression expX = ((InternalSelection)x).getCurrentNode();
expX = org.eclipse.persistence.expressions.Expression.from(expX, coalesce);
coalesce.addChild(expX);
org.eclipse.persistence.expressions.Expression expY = ((InternalSelection)y).getCurrentNode();
expY = org.eclipse.persistence.expressions.Expression.from(expY, coalesce);
coalesce.addChild(expY);
return new CoalesceImpl(metamodel, x.getJavaType(), coalesce, buildList(x, y), "coalesce");
}
/**
* Create an expression that returns null if all its arguments evaluate to
* null, and the value of the first non-null argument otherwise.
*
* @param x
* expression
* @param y
* value
* @return coalesce expression
*/
@Override
public <Y> Expression<Y> coalesce(Expression<? extends Y> x, Y y) {
ArgumentListFunctionExpression coalesce = ((InternalSelection)x).getCurrentNode().coalesce();
org.eclipse.persistence.expressions.Expression expX = ((InternalSelection)x).getCurrentNode();
expX = org.eclipse.persistence.expressions.Expression.from(expX, coalesce);
coalesce.addChild(expX);
org.eclipse.persistence.expressions.Expression expY = org.eclipse.persistence.expressions.Expression.from(y, new ExpressionBuilder());
coalesce.addChild(expY);
return new CoalesceImpl(metamodel, x.getJavaType(), coalesce, buildList(x, internalLiteral(y)), "coalesce");
}
/**
* Create an expression that tests whether its argument are equal, returning
* null if they are and the value of the first expression if they are not.
*
* @param x
* expression
* @param y
* expression
* @return expression corresponding to the given nullif expression
*/
@Override
public <Y> Expression<Y> nullif(Expression<Y> x, Expression<?> y){
return new FunctionExpressionImpl(metamodel, x.getJavaType(), ((InternalSelection)x).getCurrentNode().nullIf(((InternalSelection)y).getCurrentNode()), buildList(x, y), "nullIf");
}
/**
* Create an expression that tests whether its argument are equal, returning
* null if they are and the value of the first expression if they are not.
*
* @param x
* expression
* @param y
* value
* @return expression corresponding to the given nullif expression
*/
@Override
public <Y> Expression<Y> nullif(Expression<Y> x, Y y){
return new FunctionExpressionImpl(metamodel, x.getJavaType(), ((InternalSelection)x).getCurrentNode().nullIf(y), buildList(x, internalLiteral(y)), "nullIf");
}
/**
* Create a coalesce expression.
*
* @return coalesce expression
*/
@Override
public <T> Coalesce<T> coalesce(){
ArgumentListFunctionExpression coalesce = new ExpressionBuilder().coalesce();
return new CoalesceImpl(metamodel, Object.class, coalesce, new ArrayList<>());
}
/**
* Create simple case expression.
*
* @param expression
* to be tested against the case conditions
* @return simple case expression
*/
@Override
public <C, R> SimpleCase<C, R> selectCase(Expression<? extends C> expression){
ArgumentListFunctionExpression caseStatement = new ExpressionBuilder().caseStatement();
return new SimpleCaseImpl(metamodel, Object.class, caseStatement, new ArrayList<>(), expression);
}
/**
* Create a general case expression.
*
* @return general case expression
*/
@Override
public <R> Case<R> selectCase(){
ArgumentListFunctionExpression caseStatement = new ExpressionBuilder().caseConditionStatement();
return new CaseImpl(metamodel, Object.class, caseStatement, new ArrayList<>());
}
/**
* Create an expression for execution of a database function.
*
* @param name
* function name
* @param type
* expected result type
* @param args
* function arguments
* @return expression
*/
@Override
public <T> Expression<T> function(String name, Class<T> type, Expression<?>... args){
if (args != null && args.length > 0){
List<org.eclipse.persistence.expressions.Expression> params = new ArrayList<org.eclipse.persistence.expressions.Expression>();
for (int index = 1; index < args.length; ++index){
Expression<?> x = args[index];
params.add(((InternalSelection)x).getCurrentNode());
}
return new FunctionExpressionImpl<T>(metamodel, type, ((InternalSelection)args[0]).getCurrentNode().getFunctionWithArguments(name, params), buildList(args), name);
}else{
return new FunctionExpressionImpl<T>(metamodel, type, new ExpressionBuilder().getFunction(name), new ArrayList<>(0), name);
}
}
/**
* ADVANCED:
* Allow a Criteria Expression to be built from a EclipseLink native API Expression object.
* This allows for an extended functionality supported in EclipseLink Expressions to be used in Criteria.
*/
@Override
public <T> Expression<T> fromExpression(org.eclipse.persistence.expressions.Expression expression, Class<T> type) {
return new FunctionExpressionImpl<T>(this.metamodel, type, expression, new ArrayList<>(0));
}
/**
* ADVANCED:
* Allow a Criteria Expression to be built from a EclipseLink native API Expression object.
* This allows for an extended functionality supported in EclipseLink Expressions to be used in Criteria.
*/
@Override
public Expression fromExpression(org.eclipse.persistence.expressions.Expression expression) {
return new FunctionExpressionImpl(this.metamodel, Object.class, expression, new ArrayList<>(0));
}
/**
* ADVANCED:
* Allow a Criteria Expression to be converted to a EclipseLink native API Expression object.
* This allows for roots and paths defined in the Criteria to be used with EclipseLink native API Expresions.
*/
@Override
public org.eclipse.persistence.expressions.Expression toExpression(Expression expression) {
return ((SelectionImpl)expression).getCurrentNode();
}
/**
* Interface used to build coalesce expressions.
*
* A coalesce expression is equivalent to a case expression
* that returns null if all its arguments evaluate to null,
* and the value of its first non-null argument otherwise.
*/
public class CoalesceImpl<X> extends FunctionExpressionImpl<X> implements Coalesce<X> {
protected <T> CoalesceImpl (Metamodel metamodel, Class<X> resultClass, org.eclipse.persistence.expressions.Expression expressionNode, List<Expression<?>> compoundExpressions) {
super(metamodel, resultClass, expressionNode, compoundExpressions);
}
protected <T> CoalesceImpl (Metamodel metamodel, Class<X> resultClass, org.eclipse.persistence.expressions.Expression expressionNode, List<Expression<?>> compoundExpressions, String operator) {
super(metamodel, resultClass, expressionNode, compoundExpressions, operator);
}
/**
* Add an argument to the coalesce expression.
* @param value value
* @return coalesce expression
*/
@Override
public Coalesce<X> value(X value) {
org.eclipse.persistence.expressions.Expression exp = org.eclipse.persistence.expressions.Expression.from(value, new ExpressionBuilder());
((FunctionExpression)currentNode).addChild(exp);
Expression<? extends X> valueLiteral = internalLiteral(value);
this.expressions.add(valueLiteral);
return this;
}
/**
* Add an argument to the coalesce expression.
* @param value expression
* @return coalesce expression
*/
@Override
public Coalesce<X> value(Expression<? extends X> value) {
org.eclipse.persistence.expressions.Expression exp = ((InternalSelection)value).getCurrentNode();
exp = org.eclipse.persistence.expressions.Expression.from(exp, currentNode);
((FunctionExpression)currentNode).addChild(exp);
this.expressions.add(value);
return this;
}
}
/**
* Implementation of Case interface from Criteria Builder
* @author tware
*
* @param <R>
*/
public class CaseImpl<R> extends FunctionExpressionImpl<R> implements Case<R> {
// Track the else expression separate to the when expressions as there should only be one
private Expression<? extends R> elseExpression;
protected <T> CaseImpl (Metamodel metamodel, Class<R> resultClass, org.eclipse.persistence.expressions.Expression expressionNode, List<Expression<?>> compoundExpressions) {
super(metamodel, resultClass, expressionNode, compoundExpressions);
}
protected <T> CaseImpl (Metamodel metamodel, Class<R> resultClass, org.eclipse.persistence.expressions.Expression expressionNode, List<Expression<?>> compoundExpressions, String operator) {
super(metamodel, resultClass, expressionNode, compoundExpressions, operator);
}
/**
* Add a when/then clause to the case expression.
* @param condition "when" condition
* @param result "then" result value
* @return general case expression
*/
@Override
public Case<R> when(Expression<Boolean> condition, R result) {
org.eclipse.persistence.expressions.Expression conditionExp = ((InternalSelection)condition).getCurrentNode();
conditionExp = org.eclipse.persistence.expressions.Expression.from(conditionExp, currentNode);
((FunctionExpression)currentNode).addChild(conditionExp);
this.expressions.add(condition);
org.eclipse.persistence.expressions.Expression resultExp = org.eclipse.persistence.expressions.Expression.from(result, new ExpressionBuilder());
((FunctionExpression)currentNode).addChild(resultExp);
Expression<R> resultLiteral = internalLiteral(result);
this.expressions.add(resultLiteral);
setJavaType((Class<R>) resultLiteral.getJavaType());
return this;
}
/**
* Add a when/then clause to the case expression.
* @param condition "when" condition
* @param result "then" result expression
* @return general case expression
*/
@Override
public Case<R> when(Expression<Boolean> condition, Expression<? extends R> result) {
org.eclipse.persistence.expressions.Expression conditionExp = ((InternalSelection)condition).getCurrentNode();
conditionExp = org.eclipse.persistence.expressions.Expression.from(conditionExp, currentNode);
((FunctionExpression)currentNode).addChild(conditionExp);
this.expressions.add(condition);
org.eclipse.persistence.expressions.Expression resultExp = ((InternalSelection)result).getCurrentNode();
resultExp = org.eclipse.persistence.expressions.Expression.from(resultExp, currentNode);
((FunctionExpression)currentNode).addChild(resultExp);
this.expressions.add(result);
setJavaType((Class<R>) result.getJavaType());
return this;
}
/**
* Add an "else" clause to the case expression.
* @param result "else" result
* @return expression
*/
@Override
public Expression<R> otherwise(R result) {
org.eclipse.persistence.expressions.Expression resultExp = org.eclipse.persistence.expressions.Expression.from(result, new ExpressionBuilder());
((ArgumentListFunctionExpression)currentNode).addRightMostChild(resultExp);
Expression<R> resultLiteral = internalLiteral(result);
this.elseExpression = resultLiteral;
setJavaType((Class<R>) resultLiteral.getJavaType());
return this;
}
/**
* Add an "else" clause to the case expression.
* @param result "else" result expression
* @return expression
*/
@Override
public Expression<R> otherwise(Expression<? extends R> result) {
org.eclipse.persistence.expressions.Expression resultExp = ((InternalSelection)result).getCurrentNode();
resultExp = org.eclipse.persistence.expressions.Expression.from(resultExp, currentNode);
((ArgumentListFunctionExpression)currentNode).addRightMostChild(resultExp);
this.elseExpression = result;
setJavaType((Class<R>) result.getJavaType());
return this;
}
@Override
public void findRootAndParameters(CommonAbstractCriteriaImpl query) {
super.findRootAndParameters(query);
if (this.elseExpression != null){
((InternalSelection)elseExpression).findRootAndParameters(query);
}
}
}
/**
* Implementation of SimpleCase interface from CriteriaBuilder
* @author tware
*
* @param <C>
* @param <R>
*/
public class SimpleCaseImpl<C,R> extends FunctionExpressionImpl<R> implements SimpleCase<C, R> {
private Expression<C> expression;
// Track the else expression separate to the when expressions as there should only be one
private Expression<? extends R> elseExpression;
protected <T> SimpleCaseImpl (Metamodel metamodel, Class<R> resultClass, FunctionExpression expressionNode, List<Expression<?>> compoundExpressions, Expression<C> expression) {
super(metamodel, resultClass, expressionNode, compoundExpressions);
this.expression = expression;
expressionNode.addChild(((InternalSelection)expression).getCurrentNode());
}
protected <T> SimpleCaseImpl (Metamodel metamodel, Class<R> resultClass, FunctionExpression expressionNode, List<Expression<?>> compoundExpressions, String operator, Expression<C> expression) {
super(metamodel, resultClass, expressionNode, compoundExpressions, operator);
this.expression = expression;
expressionNode.addChild(((InternalSelection)expression).getCurrentNode());
}
/**
* Returns the expression to be tested against the
* conditions.
* @return expression
*/
@Override
public Expression<C> getExpression(){
return expression;
}
/**
* Add a when/then clause to the case expression.
* @param condition "when" condition
* @param result "then" result value
* @return simple case expression
*/
@Override
public SimpleCase<C, R> when(C condition, R result) {
org.eclipse.persistence.expressions.Expression conditionExp = org.eclipse.persistence.expressions.Expression.from(condition, new ExpressionBuilder());
((FunctionExpression)currentNode).addChild(conditionExp);
Expression<C> conditionLiteral = internalLiteral(condition);
this.expressions.add(conditionLiteral);
org.eclipse.persistence.expressions.Expression resultExp = org.eclipse.persistence.expressions.Expression.from(result, new ExpressionBuilder());
((FunctionExpression)currentNode).addChild(resultExp);
Expression<R> resultLiteral = internalLiteral(result);
this.expressions.add(resultLiteral);
setJavaType((Class<R>) resultLiteral.getJavaType());
return this;
}
/**
* Add a when/then clause to the case expression.
* @param condition "when" condition
* @param result "then" result expression
* @return simple case expression
*/
@Override
public SimpleCase<C, R> when(C condition, Expression<? extends R> result) {
org.eclipse.persistence.expressions.Expression conditionExp = org.eclipse.persistence.expressions.Expression.from(condition, new ExpressionBuilder());
((FunctionExpression)currentNode).addChild(conditionExp);
Expression<C> conditionLiteral = internalLiteral(condition);
this.expressions.add(conditionLiteral);
org.eclipse.persistence.expressions.Expression resultExp = ((InternalSelection)result).getCurrentNode();
resultExp = org.eclipse.persistence.expressions.Expression.from(resultExp, currentNode);
((FunctionExpression)currentNode).addChild(resultExp);
this.expressions.add(result);
setJavaType((Class<R>) result.getJavaType());
return this;
}
/**
* Add a when/then clause to the case expression.
* @param condition "when" condition
* @param result "then" result value
* @return simple case expression
*/
@Override
public SimpleCase<C, R> when(Expression<? extends C> condition, R result) {
org.eclipse.persistence.expressions.Expression conditionExp = org.eclipse.persistence.expressions.Expression.from(condition, new ExpressionBuilder());
((FunctionExpression)currentNode).addChild(conditionExp);
this.expressions.add(condition);
org.eclipse.persistence.expressions.Expression resultExp = ((InternalSelection)result).getCurrentNode();
resultExp = org.eclipse.persistence.expressions.Expression.from(resultExp, currentNode);
((FunctionExpression)currentNode).addChild(resultExp);
Expression<R> resultLiteral = internalLiteral(result);
this.expressions.add(resultLiteral);
setJavaType((Class<R>) resultLiteral.getJavaType());
return this;
}
/**
* Add a when/then clause to the case expression.
* @param condition "when" condition
* @param result "then" result expression
* @return simple case expression
*/
@Override
public SimpleCase<C, R> when(Expression<? extends C> condition, Expression<? extends R> result) {
org.eclipse.persistence.expressions.Expression conditionExp = org.eclipse.persistence.expressions.Expression.from(condition, new ExpressionBuilder());
((FunctionExpression)currentNode).addChild(conditionExp);
this.expressions.add(condition);
org.eclipse.persistence.expressions.Expression resultExp = ((InternalSelection)result).getCurrentNode();
resultExp = org.eclipse.persistence.expressions.Expression.from(resultExp, currentNode);
((FunctionExpression)currentNode).addChild(resultExp);
this.expressions.add(result);
setJavaType((Class<R>) result.getJavaType());
return this;
}
/**
* Add an "else" clause to the case expression.
* @param result "else" result
* @return expression
*/
@Override
public Expression<R> otherwise(R result) {
org.eclipse.persistence.expressions.Expression resultExp = org.eclipse.persistence.expressions.Expression.from(result, new ExpressionBuilder());
((ArgumentListFunctionExpression)currentNode).addRightMostChild(resultExp);
Expression<R> resultLiteral = internalLiteral(result);
this.elseExpression = resultLiteral;
setJavaType((Class<R>) resultLiteral.getJavaType());
return this;
}
/**
* Add an "else" clause to the case expression.
* @param result "else" result expression
* @return expression
*/
@Override
public Expression<R> otherwise(Expression<? extends R> result) {
org.eclipse.persistence.expressions.Expression resultExp = ((InternalSelection)result).getCurrentNode();
resultExp = org.eclipse.persistence.expressions.Expression.from(resultExp, currentNode);
((ArgumentListFunctionExpression)currentNode).addRightMostChild(resultExp);
this.elseExpression = result;
setJavaType((Class<R>) result.getJavaType());
return this;
}
@Override
public void findRootAndParameters(CommonAbstractCriteriaImpl query) {
super.findRootAndParameters(query);
if(expression != null) {
((InternalSelection)expression).findRootAndParameters(query);
}
if (this.elseExpression != null){
((InternalSelection)elseExpression).findRootAndParameters(query);
}
}
}
@Override
public <T> CriteriaDelete<T> createCriteriaDelete(Class<T> targetEntity) {
if (targetEntity != null) {
TypeImpl<T> type = ((MetamodelImpl)this.metamodel).getType(targetEntity);
if (type != null && type.getPersistenceType().equals(PersistenceType.ENTITY)) {
return new CriteriaDeleteImpl(this.metamodel, this, targetEntity);
}
}
throw new IllegalArgumentException(ExceptionLocalization.buildMessage("unknown_bean_class", new Object[] { targetEntity }));
}
@Override
public <T> CriteriaUpdate<T> createCriteriaUpdate(Class<T> targetEntity) {
if (targetEntity != null) {
TypeImpl<T> type = ((MetamodelImpl)this.metamodel).getType(targetEntity);
if (type != null && type.getPersistenceType().equals(PersistenceType.ENTITY)) {
return new CriteriaUpdateImpl(this.metamodel, this, targetEntity);
}
}
throw new IllegalArgumentException(ExceptionLocalization.buildMessage("unknown_bean_class", new Object[] { targetEntity }));
}
@Override
public <X, T, V extends T> Join<X, V> treat(Join<X, T> join, Class<V> type) {
JoinImpl parentJoin = (JoinImpl)join;
JoinImpl<X, V> joinImpl = new JoinImpl<X, V>(parentJoin, this.metamodel.managedType(type), this.metamodel,
type, parentJoin.currentNode.treat(type), parentJoin.getModel(), parentJoin.getJoinType());
parentJoin.joins.add(joinImpl);
joinImpl.isJoin = parentJoin.isJoin;
parentJoin.isJoin = false;
return joinImpl;
}
@Override
public <X, T, E extends T> CollectionJoin<X, E> treat(CollectionJoin<X, T> join, Class<E> type) {
CollectionJoinImpl parentJoin = (CollectionJoinImpl)join;
CollectionJoin joinImpl = null;
if (join instanceof BasicCollectionJoinImpl) {
joinImpl = new BasicCollectionJoinImpl<X, E>(parentJoin, this.metamodel, type,
parentJoin.currentNode.treat(type), parentJoin.getModel(), parentJoin.getJoinType());
} else {
joinImpl = new CollectionJoinImpl<X, E>((Path)join, this.metamodel.managedType(type), this.metamodel,
type, parentJoin.currentNode.treat(type), parentJoin.getModel(), parentJoin.getJoinType());
}
parentJoin.joins.add(joinImpl);
((FromImpl)joinImpl).isJoin = parentJoin.isJoin;
parentJoin.isJoin = false;
return joinImpl;
}
@Override
public <X, T, E extends T> SetJoin<X, E> treat(SetJoin<X, T> join, Class<E> type) {
SetJoinImpl parentJoin = (SetJoinImpl)join;
SetJoin joinImpl = null;
if (join instanceof BasicSetJoinImpl) {
joinImpl = new BasicSetJoinImpl<X, E>(parentJoin, this.metamodel, type,
parentJoin.currentNode.treat(type), parentJoin.getModel(), parentJoin.getJoinType());
} else {
joinImpl = new SetJoinImpl<X, E>((Path)join, this.metamodel.managedType(type), this.metamodel,
type, parentJoin.currentNode.treat(type), parentJoin.getModel(), parentJoin.getJoinType());
}
parentJoin.joins.add(joinImpl);
((FromImpl)joinImpl).isJoin = parentJoin.isJoin;
parentJoin.isJoin = false;
return joinImpl;
}
@Override
public <X, T, E extends T> ListJoin<X, E> treat(ListJoin<X, T> join, Class<E> type) {
ListJoinImpl parentJoin = (ListJoinImpl)join;
ListJoin joinImpl = null;
if (join instanceof BasicListJoinImpl) {
joinImpl = new BasicListJoinImpl<X, E>(parentJoin, this.metamodel, type,
parentJoin.currentNode.treat(type), parentJoin.getModel(), parentJoin.getJoinType());
} else {
joinImpl = new ListJoinImpl<X, E>((Path)join, this.metamodel.managedType(type), this.metamodel,
type, parentJoin.currentNode.treat(type), parentJoin.getModel(), parentJoin.getJoinType());
}
parentJoin.joins.add(joinImpl);
((FromImpl)joinImpl).isJoin = parentJoin.isJoin;
parentJoin.isJoin = false;
return joinImpl;
}
@Override
public <X, K, T, V extends T> MapJoin<X, K, V> treat(MapJoin<X, K, T> join, Class<V> type) {
MapJoinImpl parentJoin = (MapJoinImpl)join;
MapJoin joinImpl = null;
if (join instanceof BasicMapJoinImpl) {
joinImpl = new BasicMapJoinImpl<X, K, V>(parentJoin, this.metamodel, type,
parentJoin.currentNode.treat(type), parentJoin.getModel(), parentJoin.getJoinType());
} else {
joinImpl = new MapJoinImpl<X, K, V>((Path)join, this.metamodel.managedType(type), this.metamodel,
type, parentJoin.currentNode.treat(type), parentJoin.getModel(), parentJoin.getJoinType());
}
parentJoin.joins.add(joinImpl);
((FromImpl)joinImpl).isJoin = parentJoin.isJoin;
parentJoin.isJoin = false;
return joinImpl;
}
@Override
public <X, T extends X> Path<T> treat(Path<X> path, Class<T> type) {
//Handle all the paths that might get passed in.:
PathImpl parentPath = (PathImpl)path;
PathImpl newPath = (PathImpl)parentPath.clone();
newPath.currentNode = newPath.currentNode.treat(type);
newPath.pathParent = parentPath;
newPath.javaType = type;
newPath.modelArtifact = this.metamodel.managedType(type);
return newPath;
}
@Override
public <X, T extends X> Root<T> treat(Root<X> root, Class<T> type) {
RootImpl parentRoot = (RootImpl)root;
EntityType<T> entity = this.metamodel.entity(type);
return new RootImpl<T>(entity, this.metamodel, type, parentRoot.currentNode.treat(type), entity);
}
}