public static <T extends Storable> QueryExecutor<T>
        build(RepositoryAccess repoAccess,
              ChainedProperty<T> targetToSourceProperty,
              Filter<T> targetFilter,
              OrderingList<T> targetOrdering,
              QueryHints hints)
        throws RepositoryException
    {
        if (targetOrdering == null) {
            targetOrdering = OrderingList.emptyList();
        }

        QueryExecutor<T> executor =
            buildJoin(repoAccess, targetToSourceProperty, targetFilter, targetOrdering, hints);

        OrderingList<T> handledOrdering = executor.getOrdering();

        // Apply sort if any remaining ordering properties.
        int handledCount = commonOrderingCount(handledOrdering, targetOrdering);

        OrderingList<T> remainderOrdering =
            targetOrdering.subList(handledCount, targetOrdering.size());

        if (remainderOrdering.size() > 0) {
            SortedQueryExecutor.Support<T> support = repoAccess
                .storageAccessFor(targetToSourceProperty.getPrimeProperty().getEnclosingType());
            executor = new SortedQueryExecutor<T>
                (support, executor, handledOrdering, remainderOrdering);
        }

        return executor;
    }
public static < T extends Storable > QueryExecutor < T > build ( RepositoryAccess repoAccess , ChainedProperty < T > targetToSourceProperty , Filter < T > targetFilter , OrderingList < T > targetOrdering , QueryHints hints ) throws RepositoryException { if ( targetOrdering == null ) { targetOrdering = OrderingList . emptyList ( ) ; } QueryExecutor < T > executor = buildJoin ( repoAccess , targetToSourceProperty , targetFilter , targetOrdering , hints ) ; OrderingList < T > handledOrdering = executor . getOrdering ( ) ; int handledCount = commonOrderingCount ( handledOrdering , targetOrdering ) ; OrderingList < T > remainderOrdering = targetOrdering . subList ( handledCount , targetOrdering . size ( ) ) ; if ( remainderOrdering . size ( ) > 0 ) { SortedQueryExecutor . Support < T > support = repoAccess . storageAccessFor ( targetToSourceProperty . getPrimeProperty ( ) . getEnclosingType ( ) ) ; executor = new SortedQueryExecutor < T > ( support , executor , handledOrdering , remainderOrdering ) ; } return executor ; }
Builds and returns a complex joined excutor against a chained property,
supporting multi-way joins. Filtering and ordering may also be supplied,
in order to better distribute work throughout the join.

@param repoAccess used to create query executors for outer and inner loops
@param targetToSourceProperty join property of <i>target</i> type which maps
to instances of <i>source</i> type
@param targetFilter optional filter for fetching <i>target</i> instances
@param targetOrdering optional ordering to apply to <i>target</i> executor
& @param hints optional hints
@throws IllegalArgumentException if any parameter is null or if join
property is not a Storable type
@throws RepositoryException from RepositoryAccess