import com.google.common.base.Function;
import org.apache.ibatis.session.RowBounds;
-import org.sonar.api.ServerComponent;
import org.sonar.api.ServerSide;
import org.sonar.api.resources.Qualifiers;
import org.sonar.api.resources.Scopes;
import javax.annotation.CheckForNull;
import javax.annotation.Nullable;
-
import java.util.Collection;
import java.util.Collections;
-import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import static com.google.common.collect.Maps.newHashMapWithExpectedSize;
+
/**
* @since 4.3
*/
}
public List<ComponentDto> selectProvisionedProjects(DbSession session, SearchOptions searchOptions, @Nullable String query) {
- Map<String, String> parameters = new HashMap<>();
- parameters.put("qualifier", Qualifiers.PROJECT);
- if (query != null) {
- parameters.put("query", "%" + query + "%");
- }
+ Map<String, String> parameters = newHashMapWithExpectedSize(2);
+ addProjectQualifier(parameters);
+ addPartialQueryParameterIfNotNull(parameters, query);
+
return mapper(session).selectProvisionedProjects(parameters, new RowBounds(searchOptions.getOffset(), searchOptions.getLimit()));
}
public int countProvisionedProjects(DbSession session, @Nullable String query) {
- Map<String, String> parameters = new HashMap<>();
- parameters.put("qualifier", Qualifiers.PROJECT);
+ Map<String, String> parameters = newHashMapWithExpectedSize(2);
+ addProjectQualifier(parameters);
+ addPartialQueryParameterIfNotNull(parameters, query);
+
+ return mapper(session).countProvisionedProjects(parameters);
+ }
+
+ public List<ComponentDto> selectGhostProjects(DbSession session, @Nullable String query, SearchOptions options) {
+ Map<String, String> parameters = newHashMapWithExpectedSize(2);
+ addProjectQualifier(parameters);
+ addPartialQueryParameterIfNotNull(parameters, query);
+
+ return mapper(session).selectGhostProjects(parameters, new RowBounds(options.getOffset(), options.getLimit()));
+ }
+
+ public long countGhostProjects(DbSession session, @Nullable String query) {
+ Map<String, String> parameters = newHashMapWithExpectedSize(2);
+ addProjectQualifier(parameters);
+ addPartialQueryParameterIfNotNull(parameters, query);
+
+ return mapper(session).countGhostProjects(parameters);
+ }
+
+ private void addPartialQueryParameterIfNotNull(Map<String, String> parameters, @Nullable String query) {
if (query != null) {
- parameters.put("query", "%" + query + "%");
+ parameters.put("query", "%" + query.toUpperCase() + "%");
}
- return mapper(session).countProvisionedProjects(parameters);
+ }
+
+ private void addProjectQualifier(Map<String, String> parameters) {
+ parameters.put("qualifier", Qualifiers.PROJECT);
}
}
--- /dev/null
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.sonar.server.component.ws;
+
+import com.google.common.io.Resources;
+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.text.JsonWriter;
+import org.sonar.api.web.UserRole;
+import org.sonar.core.component.ComponentDto;
+import org.sonar.core.persistence.DbSession;
+import org.sonar.core.persistence.MyBatis;
+import org.sonar.server.db.DbClient;
+import org.sonar.server.es.SearchOptions;
+import org.sonar.server.user.UserSession;
+
+import javax.annotation.Nullable;
+
+import java.util.Date;
+import java.util.List;
+import java.util.Set;
+
+import static com.google.common.collect.Sets.newHashSet;
+
+public class ProjectsGhostsAction implements ProjectsWsAction {
+ public static final String ACTION = "ghosts";
+ private static final Set<String> POSSIBLE_FIELDS = newHashSet("uuid", "key", "name", "creationDate");
+
+ private final DbClient dbClient;
+ private final UserSession userSession;
+
+ public ProjectsGhostsAction(DbClient dbClient, UserSession userSession) {
+ this.dbClient = dbClient;
+ this.userSession = userSession;
+ }
+
+ @Override
+ public void define(WebService.NewController context) {
+ context
+ .createAction(ACTION)
+ .setDescription("List ghost projects.<br /> Requires admin role.")
+ .setResponseExample(Resources.getResource(getClass(), "projects-example-ghosts.json"))
+ .setSince("5.2")
+ .addPagingParams(100)
+ .addFieldsParam(POSSIBLE_FIELDS)
+ .addSearchQuery("sonar", "names", "keys")
+ .setHandler(this);
+ }
+
+ @Override
+ public void handle(Request request, Response response) throws Exception {
+ userSession.checkGlobalPermission(UserRole.ADMIN);
+ DbSession dbSession = dbClient.openSession(false);
+ SearchOptions searchOptions = new SearchOptions()
+ .setPage(request.mandatoryParamAsInt(Param.PAGE),
+ request.mandatoryParamAsInt(Param.PAGE_SIZE));
+ Set<String> desiredFields = fieldsToReturn(request.paramAsStrings(Param.FIELDS));
+ String query = request.param(Param.TEXT_QUERY);
+
+ try {
+ long nbOfProjects = dbClient.componentDao().countGhostProjects(dbSession, query);
+ List<ComponentDto> projects = dbClient.componentDao().selectGhostProjects(dbSession, query, searchOptions);
+ JsonWriter json = response.newJsonWriter().beginObject();
+ writeProjects(json, projects, desiredFields);
+ searchOptions.writeJson(json, nbOfProjects);
+ json.endObject().close();
+ } finally {
+ MyBatis.closeQuietly(dbSession);
+ }
+ }
+
+ private void writeProjects(JsonWriter json, List<ComponentDto> projects, Set<String> fieldsToReturn) {
+ json.name("projects");
+ json.beginArray();
+ for (ComponentDto project : projects) {
+ json.beginObject();
+ json.prop("uuid", project.uuid());
+ writeIfWished(json, "key", project.key(), fieldsToReturn);
+ writeIfWished(json, "name", project.name(), fieldsToReturn);
+ writeIfWished(json, "creationDate", project.getCreatedAt(), fieldsToReturn);
+ json.endObject();
+ }
+ json.endArray();
+ }
+
+ private void writeIfWished(JsonWriter json, String key, String value, Set<String> fieldsToReturn) {
+ if (fieldsToReturn.contains(key)) {
+ json.prop(key, value);
+ }
+ }
+
+ private void writeIfWished(JsonWriter json, String key, Date value, Set<String> desiredFields) {
+ if (desiredFields.contains(key)) {
+ json.propDateTime(key, value);
+ }
+ }
+
+ private Set<String> fieldsToReturn(@Nullable List<String> desiredFieldsFromRequest) {
+ if (desiredFieldsFromRequest == null) {
+ return POSSIBLE_FIELDS;
+ }
+
+ return newHashSet(desiredFieldsFromRequest);
+ }
+}
--- /dev/null
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.sonar.server.component.ws;
+
+import com.google.common.io.Resources;
+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.text.JsonWriter;
+import org.sonar.api.web.UserRole;
+import org.sonar.core.component.ComponentDto;
+import org.sonar.core.persistence.DbSession;
+import org.sonar.core.persistence.MyBatis;
+import org.sonar.server.db.DbClient;
+import org.sonar.server.es.SearchOptions;
+import org.sonar.server.user.UserSession;
+
+import java.util.Date;
+import java.util.List;
+import java.util.Set;
+
+import static com.google.common.collect.Sets.newHashSet;
+
+public class ProjectsProvisionedAction implements ProjectsWsAction {
+ private static final Set<String> POSSIBLE_FIELDS = newHashSet("uuid", "key", "name", "creationDate");
+
+ private final DbClient dbClient;
+ private final UserSession userSession;
+
+ public ProjectsProvisionedAction(DbClient dbClient, UserSession userSession) {
+ this.dbClient = dbClient;
+ this.userSession = userSession;
+ }
+
+ @Override
+ public void define(WebService.NewController controller) {
+ controller
+ .createAction("provisioned")
+ .setDescription(
+ "Get the list of provisioned projects.<br /> " +
+ "Require admin role.")
+ .setSince("5.2")
+ .setResponseExample(Resources.getResource(getClass(), "projects-example-provisioned.json"))
+ .setHandler(this)
+ .addPagingParams(100)
+ .addSearchQuery("sonar", "names", "keys")
+ .addFieldsParam(POSSIBLE_FIELDS);
+ }
+
+ @Override
+ public void handle(Request request, Response response) throws Exception {
+ userSession.checkGlobalPermission(UserRole.ADMIN, "You need admin rights.");
+ SearchOptions options = new SearchOptions().setPage(
+ request.mandatoryParamAsInt(Param.PAGE),
+ request.mandatoryParamAsInt(Param.PAGE_SIZE)
+ );
+ Set<String> desiredFields = desiredFields(request);
+ String query = request.param(Param.TEXT_QUERY);
+
+ DbSession dbSession = dbClient.openSession(false);
+ try {
+ List<ComponentDto> projects = dbClient.componentDao().selectProvisionedProjects(dbSession, options, query);
+ int nbOfProjects = dbClient.componentDao().countProvisionedProjects(dbSession, query);
+ JsonWriter json = response.newJsonWriter().beginObject();
+ writeProjects(projects, json, desiredFields);
+ options.writeJson(json, nbOfProjects);
+ json.endObject().close();
+ } finally {
+ MyBatis.closeQuietly(dbSession);
+ }
+ }
+
+ private void writeProjects(List<ComponentDto> projects, JsonWriter json, Set<String> desiredFields) {
+ json.name("projects");
+ json.beginArray();
+ for (ComponentDto project : projects) {
+ json.beginObject();
+ json.prop("uuid", project.uuid());
+ writeIfNeeded(json, "key", project.key(), desiredFields);
+ writeIfNeeded(json, "name", project.name(), desiredFields);
+ writeIfNeeded(json, "creationDate", project.getCreatedAt(), desiredFields);
+ json.endObject();
+ }
+ json.endArray();
+ }
+
+ private void writeIfNeeded(JsonWriter json, String fieldName, String value, Set<String> desiredFields) {
+ if (desiredFields.contains(fieldName)) {
+ json.prop(fieldName, value);
+ }
+ }
+
+ private void writeIfNeeded(JsonWriter json, String fieldName, Date date, Set<String> desiredFields) {
+ if (desiredFields.contains(fieldName)) {
+ json.propDateTime(fieldName, date);
+ }
+ }
+
+ private Set<String> desiredFields(Request request) {
+ List<String> desiredFields = request.paramAsStrings(Param.FIELDS);
+ if (desiredFields == null) {
+ return POSSIBLE_FIELDS;
+ }
+
+ return newHashSet(desiredFields);
+ }
+}
import org.sonar.api.server.ws.WebService;
public class ProjectsWs implements WebService {
+ private static final String ENDPOINT = "api/projects";
+
private final ProjectsWsAction[] actions;
public ProjectsWs(ProjectsWsAction... actions) {
@Override
public void define(Context context) {
- NewController controller = context.createController("api/projects")
+ NewController controller = context.createController(ENDPOINT)
.setSince("2.10")
.setDescription("Projects management");
+++ /dev/null
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * SonarQube is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-package org.sonar.server.component.ws;
-
-import com.google.common.io.Resources;
-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.text.JsonWriter;
-import org.sonar.api.web.UserRole;
-import org.sonar.core.component.ComponentDto;
-import org.sonar.core.persistence.DbSession;
-import org.sonar.core.persistence.MyBatis;
-import org.sonar.server.db.DbClient;
-import org.sonar.server.es.SearchOptions;
-import org.sonar.server.user.UserSession;
-
-import java.util.Arrays;
-import java.util.Date;
-import java.util.List;
-
-public class ProvisionedProjectsAction implements ProjectsWsAction {
- private static final List<String> POSSIBLE_FIELDS = Arrays.asList("uuid", "key", "name", "creationDate");
-
- private final DbClient dbClient;
- private final UserSession userSession;
-
- public ProvisionedProjectsAction(DbClient dbClient, UserSession userSession) {
- this.dbClient = dbClient;
- this.userSession = userSession;
- }
-
- @Override
- public void define(WebService.NewController controller) {
- WebService.NewAction action = controller
- .createAction("provisioned")
- .setDescription(
- "Get the list of provisioned projects.<br /> " +
- "Require admin role.")
- .setSince("5.2")
- .setResponseExample(Resources.getResource(getClass(), "projects-example-provisioned.json"))
- .setHandler(this)
- .addPagingParams(100)
- .addFieldsParam(POSSIBLE_FIELDS);
-
- action
- .createParam(Param.TEXT_QUERY)
- .setDescription("UTF-8 search query")
- .setExampleValue("sonar");
- }
-
- @Override
- public void handle(Request request, Response response) throws Exception {
- userSession.checkGlobalPermission(UserRole.ADMIN, "You need admin rights.");
- SearchOptions options = new SearchOptions().setPage(
- request.mandatoryParamAsInt(Param.PAGE),
- request.mandatoryParamAsInt(Param.PAGE_SIZE)
- );
- List<String> desiredFields = desiredFields(request);
- String query = request.param(Param.TEXT_QUERY);
-
- DbSession dbSession = dbClient.openSession(false);
- try {
- List<ComponentDto> projects = dbClient.componentDao().selectProvisionedProjects(dbSession, options, query);
- int nbOfProjects = dbClient.componentDao().countProvisionedProjects(dbSession, query);
- JsonWriter json = response.newJsonWriter().beginObject();
- writeProjects(projects, json, desiredFields);
- options.writeJson(json, nbOfProjects);
- json.endObject().close();
- } finally {
- MyBatis.closeQuietly(dbSession);
- }
- }
-
- private void writeProjects(List<ComponentDto> projects, JsonWriter json, List<String> desiredFields) {
- json.name("projects");
- json.beginArray();
- for (ComponentDto project : projects) {
- json.beginObject();
- json.prop("uuid", project.uuid());
- writeIfNeeded(json, "key", project.key(), desiredFields);
- writeIfNeeded(json, "name", project.name(), desiredFields);
- writeIfNeeded(json, "creationDate", project.getCreatedAt(), desiredFields);
- json.endObject();
- }
- json.endArray();
- }
-
- private void writeIfNeeded(JsonWriter json, String fieldName, String value, List<String> desiredFields) {
- if (desiredFields.contains(fieldName)) {
- json.prop(fieldName, value);
- }
- }
-
- private void writeIfNeeded(JsonWriter json, String fieldName, Date date, List<String> desiredFields) {
- if (desiredFields.contains(fieldName)) {
- json.propDateTime(fieldName, date);
- }
- }
-
- private List<String> desiredFields(Request request) {
- List<String> desiredFields = request.paramAsStrings(Param.FIELDS);
- if (desiredFields == null) {
- desiredFields = POSSIBLE_FIELDS;
- }
-
- return desiredFields;
- }
-}
import org.sonar.server.component.ws.ComponentAppAction;
import org.sonar.server.component.ws.ComponentsWs;
import org.sonar.server.component.ws.EventsWs;
+import org.sonar.server.component.ws.ProjectsGhostsAction;
import org.sonar.server.component.ws.ProjectsWs;
-import org.sonar.server.component.ws.ProvisionedProjectsAction;
+import org.sonar.server.component.ws.ProjectsProvisionedAction;
import org.sonar.server.component.ws.ResourcesWs;
import org.sonar.server.computation.ComputationThreadLauncher;
import org.sonar.server.computation.ReportQueue;
pico.addSingleton(org.sonar.server.component.ws.SearchAction.class);
pico.addSingleton(EventsWs.class);
pico.addSingleton(ComponentCleanerService.class);
- pico.addSingleton(ProvisionedProjectsAction.class);
+ pico.addSingleton(ProjectsProvisionedAction.class);
+ pico.addSingleton(ProjectsGhostsAction.class);
// views
pico.addSingleton(ViewIndexDefinition.class);
--- /dev/null
+{
+ "projects": [
+ {
+ "uuid": "ce4c03d6-430f-40a9-b777-ad877c00aa4d",
+ "key": "org.apache.hbas:hbase",
+ "name": "HBase",
+ "creationDate": "2015-03-04T23:03:44+0100"
+ },
+ {
+ "uuid": "c526ef20-131b-4486-9357-063fa64b5079",
+ "key": "com.microsoft.roslyn:roslyn",
+ "name": "Roslyn",
+ "creationDate": "2013-03-04T23:03:44+0100"
+ }
+ ],
+ "total": 2,
+ "p": 1,
+ "ps": 100
+}
assertThat(numberOfProjects).isEqualTo(1);
}
+
+ @Test
+ public void select_ghost_projects() throws Exception {
+ db.prepareDbUnit(getClass(), "select_ghost_projects.xml");
+
+ List<ComponentDto> result = sut.selectGhostProjects(session, null, new SearchOptions());
+
+ assertThat(result).hasSize(1);
+ assertThat(result.get(0).key()).isEqualTo("org.ghost.project");
+ assertThat(sut.countGhostProjects(session, null)).isEqualTo(1);
+ }
}
--- /dev/null
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.sonar.server.component.ws;
+
+import com.google.common.io.Resources;
+import org.apache.commons.lang.StringUtils;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.ClassRule;
+import org.junit.Rule;
+import org.junit.Test;
+import org.sonar.api.server.ws.WebService.Param;
+import org.sonar.api.utils.DateUtils;
+import org.sonar.api.utils.System2;
+import org.sonar.api.web.UserRole;
+import org.sonar.core.component.ComponentDto;
+import org.sonar.core.component.SnapshotDto;
+import org.sonar.core.persistence.DbSession;
+import org.sonar.core.persistence.DbTester;
+import org.sonar.server.component.ComponentTesting;
+import org.sonar.server.component.SnapshotTesting;
+import org.sonar.server.component.db.ComponentDao;
+import org.sonar.server.component.db.SnapshotDao;
+import org.sonar.server.db.DbClient;
+import org.sonar.server.exceptions.ForbiddenException;
+import org.sonar.server.tester.UserSessionRule;
+import org.sonar.server.ws.WsTester;
+import org.sonar.test.JsonAssert;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class ProjectsGhostsActionTest {
+
+ @ClassRule
+ public static DbTester db = new DbTester();
+ @Rule
+ public UserSessionRule userSessionRule = UserSessionRule.standalone();
+ WsTester ws;
+
+ DbClient dbClient;
+ DbSession dbSession;
+
+ @Before
+ public void setUp() {
+ dbClient = new DbClient(db.database(), db.myBatis(), new ComponentDao(), new SnapshotDao(System2.INSTANCE));
+ dbSession = dbClient.openSession(false);
+ ws = new WsTester(new ProjectsWs(new ProjectsGhostsAction(dbClient, userSessionRule)));
+ db.truncateTables();
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ dbSession.close();
+ }
+
+ @Test
+ public void ghost_projects_without_analyzed_projects() throws Exception {
+ userSessionRule.setGlobalPermissions(UserRole.ADMIN);
+ insertNewGhostProject("1");
+ insertNewGhostProject("2");
+ insertNewActiveProject("3");
+
+ WsTester.Result result = ws.newGetRequest("api/projects", "ghosts").execute();
+
+ result.assertJson(getClass(), "all-projects.json");
+ assertThat(result.outputAsString()).doesNotContain("analyzed-uuid-3");
+ }
+
+ @Test
+ public void ghost_projects_with_correct_pagination() throws Exception {
+ userSessionRule.setGlobalPermissions(UserRole.ADMIN);
+ for (int i = 1; i <= 10; i++) {
+ insertNewGhostProject(String.valueOf(i));
+ }
+
+ WsTester.Result result = ws.newGetRequest("api/projects", "ghosts")
+ .setParam(Param.PAGE, "3")
+ .setParam(Param.PAGE_SIZE, "4")
+ .execute();
+
+ result.assertJson(getClass(), "pagination.json");
+ assertThat(StringUtils.countMatches(result.outputAsString(), "ghost-uuid-")).isEqualTo(2);
+ }
+
+ @Test
+ public void ghost_projects_with_chosen_fields() throws Exception {
+ userSessionRule.setGlobalPermissions(UserRole.ADMIN);
+ insertNewGhostProject("1");
+
+ WsTester.Result result = ws.newGetRequest("api/projects", "ghosts")
+ .setParam(Param.FIELDS, "name")
+ .execute();
+
+ assertThat(result.outputAsString()).contains("uuid", "name")
+ .doesNotContain("key")
+ .doesNotContain("creationDate");
+ }
+
+ @Test
+ public void ghost_projects_with_partial_query_on_name() throws Exception {
+ userSessionRule.setGlobalPermissions(UserRole.ADMIN);
+
+ insertNewGhostProject("10");
+ insertNewGhostProject("11");
+ insertNewGhostProject("2");
+
+ WsTester.Result result = ws.newGetRequest("api/projects", "ghosts")
+ .setParam(Param.TEXT_QUERY, "name-1")
+ .execute();
+
+ assertThat(result.outputAsString()).contains("ghost-name-10", "ghost-name-11")
+ .doesNotContain("ghost-name-2");
+ }
+
+ @Test
+ public void ghost_projects_with_partial_query_on_key() throws Exception {
+ userSessionRule.setGlobalPermissions(UserRole.ADMIN);
+
+ insertNewGhostProject("1");
+
+ WsTester.Result result = ws.newGetRequest("api/projects", "ghosts")
+ .setParam(Param.TEXT_QUERY, "GHOST-key")
+ .execute();
+
+ assertThat(result.outputAsString()).contains("ghost-key-1");
+ }
+
+ @Test
+ public void ghost_projects_base_on_json_example() throws Exception {
+ userSessionRule.setGlobalPermissions(UserRole.ADMIN);
+ ComponentDto hBaseProject = ComponentTesting.newProjectDto("ce4c03d6-430f-40a9-b777-ad877c00aa4d")
+ .setKey("org.apache.hbas:hbase")
+ .setName("HBase")
+ .setCreatedAt(DateUtils.parseDateTime("2015-03-04T23:03:44+0100"));
+ hBaseProject = dbClient.componentDao().insert(dbSession, hBaseProject);
+ dbClient.snapshotDao().insert(dbSession, SnapshotTesting.createForProject(hBaseProject)
+ .setStatus(SnapshotDto.STATUS_UNPROCESSED));
+ ComponentDto roslynProject = ComponentTesting.newProjectDto("c526ef20-131b-4486-9357-063fa64b5079")
+ .setKey("com.microsoft.roslyn:roslyn")
+ .setName("Roslyn")
+ .setCreatedAt(DateUtils.parseDateTime("2013-03-04T23:03:44+0100"));
+ roslynProject = dbClient.componentDao().insert(dbSession, roslynProject);
+ dbClient.snapshotDao().insert(dbSession, SnapshotTesting.createForProject(roslynProject)
+ .setStatus(SnapshotDto.STATUS_UNPROCESSED));
+ dbSession.commit();
+
+ WsTester.Result result = ws.newGetRequest("api/projects", "ghosts").execute();
+
+ JsonAssert.assertJson(result.outputAsString()).isSimilarTo(Resources.getResource(getClass(), "projects-example-ghosts.json"));
+ }
+
+ @Test(expected = ForbiddenException.class)
+ public void fail_if_does_not_have_sufficient_rights() throws Exception {
+ userSessionRule.setGlobalPermissions(UserRole.USER, UserRole.ISSUE_ADMIN, UserRole.CODEVIEWER);
+
+ ws.newGetRequest("api/projects", "ghosts").execute();
+ }
+
+ private void insertNewGhostProject(String id) {
+ ComponentDto project = ComponentTesting
+ .newProjectDto("ghost-uuid-" + id)
+ .setName("ghost-name-" + id)
+ .setKey("ghost-key-" + id);
+ project = dbClient.componentDao().insert(dbSession, project);
+ SnapshotDto snapshot = SnapshotTesting.createForProject(project)
+ .setStatus(SnapshotDto.STATUS_UNPROCESSED);
+ dbClient.snapshotDao().insert(dbSession, snapshot);
+ dbSession.commit();
+ }
+
+ private void insertNewActiveProject(String id) {
+ ComponentDto project = ComponentTesting
+ .newProjectDto("analyzed-uuid-" + id)
+ .setName("analyzed-name-" + id)
+ .setKey("analyzed-key-" + id);
+ project = dbClient.componentDao().insert(dbSession, project);
+ SnapshotDto snapshot = SnapshotTesting.createForProject(project);
+ dbClient.snapshotDao().insert(dbSession, snapshot);
+ dbSession.commit();
+ }
+}
--- /dev/null
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.sonar.server.component.ws;
+
+import com.google.common.io.Resources;
+import org.apache.commons.lang.StringUtils;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.ClassRule;
+import org.junit.Rule;
+import org.junit.Test;
+import org.sonar.api.server.ws.WebService.Param;
+import org.sonar.api.utils.DateUtils;
+import org.sonar.api.utils.System2;
+import org.sonar.api.web.UserRole;
+import org.sonar.core.component.ComponentDto;
+import org.sonar.core.component.SnapshotDto;
+import org.sonar.core.persistence.DbSession;
+import org.sonar.core.persistence.DbTester;
+import org.sonar.server.component.ComponentTesting;
+import org.sonar.server.component.SnapshotTesting;
+import org.sonar.server.component.db.ComponentDao;
+import org.sonar.server.component.db.SnapshotDao;
+import org.sonar.server.db.DbClient;
+import org.sonar.server.tester.UserSessionRule;
+import org.sonar.server.ws.WsTester;
+import org.sonar.test.JsonAssert;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
+
+public class ProjectsProvisionedActionTest {
+
+ @ClassRule
+ public static DbTester db = new DbTester();
+ @Rule
+ public UserSessionRule userSessionRule = UserSessionRule.standalone();
+
+ WsTester ws;
+ DbClient dbClient;
+ DbSession dbSession;
+ ComponentDao componentDao;
+ System2 system2 = mock(System2.class);
+
+ @After
+ public void tearDown() {
+ dbSession.close();
+ }
+
+ @Before
+ public void setUp() {
+ dbClient = new DbClient(db.database(), db.myBatis(), new ComponentDao(system2), new SnapshotDao(System2.INSTANCE));
+ dbSession = dbClient.openSession(false);
+ componentDao = dbClient.componentDao();
+ db.truncateTables();
+ ws = new WsTester(new ProjectsWs(new ProjectsProvisionedAction(dbClient, userSessionRule)));
+ }
+
+ @Test
+ public void all_provisioned_projects_without_analyzed_projects() throws Exception {
+ userSessionRule.setGlobalPermissions(UserRole.ADMIN);
+ ComponentDto analyzedProject = ComponentTesting.newProjectDto("analyzed-uuid-1");
+ componentDao.insert(dbSession, newProvisionedProject("1"), newProvisionedProject("2"));
+ analyzedProject = dbClient.componentDao().insert(dbSession, analyzedProject);
+ SnapshotDto snapshot = SnapshotTesting.createForProject(analyzedProject);
+ dbClient.snapshotDao().insert(dbSession, snapshot);
+ dbSession.commit();
+
+ WsTester.Result result = ws.newGetRequest("api/projects", "provisioned").execute();
+
+ result.assertJson(getClass(), "all-projects.json");
+ assertThat(result.outputAsString()).doesNotContain("analyzed-uuid-1");
+ }
+
+ @Test
+ public void provisioned_projects_with_correct_pagination() throws Exception {
+ userSessionRule.setGlobalPermissions(UserRole.ADMIN);
+ for (int i = 1; i <= 10; i++) {
+ componentDao.insert(dbSession, newProvisionedProject(String.valueOf(i)));
+ }
+ dbSession.commit();
+
+ WsTester.TestRequest request = ws.newGetRequest("api/projects", "provisioned")
+ .setParam(Param.PAGE, "3")
+ .setParam(Param.PAGE_SIZE, "4");
+
+ String jsonOutput = request.execute().outputAsString();
+
+ assertThat(StringUtils.countMatches(jsonOutput, "provisioned-uuid-")).isEqualTo(2);
+ }
+
+ @Test
+ public void provisioned_projects_with_desired_fields() throws Exception {
+ userSessionRule.setGlobalPermissions(UserRole.ADMIN);
+ componentDao.insert(dbSession, newProvisionedProject("1"));
+ dbSession.commit();
+
+ String jsonOutput = ws.newGetRequest("api/projects", "provisioned")
+ .setParam(Param.FIELDS, "key")
+ .execute().outputAsString();
+
+ assertThat(jsonOutput).contains("uuid", "key")
+ .doesNotContain("name")
+ .doesNotContain("creationDate");
+ }
+
+ @Test
+ public void provisioned_projects_with_query() throws Exception {
+ userSessionRule.setGlobalPermissions(UserRole.ADMIN);
+ componentDao.insert(dbSession, newProvisionedProject("1"), newProvisionedProject("2"));
+ dbSession.commit();
+
+ String jsonOutput = ws.newGetRequest("api/projects", "provisioned")
+ .setParam(Param.TEXT_QUERY, "provisioned-name-2")
+ .execute().outputAsString();
+
+ assertThat(jsonOutput)
+ .contains("provisioned-name-2", "provisioned-uuid-2")
+ .doesNotContain("provisioned-uuid-1");
+ assertThat(componentDao.countProvisionedProjects(dbSession, "name-2")).isEqualTo(1);
+ assertThat(componentDao.countProvisionedProjects(dbSession, "key-2")).isEqualTo(1);
+ assertThat(componentDao.countProvisionedProjects(dbSession, "visioned-name-")).isEqualTo(2);
+ }
+
+ private static ComponentDto newProvisionedProject(String id) {
+ return ComponentTesting
+ .newProjectDto("provisioned-uuid-" + id)
+ .setName("provisioned-name-" + id)
+ .setKey("provisioned-key-" + id);
+ }
+
+ @Test
+ public void provisioned_projects_as_defined_in_the_example() throws Exception {
+ userSessionRule.setGlobalPermissions(UserRole.ADMIN);
+ ComponentDto hBaseProject = ComponentTesting.newProjectDto("ce4c03d6-430f-40a9-b777-ad877c00aa4d")
+ .setKey("org.apache.hbas:hbase")
+ .setName("HBase")
+ .setCreatedAt(DateUtils.parseDateTime("2015-03-04T23:03:44+0100"));
+ ComponentDto roslynProject = ComponentTesting.newProjectDto("c526ef20-131b-4486-9357-063fa64b5079")
+ .setKey("com.microsoft.roslyn:roslyn")
+ .setName("Roslyn")
+ .setCreatedAt(DateUtils.parseDateTime("2013-03-04T23:03:44+0100"));
+ componentDao.insert(dbSession, hBaseProject, roslynProject);
+ dbSession.commit();
+
+ WsTester.Result result = ws.newGetRequest("api/projects", "provisioned").execute();
+
+ JsonAssert.assertJson(result.outputAsString()).isSimilarTo(Resources.getResource(getClass(), "projects-example-provisioned.json"));
+ }
+}
public class ProjectsWsTest {
WebService.Controller controller;
+ WsTester ws;
@Before
public void setUp() {
- WsTester tester = new WsTester(new ProjectsWs());
- controller = tester.controller("api/projects");
+ ws = new WsTester(new ProjectsWs());
+ controller = ws.controller("api/projects");
}
@Test
+++ /dev/null
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * SonarQube is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-package org.sonar.server.component.ws;
-
-import com.google.common.io.Resources;
-import org.apache.commons.lang.StringUtils;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.ClassRule;
-import org.junit.Rule;
-import org.junit.Test;
-import org.sonar.api.server.ws.WebService.Param;
-import org.sonar.api.utils.DateUtils;
-import org.sonar.api.utils.System2;
-import org.sonar.api.web.UserRole;
-import org.sonar.core.component.ComponentDto;
-import org.sonar.core.component.SnapshotDto;
-import org.sonar.core.persistence.DbSession;
-import org.sonar.core.persistence.DbTester;
-import org.sonar.server.component.ComponentTesting;
-import org.sonar.server.component.SnapshotTesting;
-import org.sonar.server.component.db.ComponentDao;
-import org.sonar.server.component.db.SnapshotDao;
-import org.sonar.server.db.DbClient;
-import org.sonar.server.tester.UserSessionRule;
-import org.sonar.server.ws.WsTester;
-import org.sonar.test.JsonAssert;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.Mockito.mock;
-
-public class ProvisionedProjectsActionTest {
-
- @ClassRule
- public static DbTester db = new DbTester();
- @Rule
- public UserSessionRule userSessionRule = UserSessionRule.standalone();
-
- WsTester ws;
- DbClient dbClient;
- DbSession dbSession;
- ComponentDao componentDao;
- System2 system2 = mock(System2.class);
-
- @After
- public void tearDown() {
- dbSession.close();
- }
-
- @Before
- public void setUp() {
- dbClient = new DbClient(db.database(), db.myBatis(), new ComponentDao(system2), new SnapshotDao(System2.INSTANCE));
- dbSession = dbClient.openSession(false);
- componentDao = dbClient.componentDao();
- db.truncateTables();
- ws = new WsTester(new ProjectsWs(new ProvisionedProjectsAction(dbClient, userSessionRule)));
- }
-
- @Test
- public void all_provisioned_projects_without_analyzed_projects() throws Exception {
- userSessionRule.setGlobalPermissions(UserRole.ADMIN);
- ComponentDto analyzedProject = ComponentTesting.newProjectDto("analyzed-uuid-1");
- componentDao.insert(dbSession, newProvisionedProject("1"), newProvisionedProject("2"));
- analyzedProject = componentDao.insert(dbSession, analyzedProject);
- SnapshotDto snapshot = SnapshotTesting.createForProject(analyzedProject);
- dbClient.snapshotDao().insert(dbSession, snapshot);
- dbSession.commit();
-
- WsTester.TestRequest request = ws.newGetRequest("api/projects", "provisioned");
-
- request.execute().assertJson(getClass(), "all-projects.json");
- }
-
- @Test
- public void provisioned_projects_with_correct_paginated() throws Exception {
- userSessionRule.setGlobalPermissions(UserRole.ADMIN);
- for (int i = 1; i <= 10; i++) {
- componentDao.insert(dbSession, newProvisionedProject(String.valueOf(i)));
- }
- dbSession.commit();
-
- WsTester.TestRequest request = ws.newGetRequest("api/projects", "provisioned")
- .setParam(Param.PAGE, "3")
- .setParam(Param.PAGE_SIZE, "4");
-
- String jsonOutput = request.execute().outputAsString();
-
- assertThat(StringUtils.countMatches(jsonOutput, "provisioned-uuid-")).isEqualTo(2);
- }
-
- @Test
- public void provisioned_projects_with_desired_fields() throws Exception {
- userSessionRule.setGlobalPermissions(UserRole.ADMIN);
- componentDao.insert(dbSession, newProvisionedProject("1"));
- dbSession.commit();
-
- String jsonOutput = ws.newGetRequest("api/projects", "provisioned")
- .setParam(Param.FIELDS, "key")
- .execute().outputAsString();
-
- assertThat(jsonOutput).contains("uuid", "key")
- .doesNotContain("name")
- .doesNotContain("creationDate");
- }
-
- @Test
- public void provisioned_projects_with_query() throws Exception {
- userSessionRule.setGlobalPermissions(UserRole.ADMIN);
- componentDao.insert(dbSession, newProvisionedProject("1"), newProvisionedProject("2"));
- dbSession.commit();
-
- String jsonOutput = ws.newGetRequest("api/projects", "provisioned")
- .setParam(Param.TEXT_QUERY, "provisioned-name-2")
- .execute().outputAsString();
-
- assertThat(jsonOutput)
- .contains("provisioned-name-2", "provisioned-uuid-2")
- .doesNotContain("provisioned-uuid-1");
- assertThat(componentDao.countProvisionedProjects(dbSession, "name-2")).isEqualTo(1);
- assertThat(componentDao.countProvisionedProjects(dbSession, "key-2")).isEqualTo(1);
- assertThat(componentDao.countProvisionedProjects(dbSession, "visioned-name-")).isEqualTo(2);
- }
-
- private static ComponentDto newProvisionedProject(String id) {
- return ComponentTesting
- .newProjectDto("provisioned-uuid-" + id)
- .setName("provisioned-name-" + id)
- .setKey("provisioned-key-" + id);
- }
-
- @Test
- public void provisioned_projects_as_defined_in_the_example() throws Exception {
- userSessionRule.setGlobalPermissions(UserRole.ADMIN);
- ComponentDto hBaseProject = ComponentTesting.newProjectDto("ce4c03d6-430f-40a9-b777-ad877c00aa4d")
- .setKey("org.apache.hbas:hbase")
- .setName("HBase")
- .setCreatedAt(DateUtils.parseDateTime("2015-03-04T23:03:44+0100"));
- ComponentDto roslynProject = ComponentTesting.newProjectDto("c526ef20-131b-4486-9357-063fa64b5079")
- .setKey("com.microsoft.roslyn:roslyn")
- .setName("Roslyn")
- .setCreatedAt(DateUtils.parseDateTime("2013-03-04T23:03:44+0100"));
- componentDao.insert(dbSession, hBaseProject, roslynProject);
- dbSession.commit();
-
- WsTester.Result result = ws.newGetRequest("api/projects", "provisioned").execute();
-
- JsonAssert.assertJson(result.outputAsString()).isSimilarTo(Resources.getResource(getClass(), "projects-example-provisioned.json"));
- }
-}
--- /dev/null
+<dataset>
+
+ <!-- Struts projects is authorized for all user -->
+ <group_roles id="1" group_id="[null]" resource_id="1" role="user"/>
+
+ <!-- Ghost project -->
+ <projects id="42" root_id="[null]" scope="PRJ" qualifier="TRK" kee="org.ghost.project" name="Ghost Project"
+ uuid="PPAA" project_uuid="PPAA" module_uuid="[null]" module_uuid_path="."
+ description="the description" long_name="Ghost Project"
+ enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" path="[null]" authorization_updated_at="123456789" />
+
+ <!-- root project -->
+ <projects id="1" root_id="[null]" scope="PRJ" qualifier="TRK" kee="org.struts:struts" deprecated_kee="org.struts:struts" name="Struts"
+ uuid="ABCD" project_uuid="ABCD" module_uuid="[null]" module_uuid_path=".ABCD."
+ description="the description" long_name="Apache Struts"
+ enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" path="[null]" authorization_updated_at="123456789" />
+ <snapshots id="1" project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[null]"
+ status="P" islast="[true]" purge_status="[null]"
+ period1_mode="[null]" period1_param="[null]" period1_date="[null]"
+ period2_mode="[null]" period2_param="[null]" period2_date="[null]"
+ period3_mode="[null]" period3_param="[null]" period3_date="[null]"
+ period4_mode="[null]" period4_param="[null]" period4_date="[null]"
+ period5_mode="[null]" period5_param="[null]" period5_date="[null]"
+ depth="[null]" scope="PRJ" qualifier="TRK" created_at="1228222680000" build_date="1228222680000"
+ version="[null]" path=""/>
+ <snapshots id="10" project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[null]"
+ status="P" islast="[false]" purge_status="[null]"
+ period1_mode="[null]" period1_param="[null]" period1_date="[null]"
+ period2_mode="[null]" period2_param="[null]" period2_date="[null]"
+ period3_mode="[null]" period3_param="[null]" period3_date="[null]"
+ period4_mode="[null]" period4_param="[null]" period4_date="[null]"
+ period5_mode="[null]" period5_param="[null]" period5_date="[null]"
+ depth="[null]" scope="PRJ" qualifier="TRK" created_at="1228136280000" build_date="1228136280000"
+ version="[null]" path=""/>
+ <snapshots id="11" project_id="42" parent_snapshot_id="[null]" root_project_id="42" root_snapshot_id="[null]"
+ status="U" islast="[false]" purge_status="[null]"
+ period1_mode="[null]" period1_param="[null]" period1_date="[null]"
+ period2_mode="[null]" period2_param="[null]" period2_date="[null]"
+ period3_mode="[null]" period3_param="[null]" period3_date="[null]"
+ period4_mode="[null]" period4_param="[null]" period4_date="[null]"
+ period5_mode="[null]" period5_param="[null]" period5_date="[null]"
+ depth="[null]" scope="PRJ" qualifier="TRK" created_at="1228136280000" build_date="1228136280000"
+ version="[null]" path=""/>
+
+ <!-- module -->
+ <projects id="2" root_id="1" kee="org.struts:struts-core" name="Struts Core"
+ uuid="EFGH" project_uuid="ABCD" module_uuid="[null]" module_uuid_path=".ABCD.EFGH."
+ scope="PRJ" qualifier="BRC" long_name="Struts Core"
+ description="[null]" enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" authorization_updated_at="[null]" />
+ <snapshots id="2" project_id="2" parent_snapshot_id="1" root_project_id="1" root_snapshot_id="1"
+ status="P" islast="[true]" purge_status="[null]"
+ period1_mode="[null]" period1_param="[null]" period1_date="[null]"
+ period2_mode="[null]" period2_param="[null]" period2_date="[null]"
+ period3_mode="[null]" period3_param="[null]" period3_date="[null]"
+ period4_mode="[null]" period4_param="[null]" period4_date="[null]"
+ period5_mode="[null]" period5_param="[null]" period5_date="[null]"
+ depth="[null]" scope="PRJ" qualifier="BRC" created_at="1228222680000" build_date="1228222680000"
+ version="[null]" path="1."/>
+
+ <!-- directory -->
+ <projects long_name="org.struts" id="3" scope="DIR" qualifier="DIR" kee="org.struts:struts-core:src/org/struts"
+ uuid="GHIJ" project_uuid="ABCD" module_uuid="EFGH" module_uuid_path=".ABCD.EFGH."
+ name="src/org/struts" root_id="2"
+ description="[null]"
+ enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" path="src/org/struts" authorization_updated_at="[null]" />
+ <snapshots id="3" project_id="3" parent_snapshot_id="2" root_project_id="1" root_snapshot_id="1"
+ status="P" islast="[true]" purge_status="[null]"
+ period1_mode="[null]" period1_param="[null]" period1_date="[null]"
+ period2_mode="[null]" period2_param="[null]" period2_date="[null]"
+ period3_mode="[null]" period3_param="[null]" period3_date="[null]"
+ period4_mode="[null]" period4_param="[null]" period4_date="[null]"
+ period5_mode="[null]" period5_param="[null]" period5_date="[null]"
+ depth="[null]" scope="DIR" qualifier="PAC" created_at="1228222680000" build_date="1228222680000"
+ version="[null]" path="1.2."/>
+
+ <!-- file -->
+ <projects long_name="org.struts.RequestContext" id="4" scope="FIL" qualifier="FIL" kee="org.struts:struts-core:src/org/struts/RequestContext.java"
+ uuid="KLMN" project_uuid="ABCD" module_uuid="EFGH" module_uuid_path=".ABCD.EFGH."
+ name="RequestContext.java" root_id="2"
+ description="[null]"
+ enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" path="src/org/struts/RequestContext.java" authorization_updated_at="[null]" />
+
+ <snapshots id="4" project_id="4" parent_snapshot_id="3" root_project_id="1" root_snapshot_id="1"
+ status="P" islast="[true]" purge_status="[null]"
+ period1_mode="[null]" period1_param="[null]" period1_date="[null]"
+ period2_mode="[null]" period2_param="[null]" period2_date="[null]"
+ period3_mode="[null]" period3_param="[null]" period3_date="[null]"
+ period4_mode="[null]" period4_param="[null]" period4_date="[null]"
+ period5_mode="[null]" period5_param="[null]" period5_date="[null]"
+ depth="[null]" scope="FIL" qualifier="CLA" created_at="1228222680000" build_date="1228222680000"
+ version="[null]" path="1.2.3."/>
+
+ <!-- Disabled projects -->
+ <projects id="10" root_id="[null]" scope="PRJ" qualifier="TRK" kee="org.disabled.project" name="Disabled Project"
+ uuid="DCBA" project_uuid="DCBA" module_uuid="[null]" module_uuid_path="."
+ description="the description" long_name="Disabled project"
+ enabled="[false]" language="[null]" copy_resource_id="[null]" person_id="[null]" path="[null]" authorization_updated_at="123456789" />
+
+ <!-- Developer and technical project copy -->
+ <projects id="11" root_id="[null]" scope="PRJ" qualifier="DEV" kee="DEV:anakin@skywalker.name" name="Anakin Skywalker"
+ uuid="OPQR" project_uuid="OPQR" module_uuid="[null]" module_uuid_path=".OPQR."
+ description="the description" long_name="Anakin Skywalker"
+ enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" path="[null]" authorization_updated_at="123456789" />
+ <projects id="12" root_id="11" scope="PRJ" qualifier="DEV_PRJ" kee="DEV:anakin@skywalker.name:org.struts:struts" name="Apache Struts"
+ uuid="STUV" project_uuid="OPQR" module_uuid="OPQR" module_uuid_path=".OPQR."
+ description="the description" long_name="Apache Struts"
+ enabled="[true]" language="[null]" copy_resource_id="1" person_id="11" path="[null]" authorization_updated_at="123456789" />
+
+</dataset>
--- /dev/null
+{
+ "projects": [
+ {
+ "uuid": "ghost-uuid-1",
+ "key": "ghost-key-1",
+ "name": "ghost-name-1"
+ },
+ {
+ "uuid": "ghost-uuid-2",
+ "key": "ghost-key-2",
+ "name": "ghost-name-2"
+ }
+ ]
+}
--- /dev/null
+{
+ "p": 3,
+ "ps": 4,
+ "total": 10
+}
--- /dev/null
+{
+ "projects":[
+ {
+ "uuid":"provisioned-uuid-1",
+ "key":"provisioned-key-1",
+ "name":"provisioned-name-1"
+ },
+ {
+ "uuid":"provisioned-uuid-2",
+ "key":"provisioned-key-2",
+ "name":"provisioned-name-2"
+ }
+ ]
+}
+++ /dev/null
-{
- "projects":[
- {
- "uuid":"provisioned-uuid-1",
- "key":"provisioned-key-1",
- "name":"provisioned-name-1"
- },
- {
- "uuid":"provisioned-uuid-2",
- "key":"provisioned-key-2",
- "name":"provisioned-name-2"
- }
- ]
-}
List<ComponentDto> selectProvisionedProjects(Map<String, String> parameters, RowBounds rowBounds);
int countProvisionedProjects(Map<String, String> parameters);
+
+ List<ComponentDto> selectGhostProjects(Map<String, String> parameters, RowBounds rowBounds);
+
+ long countGhostProjects(Map<String, String> parameters);
}
and p.copy_resource_id is null
<if test="query!=null">
and (
- p.name like #{query}
- or p.kee like #{query}
+ UPPER(p.name) like #{query}
+ or UPPER(p.kee) like #{query}
)
</if>
</sql>
+
+ <select id="selectGhostProjects" parameterType="map" resultType="Component">
+ select distinct <include refid="componentColumns"/>
+ from projects p
+ <include refid="ghostClauses"/>
+ </select>
+
+ <select id="countGhostProjects" parameterType="map" resultType="long">
+ select count(p.id)
+ from projects p
+ <include refid="ghostClauses"/>
+ </select>
+
+ <sql id="ghostClauses">
+ inner join snapshots s1 on s1.project_id = p.id and s1.status='U'
+ left join snapshots s2 on s2.project_id = p.id and s2.status='P'
+ where
+ s2.id is null
+ and p.qualifier=#{qualifier}
+ and p.copy_resource_id is null
+ <if test="query!=null">
+ and (
+ UPPER(p.name) like #{query}
+ or UPPER(p.kee) like #{query}
+ )
+ </if>
+ </sql>
</mapper>
*/
package org.sonar.api.server.ws;
+import com.google.common.base.Joiner;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Maps;
return this;
}
+ /**$
+ *
+ * Creates the parameter {@link org.sonar.api.server.ws.WebService.Param#TEXT_QUERY}, which is
+ * used to search for a subset of fields containing the supplied string.<br />
+ * The fields must be in the <strong>plural</strong> form (ex: "names", "keys")
+ */
+ public NewAction addSearchQuery(String exampleValue, String... pluralFields) {
+ String actionDescription = String.format("Searches for %s containing the supplied string.", Joiner.on(" and ").join(pluralFields));
+ createParam(Param.TEXT_QUERY)
+ .setDescription(actionDescription)
+ .setExampleValue(exampleValue);
+ return this;
+ }
+
/**
* Add predefined parameters related to sorting of results.
*/