/* * Copyright 2014 - 2017 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.impl; import com.blazebit.persistence.BaseOngoingSetOperationBuilder; import com.blazebit.persistence.impl.expression.Expression; import com.blazebit.persistence.impl.expression.ExpressionFactory; import com.blazebit.persistence.spi.DbmsStatementType; import com.blazebit.persistence.spi.SetOperationType; import javax.persistence.Tuple; import java.util.ArrayList; import java.util.List; import java.util.Set; /** * * @author Christian Beikov * @author Moritz Becker * @since 1.0 */ public abstract class BaseSubqueryBuilderImpl<T, X, Y extends BaseOngoingSetOperationBuilder<?, ?, ?>, Z extends BaseOngoingSetOperationBuilder<?, ?, ?>> extends AbstractCommonQueryBuilder<Tuple, X, Y, Z, BaseFinalSetOperationSubqueryBuilderImpl<T, ?>> implements SubqueryInternalBuilder<T> { protected final T result; protected final SubqueryBuilderListener<T> listener; protected final SubqueryBuilderListenerImpl<T> subListener; public BaseSubqueryBuilderImpl(MainQuery mainQuery, AliasManager aliasManager, JoinManager parentJoinManager, ExpressionFactory expressionFactory, T result, SubqueryBuilderListener<T> listener, BaseFinalSetOperationSubqueryBuilderImpl<T, ?> finalSetOperationBuilder) { super(mainQuery, false, DbmsStatementType.SELECT, Tuple.class, null, aliasManager, parentJoinManager, expressionFactory, finalSetOperationBuilder, true); this.result = result; this.listener = listener; this.subListener = new SubqueryBuilderListenerImpl<T>(); } public SubqueryBuilderListenerImpl<T> getSubListener() { return subListener; } @Override public List<Expression> getSelectExpressions() { List<Expression> selectExpressions = new ArrayList<Expression>(selectManager.getSelectInfos().size()); for (SelectInfo info : selectManager.getSelectInfos()) { selectExpressions.add(info.getExpression()); } return selectExpressions; } @Override public Set<Expression> getCorrelatedExpressions() { prepareAndCheck(); CorrelatedExpressionGatheringVisitor visitor = new CorrelatedExpressionGatheringVisitor(aliasManager); applyVisitor(visitor); return visitor.getExpressions(); } public T getResult() { return result; } protected BaseFinalSetOperationSubqueryBuilderImpl<T, ?> createFinalSetOperationBuilder(SetOperationType operator, boolean nested, boolean isSubquery) { SubqueryBuilderImpl<?> newInitiator = finalSetOperationBuilder == null ? null : finalSetOperationBuilder.getInitiator(); return createFinalSetOperationBuilder(operator, nested, isSubquery, newInitiator); } protected BaseFinalSetOperationSubqueryBuilderImpl<T, ?> createFinalSetOperationBuilder(SetOperationType operator, boolean nested, boolean isSubquery, SubqueryBuilderImpl<?> newInitiator) { // TODO: this should never be null, handle it! SubqueryBuilderListener<T> newListener = finalSetOperationBuilder == null ? listener : finalSetOperationBuilder.getSubListener(); T newResult = finalSetOperationBuilder == null ? result : finalSetOperationBuilder.getResult(); if (isSubquery) { return new OngoingFinalSetOperationSubqueryBuilderImpl<T>(mainQuery, newResult, operator, nested, newListener, newInitiator); } else { return new FinalSetOperationSubqueryBuilderImpl<T>(mainQuery, newResult, operator, nested, newListener, newInitiator); } } @SuppressWarnings("unchecked") protected LeafOngoingSetOperationSubqueryBuilderImpl<T> createLeaf(BaseFinalSetOperationSubqueryBuilderImpl<T, ?> finalSetOperationBuilder) { SubqueryBuilderListener<T> newListener = finalSetOperationBuilder.getSubListener(); LeafOngoingSetOperationSubqueryBuilderImpl<T> next = new LeafOngoingSetOperationSubqueryBuilderImpl<T>(mainQuery, aliasManager.getParent(), joinManager.getParent(), expressionFactory, result, newListener, (FinalSetOperationSubqueryBuilderImpl<T>) finalSetOperationBuilder); newListener.onBuilderStarted(next); return next; } @SuppressWarnings("unchecked") protected <W> StartOngoingSetOperationSubqueryBuilderImpl<T, W> createStartOngoing(BaseFinalSetOperationSubqueryBuilderImpl<T, ?> finalSetOperationBuilder, W endSetResult) { // TODO: This is such an ugly hack, but I don't know how else to fix this generics issue for now finalSetOperationBuilder.setEndSetResult((T) endSetResult); SubqueryBuilderListener<T> newListener = finalSetOperationBuilder.getSubListener(); StartOngoingSetOperationSubqueryBuilderImpl<T, W> next = new StartOngoingSetOperationSubqueryBuilderImpl<T, W>(mainQuery, aliasManager.getParent(), joinManager.getParent(), expressionFactory, result, newListener, (OngoingFinalSetOperationSubqueryBuilderImpl<T>) finalSetOperationBuilder, endSetResult); newListener.onBuilderStarted(next); return next; } @SuppressWarnings("unchecked") protected <W> OngoingSetOperationSubqueryBuilderImpl<T, W> createOngoing(BaseFinalSetOperationSubqueryBuilderImpl<T, ?> finalSetOperationBuilder, W endSetResult) { // TODO: This is such an ugly hack, but I don't know how else to fix this generics issue for now finalSetOperationBuilder.setEndSetResult((T) endSetResult); SubqueryBuilderListener<T> newListener = finalSetOperationBuilder.getSubListener(); OngoingSetOperationSubqueryBuilderImpl<T, W> next = new OngoingSetOperationSubqueryBuilderImpl<T, W>(mainQuery, aliasManager.getParent(), joinManager.getParent(), expressionFactory, result, newListener, (OngoingFinalSetOperationSubqueryBuilderImpl<T>) finalSetOperationBuilder, endSetResult); newListener.onBuilderStarted(next); return next; } }