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

org.eclipse.persistence.internal.jpa.querydef.FromImpl Maven / Gradle / Ivy

There is a newer version: 5.0.0-B03
Show newest version
/*
 * Copyright (c) 2011, 2021 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.HashSet;
import java.util.List;
import java.util.Set;
import java.util.Stack;

import jakarta.persistence.criteria.CollectionJoin;
import jakarta.persistence.criteria.Expression;
import jakarta.persistence.criteria.Fetch;
import jakarta.persistence.criteria.From;
import jakarta.persistence.criteria.Join;
import jakarta.persistence.criteria.JoinType;
import jakarta.persistence.criteria.ListJoin;
import jakarta.persistence.criteria.MapJoin;
import jakarta.persistence.criteria.Path;
import jakarta.persistence.criteria.SetJoin;
import jakarta.persistence.metamodel.Attribute;
import jakarta.persistence.metamodel.Attribute.PersistentAttributeType;
import jakarta.persistence.metamodel.Bindable;
import jakarta.persistence.metamodel.CollectionAttribute;
import jakarta.persistence.metamodel.ListAttribute;
import jakarta.persistence.metamodel.ManagedType;
import jakarta.persistence.metamodel.MapAttribute;
import jakarta.persistence.metamodel.Metamodel;
import jakarta.persistence.metamodel.PluralAttribute;
import jakarta.persistence.metamodel.PluralAttribute.CollectionType;
import jakarta.persistence.metamodel.SingularAttribute;
import jakarta.persistence.metamodel.Type.PersistenceType;

import org.eclipse.persistence.internal.expressions.ObjectExpression;
import org.eclipse.persistence.internal.helper.ClassConstants;
import org.eclipse.persistence.internal.localization.ExceptionLocalization;

/**
 * 

* Purpose: Contains the implementation of the From interface of the JPA * criteria API. *

* Description: This class represents a from clause element which could * be the root of the query of the end node of a join statement. *

* * @see jakarta.persistence.criteria From * * @author gyorke * @since EclipseLink 1.2 */ public class FromImpl extends PathImpl implements jakarta.persistence.criteria.From { protected ManagedType managedType; protected Set> joins; protected Set> fetches; protected boolean isJoin = false; protected boolean isFetch = false; protected FromImpl correlatedParent; public FromImpl(Path parentPath, ManagedType managedType, Metamodel metamodel, Class javaClass, org.eclipse.persistence.expressions.Expression expressionNode, Bindable modelArtifact) { super(parentPath, metamodel, javaClass, expressionNode, modelArtifact); this.managedType = managedType; this.joins = new HashSet>(); this.fetches = new HashSet>(); } public FromImpl(Path parentPath, ManagedType managedType, Metamodel metamodel, Class javaClass, org.eclipse.persistence.expressions.Expression expressionNode, Bindable modelArtifact, FromImpl correlatedParent) { this(parentPath, managedType, metamodel, javaClass, expressionNode, modelArtifact); this.correlatedParent = correlatedParent; } /** * Return the fetch joins that have been made from this type. * * @return fetch joins made from this type */ @Override public java.util.Set> getFetches(){ return this.fetches; } /** * Whether the From object has been obtained as a result of * correlation (use of a Subquery correlate * method). * @return boolean indicating whether the object has been * obtained through correlation */ @Override public boolean isCorrelated(){ return this.correlatedParent != null; } /** * Returns the parent From object from which the correlated * From object has been obtained through correlation (use * of a Subquery correlate method). * @return the parent of the correlated From object * @throws IllegalStateException if the From object has * not been obtained through correlation */ @Override public From getCorrelationParent() { if (this.correlatedParent == null){ throw new IllegalStateException(ExceptionLocalization.buildMessage("cannot_get_from_non_correlated_query")); } return this.correlatedParent; } /** * Fetch join to the specified attribute using an inner join. * * @param assoc * target of the join * @return the resulting fetch join */ @Override public Fetch fetch(SingularAttribute assoc){ return this.fetch(assoc, JoinType.INNER); } /** * Fetch join to the specified attribute using the given join type. * * @param assoc * target of the join * @param jt * join type * @return the resulting fetch join */ @Override public Fetch fetch(SingularAttribute assoc, JoinType jt){ if (((SingularAttribute)assoc).getType().getPersistenceType().equals(PersistenceType.BASIC)){ throw new IllegalStateException(ExceptionLocalization.buildMessage("CAN_NOT_JOIN_TO_BASIC")); } Class clazz = assoc.getBindableJavaType(); Fetch join = null; ObjectExpression exp = ((ObjectExpression)this.currentNode).newDerivedExpressionNamed(assoc.getName()); if (jt.equals(JoinType.LEFT)){ exp.doUseOuterJoin(); }else if(jt.equals(JoinType.RIGHT)){ throw new UnsupportedOperationException(ExceptionLocalization.buildMessage("RIGHT_JOIN_NOT_SUPPORTED")); }else{ exp.doNotUseOuterJoin(); } join = new JoinImpl(this, this.metamodel.managedType(clazz), this.metamodel, clazz, exp, assoc, jt); this.fetches.add(join); ((FromImpl)join).isFetch = true; return join; } /** * Fetch join to the specified collection using an inner join. * * @param assoc * target of the join * @return the resulting join */ @Override public Fetch fetch(PluralAttribute assoc){ return fetch(assoc, JoinType.INNER); } /** * Fetch join to the specified collection using the given join type. * * @param assoc * target of the join * @param jt * join type * @return the resulting join */ @Override public Fetch fetch(PluralAttribute assoc, JoinType jt) { org.eclipse.persistence.expressions.Expression node; Fetch fetch; if (jt.equals(JoinType.LEFT)) { node = this.currentNode.anyOfAllowingNone(assoc.getName()); } else if (jt.equals(JoinType.RIGHT)) { throw new UnsupportedOperationException(ExceptionLocalization.buildMessage("RIGHT_JOIN_NOT_SUPPORTED")); } else { node = this.currentNode.anyOf(assoc.getName()); } if (assoc.getElementType().getPersistenceType().equals(PersistenceType.BASIC)) { if (assoc.getCollectionType().equals(CollectionType.COLLECTION)) { fetch = new BasicCollectionJoinImpl(this, this.metamodel, ((PluralAttribute) assoc).getBindableJavaType(), node, (Bindable) assoc, jt); } else if (assoc.getCollectionType().equals(CollectionType.LIST)) { fetch = new BasicListJoinImpl(this, this.metamodel, ((PluralAttribute) assoc).getBindableJavaType(), node, (Bindable) assoc, jt); } else if (assoc.getCollectionType().equals(CollectionType.SET)) { fetch = new BasicSetJoinImpl(this, this.metamodel, ((PluralAttribute) assoc).getBindableJavaType(), node, (Bindable) assoc, jt); } else { fetch = new BasicMapJoinImpl(this, this.metamodel, ((PluralAttribute) assoc).getBindableJavaType(), node, assoc, jt); } } else { if (assoc.getCollectionType().equals(CollectionType.COLLECTION)) { fetch = new CollectionJoinImpl(this, metamodel.managedType(((PluralAttribute) assoc).getBindableJavaType()), this.metamodel, ((PluralAttribute) assoc).getBindableJavaType(), node, (Bindable) assoc, jt); } else if (assoc.getCollectionType().equals(CollectionType.LIST)) { fetch = new ListJoinImpl(this, metamodel.managedType(((PluralAttribute) assoc).getBindableJavaType()), this.metamodel, ((PluralAttribute) assoc).getBindableJavaType(), node, (Bindable) assoc, jt); } else if (assoc.getCollectionType().equals(CollectionType.SET)) { fetch = new SetJoinImpl(this, metamodel.managedType(((PluralAttribute) assoc).getBindableJavaType()), this.metamodel, ((PluralAttribute) assoc).getBindableJavaType(), node, (Bindable) assoc, jt); } else { fetch = new MapJoinImpl(this, metamodel.managedType(((PluralAttribute) assoc).getBindableJavaType()), this.metamodel, ((PluralAttribute) assoc).getBindableJavaType(), node, assoc, jt); } } this.fetches.add(fetch); ((FromImpl)fetch).isFetch = true; return fetch; } // String-based: /** * Fetch join to the specified attribute or association using an inner join. * * @param assocName * name of the attribute or association for the target of the * join * @return the resulting fetch join */ @Override public Fetch fetch(String assocName){ return fetch(assocName, JoinType.INNER); } /** * Fetch join to the specified attribute or association using the given join * type. * * @param assocName * assocName of the attribute or association for the target of * the join * @param jt * join type * @return the resulting fetch join */ @Override public Fetch fetch(String assocName, JoinType jt){ Attribute attribute = this.managedType.getAttribute(assocName); if (attribute.isCollection()) { return fetch(((PluralAttribute)attribute), jt); }else{ return fetch(((SingularAttribute)attribute), jt); } } @Override public Set> getJoins() { return joins; } /** * Return the path corresponding to the referenced non-collection valued * attribute. * * @param att * attribute * @return path corresponding to the referenced attribute */ @Override public Path get(SingularAttribute att){ if (att.getPersistentAttributeType().equals(PersistentAttributeType.BASIC)){ return new PathImpl(this, this.metamodel, att.getBindableJavaType(),this.currentNode.get(att.getName()), att); }else{ Class clazz = att.getBindableJavaType(); Join join = new JoinImpl(this, this.metamodel.managedType(clazz), this.metamodel, clazz,this.currentNode.get(att.getName()), att); this.joins.add(join); return join; } } /** * Return the path corresponding to the referenced collection-valued * attribute. * * @param collection * collection-valued attribute * @return expression corresponding to the referenced attribute */ @Override public > Expression get(PluralAttribute collection){ // This is a special Expression that represents just the collection for member of etc... return new ExpressionImpl(this.metamodel, ClassConstants.Collection_Class ,this.currentNode.anyOf(collection.getName())); } /** * Return the path corresponding to the referenced map-valued attribute. * * @param map * map-valued attribute * @return expression corresponding to the referenced attribute */ @Override public > Expression get(MapAttribute map){ return new ExpressionImpl(this.metamodel, ClassConstants.Map_Class ,this.currentNode.anyOf(map.getName())); } /** * Return an expression corresponding to the type of the path. * * @return expression corresponding to the type of the path */ @Override public Expression> type(){ return new ExpressionImpl(this.metamodel, ClassConstants.CLASS,this.currentNode.type()); } @Override public Path get(String attName) { Attribute attribute = this.managedType.getAttribute(attName); Join join; if (attribute.isCollection()) { if (!((PluralAttribute) attribute).getElementType().getPersistenceType().equals(PersistenceType.BASIC)) { if (((PluralAttribute) attribute).getCollectionType().equals(CollectionType.COLLECTION)) { join = new CollectionJoinImpl(this, metamodel.managedType(((PluralAttribute) attribute).getBindableJavaType()), this.metamodel, ((PluralAttribute) attribute).getBindableJavaType(), this.currentNode.anyOf(attribute.getName()), (Bindable) attribute); } else if (((PluralAttribute) attribute).getCollectionType().equals(CollectionType.LIST)) { join = new ListJoinImpl(this, metamodel.managedType(((PluralAttribute) attribute).getBindableJavaType()), this.metamodel, ((PluralAttribute) attribute).getBindableJavaType(), this.currentNode.anyOf(attribute.getName()), (Bindable) attribute); } else if (((PluralAttribute) attribute).getCollectionType().equals(CollectionType.SET)) { join = new SetJoinImpl(this, metamodel.managedType(((PluralAttribute) attribute).getBindableJavaType()), this.metamodel, ((PluralAttribute) attribute).getBindableJavaType(), this.currentNode.anyOf(attribute.getName()), (Bindable) attribute); } else { join = new MapJoinImpl(this, metamodel.managedType(((PluralAttribute) attribute).getBindableJavaType()), this.metamodel, ((PluralAttribute) attribute).getBindableJavaType(), this.currentNode.anyOf(attribute.getName()), (Bindable) attribute); } } else { if (((PluralAttribute) attribute).getCollectionType().equals(CollectionType.COLLECTION)) { join = new BasicCollectionJoinImpl(this, this.metamodel, ((PluralAttribute) attribute).getBindableJavaType(), this.currentNode.anyOf(attribute.getName()), (Bindable) attribute); } else if (((PluralAttribute) attribute).getCollectionType().equals(CollectionType.LIST)) { join = new BasicListJoinImpl(this, this.metamodel, ((PluralAttribute) attribute).getBindableJavaType(), this.currentNode.anyOf(attribute.getName()), (Bindable) attribute); } else if (((PluralAttribute) attribute).getCollectionType().equals(CollectionType.SET)) { join = new BasicSetJoinImpl(this, this.metamodel, ((PluralAttribute) attribute).getBindableJavaType(), this.currentNode.anyOf(attribute.getName()), (Bindable) attribute); } else{ join = new BasicMapJoinImpl(this, this.metamodel, ((PluralAttribute) attribute).getBindableJavaType(), this.currentNode.anyOf(attribute.getName()), (Bindable) attribute); } } }else{ Class clazz = ((SingularAttribute)attribute).getBindableJavaType(); if (((SingularAttribute)attribute).getType().getPersistenceType().equals(PersistenceType.BASIC)){ return new PathImpl(this, this.metamodel, clazz, this.currentNode.get(attribute.getName()), (Bindable)attribute); }else{ join = new JoinImpl(this, this.metamodel.managedType(clazz), this.metamodel, clazz, this.currentNode.get(attribute.getName()), (Bindable)attribute); } } this.joins.add(join); return join; } @Override public Join join(SingularAttribute attribute) { return this.join(attribute, JoinType.INNER); } @Override public Join join(SingularAttribute attribute, JoinType jt) { if (((SingularAttribute)attribute).getType().getPersistenceType().equals(PersistenceType.BASIC)){ throw new IllegalStateException(ExceptionLocalization.buildMessage("CAN_NOT_JOIN_TO_BASIC")); } Class clazz = attribute.getBindableJavaType(); Join join = null; ObjectExpression exp = ((ObjectExpression)this.currentNode).newDerivedExpressionNamed(attribute.getName()); if (jt.equals(JoinType.LEFT)){ exp.doUseOuterJoin(); }else if(jt.equals(JoinType.RIGHT)){ throw new UnsupportedOperationException(ExceptionLocalization.buildMessage("RIGHT_JOIN_NOT_SUPPORTED")); }else{ exp.doNotUseOuterJoin(); } join = new JoinImpl(this, this.metamodel.managedType(clazz), this.metamodel, clazz, exp, attribute, jt); this.joins.add(join); ((FromImpl)join).isJoin = true; return join; } @Override public CollectionJoin join(CollectionAttribute collection) { return this.join(collection, JoinType.INNER); } @Override public SetJoin join(jakarta.persistence.metamodel.SetAttribute set) { return this.join(set, JoinType.INNER); } @Override public ListJoin join(ListAttribute list) { return this.join(list, JoinType.INNER); } @Override public MapJoin join(MapAttribute map) { return this.join(map, JoinType.INNER); } @Override public CollectionJoin join(CollectionAttribute collection, JoinType jt) { org.eclipse.persistence.expressions.Expression node; Class clazz = collection.getBindableJavaType(); CollectionJoin join = null; if (jt.equals(JoinType.INNER)) { node = this.currentNode.anyOf(collection.getName()); } else if (jt.equals(JoinType.RIGHT)) { throw new UnsupportedOperationException(ExceptionLocalization.buildMessage("RIGHT_JOIN_NOT_SUPPORTED")); } else { node = this.currentNode.anyOfAllowingNone(collection.getName()); } if (collection.getElementType().getPersistenceType().equals(PersistenceType.BASIC)) { join = new BasicCollectionJoinImpl(this, this.metamodel, clazz, node, (Bindable) collection, jt); } else { join = new CollectionJoinImpl(this, metamodel.managedType(clazz), this.metamodel, clazz, node, (Bindable) collection, jt); } this.joins.add(join); ((FromImpl)join).isJoin = true; return join; } @Override public SetJoin join(jakarta.persistence.metamodel.SetAttribute set, JoinType jt) { org.eclipse.persistence.expressions.Expression node; Class clazz = set.getBindableJavaType(); SetJoin join = null; if (jt.equals(JoinType.INNER)) { node = this.currentNode.anyOf(set.getName()); } else if (jt.equals(JoinType.RIGHT)) { throw new UnsupportedOperationException(ExceptionLocalization.buildMessage("RIGHT_JOIN_NOT_SUPPORTED")); } else { node = this.currentNode.anyOfAllowingNone(set.getName()); } if (set.getElementType().getPersistenceType().equals(PersistenceType.BASIC)) { join = new BasicSetJoinImpl(this, this.metamodel, clazz, node, (Bindable) set, jt); } else { join = new SetJoinImpl(this, metamodel.managedType(clazz), this.metamodel, clazz, node, (Bindable) set, jt); } this.joins.add(join); ((FromImpl)join).isJoin = true; return join; } @Override public ListJoin join(ListAttribute list, JoinType jt) { org.eclipse.persistence.expressions.Expression node; Class clazz = list.getBindableJavaType(); ListJoin join = null; if (jt.equals(JoinType.INNER)) { node = this.currentNode.anyOf(list.getName()); } else if (jt.equals(JoinType.RIGHT)) { throw new UnsupportedOperationException(ExceptionLocalization.buildMessage("RIGHT_JOIN_NOT_SUPPORTED")); } else { node = this.currentNode.anyOfAllowingNone(list.getName()); } if (list.getElementType().getPersistenceType().equals(PersistenceType.BASIC)) { join = new BasicListJoinImpl(this, this.metamodel, clazz, node, (Bindable) list, jt); } else { join = new ListJoinImpl(this, metamodel.managedType(clazz), this.metamodel, clazz, node, (Bindable) list, jt); } this.joins.add(join); ((FromImpl)join).isJoin = true; return join; } @Override public MapJoin join(MapAttribute map, JoinType jt) { org.eclipse.persistence.expressions.Expression node; Class clazz = map.getBindableJavaType(); MapJoin join = null; if (jt.equals(JoinType.INNER)) { node = this.currentNode.anyOf(map.getName()); } else if (jt.equals(JoinType.RIGHT)) { throw new UnsupportedOperationException(ExceptionLocalization.buildMessage("RIGHT_JOIN_NOT_SUPPORTED")); } else { node = this.currentNode.anyOfAllowingNone(map.getName()); } if (map.getElementType().getPersistenceType().equals(PersistenceType.BASIC)) { join = new BasicMapJoinImpl(this, this.metamodel, clazz, node, map, jt); } else { join = new MapJoinImpl(this, metamodel.managedType(clazz), this.metamodel, clazz, node, map, jt); } this.joins.add(join); ((FromImpl)join).isJoin = true; return join; } @Override public Join join(String attributeName) { return join(attributeName, JoinType.INNER); } @Override public Join join(String attributeName, JoinType jt) { Attribute attribute = this.managedType.getAttribute(attributeName); if (attribute.isCollection()) { org.eclipse.persistence.expressions.Expression node; if (jt.equals(JoinType.INNER)) { node = this.currentNode.anyOf(attribute.getName()); } else if (jt.equals(JoinType.RIGHT)) { throw new UnsupportedOperationException(ExceptionLocalization.buildMessage("RIGHT_JOIN_NOT_SUPPORTED")); } else { node = this.currentNode.anyOfAllowingNone(attribute.getName()); } Join join; if (((PluralAttribute) attribute).getElementType().getPersistenceType().equals(PersistenceType.BASIC)) { if (((PluralAttribute) attribute).getCollectionType().equals(CollectionType.COLLECTION)) { join = new BasicCollectionJoinImpl(this, this.metamodel, ((PluralAttribute) attribute).getBindableJavaType(), node, (Bindable) attribute, jt); } else if (((PluralAttribute) attribute).getCollectionType().equals(CollectionType.LIST)) { join = new BasicListJoinImpl(this, this.metamodel, ((PluralAttribute) attribute).getBindableJavaType(), node, (Bindable) attribute, jt); } else if (((PluralAttribute) attribute).getCollectionType().equals(CollectionType.SET)) { join = new BasicSetJoinImpl(this, this.metamodel, ((PluralAttribute) attribute).getBindableJavaType(), node, (Bindable) attribute, jt); } else{ join = new BasicMapJoinImpl(this, this.metamodel, ((PluralAttribute) attribute).getBindableJavaType(), node, (Bindable) attribute, jt); } } else { if (((PluralAttribute) attribute).getCollectionType().equals(CollectionType.COLLECTION)) { join = new CollectionJoinImpl(this, metamodel.managedType(((PluralAttribute) attribute).getBindableJavaType()), this.metamodel, ((PluralAttribute) attribute).getBindableJavaType(), node, (Bindable) attribute, jt); } else if (((PluralAttribute) attribute).getCollectionType().equals(CollectionType.LIST)) { join = new ListJoinImpl(this, metamodel.managedType(((PluralAttribute) attribute).getBindableJavaType()), this.metamodel, ((PluralAttribute) attribute).getBindableJavaType(), node, (Bindable) attribute, jt); } else if (((PluralAttribute) attribute).getCollectionType().equals(CollectionType.SET)) { join = new SetJoinImpl(this, metamodel.managedType(((PluralAttribute) attribute).getBindableJavaType()), this.metamodel, ((PluralAttribute) attribute).getBindableJavaType(), node, (Bindable) attribute, jt); } else { join = new MapJoinImpl(this, metamodel.managedType(((PluralAttribute) attribute).getBindableJavaType()), this.metamodel, ((PluralAttribute) attribute).getBindableJavaType(), node, (Bindable) attribute, jt); } } this.joins.add(join); ((FromImpl)join).isJoin = true; return join; }else{ return join(((SingularAttribute)attribute), jt); } } @Override public CollectionJoin joinCollection(String attributeName) { return joinCollection(attributeName, JoinType.INNER); } @Override public CollectionJoin joinCollection(String attributeName, JoinType jt) { try { return (CollectionJoin) join(attributeName, jt); } catch (ClassCastException ex) { throw new IllegalArgumentException(ExceptionLocalization.buildMessage("metamodel_attribute_not_collection", new Object[] { attributeName, this.managedType.getJavaType().getName() }), ex); } } @Override public ListJoin joinList(String attributeName) { return joinList(attributeName, JoinType.INNER); } @Override public ListJoin joinList(String attributeName, JoinType jt) { try { return (ListJoin) join(attributeName, jt); } catch (ClassCastException ex) { throw new IllegalArgumentException(ExceptionLocalization.buildMessage("metamodel_attribute_not_list", new Object[] { attributeName, this.managedType.getJavaType().getName() }), ex); } } @Override public MapJoin joinMap(String attributeName) { return joinMap(attributeName, JoinType.INNER); } @Override public MapJoin joinMap(String attributeName, JoinType jt) { try { return (MapJoin) join(attributeName, jt); } catch (ClassCastException ex) { throw new IllegalArgumentException(ExceptionLocalization.buildMessage("metamodel_attribute_not_map", new Object[] { attributeName, this.managedType.getJavaType().getName() }), ex); } } @Override public SetJoin joinSet(String attributeName) { return joinSet(attributeName, JoinType.INNER); } @Override public SetJoin joinSet(String attributeName, JoinType jt) { try { return (SetJoin) join(attributeName, jt); } catch (ClassCastException ex) { throw new IllegalArgumentException(ExceptionLocalization.buildMessage("metamodel_attribute_not_set", new Object[] { attributeName, this.managedType.getJavaType().getName() }), ex); } } public void findJoins(AbstractQueryImpl query){ Stack stack = new Stack(); stack.push(this); while(!stack.isEmpty()){ FromImpl currentJoin = (FromImpl) stack.pop(); stack.addAll(currentJoin.getJoins()); if (currentJoin.isJoin) { query.addJoin(currentJoin); } } } public List findJoinFetches(){ List fetches = new ArrayList(); Stack stack = new Stack(); stack.push(this); while(!stack.isEmpty()){ FromImpl currentFetch = (FromImpl) stack.pop(); stack.addAll(currentFetch.getFetches()); if (currentFetch.isFetch) { fetches.add(currentFetch.getCurrentNode()); } } return fetches; } @Override public boolean isFrom(){ return true; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy