Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
com.blazebit.persistence.criteria.impl.path.AbstractFrom Maven / Gradle / Ivy
/*
* Copyright 2014 - 2021 Blazebit.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.blazebit.persistence.criteria.impl.path;
import com.blazebit.persistence.criteria.BlazeCollectionJoin;
import com.blazebit.persistence.criteria.BlazeFetchParent;
import com.blazebit.persistence.criteria.BlazeFrom;
import com.blazebit.persistence.criteria.BlazeJoin;
import com.blazebit.persistence.criteria.BlazeListJoin;
import com.blazebit.persistence.criteria.BlazeMapJoin;
import com.blazebit.persistence.criteria.BlazeSetJoin;
import com.blazebit.persistence.criteria.impl.BlazeCriteriaBuilderImpl;
import com.blazebit.persistence.criteria.impl.ParameterVisitor;
import com.blazebit.persistence.criteria.impl.RenderContext;
import com.blazebit.persistence.criteria.impl.expression.FromSelection;
import com.blazebit.persistence.criteria.impl.expression.SubqueryExpression;
import javax.persistence.criteria.Fetch;
import javax.persistence.criteria.Join;
import javax.persistence.criteria.JoinType;
import javax.persistence.criteria.Selection;
import javax.persistence.metamodel.Attribute;
import javax.persistence.metamodel.CollectionAttribute;
import javax.persistence.metamodel.EntityType;
import javax.persistence.metamodel.ListAttribute;
import javax.persistence.metamodel.ManagedType;
import javax.persistence.metamodel.MapAttribute;
import javax.persistence.metamodel.PluralAttribute;
import javax.persistence.metamodel.SetAttribute;
import javax.persistence.metamodel.SingularAttribute;
import javax.persistence.metamodel.Type;
import java.io.Serializable;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
/**
* @author Christian Beikov
* @since 1.2.0
*/
public abstract class AbstractFrom extends AbstractPath implements BlazeFrom {
public static final JoinType DEFAULT_JOIN_TYPE = JoinType.INNER;
private static final long serialVersionUID = 1L;
private AbstractFrom correlationParent;
private JoinScope joinScope = new BasicJoinScope();
private Set> joins;
private Set> fetches;
private Map, TreatedPath> treatedPaths;
public AbstractFrom(BlazeCriteriaBuilderImpl criteriaBuilder, Class javaType) {
this(criteriaBuilder, javaType, null);
}
public AbstractFrom(BlazeCriteriaBuilderImpl criteriaBuilder, Class javaType, AbstractPath pathSource) {
super(criteriaBuilder, javaType, pathSource);
}
@Override
public Selection alias(String alias) {
return new FromSelection(this.criteriaBuilder, this, alias);
}
@Override
public String getPathExpression() {
return getAlias();
}
@Override
public void renderPathExpression(RenderContext context) {
context.getBuffer().append(resolveAlias(context));
}
@Override
protected boolean isDereferencable() {
return true;
}
public void visit(ParameterVisitor visitor) {
for (AbstractJoin j : joins) {
j.visit(visitor);
}
}
@Override
public String resolveAlias(RenderContext context) {
if (getAttribute() != null && getAttribute().getPersistentAttributeType() == Attribute.PersistentAttributeType.EMBEDDED) {
return getBasePath().resolveAlias(context) + "." + getAttribute().getName();
} else {
String alias = getAlias();
if (alias == null) {
if (isCorrelated()) {
alias = getCorrelationParent().getAlias();
} else if (getJavaType() == null) {
alias = context.resolveAlias(this, ((EntityType) getManagedType()).getName());
} else {
alias = context.resolveAlias(this, getJavaType());
}
}
return alias;
}
}
@Override
public void render(RenderContext context) {
context.getBuffer().append(resolveAlias(context));
}
@Override
public Attribute getAttribute() {
return null;
}
public BlazeFetchParent getParent() {
return null;
}
@Override
@SuppressWarnings({"unchecked"})
protected Attribute findAttribute(String name) {
return (Attribute) getManagedType().getAttribute(name);
}
@SuppressWarnings({"unchecked"})
protected ManagedType getManagedType() {
return (ManagedType) getModel();
}
@Override
public boolean isCorrelated() {
return correlationParent != null;
}
@Override
public AbstractFrom getCorrelationParent() {
if (correlationParent == null) {
throw new IllegalStateException("This from node has no correlation parent!");
}
return correlationParent;
}
@SuppressWarnings({"unchecked"})
public AbstractFrom correlateTo(SubqueryExpression subquery) {
final AbstractFrom correlationDelegate = createCorrelationDelegate();
correlationDelegate.prepareCorrelationDelegate(this);
return correlationDelegate;
}
protected abstract AbstractFrom createCorrelationDelegate();
public void prepareCorrelationDelegate(AbstractFrom parent) {
this.joinScope = new CorrelationJoinScope();
this.correlationParent = parent;
}
@Override
public String getAlias() {
return isCorrelated() ? getCorrelationParent().getAlias() : super.getAlias();
}
@Override
public abstract AbstractFrom treatAs(Class treatAsType);
@SuppressWarnings("unchecked")
protected final > T addTreatedPath(T treatedPath) {
if (treatedPaths == null) {
treatedPaths = new LinkedHashMap<>();
}
T realJoin = (T) treatedPaths.get(treatedPath.getTreatType());
if (realJoin == null) {
realJoin = treatedPath;
treatedPaths.put(treatedPath.getTreatType(), treatedPath);
}
return realJoin;
}
public Collection> getTreatedPaths() {
if (treatedPaths == null) {
return Collections.emptyList();
}
return treatedPaths.values();
}
/***************************************************
* Joins
****************************************************/
protected abstract boolean isJoinAllowed();
protected JoinScope getJoinScope() {
return joinScope;
}
protected void checkJoinAllowed() {
if (!isJoinAllowed()) {
throw new IllegalArgumentException("Joins on '" + getPathExpression() + "' are not allowed");
}
}
private void checkJoin(Attribute attribute, JoinType jt) {
checkJoinAllowed();
if (jt == JoinType.RIGHT) {
throw new UnsupportedOperationException("RIGHT JOIN not supported");
}
ManagedType t = getManagedType();
if (t == null) {
throw new IllegalArgumentException("Joins on '" + getPathExpression() + "' are not allowed");
}
// getAttribute will throw an exception if the attribute does not exist
if (t.getAttribute(attribute.getName()) == null) {
// Some old hibernate versions don't throw an exception but return null
throw new IllegalArgumentException("Could not resolve attribute named: " + attribute.getName());
}
}
@Override
@SuppressWarnings({"unchecked"})
public Set> getJoins() {
return joins == null ? Collections.EMPTY_SET : (Set>) (Set) joins;
}
@Override
@SuppressWarnings({"unchecked"})
public Set> getBlazeJoins() {
return joins == null ? Collections.EMPTY_SET : (Set>) (Set) joins;
}
@Override
public BlazeJoin join(SingularAttribute singularAttribute, String alias) {
return join(singularAttribute, alias, DEFAULT_JOIN_TYPE);
}
@Override
public BlazeJoin join(SingularAttribute attribute, String alias, JoinType jt) {
AbstractJoin join = constructJoin(attribute, alias, jt);
joinScope.addJoin(join);
return join;
}
private AbstractJoin constructJoin(SingularAttribute attribute, String alias, JoinType jt) {
if (Type.PersistenceType.BASIC.equals(attribute.getType().getPersistenceType())) {
throw new IllegalArgumentException("Cannot join to attribute of basic type: " + attribute.getJavaType().getName());
}
checkJoin(attribute, jt);
final Class attributeType = attribute.getBindableJavaType();
SingularAttributeJoin join = new SingularAttributeJoin(criteriaBuilder, attributeType, this, attribute, jt);
join.setAlias(alias);
return join;
}
@Override
public BlazeCollectionJoin join(CollectionAttribute collection, String alias) {
return join(collection, alias, DEFAULT_JOIN_TYPE);
}
@Override
public BlazeCollectionJoin join(CollectionAttribute collection, String alias, JoinType jt) {
final CollectionAttributeJoin join = constructJoin(collection, alias, jt);
joinScope.addJoin(join);
return join;
}
private CollectionAttributeJoin constructJoin(CollectionAttribute collection, String alias, JoinType jt) {
checkJoin(collection, jt);
final Class attributeType = collection.getBindableJavaType();
CollectionAttributeJoin join = new CollectionAttributeJoin(criteriaBuilder, attributeType, this, collection, jt);
join.setAlias(alias);
return join;
}
@Override
public BlazeSetJoin join(SetAttribute set, String alias) {
return join(set, alias, DEFAULT_JOIN_TYPE);
}
@Override
public BlazeSetJoin join(SetAttribute set, String alias, JoinType jt) {
final SetAttributeJoin join = constructJoin(set, alias, jt);
joinScope.addJoin(join);
return join;
}
private SetAttributeJoin constructJoin(SetAttribute set, String alias, JoinType jt) {
checkJoin(set, jt);
final Class attributeType = set.getBindableJavaType();
SetAttributeJoin join = new SetAttributeJoin(criteriaBuilder, attributeType, this, set, jt);
join.setAlias(alias);
return join;
}
@Override
public BlazeListJoin join(ListAttribute list, String alias) {
return join(list, alias, DEFAULT_JOIN_TYPE);
}
@Override
public BlazeListJoin join(ListAttribute list, String alias, JoinType jt) {
final ListAttributeJoin join = constructJoin(list, alias, jt);
joinScope.addJoin(join);
return join;
}
private ListAttributeJoin constructJoin(ListAttribute list, String alias, JoinType jt) {
checkJoin(list, jt);
final Class attributeType = list.getBindableJavaType();
ListAttributeJoin join = new ListAttributeJoin(criteriaBuilder, attributeType, this, list, jt);
join.setAlias(alias);
return join;
}
@Override
public BlazeMapJoin join(MapAttribute map, String alias) {
return join(map, alias, DEFAULT_JOIN_TYPE);
}
@Override
public BlazeMapJoin join(MapAttribute map, String alias, JoinType jt) {
final MapAttributeJoin join = constructJoin(map, alias, jt);
joinScope.addJoin(join);
return join;
}
private MapAttributeJoin constructJoin(MapAttribute map, String alias, JoinType jt) {
checkJoin(map, jt);
final Class attributeType = map.getBindableJavaType();
MapAttributeJoin join = new MapAttributeJoin(criteriaBuilder, attributeType, this, map, jt);
join.setAlias(alias);
return join;
}
@Override
public BlazeJoin join(String attributeName, String alias) {
return join(attributeName, alias, DEFAULT_JOIN_TYPE);
}
@Override
@SuppressWarnings({"unchecked"})
public BlazeJoin join(String attributeName, String alias, JoinType jt) {
checkJoinAllowed();
if (jt == JoinType.RIGHT) {
throw new UnsupportedOperationException("RIGHT JOIN not supported");
}
final Attribute attribute = (Attribute) getAttribute(attributeName);
if (attribute.isCollection()) {
final PluralAttribute pluralAttribute = (PluralAttribute) attribute;
if (PluralAttribute.CollectionType.COLLECTION.equals(pluralAttribute.getCollectionType())) {
return (BlazeJoin) join((CollectionAttribute) attribute, alias, jt);
} else if (PluralAttribute.CollectionType.LIST.equals(pluralAttribute.getCollectionType())) {
return (BlazeJoin) join((ListAttribute) attribute, alias, jt);
} else if (PluralAttribute.CollectionType.SET.equals(pluralAttribute.getCollectionType())) {
return (BlazeJoin) join((SetAttribute) attribute, alias, jt);
} else {
return (BlazeJoin) join((MapAttribute) attribute, alias, jt);
}
} else {
return (BlazeJoin) join((SingularAttribute) attribute, alias, jt);
}
}
@Override
public BlazeCollectionJoin joinCollection(String attributeName, String alias) {
return joinCollection(attributeName, alias, DEFAULT_JOIN_TYPE);
}
@Override
@SuppressWarnings({"unchecked"})
public BlazeCollectionJoin joinCollection(String attributeName, String alias, JoinType jt) {
final Attribute attribute = (Attribute) getAttribute(attributeName);
if (!attribute.isCollection()) {
throw new IllegalArgumentException("Requested attribute was not a collection");
}
final PluralAttribute pluralAttribute = (PluralAttribute) attribute;
if (!PluralAttribute.CollectionType.COLLECTION.equals(pluralAttribute.getCollectionType())) {
throw new IllegalArgumentException("Requested attribute was not a collection");
}
return (BlazeCollectionJoin) join((CollectionAttribute) attribute, alias, jt);
}
@Override
public BlazeSetJoin joinSet(String attributeName, String alias) {
return joinSet(attributeName, alias, DEFAULT_JOIN_TYPE);
}
@Override
@SuppressWarnings({"unchecked"})
public BlazeSetJoin joinSet(String attributeName, String alias, JoinType jt) {
final Attribute attribute = (Attribute) getAttribute(attributeName);
if (!attribute.isCollection()) {
throw new IllegalArgumentException("Requested attribute was not a set");
}
final PluralAttribute pluralAttribute = (PluralAttribute) attribute;
if (!PluralAttribute.CollectionType.SET.equals(pluralAttribute.getCollectionType())) {
throw new IllegalArgumentException("Requested attribute was not a set");
}
return (BlazeSetJoin) join((SetAttribute) attribute, alias, jt);
}
@Override
public BlazeListJoin joinList(String attributeName, String alias) {
return joinList(attributeName, alias, DEFAULT_JOIN_TYPE);
}
@Override
@SuppressWarnings({"unchecked"})
public BlazeListJoin joinList(String attributeName, String alias, JoinType jt) {
final Attribute attribute = (Attribute) getAttribute(attributeName);
if (!attribute.isCollection()) {
throw new IllegalArgumentException("Requested attribute was not a list");
}
final PluralAttribute pluralAttribute = (PluralAttribute) attribute;
if (!PluralAttribute.CollectionType.LIST.equals(pluralAttribute.getCollectionType())) {
throw new IllegalArgumentException("Requested attribute was not a list");
}
return (BlazeListJoin) join((ListAttribute) attribute, alias, jt);
}
@Override
public BlazeMapJoin joinMap(String attributeName, String alias) {
return joinMap(attributeName, alias, DEFAULT_JOIN_TYPE);
}
@Override
@SuppressWarnings({"unchecked"})
public BlazeMapJoin joinMap(String attributeName, String alias, JoinType jt) {
final Attribute attribute = (Attribute) getAttribute(attributeName);
if (!attribute.isCollection()) {
throw new IllegalArgumentException("Requested attribute was not a map");
}
final PluralAttribute pluralAttribute = (PluralAttribute) attribute;
if (!PluralAttribute.CollectionType.MAP.equals(pluralAttribute.getCollectionType())) {
throw new IllegalArgumentException("Requested attribute was not a map");
}
return (BlazeMapJoin) join((MapAttribute) attribute, alias, jt);
}
@Override
public BlazeJoin join(EntityType entityType, String alias) {
return join(entityType, alias, DEFAULT_JOIN_TYPE);
}
@Override
public BlazeJoin join(Class entityTypeClass, String alias) {
return join(criteriaBuilder.getEntityMetamodel().entity(entityTypeClass), alias, DEFAULT_JOIN_TYPE);
}
@Override
public BlazeJoin join(EntityType entityType) {
return join(entityType, null, DEFAULT_JOIN_TYPE);
}
@Override
public BlazeJoin join(Class entityTypeClass) {
return join(criteriaBuilder.getEntityMetamodel().entity(entityTypeClass), null, DEFAULT_JOIN_TYPE);
}
@Override
public BlazeJoin join(EntityType entityType, JoinType joinType) {
return join(entityType, null, joinType);
}
@Override
public BlazeJoin join(Class entityTypeClass, JoinType joinType) {
return join(criteriaBuilder.getEntityMetamodel().entity(entityTypeClass), null, joinType);
}
@Override
public BlazeJoin join(Class entityTypeClass, String alias, JoinType joinType) {
return join(criteriaBuilder.getEntityMetamodel().entity(entityTypeClass), alias, joinType);
}
@Override
public BlazeJoin join(EntityType entityType, String alias, JoinType joinType) {
if (entityType == null) {
throw new IllegalArgumentException("Null entity type");
}
if (joinType == null) {
throw new IllegalArgumentException("Null join type");
}
EntityJoin join = new EntityJoin<>(criteriaBuilder,this, entityType, joinType);
join.setAlias(alias);
joinScope.addJoin(join);
return join;
}
/***************************************************
* Fetches
****************************************************/
protected boolean isFetchAllowed() {
return isJoinAllowed();
}
protected void checkFetchAllowed() {
if (!isFetchAllowed()) {
throw new IllegalArgumentException("Join fetches on '" + getPathExpression() + "' are not allowed");
}
}
@Override
@SuppressWarnings({"unchecked"})
public Set> getFetches() {
return fetches == null ? Collections.EMPTY_SET : (Set>) (Set) fetches;
}
@Override
public BlazeJoin fetch(SingularAttribute singularAttribute, String alias) {
return fetch(singularAttribute, alias, DEFAULT_JOIN_TYPE);
}
@Override
public BlazeJoin fetch(SingularAttribute attribute, String alias, JoinType jt) {
checkFetchAllowed();
AbstractJoin fetch = constructJoin(attribute, alias, jt);
joinScope.addFetch(fetch);
return fetch;
}
@Override
public BlazeJoin fetch(PluralAttribute pluralAttribute, String alias) {
return fetch(pluralAttribute, alias, DEFAULT_JOIN_TYPE);
}
@Override
@SuppressWarnings({"unchecked"})
public BlazeJoin fetch(PluralAttribute pluralAttribute, String alias, JoinType jt) {
checkFetchAllowed();
final AbstractJoin fetch;
if (PluralAttribute.CollectionType.COLLECTION.equals(pluralAttribute.getCollectionType())) {
fetch = constructJoin((CollectionAttribute) pluralAttribute, alias, jt);
} else if (PluralAttribute.CollectionType.LIST.equals(pluralAttribute.getCollectionType())) {
fetch = constructJoin((ListAttribute) pluralAttribute, alias, jt);
} else if (PluralAttribute.CollectionType.SET.equals(pluralAttribute.getCollectionType())) {
fetch = constructJoin((SetAttribute) pluralAttribute, alias, jt);
} else {
fetch = constructJoin((MapAttribute) pluralAttribute, alias, jt);
}
joinScope.addFetch(fetch);
return fetch;
}
@Override
public BlazeJoin fetch(String attributeName, String alias) {
return fetch(attributeName, alias, DEFAULT_JOIN_TYPE);
}
@Override
@SuppressWarnings({"unchecked"})
public BlazeJoin fetch(String attributeName, String alias, JoinType jt) {
checkFetchAllowed();
Attribute attribute = (Attribute) getAttribute(attributeName);
if (attribute.isCollection()) {
return (BlazeJoin) fetch((PluralAttribute) attribute, alias, jt);
} else {
return (BlazeJoin) fetch((SingularAttribute) attribute, alias, jt);
}
}
/* Non-aliased joins and fetches */
@Override
public BlazeJoin fetch(SingularAttribute attribute) {
return fetch(attribute, (String) null);
}
@Override
public BlazeJoin fetch(SingularAttribute attribute, JoinType jt) {
return fetch(attribute, null, jt);
}
@Override
public BlazeJoin fetch(PluralAttribute attribute) {
return fetch(attribute, (String) null);
}
@Override
public BlazeJoin fetch(PluralAttribute attribute, JoinType jt) {
return fetch(attribute, null, jt);
}
@Override
public BlazeJoin fetch(String attributeName) {
return fetch(attributeName, (String) null);
}
@Override
public BlazeJoin fetch(String attributeName, JoinType jt) {
return fetch(attributeName, (String) null, jt);
}
@Override
public BlazeJoin join(SingularAttribute attribute) {
return join(attribute, (String) null);
}
@Override
public BlazeJoin join(SingularAttribute attribute, JoinType jt) {
return join(attribute, (String) null, jt);
}
@Override
public BlazeCollectionJoin join(CollectionAttribute collection) {
return join(collection, (String) null);
}
@Override
public BlazeSetJoin join(SetAttribute set) {
return join(set, (String) null);
}
@Override
public BlazeListJoin join(ListAttribute list) {
return join(list, (String) null);
}
@Override
public BlazeMapJoin join(MapAttribute map) {
return join(map, (String) null);
}
@Override
public BlazeCollectionJoin join(CollectionAttribute collection, JoinType jt) {
return join(collection, (String) null, jt);
}
@Override
public BlazeSetJoin join(SetAttribute set, JoinType jt) {
return join(set, (String) null, jt);
}
@Override
public BlazeListJoin join(ListAttribute list, JoinType jt) {
return join(list, (String) null, jt);
}
@Override
public BlazeMapJoin join(MapAttribute map, JoinType jt) {
return join(map, (String) null, jt);
}
@Override
public BlazeJoin join(String attributeName) {
return join(attributeName, (String) null);
}
@Override
public BlazeCollectionJoin joinCollection(String attributeName) {
return joinCollection(attributeName, (String) null);
}
@Override
public BlazeSetJoin joinSet(String attributeName) {
return joinSet(attributeName, (String) null);
}
@Override
public BlazeListJoin joinList(String attributeName) {
return joinList(attributeName, (String) null);
}
@Override
public BlazeMapJoin joinMap(String attributeName) {
return joinMap(attributeName, (String) null);
}
@Override
public BlazeJoin join(String attributeName, JoinType jt) {
return join(attributeName, (String) null, jt);
}
@Override
public BlazeCollectionJoin joinCollection(String attributeName, JoinType jt) {
return joinCollection(attributeName, (String) null, jt);
}
@Override
public BlazeSetJoin joinSet(String attributeName, JoinType jt) {
return joinSet(attributeName, (String) null, jt);
}
@Override
public BlazeListJoin joinList(String attributeName, JoinType jt) {
return joinList(attributeName, (String) null, jt);
}
@Override
public BlazeMapJoin joinMap(String attributeName, JoinType joinType) {
return joinMap(attributeName, (String) null, joinType);
}
/* Join scope implementations */
/**
* @author Christian Beikov
* @since 1.2.0
*/
public static interface JoinScope extends Serializable {
public void addJoin(AbstractJoin join);
public void addFetch(AbstractJoin fetch);
}
/**
* @author Christian Beikov
* @since 1.2.0
*/
protected class BasicJoinScope implements JoinScope {
@Override
public void addJoin(AbstractJoin join) {
if (joins == null) {
joins = new LinkedHashSet<>();
}
joins.add(join);
}
@Override
public void addFetch(AbstractJoin fetch) {
fetch.setFetch(true);
addJoin(fetch);
if (fetches == null) {
fetches = new LinkedHashSet<>();
}
fetches.add(fetch);
}
}
/**
* @author Christian Beikov
* @since 1.2.0
*/
protected class CorrelationJoinScope implements JoinScope {
@Override
public void addJoin(AbstractJoin join) {
if (joins == null) {
joins = new LinkedHashSet<>();
}
joins.add(join);
}
@Override
public void addFetch(AbstractJoin fetch) {
throw new UnsupportedOperationException("Cannot define fetch from a subquery correlation");
}
}
}