| /* |
| * Copyright (c) 2011, 2020 Oracle and/or its affiliates. All rights reserved. |
| * |
| * This program and the accompanying materials are made available under the |
| * terms of the Eclipse Public License 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.util.ArrayList; |
| import java.util.Collection; |
| import java.util.List; |
| |
| import jakarta.persistence.criteria.Expression; |
| import jakarta.persistence.criteria.Predicate; |
| import jakarta.persistence.metamodel.Metamodel; |
| |
| import org.eclipse.persistence.descriptors.ClassDescriptor; |
| import org.eclipse.persistence.internal.jpa.metamodel.MetamodelImpl; |
| import org.eclipse.persistence.internal.localization.ExceptionLocalization; |
| import org.eclipse.persistence.sessions.Project; |
| |
| /** |
| * <p> |
| * <b>Purpose</b>: Represents an Expression in the Criteria API heirarchy. |
| * <p> |
| * <b>Description</b>: Expressions are expression nodes that can not be joined from |
| * and may or not be the result of a Path expression. |
| * <p> |
| * |
| * @see jakarta.persistence.criteria Expression |
| * |
| * @author gyorke |
| * @since EclipseLink 1.2 |
| */ |
| public class ExpressionImpl<X> extends SelectionImpl<X> implements Expression<X>, InternalExpression{ |
| protected Metamodel metamodel; |
| protected boolean isLiteral; |
| protected Object literal; |
| |
| protected ExpressionImpl(Metamodel metamodel, Class<X> javaType, org.eclipse.persistence.expressions.Expression expressionNode){ |
| super(javaType, expressionNode); |
| this.metamodel = metamodel; |
| } |
| |
| public ExpressionImpl(Metamodel metamodel, Class<X> javaType, org.eclipse.persistence.expressions.Expression expressionNode, Object value){ |
| super(javaType, expressionNode); |
| this.metamodel = metamodel; |
| this.literal = value; |
| this.isLiteral = true; |
| } |
| |
| @Override |
| public <T> Expression<T> as(Class<T> type) { |
| Project project = ((MetamodelImpl)metamodel).getProject(); |
| if (project != null){ |
| ClassDescriptor descriptor = project.getClassDescriptor(javaType); |
| if (descriptor != null && descriptor.hasInheritance()){ |
| descriptor = descriptor.getInheritancePolicy().getSubclassDescriptor(type); |
| if (descriptor != null){ |
| return buildExpressionForAs(type); |
| } |
| } |
| } |
| return (Expression<T>) this; |
| } |
| |
| protected <T> Expression<T> buildExpressionForAs(Class<T> type) { |
| return (Expression<T>) this; |
| } |
| |
| @Override |
| public Predicate in(Object... values) { |
| List list = new ArrayList(); |
| list.add(this); |
| return new CompoundExpressionImpl(this.metamodel, this.currentNode.in(values), list, "in"); |
| } |
| |
| /** |
| * Apply a predicate to test whether the expression is a member |
| * of the argument list. |
| * @param values |
| * @return predicate testing for membership |
| */ |
| @Override |
| public Predicate in(Expression<?>... values) { |
| if (values != null) { |
| if (values.length == 1 && ((InternalExpression) values[0]).isParameter() |
| && Collection.class.isAssignableFrom(((ParameterExpressionImpl) values[0]).getJavaType())) { |
| // bug 349477 - Collection from Expression<Collection> was lost during compilation |
| // and if we know that Collection is there we should help the runtime |
| // and route the execution to the right method |
| return in((Expression<Collection<?>>) values[0]); |
| } |
| List list = new ArrayList(); |
| list.add(this); |
| if (values.length == 1 && ((InternalExpression) values[0]).isSubquery()) { |
| list.add(values[0]); |
| return new CompoundExpressionImpl(this.metamodel, this.currentNode.in(((SubQueryImpl) values[0]).subQuery), list, "in"); |
| } else { |
| List<Object> inValues = new ArrayList<Object>(); |
| for (Expression exp : values) { |
| if (!((InternalExpression) exp).isLiteral() && !((InternalExpression) exp).isParameter()) { |
| Object[] params = new Object[]{exp}; |
| throw new IllegalArgumentException(ExceptionLocalization.buildMessage("CRITERIA_NON_LITERAL_PASSED_TO_IN",params)); |
| } else { |
| list.add(exp); |
| inValues.add(((InternalSelection)exp).getCurrentNode()); |
| } |
| } |
| |
| return new CompoundExpressionImpl(this.metamodel, this.currentNode.in(inValues), list, "in"); |
| } |
| } |
| throw new IllegalArgumentException(ExceptionLocalization.buildMessage("NULL_PASSED_TO_EXPRESSION_IN")); |
| } |
| |
| /** |
| * Apply a predicate to test whether the expression is a member |
| * of the collection. |
| * @param values collection |
| * @return predicate testing for membership |
| */ |
| @Override |
| public Predicate in(Collection<?> values) { |
| List list = new ArrayList(); |
| list.add(this); |
| return new InImpl(this.metamodel, this, values, list); |
| } |
| /** |
| * Apply a predicate to test whether the expression is a member |
| * of the collection. |
| * @param values expression corresponding to collection |
| * @return predicate testing for membership |
| */ |
| @Override |
| public Predicate in(Expression<Collection<?>> values) { |
| List list = new ArrayList(); |
| list.add(values); |
| list.add(this); |
| return new InImpl(metamodel, this, (ExpressionImpl)values, list); |
| } |
| |
| @Override |
| public Predicate isNotNull() { |
| List list = new ArrayList(); |
| list.add(this); |
| return new CompoundExpressionImpl(this.metamodel, this.currentNode.notNull(), list, "not null"); |
| } |
| |
| |
| @Override |
| public Predicate isNull() { |
| List list = new ArrayList(); |
| list.add(this); |
| return new CompoundExpressionImpl(this.metamodel, this.currentNode.isNull(), list, "is null"); |
| } |
| |
| @Override |
| public boolean isPredicate(){ |
| return false; |
| } |
| |
| @Override |
| public boolean isSubquery(){ |
| return false; |
| } |
| |
| @Override |
| public boolean isCompoundExpression(){ |
| return false; |
| } |
| @Override |
| public boolean isExpression(){ |
| return true; |
| } |
| |
| @Override |
| public boolean isJunction(){ |
| return false; |
| } |
| |
| @Override |
| public boolean isLiteral(){ |
| return this.isLiteral; |
| } |
| @Override |
| public boolean isParameter(){ |
| return false; |
| } |
| @Override |
| public void findRootAndParameters(CommonAbstractCriteriaImpl criteriaQuery){ |
| //no-op because an expression will have no root |
| } |
| |
| } |