import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
+import org.apache.commons.lang.BooleanUtils;
import org.apache.commons.lang.ObjectUtils;
import org.sonar.api.ServerComponent;
import org.sonar.api.resources.Qualifiers;
.assignees(RubyUtils.toStrings(params.get(IssueFilterParameters.ASSIGNEES)))
.languages(RubyUtils.toStrings(params.get(IssueFilterParameters.LANGUAGES)))
.tags(RubyUtils.toStrings(params.get(IssueFilterParameters.TAGS)))
- .onComponentOnly(RubyUtils.toBoolean(params.get(IssueFilterParameters.ON_COMPONENT_ONLY)))
.assigned(RubyUtils.toBoolean(params.get(IssueFilterParameters.ASSIGNED)))
.planned(RubyUtils.toBoolean(params.get(IssueFilterParameters.PLANNED)))
.hideRules(RubyUtils.toBoolean(params.get(IssueFilterParameters.HIDE_RULES)))
.createdAfter(RubyUtils.toDate(params.get(IssueFilterParameters.CREATED_AFTER)))
.createdBefore(RubyUtils.toDate(params.get(IssueFilterParameters.CREATED_BEFORE)));
- addComponentUuids(builder, session,
+ addComponentParameters(builder, session,
+ RubyUtils.toBoolean(params.get(IssueFilterParameters.ON_COMPONENT_ONLY)),
+ RubyUtils.toStrings(params.get(IssueFilterParameters.COMPONENTS)),
RubyUtils.toStrings(params.get(IssueFilterParameters.COMPONENT_UUIDS)),
- RubyUtils.toStrings(
- ObjectUtils.defaultIfNull(
- params.get(IssueFilterParameters.COMPONENT_KEYS),
- params.get(IssueFilterParameters.COMPONENTS)
- )
- ),
+ RubyUtils.toStrings(params.get(IssueFilterParameters.COMPONENT_KEYS)),
RubyUtils.toStrings(params.get(IssueFilterParameters.COMPONENT_ROOT_UUIDS)),
RubyUtils.toStrings(params.get(IssueFilterParameters.COMPONENT_ROOTS)),
RubyUtils.toStrings(params.get(IssueFilterParameters.PROJECT_UUIDS)),
.assignees(request.paramAsStrings(IssueFilterParameters.ASSIGNEES))
.languages(request.paramAsStrings(IssueFilterParameters.LANGUAGES))
.tags(request.paramAsStrings(IssueFilterParameters.TAGS))
- .onComponentOnly(request.paramAsBoolean(IssueFilterParameters.ON_COMPONENT_ONLY))
.assigned(request.paramAsBoolean(IssueFilterParameters.ASSIGNED))
.planned(request.paramAsBoolean(IssueFilterParameters.PLANNED))
.createdAt(request.paramAsDateTime(IssueFilterParameters.CREATED_AT))
.createdBefore(request.paramAsDateTime(IssueFilterParameters.CREATED_BEFORE))
.ignorePaging(request.paramAsBoolean(IssueFilterParameters.IGNORE_PAGING));
- addComponentUuids(builder, session,
- request.paramAsStrings(IssueFilterParameters.COMPONENT_UUIDS), request.paramAsStrings(IssueFilterParameters.COMPONENT_KEYS),
- request.paramAsStrings(IssueFilterParameters.COMPONENT_ROOT_UUIDS), request.paramAsStrings(IssueFilterParameters.COMPONENT_ROOTS),
+ addComponentParameters(builder, session,
+ request.paramAsBoolean(IssueFilterParameters.ON_COMPONENT_ONLY),
+ request.paramAsStrings(IssueFilterParameters.COMPONENTS),
+ request.paramAsStrings(IssueFilterParameters.COMPONENT_UUIDS),
+ request.paramAsStrings(IssueFilterParameters.COMPONENT_KEYS),
+ request.paramAsStrings(IssueFilterParameters.COMPONENT_ROOT_UUIDS),
+ request.paramAsStrings(IssueFilterParameters.COMPONENT_ROOTS),
request.paramAsStrings(IssueFilterParameters.PROJECT_UUIDS), request.paramAsStrings(IssueFilterParameters.PROJECT_KEYS),
request.paramAsStrings(IssueFilterParameters.MODULE_UUIDS),
request.paramAsStrings(IssueFilterParameters.DIRECTORIES),
}
}
- private void addComponentUuids(IssueQuery.Builder builder, DbSession session,
- @Nullable Collection<String> componentUuids, @Nullable Collection<String> components,
+ private void addComponentParameters(IssueQuery.Builder builder, DbSession session,
+ @Nullable Boolean onComponentOnly,
+ @Nullable Collection<String> components,
+ @Nullable Collection<String> componentUuids,
+ @Nullable Collection<String> componentKeys,
/*
* Since 5.1, search of issues is recursive by default (module + submodules),
* but "componentKeys" parameter already deprecates "components" parameter,
* so queries specifying "componentRoots" must be handled manually
*/
- @Nullable Collection<String> componentRootUuids, @Nullable Collection<String> componentRoots,
+ @Nullable Collection<String> componentRootUuids,
+ @Nullable Collection<String> componentRoots,
@Nullable Collection<String> projectUuids, @Nullable Collection<String> projects,
@Nullable Collection<String> moduleUuids,
@Nullable Collection<String> directories,
@Nullable Collection<String> fileUuids) {
Set<String> allComponentUuids = Sets.newHashSet();
+ boolean effectiveOnComponentOnly = mergeComponentParameters(session, onComponentOnly,
+ components,
+ componentUuids,
+ componentKeys,
+ componentRootUuids,
+ componentRoots,
+ allComponentUuids);
- if (componentUuids != null || componentRootUuids != null) {
- if (components != null || componentRoots != null) {
- throw new IllegalArgumentException("components and componentUuids cannot be set simultaneously");
- }
- allComponentUuids.addAll((Collection<String>) ObjectUtils.defaultIfNull(componentUuids, Sets.newHashSet()));
- allComponentUuids.addAll((Collection<String>) ObjectUtils.defaultIfNull(componentRootUuids, Sets.newHashSet()));
- } else {
- Set<String> allComponents = Sets.newHashSet();
- allComponents.addAll((Collection<String>) ObjectUtils.defaultIfNull(components, Sets.newHashSet()));
- allComponents.addAll((Collection<String>) ObjectUtils.defaultIfNull(componentRoots, Sets.newHashSet()));
- allComponentUuids.addAll(componentUuids(session, allComponents));
- }
+ builder.onComponentOnly(effectiveOnComponentOnly);
if (allComponentUuids.isEmpty()) {
builder.setContextualized(false);
addComponentsBelowView(builder, session, projects, projectUuids, moduleUuids, directories, fileUuids);
} else {
+ if (effectiveOnComponentOnly) {
+ builder.setContextualized(false);
+ builder.componentUuids(allComponentUuids);
+ return;
+ }
+
builder.setContextualized(true);
Set<String> qualifiers = componentService.getDistinctQualifiers(session, allComponentUuids);
}
}
+ private boolean mergeComponentParameters(DbSession session, Boolean onComponentOnly,
+ Collection<String> components,
+ Collection<String> componentUuids,
+ Collection<String> componentKeys,
+ Collection<String> componentRootUuids,
+ Collection<String> componentRoots,
+ Set<String> allComponentUuids) {
+ boolean effectiveOnComponentOnly = false;
+
+ if (componentRootUuids != null) {
+ if (componentRoots != null) {
+ throw new IllegalArgumentException("componentRoots and componentRootUuids cannot be set simultaneously");
+ }
+ allComponentUuids.addAll(componentRootUuids);
+ effectiveOnComponentOnly = false;
+ } else if (componentRoots != null) {
+ allComponentUuids.addAll(componentUuids(session, componentRoots));
+ effectiveOnComponentOnly = false;
+ } else if (components != null) {
+ if (componentUuids != null) {
+ throw new IllegalArgumentException("components and componentUuids cannot be set simultaneously");
+ }
+ allComponentUuids.addAll(componentUuids(session, components));
+ effectiveOnComponentOnly = true;
+ } else if (componentUuids != null) {
+ if (componentKeys != null) {
+ throw new IllegalArgumentException("componentUuids and componentKeys cannot be set simultaneously");
+ }
+ allComponentUuids.addAll(componentUuids);
+ effectiveOnComponentOnly = BooleanUtils.isTrue(onComponentOnly);
+ } else if (componentKeys != null) {
+ allComponentUuids.addAll(componentUuids(session, componentKeys));
+ effectiveOnComponentOnly = BooleanUtils.isTrue(onComponentOnly);
+ }
+ return effectiveOnComponentOnly;
+ }
+
private void addComponentsBelowView(Builder builder, DbSession session,
@Nullable Collection<String> projects, @Nullable Collection<String> projectUuids,
@Nullable Collection<String> moduleUuids, Collection<String> directories, Collection<String> fileUuids) {
}
private void addComponentRelatedParams(WebService.NewAction action) {
+
+ action.createParam(IssueFilterParameters.ON_COMPONENT_ONLY)
+ .setDescription("Return only issues at a component's level, not on its descendants (modules, directories, files, etc). " +
+ "This parameter is only considered when componentKeys or componentUuids is set. " +
+ "Using the deprecated componentRoots or componentRootUuids parameters will set this parameter to false. " +
+ "Using the deprecated components parameter will set this parameter to true.")
+ .setBooleanPossibleValues()
+ .setDefaultValue("false");
+
action.createParam(IssueFilterParameters.COMPONENT_KEYS)
- .setDescription("To retrieve issues associated to a specific list of components and their sub-components (comma-separated list of component keys). " +
- "A component can be a project, module, directory or file. " +
+ .setDescription("To retrieve issues associated to a specific list of components sub-components (comma-separated list of component keys). " +
+ "A component can be a view, developer, project, module, directory or file. " +
"If this parameter is set, componentUuids must not be set.")
- .setDeprecatedKey(IssueFilterParameters.COMPONENTS)
.setExampleValue("org.apache.struts:struts:org.apache.struts.Action");
action.createParam(IssueFilterParameters.COMPONENTS)
- .setDescription("Deprecated since 5.1. See componentKeys.");
+ .setDescription("Deprecated since 5.1. If used, will have the same meaning as componentKeys AND onComponentOnly=true.");
action.createParam(IssueFilterParameters.COMPONENT_UUIDS)
- .setDescription("To retrieve issues associated to a specific list of components and their sub-components (comma-separated list of component UUIDs). " +
+ .setDescription("To retrieve issues associated to a specific list of components their sub-components (comma-separated list of component UUIDs). " +
INTERNAL_PARAMETER_DISCLAIMER +
"A component can be a project, module, directory or file. " +
"If this parameter is set, componentKeys must not be set.")
.setExampleValue("584a89f2-8037-4f7b-b82c-8b45d2d63fb2");
+ action.createParam(IssueFilterParameters.COMPONENT_ROOTS)
+ .setDescription("Deprecated since 5.1. If used, will have the same meaning as componentKeys AND onComponentOnly=false.");
+ action.createParam(IssueFilterParameters.COMPONENT_ROOT_UUIDS)
+ .setDescription("Deprecated since 5.1. If used, will have the same meaning as componentUuids AND onComponentOnly=false.");
+
action.createParam(IssueFilterParameters.PROJECTS)
.setDescription("Deprecated since 5.1. See projectKeys");
action.createParam(IssueFilterParameters.PROJECT_KEYS)
"Views are not supported. If this parameter is set, projectKeys must not be set.")
.setExampleValue("7d8749e8-3070-4903-9188-bdd82933bb92");
- action.createParam(IssueFilterParameters.COMPONENT_ROOTS)
- .setDescription("Deprecated since 5.1. Use componentKeys instead, with onComponentOnly=false.");
- action.createParam(IssueFilterParameters.COMPONENT_ROOT_UUIDS)
- .setDescription("Deprecated since 5.1. Use componentUuids instead, with onComponentOnly=false.");
action.createParam(IssueFilterParameters.MODULE_UUIDS)
.setDescription("To retrieve issues associated to a specific list of modules (comma-separated list of module UUIDs). " +
INTERNAL_PARAMETER_DISCLAIMER +
.setDescription("To retrieve issues associated to a specific list of files (comma-separated list of file UUIDs). " +
INTERNAL_PARAMETER_DISCLAIMER)
.setExampleValue("bdd82933-3070-4903-9188-7d8749e8bb92");
-
- action.createParam(IssueFilterParameters.ON_COMPONENT_ONLY)
- .setDescription("Return only issues at the component's level, not on its descendants (modules, directories, files, etc.)")
- .setBooleanPossibleValues()
- .setDefaultValue("false");
}
@Override
@Override
protected Result<Issue> doSearch(IssueQuery query, QueryContext context) {
- Collection<String> components = query.fileUuids();
+ Collection<String> components = query.componentUuids();
if (components != null && components.size() == 1 && BooleanUtils.isTrue(query.ignorePaging())) {
context.setShowFullResult(true);
}
map.put("statuses", newArrayList("CLOSED"));
map.put("resolutions", newArrayList("FALSE-POSITIVE"));
map.put("resolved", true);
- ArrayList<String> componentKeys = newArrayList("org.apache");
- map.put("components", componentKeys);
+ ArrayList<String> projectKeys = newArrayList("org.apache");
+ map.put("projectKeys", projectKeys);
ArrayList<String> moduleUuids = newArrayList("BCDE");
map.put("moduleUuids", moduleUuids);
map.put("directories", newArrayList("/src/main/java/example"));
map.put("assignees", newArrayList("joanna"));
map.put("languages", newArrayList("xoo"));
map.put("tags", newArrayList("tag1", "tag2"));
- map.put("onComponentOnly", true);
map.put("assigned", true);
map.put("planned", true);
map.put("hideRules", true);
assertThat(query.assignees()).containsOnly("joanna");
assertThat(query.languages()).containsOnly("xoo");
assertThat(query.tags()).containsOnly("tag1", "tag2");
- assertThat(query.onComponentOnly()).isTrue();
+ assertThat(query.onComponentOnly()).isFalse();
assertThat(query.assigned()).isTrue();
assertThat(query.planned()).isTrue();
assertThat(query.hideRules()).isTrue();
issueQueryService.createFromMap(map);
fail();
} catch (Exception e) {
- assertThat(e).isInstanceOf(IllegalArgumentException.class).hasMessage("components and componentUuids cannot be set simultaneously");
+ assertThat(e).isInstanceOf(IllegalArgumentException.class).hasMessage("componentRoots and componentRootUuids cannot be set simultaneously");
}
}