private ItemHolder getPrefilteredItemsInternal()

in rest-api/src/jetbrains/buildServer/server/rest/data/finder/impl/BranchFinder.java [220:313]


  private ItemHolder<BranchData> getPrefilteredItemsInternal(@NotNull final Locator locator, boolean existenseCheck) {
    String buildLocator = locator.getSingleDimensionValue(BUILD);
    if (!StringUtil.isEmpty(buildLocator)) {
      BuildPromotion build = myServiceLocator.getSingletonService(BuildPromotionFinder.class).getItem(buildLocator);
      return ItemHolder.of(Collections.singleton(BranchData.fromBuild(build)));
    }

    final String buildTypeLocator = locator.getSingleDimensionValue(BUILD_TYPE);
    if (buildTypeLocator == null) {
      throw new BadRequestException("No '" + BUILD_TYPE + "' dimension is present but it is required for searching branches. Locator: '" + locator.getStringRepresentation() + "'");
    }
    final List<SBuildType> buildTypes = myBuildTypeFinder.getBuildTypes(null, buildTypeLocator);

    List<ItemHolder<BranchData>> result = new ArrayList<>();

    final String groupsInclude = locator.getSingleDimensionValue(GROUP_INCLUDE);
    if (groupsInclude != null) {
      SUser user = validateAndgetGroupIncludeUser(groupsInclude);
      result.add(ItemHolder.of(
        buildTypes
          .stream()
          .flatMap(buildType -> myBranchGroupsService.getAvailableBranchGroups(
            new BranchGroupsProvider.Context((BuildTypeEx)buildType, user)
          ).stream())
          .distinct()
          .map(branchGroup -> BranchData.fromBranchGroup(branchGroup))
      ));
    }

    final String groupDimension = locator.getSingleDimensionValue(BRANCH_GROUP);
    if (groupDimension != null) {
      BranchGroupFilterDetails groupDetails = getBranchGroupFilterDetails(groupDimension, buildTypes.get(0));

      result.add(processor -> {
        try {
          buildTypes.forEach(buildType -> {
            BranchGroupsProvider.Context ctx = new BranchGroupsProvider.Context((BuildTypeEx)buildType, groupDetails.getUser());
            myBranchGroupsService.collectBranches(
              groupDetails.getBranchGroupId(),
              ctx,
              branchEx -> processor.processItem(BranchData.fromBranchEx(branchEx, myServiceLocator, null, true))
            );
          });
        } catch (IllegalStateException e) {
          throw new BadRequestException("Error retrieving branch groups: " + e.getMessage());
        }
      });
      return ItemHolder.concat(result);
    }

    BranchSearchOptions searchOptions = getBranchSearchOptions(locator);
    boolean lookingForDefaultBranch = BooleanUtils.isTrue(locator.getSingleDimensionValueAsBoolean(DEFAULT));
    // We must make sure that no unused dimensions are present as otherwise we may stop too early and then get filtered,
    // i.e. loose relevant item.
    if(lookingForDefaultBranch && existenseCheck && locator.getUnusedDimensions().isEmpty()) {
      for (SBuildType buildType : buildTypes) {
        final BranchData branch = detectDefaultBranch(buildType, searchOptions);

        // As soon as default branch is found, create a simple processor and don't look into other buildTypes.
        if(branch != null) {
          result.add(processor -> processor.processItem(branch));
          break;
        }
      }
    } else {
      locator.markUnused(DEFAULT);

      Filter<SBuildType> dependenciesFilter = getBranchDependenciesFilter(buildTypes);

      if(existenseCheck) {
        // We don't use deduplication here as in this case we have a chance to stop earlier
        // using lazy stream evaluation and avoid getting branches from all build types.
        // We also skip computing timestamps as that is unnecessary for an existence check.
        locator.markUsed(COMPUTE_TIMESTAMPS);

        Stream<BranchData> branchStream = buildTypes.stream()
                                                    .flatMap(buildType -> getBranches(buildType, searchOptions, false, dependenciesFilter));

        result.add(ItemHolder.of(branchStream));
      } else {
        DeduplicatingAccumulator resultAccumulator = new DeduplicatingAccumulator();
        for (SBuildType buildType : buildTypes) {
          Boolean locatorComputeTimestamps = locator.getSingleDimensionValueAsBoolean(COMPUTE_TIMESTAMPS);
          boolean finalComputeTimestamps = locatorComputeTimestamps != null ? locatorComputeTimestamps : TeamCityProperties.getBoolean("rest.beans.branch.defaultComputeTimestamp");
          Stream<BranchData> branchStream = getBranches(buildType, searchOptions, finalComputeTimestamps, dependenciesFilter);
          resultAccumulator.addAll(branchStream);
        }

        result.add(ItemHolder.of(resultAccumulator.get()));
      }
    }

    return ItemHolder.concat(result);
  }