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);
}