blob: 232333c306d1c0e9034f29e757076a0afaa7be80 [file] [log] [blame]
/*
* 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;
/**
* <p>
* <b>Purpose</b>: Contains the implementation of the From interface of the JPA
* criteria API.
* <p>
* <b>Description</b>: 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<Z, X> extends PathImpl<X> implements jakarta.persistence.criteria.From<Z, X> {
protected ManagedType managedType;
protected Set<Join<X, ?>> joins;
protected Set<Fetch<X, ?>> fetches;
protected boolean isJoin = false;
protected boolean isFetch = false;
protected FromImpl correlatedParent;
public <T> FromImpl(Path<Z> parentPath, ManagedType managedType, Metamodel metamodel, Class<X> javaClass, org.eclipse.persistence.expressions.Expression expressionNode, Bindable<T> modelArtifact) {
super(parentPath, metamodel, javaClass, expressionNode, modelArtifact);
this.managedType = managedType;
this.joins = new HashSet<Join<X, ?>>();
this.fetches = new HashSet<Fetch<X, ?>>();
}
public <T> FromImpl(Path<Z> parentPath, ManagedType managedType, Metamodel metamodel, Class<X> javaClass, org.eclipse.persistence.expressions.Expression expressionNode, Bindable<T> 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<Fetch<X, ?>> getFetches(){
return this.fetches;
}
/**
* Whether the <code>From</code> object has been obtained as a result of
* correlation (use of a <code>Subquery</code> <code>correlate</code>
* method).
* @return boolean indicating whether the object has been
* obtained through correlation
*/
@Override
public boolean isCorrelated(){
return this.correlatedParent != null;
}
/**
* Returns the parent <code>From</code> object from which the correlated
* <code>From</code> object has been obtained through correlation (use
* of a <code>Subquery</code> <code>correlate</code> method).
* @return the parent of the correlated From object
* @throws IllegalStateException if the From object has
* not been obtained through correlation
*/
@Override
public From<Z, X> 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 <Y> Fetch<X, Y> fetch(SingularAttribute<? super X, Y> 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 <Y> Fetch<X, Y> fetch(SingularAttribute<? super X, Y> 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<X, Y> 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<X, Y>(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 <Y> Fetch<X, Y> fetch(PluralAttribute<? super X, ?, Y> 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 <Y> Fetch<X, Y> fetch(PluralAttribute<? super X, ?, Y> 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<X, Y>(this, this.metamodel, ((PluralAttribute) assoc).getBindableJavaType(), node, (Bindable) assoc, jt);
} else if (assoc.getCollectionType().equals(CollectionType.LIST)) {
fetch = new BasicListJoinImpl<X, Y>(this, this.metamodel, ((PluralAttribute) assoc).getBindableJavaType(), node, (Bindable) assoc, jt);
} else if (assoc.getCollectionType().equals(CollectionType.SET)) {
fetch = new BasicSetJoinImpl<X, Y>(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<X, Y>(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<X, Y>(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<X, Y>(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 <T, Y> Fetch<T, Y> 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 <T, Y> Fetch<T, Y> 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<Join<X, ?>> 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 <Y> Path<Y> get(SingularAttribute<? super X, Y> att){
if (att.getPersistentAttributeType().equals(PersistentAttributeType.BASIC)){
return new PathImpl<Y>(this, this.metamodel, att.getBindableJavaType(),this.currentNode.get(att.getName()), att);
}else{
Class<Y> clazz = att.getBindableJavaType();
Join join = new JoinImpl<X, Y>(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 <E, C extends java.util.Collection<E>> Expression<C> get(PluralAttribute<X, C, E> collection){
// This is a special Expression that represents just the collection for member of etc...
return new ExpressionImpl<C>(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 <K, V, M extends java.util.Map<K, V>> Expression<M> get(MapAttribute<X, K, V> map){
return new ExpressionImpl<M>(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<Class<? extends X>> type(){
return new ExpressionImpl(this.metamodel, ClassConstants.CLASS,this.currentNode.type());
}
@Override
public <Y> Path<Y> 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<X, Y>(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<X, Y>(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<X, Y>(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<X, Y>(this, this.metamodel, ((PluralAttribute) attribute).getBindableJavaType(), this.currentNode.anyOf(attribute.getName()), (Bindable) attribute);
} else if (((PluralAttribute) attribute).getCollectionType().equals(CollectionType.LIST)) {
join = new BasicListJoinImpl<X, Y>(this, this.metamodel, ((PluralAttribute) attribute).getBindableJavaType(), this.currentNode.anyOf(attribute.getName()), (Bindable) attribute);
} else if (((PluralAttribute) attribute).getCollectionType().equals(CollectionType.SET)) {
join = new BasicSetJoinImpl<X, Y>(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<Y>(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 <Y> Join<X, Y> join(SingularAttribute<? super X, Y> attribute) {
return this.join(attribute, JoinType.INNER);
}
@Override
public <Y> Join<X, Y> join(SingularAttribute<? super X, Y> 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<X, Y> 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<X, Y>(this, this.metamodel.managedType(clazz), this.metamodel, clazz, exp, attribute, jt);
this.joins.add(join);
((FromImpl)join).isJoin = true;
return join;
}
@Override
public <Y> CollectionJoin<X, Y> join(CollectionAttribute<? super X, Y> collection) {
return this.join(collection, JoinType.INNER);
}
@Override
public <Y> SetJoin<X, Y> join(jakarta.persistence.metamodel.SetAttribute<? super X, Y> set) {
return this.join(set, JoinType.INNER);
}
@Override
public <Y> ListJoin<X, Y> join(ListAttribute<? super X, Y> list) {
return this.join(list, JoinType.INNER);
}
@Override
public <K, V> MapJoin<X, K, V> join(MapAttribute<? super X, K, V> map) {
return this.join(map, JoinType.INNER);
}
@Override
public <Y> CollectionJoin<X, Y> join(CollectionAttribute<? super X, Y> collection, JoinType jt) {
org.eclipse.persistence.expressions.Expression node;
Class clazz = collection.getBindableJavaType();
CollectionJoin<X, Y> 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<X, Y>(this, this.metamodel, clazz, node, (Bindable) collection, jt);
} else {
join = new CollectionJoinImpl<X, Y>(this, metamodel.managedType(clazz), this.metamodel, clazz, node, (Bindable) collection, jt);
}
this.joins.add(join);
((FromImpl)join).isJoin = true;
return join;
}
@Override
public <Y> SetJoin<X, Y> join(jakarta.persistence.metamodel.SetAttribute<? super X, Y> set, JoinType jt) {
org.eclipse.persistence.expressions.Expression node;
Class clazz = set.getBindableJavaType();
SetJoin<X, Y> 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<X, Y>(this, this.metamodel, clazz, node, (Bindable) set, jt);
} else {
join = new SetJoinImpl<X, Y>(this, metamodel.managedType(clazz), this.metamodel, clazz, node, (Bindable) set, jt);
}
this.joins.add(join);
((FromImpl)join).isJoin = true;
return join;
}
@Override
public <Y> ListJoin<X, Y> join(ListAttribute<? super X, Y> list, JoinType jt) {
org.eclipse.persistence.expressions.Expression node;
Class clazz = list.getBindableJavaType();
ListJoin<X, Y> 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<X, Y>(this, this.metamodel, clazz, node, (Bindable) list, jt);
} else {
join = new ListJoinImpl<X, Y>(this, metamodel.managedType(clazz), this.metamodel, clazz, node, (Bindable) list, jt);
}
this.joins.add(join);
((FromImpl)join).isJoin = true;
return join;
}
@Override
public <K, V> MapJoin<X, K, V> join(MapAttribute<? super X, K, V> map, JoinType jt) {
org.eclipse.persistence.expressions.Expression node;
Class clazz = map.getBindableJavaType();
MapJoin<X, K, V> 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 <T, Y> Join<T, Y> join(String attributeName) {
return join(attributeName, JoinType.INNER);
}
@Override
public <T, Y> Join<T, Y> 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 <T, Y> CollectionJoin<T, Y> joinCollection(String attributeName) {
return joinCollection(attributeName, JoinType.INNER);
}
@Override
public <T, Y> CollectionJoin<T, Y> joinCollection(String attributeName, JoinType jt) {
try {
return (CollectionJoin<T, Y>) 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 <T, Y> ListJoin<T, Y> joinList(String attributeName) {
return joinList(attributeName, JoinType.INNER);
}
@Override
public <T, Y> ListJoin<T, Y> joinList(String attributeName, JoinType jt) {
try {
return (ListJoin<T, Y>) 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 <T, K, Y> MapJoin<T, K, Y> joinMap(String attributeName) {
return joinMap(attributeName, JoinType.INNER);
}
@Override
public <T, K, Y> MapJoin<T, K, Y> joinMap(String attributeName, JoinType jt) {
try {
return (MapJoin<T, K, Y>) 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 <T, Y> SetJoin<T, Y> joinSet(String attributeName) {
return joinSet(attributeName, JoinType.INNER);
}
@Override
public <T, Y> SetJoin<T, Y> joinSet(String attributeName, JoinType jt) {
try {
return (SetJoin<T, Y>) 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<org.eclipse.persistence.expressions.Expression> findJoinFetches(){
List<org.eclipse.persistence.expressions.Expression> fetches = new ArrayList<org.eclipse.persistence.expressions.Expression>();
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;
}
}