*/
package org.sonar.server.component.ws;
+import com.google.common.base.Function;
import com.google.common.base.Predicates;
+import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSortedSet;
+import com.google.common.collect.Ordering;
import com.google.common.collect.Sets;
import java.util.ArrayList;
import java.util.List;
import org.sonar.db.DbSession;
import org.sonar.db.component.ComponentDto;
import org.sonar.db.component.ComponentTreeQuery;
+import org.sonar.db.component.ComponentTreeQuery.Strategy;
import org.sonar.server.component.ComponentFinder;
import org.sonar.server.user.UserSession;
import org.sonarqube.ws.WsComponents.TreeWsResponse;
import static com.google.common.base.MoreObjects.firstNonNull;
import static com.google.common.collect.FluentIterable.from;
import static com.google.common.collect.Sets.newHashSet;
+import static java.lang.String.CASE_INSENSITIVE_ORDER;
import static java.lang.String.format;
import static java.util.Collections.emptyMap;
+import static org.sonar.api.utils.Paging.offset;
import static org.sonar.core.util.Uuids.UUID_EXAMPLE_02;
+import static org.sonar.db.component.ComponentTreeQuery.Strategy.CHILDREN;
+import static org.sonar.db.component.ComponentTreeQuery.Strategy.LEAVES;
import static org.sonar.server.component.ComponentFinder.ParamNames.BASE_COMPONENT_ID_AND_KEY;
import static org.sonar.server.component.ws.ComponentDtoToWsComponent.componentDtoToWsComponent;
import static org.sonar.server.user.AbstractUserSession.insufficientPrivilegesException;
import static org.sonarqube.ws.client.component.ComponentsWsParameters.PARAM_STRATEGY;
public class TreeAction implements ComponentsWsAction {
+
private static final int MAX_SIZE = 500;
private static final int QUERY_MINIMUM_LENGTH = 3;
private static final String ALL_STRATEGY = "all";
private static final String CHILDREN_STRATEGY = "children";
private static final String LEAVES_STRATEGY = "leaves";
- private static final Set<String> STRATEGIES = ImmutableSortedSet.of(ALL_STRATEGY, CHILDREN_STRATEGY, LEAVES_STRATEGY);
+ private static final Map<String, Strategy> STRATEGIES = ImmutableMap.of(
+ ALL_STRATEGY, LEAVES,
+ CHILDREN_STRATEGY, CHILDREN,
+ LEAVES_STRATEGY, LEAVES);
+
private static final String NAME_SORT = "name";
private static final String PATH_SORT = "path";
private static final String QUALIFIER_SORT = "qualifier";
"<li>all: return all the descendants components of the base component. Grandchildren are returned.</li>" +
"<li>leaves: return all the descendant components (files, in general) which don't have other children. They are the leaves of the component tree.</li>" +
"</ul>")
- .setPossibleValues(STRATEGIES)
+ .setPossibleValues(STRATEGIES.keySet())
.setDefaultValue(ALL_STRATEGY);
}
}
private TreeWsResponse doHandle(TreeWsRequest treeWsRequest) {
- DbSession dbSession = dbClient.openSession(false);
- try {
+ try (DbSession dbSession = dbClient.openSession(false)) {
ComponentDto baseComponent = componentFinder.getByUuidOrKey(dbSession, treeWsRequest.getBaseComponentId(), treeWsRequest.getBaseComponentKey(), BASE_COMPONENT_ID_AND_KEY);
checkPermissions(baseComponent);
ComponentTreeQuery query = toComponentTreeQuery(treeWsRequest, baseComponent);
- List<ComponentDto> components;
- int total;
- switch (treeWsRequest.getStrategy()) {
- case CHILDREN_STRATEGY:
- components = dbClient.componentDao().selectDescendants(dbSession, query);
- total = components.size();
- break;
- case LEAVES_STRATEGY:
- case ALL_STRATEGY:
- components = dbClient.componentDao().selectDescendants(dbSession, query);
- total = components.size();
- break;
- default:
- throw new IllegalStateException("Unknown component tree strategy");
- }
+ List<ComponentDto> components = dbClient.componentDao().selectDescendants(dbSession, query);
+ int total = components.size();
+ components = sortComponents(components, treeWsRequest);
+ components = paginateComponents(components, treeWsRequest);
+
Map<String, ComponentDto> referenceComponentsByUuid = searchReferenceComponentsByUuid(dbSession, components);
return buildResponse(baseComponent, components, referenceComponentsByUuid,
- Paging.forPageIndex(query.getPage()).withPageSize(query.getPageSize()).andTotal(total));
- } finally {
- dbClient.closeSession(dbSession);
+ Paging.forPageIndex(treeWsRequest.getPage()).withPageSize(treeWsRequest.getPageSize()).andTotal(total));
}
}
}
}
- private static TreeWsResponse buildResponse(ComponentDto baseComponent, List<ComponentDto> components,
- Map<String, ComponentDto> referenceComponentsByUuid, Paging paging) {
+ private static TreeWsResponse buildResponse(ComponentDto baseComponent, List<ComponentDto> components, Map<String, ComponentDto> referenceComponentsByUuid, Paging paging) {
TreeWsResponse.Builder response = TreeWsResponse.newBuilder();
response.getPagingBuilder()
.setPageIndex(paging.pageIndex())
ComponentTreeQuery.Builder query = ComponentTreeQuery.builder()
.setBaseUuid(baseComponent.uuid())
- .setPage(request.getPage())
- .setPageSize(request.getPageSize())
- .setSortFields(request.getSort())
- .setAsc(request.getAsc());
+ .setStrategy(STRATEGIES.get(request.getStrategy()));
if (request.getQuery() != null) {
query.setNameOrKeyQuery(request.getQuery());
}
TreeWsRequest treeWsRequest = new TreeWsRequest()
.setBaseComponentId(request.param(PARAM_BASE_COMPONENT_ID))
.setBaseComponentKey(request.param(PARAM_BASE_COMPONENT_KEY))
- .setStrategy(request.param(PARAM_STRATEGY))
+ .setStrategy(request.mandatoryParam(PARAM_STRATEGY))
.setQuery(request.param(Param.TEXT_QUERY))
.setQualifiers(request.paramAsStrings(PARAM_QUALIFIERS))
.setSort(request.mandatoryParamAsStrings(Param.SORT))
return treeWsRequest;
}
+ private static List<ComponentDto> paginateComponents(List<ComponentDto> components, TreeWsRequest wsRequest) {
+ return from(components)
+ .skip(offset(wsRequest.getPage(), wsRequest.getPageSize()))
+ .limit(wsRequest.getPageSize())
+ .toList();
+ }
+
+ public static List<ComponentDto> sortComponents(List<ComponentDto> components, TreeWsRequest wsRequest) {
+ List<String> sortParameters = wsRequest.getSort();
+ if (sortParameters == null || sortParameters.isEmpty()) {
+ return components;
+ }
+ boolean isAscending = wsRequest.getAsc();
+ Map<String, Ordering<ComponentDto>> orderingsBySortField = ImmutableMap.<String, Ordering<ComponentDto>>builder()
+ .put(NAME_SORT, stringOrdering(isAscending, ComponentDto::name))
+ .put(QUALIFIER_SORT, stringOrdering(isAscending, ComponentDto::qualifier))
+ .put(PATH_SORT, stringOrdering(isAscending, ComponentDto::path))
+ .build();
+
+ String firstSortParameter = sortParameters.get(0);
+ Ordering<ComponentDto> primaryOrdering = orderingsBySortField.get(firstSortParameter);
+ if (sortParameters.size() > 1) {
+ for (int i = 1; i < sortParameters.size(); i++) {
+ String secondarySortParameter = sortParameters.get(i);
+ Ordering<ComponentDto> secondaryOrdering = orderingsBySortField.get(secondarySortParameter);
+ primaryOrdering = primaryOrdering.compound(secondaryOrdering);
+ }
+ }
+ return primaryOrdering.immutableSortedCopy(components);
+ }
+
+ private static Ordering<ComponentDto> stringOrdering(boolean isAscending, Function<ComponentDto, String> function) {
+ Ordering<String> ordering = Ordering.from(CASE_INSENSITIVE_ORDER);
+ if (!isAscending) {
+ ordering = ordering.reverse();
+ }
+ return ordering.nullsLast().onResultOf(function);
+ }
+
}
*/
package org.sonar.server.measure.ws;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSortedSet;
+import java.util.Map;
+import java.util.Set;
+import org.sonar.api.i18n.I18n;
+import org.sonar.api.resources.ResourceTypes;
+import org.sonar.api.server.ws.Request;
+import org.sonar.api.server.ws.Response;
+import org.sonar.api.server.ws.WebService;
+import org.sonar.api.server.ws.WebService.Param;
+import org.sonar.api.utils.Paging;
+import org.sonar.db.component.ComponentDto;
+import org.sonar.db.component.ComponentTreeQuery.Strategy;
+import org.sonar.db.metric.MetricDto;
+import org.sonarqube.ws.WsMeasures;
+import org.sonarqube.ws.WsMeasures.ComponentTreeWsResponse;
+import org.sonarqube.ws.client.measure.ComponentTreeWsRequest;
+
import static java.lang.String.format;
import static org.sonar.core.util.Uuids.UUID_EXAMPLE_02;
+import static org.sonar.db.component.ComponentTreeQuery.Strategy.CHILDREN;
+import static org.sonar.db.component.ComponentTreeQuery.Strategy.LEAVES;
import static org.sonar.server.measure.ws.ComponentDtoToWsComponent.componentDtoToWsComponent;
import static org.sonar.server.measure.ws.MeasuresWsParametersBuilder.createAdditionalFieldsParameter;
import static org.sonar.server.measure.ws.MeasuresWsParametersBuilder.createDeveloperParameters;
import static org.sonar.server.measure.ws.MeasuresWsParametersBuilder.createMetricKeysParameter;
import static org.sonar.server.measure.ws.MetricDtoToWsMetric.metricDtoToWsMetric;
import static org.sonar.server.ws.KeyExamples.KEY_PROJECT_EXAMPLE_001;
-import static org.sonar.server.ws.WsParameterBuilder.QualifierParameterContext.newQualifierParameterContext;
import static org.sonar.server.ws.WsParameterBuilder.createQualifiersParameter;
+import static org.sonar.server.ws.WsParameterBuilder.QualifierParameterContext.newQualifierParameterContext;
import static org.sonar.server.ws.WsUtils.checkRequest;
import static org.sonar.server.ws.WsUtils.writeProtobuf;
import static org.sonarqube.ws.client.measure.MeasuresWsParameters.ACTION_COMPONENT_TREE;
import static org.sonarqube.ws.client.measure.MeasuresWsParameters.PARAM_QUALIFIERS;
import static org.sonarqube.ws.client.measure.MeasuresWsParameters.PARAM_STRATEGY;
-import com.google.common.collect.ImmutableSortedSet;
-import java.util.Set;
-import org.sonar.api.i18n.I18n;
-import org.sonar.api.resources.ResourceTypes;
-import org.sonar.api.server.ws.Request;
-import org.sonar.api.server.ws.Response;
-import org.sonar.api.server.ws.WebService;
-import org.sonar.api.server.ws.WebService.Param;
-import org.sonar.api.utils.Paging;
-import org.sonar.db.component.ComponentDto;
-import org.sonar.db.metric.MetricDto;
-import org.sonarqube.ws.WsMeasures;
-import org.sonarqube.ws.WsMeasures.ComponentTreeWsResponse;
-import org.sonarqube.ws.client.measure.ComponentTreeWsRequest;
-
/**
* <p>Navigate through components based on different strategy with specified measures.
* To limit the number of rows in database, a best value algorithm exists in database.</p>
static final String ALL_STRATEGY = "all";
static final String CHILDREN_STRATEGY = "children";
static final String LEAVES_STRATEGY = "leaves";
- static final Set<String> STRATEGIES = ImmutableSortedSet.of(ALL_STRATEGY, CHILDREN_STRATEGY, LEAVES_STRATEGY);
+ static final Map<String, Strategy> STRATEGIES = ImmutableMap.of(
+ ALL_STRATEGY, LEAVES,
+ CHILDREN_STRATEGY, CHILDREN,
+ LEAVES_STRATEGY, LEAVES);
// sort
static final String NAME_SORT = "name";
static final String PATH_SORT = "path";
"<li>all: return all the descendants components of the base component. Grandchildren are returned.</li>" +
"<li>leaves: return all the descendant components (files, in general) which don't have other children. They are the leaves of the component tree.</li>" +
"</ul>")
- .setPossibleValues(STRATEGIES)
+ .setPossibleValues(STRATEGIES.keySet())
.setDefaultValue(ALL_STRATEGY);
}
import com.google.common.base.Predicates;
import com.google.common.collect.FluentIterable;
import com.google.common.collect.HashBasedTable;
-import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.google.common.collect.Table;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.LinkedHashSet;
import org.sonar.db.component.ComponentTreeQuery;
import org.sonar.db.component.SnapshotDto;
import org.sonar.db.measure.MeasureDto;
-import org.sonar.db.measure.MeasureQuery;
+import org.sonar.db.measure.MeasureTreeQuery;
import org.sonar.db.metric.MetricDto;
import org.sonar.db.metric.MetricDtoFunctions;
import org.sonar.server.component.ComponentFinder;
import static com.google.common.base.MoreObjects.firstNonNull;
import static com.google.common.base.Preconditions.checkState;
import static com.google.common.collect.FluentIterable.from;
-import static com.google.common.collect.Lists.newArrayList;
import static com.google.common.collect.Sets.newHashSet;
import static java.lang.String.format;
import static java.util.Collections.emptyMap;
-import static java.util.Collections.singletonList;
import static java.util.Objects.requireNonNull;
import static org.sonar.api.utils.Paging.offset;
import static org.sonar.server.component.ComponentFinder.ParamNames.BASE_COMPONENT_ID_AND_KEY;
import static org.sonar.server.component.ComponentFinder.ParamNames.DEVELOPER_ID_AND_KEY;
-import static org.sonar.server.measure.ws.ComponentTreeAction.ALL_STRATEGY;
-import static org.sonar.server.measure.ws.ComponentTreeAction.CHILDREN_STRATEGY;
import static org.sonar.server.measure.ws.ComponentTreeAction.LEAVES_STRATEGY;
-import static org.sonar.server.measure.ws.ComponentTreeAction.METRIC_PERIOD_SORT;
-import static org.sonar.server.measure.ws.ComponentTreeAction.METRIC_SORT;
-import static org.sonar.server.measure.ws.ComponentTreeAction.NAME_SORT;
+import static org.sonar.server.measure.ws.ComponentTreeAction.STRATEGIES;
import static org.sonar.server.measure.ws.ComponentTreeAction.WITH_MEASURES_ONLY_METRIC_SORT_FILTER;
import static org.sonar.server.measure.ws.SnapshotDtoToWsPeriods.snapshotToWsPeriods;
import static org.sonar.server.user.AbstractUserSession.insufficientPrivilegesException;
}
Long developerId = searchDeveloperId(dbSession, wsRequest);
- ComponentTreeQuery dbQuery = toComponentTreeQuery(wsRequest, baseComponent);
- ComponentDtosAndTotal componentDtosAndTotal = searchComponents(dbSession, dbQuery, wsRequest);
- List<ComponentDto> components = componentDtosAndTotal.componentDtos;
+ ComponentTreeQuery componentTreeQuery = toComponentTreeQuery(wsRequest, baseComponent);
+ List<ComponentDto> components = searchComponents(dbSession, componentTreeQuery);
List<MetricDto> metrics = searchMetrics(dbSession, wsRequest);
List<WsMeasures.Period> periods = snapshotToWsPeriods(baseSnapshot.get());
- Table<String, MetricDto, MeasureDto> measuresByComponentUuidAndMetric = searchMeasuresByComponentUuidAndMetric(dbSession, baseComponent, components, metrics,
- periods, developerId);
+ Table<String, MetricDto, MeasureDto> measuresByComponentUuidAndMetric = searchMeasuresByComponentUuidAndMetric(dbSession, baseComponent, componentTreeQuery, components,
+ metrics, periods, developerId);
components = filterComponents(components, measuresByComponentUuidAndMetric, metrics, wsRequest);
components = sortComponents(components, wsRequest, metrics, measuresByComponentUuidAndMetric);
- int componentCount = computeComponentCount(componentDtosAndTotal.total, components, componentWithMeasuresOnly(wsRequest));
+
+ int componentCount = components.size();
components = paginateComponents(components, wsRequest);
- Map<String, ComponentDto> referenceComponentsById = searchReferenceComponentsById(dbSession, components);
return ComponentTreeData.builder()
.setBaseComponent(baseComponent)
.setMeasuresByComponentUuidAndMetric(measuresByComponentUuidAndMetric)
.setMetrics(metrics)
.setPeriods(periods)
- .setReferenceComponentsByUuid(referenceComponentsById)
+ .setReferenceComponentsByUuid(searchReferenceComponentsById(dbSession, components))
.build();
} finally {
dbClient.closeSession(dbSession);
}
}
- private static int computeComponentCount(int dbComponentCount, List<ComponentDto> components, boolean returnOnlyComponentsWithMeasures) {
- return returnOnlyComponentsWithMeasures ? components.size() : dbComponentCount;
- }
-
@CheckForNull
private Long searchDeveloperId(DbSession dbSession, ComponentTreeWsRequest wsRequest) {
if (wsRequest.getDeveloperId() == null && wsRequest.getDeveloperKey() == null) {
.uniqueIndex(ComponentDto::uuid);
}
- private ComponentDtosAndTotal searchComponents(DbSession dbSession, ComponentTreeQuery dbQuery, ComponentTreeWsRequest wsRequest) {
- if (dbQuery.getQualifiers() != null && dbQuery.getQualifiers().isEmpty()) {
- return new ComponentDtosAndTotal(Collections.emptyList(), 0);
- }
- String strategy = requireNonNull(wsRequest.getStrategy());
- switch (strategy) {
- case CHILDREN_STRATEGY:
- return new ComponentDtosAndTotal(
- dbClient.componentDao().selectDescendants(dbSession, dbQuery),
- 0);
- case LEAVES_STRATEGY:
- case ALL_STRATEGY:
- return new ComponentDtosAndTotal(
- dbClient.componentDao().selectDescendants(dbSession, dbQuery),
- 0);
- default:
- throw new IllegalStateException("Unknown component tree strategy");
+ private List<ComponentDto> searchComponents(DbSession dbSession, ComponentTreeQuery componentTreeQuery) {
+ Collection<String> qualifiers = componentTreeQuery.getQualifiers();
+ if (qualifiers != null && qualifiers.isEmpty()) {
+ return Collections.emptyList();
}
+ return dbClient.componentDao().selectDescendants(dbSession, componentTreeQuery);
}
private List<MetricDto> searchMetrics(DbSession dbSession, ComponentTreeWsRequest request) {
return metrics;
}
- private Table<String, MetricDto, MeasureDto> searchMeasuresByComponentUuidAndMetric(DbSession dbSession, ComponentDto baseComponent,
- List<ComponentDto> components, List<MetricDto> metrics,
- List<WsMeasures.Period> periods, @Nullable Long developerId) {
- List<String> componentUuids = new ArrayList<>();
- componentUuids.add(baseComponent.uuid());
- components.stream().forEach(c -> componentUuids.add(c.uuid()));
+ private Table<String, MetricDto, MeasureDto> searchMeasuresByComponentUuidAndMetric(DbSession dbSession, ComponentDto baseComponent, ComponentTreeQuery componentTreeQuery,
+ List<ComponentDto> components, List<MetricDto> metrics, List<WsMeasures.Period> periods, @Nullable Long developerId) {
Map<Integer, MetricDto> metricsById = Maps.uniqueIndex(metrics, MetricDtoFunctions.toId());
- MeasureQuery measureQuery = MeasureQuery.builder()
+ MeasureTreeQuery measureQuery = MeasureTreeQuery.builder()
+ .setStrategy(MeasureTreeQuery.Strategy.valueOf(componentTreeQuery.getStrategy().name()))
+ .setNameOrKeyQuery(componentTreeQuery.getNameOrKeyQuery())
+ .setQualifiers(componentTreeQuery.getQualifiers())
.setPersonId(developerId)
- .setComponentUuids(baseComponent.projectUuid(), componentUuids)
.setMetricIds(new ArrayList<>(metricsById.keySet()))
.build();
- List<MeasureDto> measureDtos = dbClient.measureDao().selectByQuery(dbSession, measureQuery);
+ List<MeasureDto> measureDtos = dbClient.measureDao().selectTreeByQuery(dbSession, baseComponent, measureQuery);
Table<String, MetricDto, MeasureDto> measuresByComponentUuidAndMetric = HashBasedTable.create(components.size(), metrics.size());
for (MeasureDto measureDto : measureDtos) {
private static List<ComponentDto> sortComponents(List<ComponentDto> components, ComponentTreeWsRequest wsRequest, List<MetricDto> metrics,
Table<String, MetricDto, MeasureDto> measuresByComponentUuidAndMetric) {
- if (!isSortByMetric(wsRequest)) {
- return components;
- }
-
return ComponentTreeSort.sortComponents(components, wsRequest, metrics, measuresByComponentUuidAndMetric);
}
private static List<ComponentDto> paginateComponents(List<ComponentDto> components, ComponentTreeWsRequest wsRequest) {
- if (!isSortByMetric(wsRequest)) {
- return components;
- }
-
return from(components)
.skip(offset(wsRequest.getPage(), wsRequest.getPageSize()))
.limit(wsRequest.getPageSize())
.toList();
}
- private static boolean isSortByMetric(ComponentTreeWsRequest wsRequest) {
- requireNonNull(wsRequest.getSort());
- return wsRequest.getSort().contains(METRIC_SORT) || wsRequest.getSort().contains(METRIC_PERIOD_SORT);
- }
-
@CheckForNull
private List<String> childrenQualifiers(ComponentTreeWsRequest request, String baseQualifier) {
List<String> requestQualifiers = request.getQualifiers();
private ComponentTreeQuery toComponentTreeQuery(ComponentTreeWsRequest wsRequest, ComponentDto baseComponent) {
List<String> childrenQualifiers = childrenQualifiers(wsRequest, baseComponent.qualifier());
- List<String> sortsWithoutMetricSort = newArrayList(Iterables.filter(wsRequest.getSort(), IsNotMetricSort.INSTANCE));
- sortsWithoutMetricSort = sortsWithoutMetricSort.isEmpty() ? singletonList(NAME_SORT) : sortsWithoutMetricSort;
-
- ComponentTreeQuery.Builder dbQuery = ComponentTreeQuery.builder()
+ ComponentTreeQuery.Builder componentTreeQueryBuilder = ComponentTreeQuery.builder()
.setBaseUuid(baseComponent.uuid())
- .setPage(wsRequest.getPage())
- .setPageSize(wsRequest.getPageSize())
- .setSortFields(sortsWithoutMetricSort)
- .setAsc(wsRequest.getAsc());
+ .setStrategy(STRATEGIES.get(wsRequest.getStrategy()));
if (wsRequest.getQuery() != null) {
- dbQuery.setNameOrKeyQuery(wsRequest.getQuery());
+ componentTreeQueryBuilder.setNameOrKeyQuery(wsRequest.getQuery());
}
if (childrenQualifiers != null) {
- dbQuery.setQualifiers(childrenQualifiers);
+ componentTreeQueryBuilder.setQualifiers(childrenQualifiers);
}
- // load all components if we must sort by metric value
- if (isSortByMetric(wsRequest)) {
- dbQuery.setPage(1);
- dbQuery.setPageSize(Integer.MAX_VALUE);
- }
-
- return dbQuery.build();
+ return componentTreeQueryBuilder.build();
}
private void checkPermissions(ComponentDto baseComponent) {
}
}
- private static class ComponentDtosAndTotal {
- private final List<ComponentDto> componentDtos;
- private final int total;
-
- private ComponentDtosAndTotal(List<ComponentDto> componentDtos, int total) {
- this.componentDtos = componentDtos;
- this.total = total;
- }
- }
-
private enum IsFileComponent implements Predicate<ComponentDto> {
INSTANCE;
}
}
- private enum IsNotMetricSort implements Predicate<String> {
- INSTANCE;
-
- @Override
- public boolean apply(@Nonnull String input) {
- return !input.equals(METRIC_SORT) && !input.equals(METRIC_PERIOD_SORT);
- }
- }
-
private static class MatchMetricKey implements Predicate<MetricDto> {
private final String metricKeyToSort;
import static org.sonar.server.measure.ws.ComponentTreeAction.PATH_SORT;
import static org.sonar.server.measure.ws.ComponentTreeAction.QUALIFIER_SORT;
-class ComponentTreeSort {
+public class ComponentTreeSort {
private static final Set<ValueType> NUMERIC_VALUE_TYPES = EnumSet.of(BOOL, FLOAT, INT, MILLISEC, WORK_DUR, PERCENT, RATING);
private static final Set<ValueType> TEXTUAL_VALUE_TYPES = EnumSet.of(DATA, DISTRIB, STRING);
// static method only
}
- static List<ComponentDto> sortComponents(List<ComponentDto> components, ComponentTreeWsRequest wsRequest, List<MetricDto> metrics,
+ public static List<ComponentDto> sortComponents(List<ComponentDto> components, ComponentTreeWsRequest wsRequest, List<MetricDto> metrics,
Table<String, MetricDto, MeasureDto> measuresByComponentUuidAndMetric) {
List<String> sortParameters = wsRequest.getSort();
if (sortParameters == null || sortParameters.isEmpty()) {
}
private static Ordering<ComponentDto> componentNameOrdering(boolean isAscending) {
- return stringOrdering(isAscending, ComponentDtoToName.INSTANCE);
+ return stringOrdering(isAscending, ComponentDto::name);
}
private static Ordering<ComponentDto> componentQualifierOrdering(boolean isAscending) {
- return stringOrdering(isAscending, ComponentDtoToQualifier.INSTANCE);
+ return stringOrdering(isAscending, ComponentDto::qualifier);
}
private static Ordering<ComponentDto> componentPathOrdering(boolean isAscending) {
- return stringOrdering(isAscending, ComponentDtoToPath.INSTANCE);
+ return stringOrdering(isAscending, ComponentDto::path);
}
private static Ordering<ComponentDto> stringOrdering(boolean isAscending, Function<ComponentDto, String> function) {
}
}
- private enum ComponentDtoToName implements Function<ComponentDto, String> {
- INSTANCE;
-
- @Override
- public String apply(@Nonnull ComponentDto input) {
- return input.name();
- }
- }
-
- private enum ComponentDtoToQualifier implements Function<ComponentDto, String> {
- INSTANCE;
-
- @Override
- public String apply(@Nonnull ComponentDto input) {
- return input.qualifier();
- }
- }
-
- private enum ComponentDtoToPath implements Function<ComponentDto, String> {
- INSTANCE;
-
- @Override
- public String apply(@Nonnull ComponentDto input) {
- return input.path();
- }
- }
}
.setParam(Param.PAGE_SIZE, "3"));
assertThat(response.getComponentsList()).extracting("id").containsExactly("file-uuid-4", "file-uuid-5", "file-uuid-6");
+ assertThat(response.getPaging().getPageIndex()).isEqualTo(2);
+ assertThat(response.getPaging().getPageSize()).isEqualTo(3);
+ assertThat(response.getPaging().getTotal()).isEqualTo(9);
}
@Test