public ItemHolder getPrefilteredItems()

in rest-api/src/jetbrains/buildServer/server/rest/data/finder/impl/ChangeFinder.java [493:638]


  public ItemHolder<SVcsModificationOrChangeDescriptor> getPrefilteredItems(@NotNull final Locator locator) {
    final String internalVersion = locator.getSingleDimensionValue(INTERNAL_VERSION);
    if (internalVersion != null) {
      return wrapModifications(((VcsModificationHistoryEx)myVcsModificationHistory).findModificationsByVersion(internalVersion));
    }

    ValueCondition displayVersionCondition = ParameterCondition.createValueCondition(locator.lookupSingleDimensionValue(VERSION));
    final String displayVersion = displayVersionCondition != null ? displayVersionCondition.getConstantValueIfSimpleEqualsCondition() : null;
    if (displayVersion != null) {
      locator.markUsed(VERSION);
      return wrapModifications(((VcsModificationHistoryEx)myVcsModificationHistory).findModificationsByDisplayVersion(displayVersion));
    }

    Boolean personal = locator.lookupSingleDimensionValueAsBoolean(PERSONAL);
    if (personal != null && personal) {
      if (locator.lookupSingleDimensionValue(BUILD) == null && locator.lookupSingleDimensionValue(USER) == null) {
        throw new BadRequestException("Filtering personal changes is supported only when '" + DIMENSION_ID + "', '" + USER + "' or '" + BUILD + "' dimensions are specified");
      }
    }

    final String buildLocator = locator.getSingleDimensionValue(BUILD);
    if (buildLocator != null) {
      BuildPromotion buildFromBuildFinder;
      try {
        buildFromBuildFinder = myBuildPromotionFinder.getItem(buildLocator);
      } catch (Exception e) {
        if (!TeamCityProperties.getBoolean("rest.request.changes.legacySingleBuildSearch")) {
          throw e;
        }
        //support for finished builds
        //todo: use buildPromotionFinder here (ensure it also supports finished builds)
        buildFromBuildFinder = myBuildFinder.getBuildPromotion(null, buildLocator);   //THIS SHOULD NEVER HAPPEN
      }

      return wrapDescriptors(getBuildChangeDescriptors(buildFromBuildFinder, locator));
    }

    //pre-9.0 compatibility
    final Long promotionLocator = locator.getSingleDimensionValueAsLong(PROMOTION);
    if (promotionLocator != null) {
      return wrapDescriptors(getBuildChangeDescriptors(myBuildPromotionFinder.getBuildPromotion(promotionLocator), locator));
    }

    final String parentChangeLocator = locator.getSingleDimensionValue(CHILD_CHANGE);
    if (parentChangeLocator != null) {
      final SVcsModification parentChange = getItem(parentChangeLocator).getSVcsModification();

      return wrapModifications(getChangesWhichHasChild(parentChange, locator.getSingleDimensionValueAsLong(DIMENSION_LOOKUP_LIMIT)));
      //todo: return iterator instead of processing lookup limit here
    }

    final String childChangeLocator = locator.getSingleDimensionValue(PARENT_CHANGE);
    if (childChangeLocator != null) {
      final SVcsModification parentChange = getItem(childChangeLocator).getSVcsModification();
      return wrapModifications(getChangesWhichHasParent(parentChange, locator.getSingleDimensionValueAsLong(DIMENSION_LOOKUP_LIMIT)));
    }

    final String graphLocator = locator.getSingleDimensionValue(DAG_TRAVERSE);
    if (graphLocator != null) {
      final GraphFinder<SVcsModification> graphFinder = new GraphFinder<>(
        locatorText -> getItems(locatorText).getEntries().stream().map(SVcsModificationOrChangeDescriptor::getSVcsModification).collect(Collectors.toList()),
        new ChangesGraphTraverser()
      );

      graphFinder.setDefaultLookupLimit(1000L);
      return wrapModifications(graphFinder.getItems(graphLocator).getEntries());
    }

    Long sinceChangeId = null;
    final String sinceChangeLocator = locator.getSingleDimensionValue(SINCE_CHANGE);
    if (sinceChangeLocator != null) {
      sinceChangeId = getChangeIdBySinceChangeLocator(sinceChangeLocator);
    }

    SBuildType buildType = null;
    final String buildTypeLocator = locator.getSingleDimensionValue(BUILD_TYPE); //todo: support multiple buildTypes here
    if (buildTypeLocator != null) {
      buildType = myBuildTypeFinder.getBuildType(null, buildTypeLocator, false);
    }

    Boolean pending = locator.getSingleDimensionValueAsBoolean(PENDING);
    if (pending != null) {
      if (pending) {
        Stream<SVcsModificationOrChangeDescriptor> changes = getPendingChanges(buildType, locator);
        return processor -> changes.allMatch(processor::processItem);
      } else {
        locator.markUnused(PENDING);
      }
    }

    if (buildType != null) {
      Stream<SVcsModificationOrChangeDescriptor> changes = getBranchChanges(buildType, SelectPrevBuildPolicy.SINCE_NULL_BUILD, locator);
      return processor -> changes.allMatch(processor::processItem);
    }

    if (locator.lookupSingleDimensionValue(BRANCH) != null) {
      throw new BadRequestException("Filtering changes by branch is only supported when buildType is specified.");
    }

    final String projectLocator = locator.getSingleDimensionValue(PROJECT);
    if (projectLocator != null) {
      return wrapModifications(getProjectChanges(myProjectFinder.getItem(projectLocator), sinceChangeId, false));
    }

    final String affectedProjectLocator = locator.getSingleDimensionValue(AFFECTED_PROJECT);
    if (affectedProjectLocator != null) {
      return wrapModifications(getProjectChanges(myProjectFinder.getItem(affectedProjectLocator), sinceChangeId, true));
    }

    final String userLocator = locator.getSingleDimensionValue(USER);
    if (userLocator != null) {
      final SUser user = myUserFinder.getItem(userLocator);
      Stream<SVcsModification> modifications = myServiceLocator.getSingletonService(UserChangesFacade.class)
                                                               .getAllVcsModifications(user).stream()
                                                               .flatMap(this::modificationWithDuplicates)
                                                               .filter(myPermissionChecker::checkCanView);
      return wrapModifications(modifications);
    }

    final String username = locator.getSingleDimensionValue(USERNAME);
    if (username != null) {
      Stream<SVcsModification> modifications = myServiceLocator.getSingletonService(VcsModificationsStorage.class)
                                                               .findModificationsByUsername(username).stream()
                                                               .flatMap(this::modificationWithDuplicates)
                                                               .filter(myPermissionChecker::checkCanView);
      return wrapModifications(modifications);
    }

    final String vcsRootInstanceLocator = locator.getSingleDimensionValue(VCS_ROOT_INSTANCE);
    if (vcsRootInstanceLocator != null) {
      final VcsRootInstance vcsRootInstance = myVcsRootInstanceFinder.getItem(vcsRootInstanceLocator);
      if (sinceChangeId != null) {
        //todo: use lookupLimit here or otherwise limit processing
        return wrapModifications(myVcsModificationHistory.getModificationsInRange(vcsRootInstance, sinceChangeId, null));
      } else {
        //todo: highly inefficient!
        return wrapModifications(myVcsModificationHistory.getAllModifications(vcsRootInstance));
      }
    }

    if (sinceChangeId != null) {
      return wrapModifications(myVcsModificationHistory.getModificationsInRange(null, sinceChangeId, null));  //todo: use lookupLimit here or otherwise limit processing
    }

    return wrapModifications(((VcsModificationHistoryEx) myVcsModificationHistory)::processModifications);  // ItemHolder
  }