}
}
+ @CheckForNull
+ public ComponentDto selectComponentByKey(String key) {
+ SqlSession session = mybatis.openSession(false);
+ try {
+ return session.getMapper(ResourceMapper.class).selectComponentByKey(key);
+ } finally {
+ MyBatis.closeQuietly(session);
+ }
+ }
+
@CheckForNull
public Component findByKey(String key) {
ResourceDto resourceDto = getResource(ResourceQuery.create().setKey(key));
List<ComponentDto> selectComponentsByIds(@Param("ids") List<Long> ids);
+ ComponentDto selectComponentByKey(String key);
+
/**
* @since 3.6
*/
</where>
</select>
+ <select id="selectComponentByKey" parameterType="String" resultType="Component">
+ select <include refid="componentColumns"/>
+ from projects p
+ inner join snapshots s on s.project_id=p.id and s.islast=${_true}
+ <where>
+ p.enabled=${_true}
+ and p.kee=#{key}
+ </where>
+ </select>
+
<select id="selectProjectsIncludingNotCompletedOnesByQualifiers" parameterType="map" resultMap="resourceResultMap">
select * from projects p
<where>
assertThat(component.path()).isNull();
}
+ @Test
+ public void select_component_by_key() {
+ setupData("fixture");
+
+ assertThat(dao.selectComponentByKey("org.struts:struts-core:src/org/struts/RequestContext.java")).isNotNull();
+ assertThat(dao.selectComponentByKey("unknown")).isNull();
+ }
+
@Test
public void select_components_by_ids_on_huge_number_of_ids() {
setupData("fixture");
--- /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.component.Component;
+import org.sonar.api.server.ws.Request;
+import org.sonar.api.server.ws.RequestHandler;
+import org.sonar.api.server.ws.Response;
+import org.sonar.api.server.ws.WebService;
+import org.sonar.api.utils.text.JsonWriter;
+import org.sonar.api.web.UserRole;
+import org.sonar.core.component.ComponentDto;
+import org.sonar.core.resource.ResourceDao;
+import org.sonar.server.exceptions.NotFoundException;
+import org.sonar.server.user.UserSession;
+
+import javax.annotation.CheckForNull;
+import javax.annotation.Nullable;
+
+public class ComponentAppAction implements RequestHandler {
+
+ private static final String KEY = "key";
+
+ private final ResourceDao resourceDao;
+
+ public ComponentAppAction(ResourceDao resourceDao) {
+ this.resourceDao = resourceDao;
+ }
+
+ void define(WebService.NewController controller) {
+ WebService.NewAction action = controller.createAction("app")
+ .setDescription("Coverage data required for rendering the component viewer")
+ .setSince("4.4")
+ .setInternal(true)
+ .setHandler(this)
+ .setResponseExample(Resources.getResource(this.getClass(), "components-app-example-show.json"));
+
+ action
+ .createParam(KEY)
+ .setRequired(true)
+ .setDescription("File key")
+ .setExampleValue("my_project:/src/foo/Bar.php");
+ }
+
+ @Override
+ public void handle(Request request, Response response) {
+ String fileKey = request.mandatoryParam(KEY);
+ UserSession.get().checkComponentPermission(UserRole.CODEVIEWER, fileKey);
+
+ JsonWriter json = response.newJsonWriter();
+ json.beginObject();
+
+ ComponentDto component = resourceDao.selectComponentByKey(fileKey);
+ if (component == null) {
+ throw new NotFoundException(String.format("Component '%s' does not exists.", fileKey));
+ }
+
+ json.prop("key", component.key());
+ json.prop("path", component.path());
+ json.prop("name", component.name());
+ json.prop("q", component.qualifier());
+
+ Component subProject = componentById(component.subProjectId());
+ json.prop("subProjectName", subProject != null ? subProject.longName() : null);
+
+ Component project = componentById(component.projectId());
+ json.prop("projectName", project != null ? project.longName() : null);
+
+ json.endObject();
+ json.close();
+ }
+
+ @CheckForNull
+ private Component componentById(@Nullable Long componentId) {
+ if (componentId != null) {
+ return resourceDao.findById(componentId);
+ }
+ return null;
+ }
+
+}
public class ComponentsWs implements WebService {
+ private final ComponentAppAction appAction;
+
+ public ComponentsWs(ComponentAppAction appAction) {
+ this.appAction = appAction;
+ }
+
@Override
public void define(Context context) {
NewController controller = context.createController("api/components")
.setSince("4.2")
.setDescription("Components management");
+ appAction.define(controller);
defineSuggestionsAction(controller);
controller.done();
import org.sonar.server.user.UserSession;
import javax.annotation.CheckForNull;
+import javax.annotation.Nullable;
import java.util.*;
}
Collection<Component> components = findComponents(componentIds);
- Collection<Component> groupComponents = findGroupComponents(components);
- Collection<Component> rootComponents = findRootComponents(components);
+ Collection<Component> groupComponents = findSubProjects(components);
+ Collection<Component> rootComponents = findProjects(components);
Set<Component> allComponents = newHashSet(components);
allComponents.addAll(groupComponents);
return Lists.<Component>newArrayList(resourceDao.selectComponentsByIds(componentIds));
}
- private Collection<Component> findGroupComponents(Collection<Component> components) {
+ private Collection<Component> findSubProjects(Collection<Component> components) {
return findComponents(newHashSet(Iterables.transform(components, new Function<Component, Long>() {
@Override
- public Long apply(Component input) {
- return ((ComponentDto) input).subProjectId();
+ public Long apply(@Nullable Component input) {
+ return input != null ? ((ComponentDto) input).subProjectId() : null;
}
})));
}
- private Collection<Component> findRootComponents(Collection<Component> components) {
+ private Collection<Component> findProjects(Collection<Component> components) {
return findComponents(newHashSet(Iterables.transform(components, new Function<Component, Long>() {
@Override
- public Long apply(Component input) {
- return ((ComponentDto) input).projectId();
+ public Long apply(@Nullable Component input) {
+ return input != null ? ((ComponentDto) input).projectId() : null;
}
})));
}
return Iterables.find(result.components(), new Predicate<Component>() {
@Override
public boolean apply(Component input) {
- Long groupId = component.subProjectId();
- return groupId != null && groupId.equals(((ComponentDto) input).getId());
+ Long subProjectId = component.subProjectId();
+ return subProjectId != null && subProjectId.equals(((ComponentDto) input).getId());
}
}, null);
}
import org.sonar.server.cluster.LocalQueueWorker;
import org.sonar.server.component.DefaultComponentFinder;
import org.sonar.server.component.DefaultRubyComponentService;
+import org.sonar.server.component.ws.ComponentAppAction;
import org.sonar.server.component.ws.ComponentsWs;
import org.sonar.server.component.ws.ProjectsWs;
import org.sonar.server.component.ws.ResourcesWs;
pico.addSingleton(ResourcesWs.class);
pico.addSingleton(ComponentsWs.class);
pico.addSingleton(ProjectsWs.class);
+ pico.addSingleton(ComponentAppAction.class);
// issues
pico.addSingleton(ServerIssueStorage.class);
--- /dev/null
+{
+ "key": "org.codehaus.sonar:sonar-plugin-api:src/main/java/org/sonar/api/Plugin.java",
+ "path": "src/main/java/org/sonar/api/Plugin.java",
+ "name": "Plugin.java",
+ "q": "FIL",
+ "subProjectName": "SonarQube :: Plugin API",
+ "projectName": "SonarQube",
+ "fav": true,
+ "periods": [],
+ "measures": {
+ "ncloc": 200,
+ "coverage": 2,
+ "duplication_density": 1,
+ "debt": 1,
+ "issues": 1,
+ "blocker_issues": 1,
+ "info_issues": 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 org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.runners.MockitoJUnitRunner;
+import org.sonar.api.web.UserRole;
+import org.sonar.core.component.ComponentDto;
+import org.sonar.core.resource.ResourceDao;
+import org.sonar.server.user.MockUserSession;
+import org.sonar.server.ws.WsTester;
+
+import static org.mockito.Mockito.when;
+
+@RunWith(MockitoJUnitRunner.class)
+public class ComponentAppActionTest {
+
+ @Mock
+ ResourceDao resourceDao;
+
+ WsTester tester;
+
+ @Before
+ public void setUp() throws Exception {
+ tester = new WsTester(new ComponentsWs(new ComponentAppAction(resourceDao)));
+ }
+
+ @Test
+ public void app() throws Exception {
+ String projectKey = "org.codehaus.sonar:sonar-plugin-api:api";
+ String componentKey = "org.codehaus.sonar:sonar-plugin-api:src/main/java/org/sonar/api/Plugin.java";
+ MockUserSession.set().addProjectPermissions(UserRole.CODEVIEWER, projectKey).addComponent(componentKey, projectKey);
+
+ ComponentDto file = new ComponentDto().setId(10L).setQualifier("FIL").setKey(componentKey).setName("Plugin.java")
+ .setPath("src/main/java/org/sonar/api/Plugin.java").setSubProjectId(5L).setProjectId(1L);
+ when(resourceDao.selectComponentByKey(componentKey)).thenReturn(file);
+ when(resourceDao.findById(5L)).thenReturn(new ComponentDto().setId(5L).setLongName("SonarQube :: Plugin API"));
+ when(resourceDao.findById(1L)).thenReturn(new ComponentDto().setId(1L).setLongName("SonarQube"));
+
+ WsTester.TestRequest request = tester.newGetRequest("api/components", "app").setParam("key", componentKey);
+ request.execute().assertJson(getClass(), "app.json");
+ }
+
+}
import org.junit.Test;
import org.sonar.api.server.ws.RailsHandler;
import org.sonar.api.server.ws.WebService;
+import org.sonar.core.resource.ResourceDao;
import org.sonar.server.ws.WsTester;
import static org.fest.assertions.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
public class ComponentsWsTest {
@Before
public void setUp() throws Exception {
- WsTester tester = new WsTester(new ComponentsWs());
+ WsTester tester = new WsTester(new ComponentsWs(new ComponentAppAction(mock(ResourceDao.class))));
controller = tester.controller("api/components");
}
assertThat(controller).isNotNull();
assertThat(controller.description()).isNotEmpty();
assertThat(controller.since()).isEqualTo("4.2");
- assertThat(controller.actions()).hasSize(1);
+ assertThat(controller.actions()).hasSize(2);
}
@Test
assertThat(action.params()).hasSize(2);
}
+ @Test
+ public void define_app_action() throws Exception {
+ WebService.Action action = controller.action("app");
+ assertThat(action).isNotNull();
+ assertThat(action.isInternal()).isTrue();
+ assertThat(action.isPost()).isFalse();
+ assertThat(action.handler()).isNotNull();
+ assertThat(action.responseExampleAsString()).isNotEmpty();
+ assertThat(action.params()).hasSize(1);
+ }
+
}
--- /dev/null
+{
+ "key": "org.codehaus.sonar:sonar-plugin-api:src/main/java/org/sonar/api/Plugin.java",
+ "path": "src/main/java/org/sonar/api/Plugin.java",
+ "name": "Plugin.java",
+ "q": "FIL",
+ "subProjectName": "SonarQube :: Plugin API",
+ "projectName": "SonarQube",
+}