package org.infinispan.query.dsl.impl; import org.infinispan.query.dsl.Expression; import org.infinispan.query.dsl.FilterConditionBeginContext; import org.infinispan.query.dsl.FilterConditionContext; import org.infinispan.query.dsl.FilterConditionContextQueryBuilder; import org.infinispan.query.dsl.FilterConditionEndContext; import org.infinispan.query.dsl.Query; import org.infinispan.query.dsl.QueryBuilder; import org.infinispan.query.dsl.QueryFactory; import org.infinispan.query.dsl.SortOrder; import org.infinispan.query.dsl.impl.logging.Log; import org.jboss.logging.Logger; /** * @author anistor@redhat.com * @since 6.0 */ abstract class BaseCondition implements FilterConditionContextQueryBuilder, Visitable { private static final Log log = Logger.getMessageLogger(Log.class, BaseCondition.class.getName()); protected BaseCondition parent = null; protected QueryBuilder queryBuilder; protected final QueryFactory queryFactory; protected BaseCondition(QueryFactory queryFactory) { this.queryFactory = queryFactory; } @Override public QueryBuilder toBuilder() { return getQueryBuilder(); } QueryBuilder getQueryBuilder() { if (queryBuilder == null) { throw log.subQueryDoesNotBelongToAParentQueryBuilder(); } return queryBuilder; } void setQueryBuilder(QueryBuilder queryBuilder) { if (this.queryBuilder != null) { throw log.queryAlreadyBelongsToAnotherBuilder(); } this.queryBuilder = queryBuilder; } /** * Returns the topmost condition, never {@code null}. * * @return the topmost condition following up the parent chain or {@code this} if parent is {@code null}. */ public BaseCondition getRoot() { BaseCondition p = this; while (p.getParent() != null) { p = p.getParent(); } return p; } public BaseCondition getParent() { return parent; } public void setParent(BaseCondition parent) { this.parent = parent; } @Override public FilterConditionBeginContext and() { IncompleteCondition rightCondition = new IncompleteCondition(queryFactory); combine(true, rightCondition); return rightCondition; } @Override public FilterConditionContextQueryBuilder and(FilterConditionContext rightCondition) { combine(true, rightCondition); return this; } @Override public FilterConditionBeginContext or() { IncompleteCondition rightCondition = new IncompleteCondition(queryFactory); combine(false, rightCondition); return rightCondition; } @Override public BaseCondition or(FilterConditionContext rightCondition) { combine(false, rightCondition); return this; } private void combine(boolean isConjunction, FilterConditionContext fcc) { if (fcc == null) { throw log.argumentCannotBeNull(); } BaseCondition rightCondition = ((BaseCondition) fcc).getRoot(); if (rightCondition.queryFactory != queryFactory) { throw log.conditionWasCreatedByAnotherFactory(); } if (rightCondition.queryBuilder != null) { throw log.conditionIsAlreadyInUseByAnotherBuilder(); } if (isConjunction && parent instanceof OrCondition) { BooleanCondition p = new AndCondition(queryFactory, this, rightCondition); ((BooleanCondition) parent).replaceChildCondition(this, p); parent = p; rightCondition.setParent(p); } else { BaseCondition root = getRoot(); BooleanCondition p = isConjunction ? new AndCondition(queryFactory, root, rightCondition) : new OrCondition(queryFactory, root, rightCondition); root.setParent(p); rightCondition.setParent(p); } rightCondition.setQueryBuilder(queryBuilder); } //////////////////////////////// Delegate to parent QueryBuilder /////////////////////////// @Override public QueryBuilder startOffset(long startOffset) { return getQueryBuilder().startOffset(startOffset); } @Override public QueryBuilder maxResults(int maxResults) { return getQueryBuilder().maxResults(maxResults); } @Override public QueryBuilder select(Expression... projection) { return getQueryBuilder().select(projection); } @Override public QueryBuilder select(String... attributePath) { return getQueryBuilder().select(attributePath); } @Override public QueryBuilder groupBy(String... attributePath) { return getQueryBuilder().groupBy(attributePath); } @Override public QueryBuilder orderBy(Expression expression) { return getQueryBuilder().orderBy(expression); } @Override public QueryBuilder orderBy(Expression expression, SortOrder sortOrder) { return getQueryBuilder().orderBy(expression); } @Override public QueryBuilder orderBy(String attributePath) { return getQueryBuilder().orderBy(attributePath); } @Override public QueryBuilder orderBy(String attributePath, SortOrder sortOrder) { return getQueryBuilder().orderBy(attributePath, sortOrder); } @Override public FilterConditionEndContext having(String attributePath) { return getQueryBuilder().having(attributePath); } @Override public FilterConditionEndContext having(Expression expression) { return getQueryBuilder().having(expression); } @Override public FilterConditionContextQueryBuilder not() { return getQueryBuilder().not(); } @Override public FilterConditionContextQueryBuilder not(FilterConditionContext fcc) { return getQueryBuilder().not(fcc); } @Override public Query build() { return getQueryBuilder().build(); } }