private PagedSearchResult getItemsByLocator()

in rest-api/src/jetbrains/buildServer/server/rest/data/finder/FinderImpl.java [229:323]


  private PagedSearchResult<ITEM> getItemsByLocator(@Nullable final Locator originalLocator, final boolean multipleItemsQuery) {
    long startTime = System.nanoTime();
    Locator locator;
    if (originalLocator == null) {
      //go on with empty locator
      locator = createLocator(null, Locator.createEmptyLocator());
    } else {
      locator = originalLocator;

      locator.processHelpRequest();
    }

    String contextItemText = locator.getSingleDimensionValue(CONTEXT_ITEM_DIMENSION_NAME);
    if (contextItemText != null) {
      List<ITEM> contextObjects = getContextItems(contextItemText);
      if (contextObjects == null) throw new BadRequestException("Context variable '" + contextItemText + "' is used in locator, but is not present in the context");
      if (contextObjects.isEmpty()) throw new BadRequestException("Context variable '" + contextItemText + "' is used in locator, but the list does not contain any elements");

      //so far do not support additional filtering or other dimensions if context item is used
      locator.checkLocatorFullyProcessed();
      return new PagedSearchResult<>(contextObjects, null, null);
    }

    if (!locator.isEmpty()) {
      final ITEM singleItem;
      try {
        singleItem = myDataBinding.findSingleItem(locator);
      } catch (NotFoundException e) {
        if (multipleItemsQuery && !isReportErrorOnNothingFound(locator)) {
          //consider adding comment/warning messages to PagedSearchResult, return it as a header in the response
          //returning empty collection for multiple items query
          return new PagedSearchResult<>(Collections.emptyList(), null, null);
        }
        throw e;
      }
      if (singleItem != null) {
        final Set<String> singleItemUsedDimensions = locator.getUsedDimensions();
        // ignore start:0 dimension
        final Long startDimension = locator.getSingleDimensionValueAsLong(PagerData.START);
        if (startDimension == null || startDimension != 0) {
          locator.markUnused(PagerData.START);
        }

        ItemFilter<ITEM> filter;
        try {
          filter = getDataBindingWithLogicOpsSupport(locator, myDataBinding).getFilter();
        } catch (NotFoundException e) {
          throw new NotFoundException("Invalid filter for found single item, try omitting extra dimensions: " + e.getMessage(), e);
        } catch (BadRequestException e) {
          throw new BadRequestException("Invalid filter for found single item, try omitting extra dimensions: " + e.getMessage(), e);
        } catch (Exception e) {
          throw new BadRequestException("Invalid filter for found single item, try omitting extra dimensions: " + e.toString(), e);
        }
        locator.markUsed(DIMENSION_UNIQUE); //mark as used as it has no influence on single item
        locator.checkLocatorFullyProcessed(); //checking before invoking filter to report any unused dimensions before possible error reporting in filter
        if (!filter.isIncluded(singleItem)) {
          final String message = "Found single item by " + StringUtil.pluralize("dimension", singleItemUsedDimensions.size()) + " " + singleItemUsedDimensions +
                                 ", but that was filtered out using the entire locator '" + locator + "'";
          if (multipleItemsQuery && !isReportErrorOnNothingFound(locator)) {
            LOG.debug(message);
            return new PagedSearchResult<>(Collections.emptyList(), null, null);
          } else {
            throw new NotFoundException(message);
          }
        }

        return new PagedSearchResult<>(Collections.singletonList(singleItem), null, null);
      }
      locator.markAllUnused(); // nothing found - no dimensions should be marked as used then
    }
    ItemHolder<ITEM> unfilteredItems;
    PagingItemFilter<ITEM> pagingFilter;
    try {
      LocatorDataBinding<ITEM> locatorDataBinding = getDataBindingWithLogicOpsSupport(locator, myDataBinding);
      unfilteredItems = locatorDataBinding.getPrefilteredItems();
      DuplicateChecker<ITEM> duplicateChecker = myDataBinding.createDuplicateChecker();
      if (duplicateChecker != null) {
        //get the dimension only for supporting finders so that unused dimension is reported otherwise
        boolean deduplicate = locator.getSingleDimensionValueAsStrictBoolean(DIMENSION_UNIQUE, locator.isAnyPresent(DIMENSION_ITEM));
        if (deduplicate) {
          unfilteredItems = unfilteredItems.filter(item -> !duplicateChecker.checkDuplicateAndRemember(item));
        }
      }

      pagingFilter = getPagingFilter(locator, locatorDataBinding.getFilter());
    } catch (LocatorProcessException | BadRequestException | IllegalArgumentException e) {
      if (!locator.isHelpRequested()) {
        throw e;
      }
      throw new BadRequestException(e.getMessage() +
                                    "\nLocator details: " + locator.getLocatorDescription(locator.helpOptions().getSingleDimensionValueAsStrictBoolean("hidden", false)), e);
    }
    locator.checkLocatorFullyProcessed();
    return getItems(pagingFilter, unfilteredItems, locator, startTime);
  }