]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-926 Add module key information on components for IntelliJ
authorJulien HENRY <julien.henry@sonarsource.com>
Fri, 21 Feb 2014 18:32:40 +0000 (19:32 +0100)
committerJulien HENRY <julien.henry@sonarsource.com>
Fri, 21 Feb 2014 18:32:40 +0000 (19:32 +0100)
15 files changed:
sonar-core/src/main/java/org/sonar/core/component/ComponentDto.java
sonar-core/src/main/java/org/sonar/core/component/ComponentVertex.java
sonar-core/src/main/java/org/sonar/core/component/ResourceComponent.java
sonar-core/src/main/java/org/sonar/core/resource/ResourceDao.java
sonar-core/src/main/java/org/sonar/core/resource/ResourceDto.java
sonar-core/src/main/resources/org/sonar/core/resource/ResourceMapper.xml
sonar-core/src/test/java/org/sonar/core/component/ComponentVertexTest.java
sonar-core/src/test/java/org/sonar/core/component/ResourceComponentTest.java
sonar-core/src/test/java/org/sonar/core/resource/ResourceDaoTest.java
sonar-core/src/test/resources/org/sonar/core/resource/ResourceDaoTest/fixture.xml
sonar-plugin-api/src/main/java/org/sonar/api/component/Component.java
sonar-plugin-api/src/main/java/org/sonar/api/component/mock/MockSourceFile.java
sonar-plugin-api/src/main/java/org/sonar/api/resources/Project.java
sonar-server/src/main/webapp/WEB-INF/app/controllers/api/issues_controller.rb
sonar-ws-client/src/main/java/org/sonar/wsclient/component/Component.java

index 1c6bcf867322c16224b87f6fcf7ce159317cd7e1..fc9cdf829b340dcc02f672351e98a8679a68d62a 100644 (file)
@@ -26,6 +26,7 @@ public class ComponentDto implements Component {
   private Long id;
   private String kee;
   private String path;
+  private String moduleKey;
   private String name;
   private String longName;
   private String qualifier;
@@ -59,6 +60,16 @@ public class ComponentDto implements Component {
     return this;
   }
 
+  @Override
+  public String moduleKey() {
+    return moduleKey;
+  }
+
+  public ComponentDto setModuleKey(String moduleKey) {
+    this.moduleKey = moduleKey;
+    return this;
+  }
+
   @Override
   public String name() {
     return name;
index 8297c0819682cadfd6c0496539e73dce1526cce7..89403dce4ac2bd2537fe9079680f5a9d71ebb315 100644 (file)
@@ -32,6 +32,10 @@ public class ComponentVertex extends BeanVertex implements Component {
     return (String) getProperty("path");
   }
 
+  public String moduleKey() {
+    return (String) getProperty("moduleKey");
+  }
+
   public String name() {
     return (String) getProperty("name");
   }
@@ -47,6 +51,7 @@ public class ComponentVertex extends BeanVertex implements Component {
   void copyFrom(Component component) {
     setProperty("key", component.key());
     setProperty("path", component.path());
+    setProperty("moduleKey", component.moduleKey());
     setProperty("name", component.name());
     setProperty("longName", component.longName());
     setProperty("qualifier", component.qualifier());
index 7a1ea53877387589fbca096723ffa35da6fae535..d50eceddbff77a64b785f86d92e9a2b4d3bf7e89 100644 (file)
@@ -20,6 +20,7 @@
 package org.sonar.core.component;
 
 import com.google.common.base.Strings;
+import org.apache.commons.lang.StringUtils;
 import org.sonar.api.component.Component;
 import org.sonar.api.database.model.Snapshot;
 import org.sonar.api.resources.Resource;
@@ -29,6 +30,7 @@ import javax.annotation.Nullable;
 public class ResourceComponent implements Component {
   private String key;
   private String path;
+  private String moduleKey;
   private String name;
   private String longName;
   private String qualifier;
@@ -39,6 +41,8 @@ public class ResourceComponent implements Component {
   public ResourceComponent(Resource resource, @Nullable Snapshot snapshot) {
     this.key = resource.getEffectiveKey();
     this.path = resource.getPath();
+    // Kind of a hack as it depends on format of resource effective key
+    this.moduleKey = StringUtils.removeEnd(resource.getEffectiveKey(), ":" + resource.getKey());
     if (Strings.isNullOrEmpty(key)) {
       throw new IllegalArgumentException("Missing component key");
     }
@@ -65,6 +69,11 @@ public class ResourceComponent implements Component {
     return path;
   }
 
+  @Override
+  public String moduleKey() {
+    return moduleKey;
+  }
+
   public String name() {
     return name;
   }
index 34f0cac01bed64caea2cf9f5ed6de4bb5fb4c445..1f46ddfa2508d4402ca673543943997aa5fa9a47 100644 (file)
@@ -307,6 +307,7 @@ public class ResourceDao {
     return new ComponentDto()
       .setId(resourceDto.getId())
       .setKey(resourceDto.getKey())
+      .setModuleKey(resourceDto.getModuleKey())
       .setPath(resourceDto.getPath())
       .setLongName(resourceDto.getLongName())
       .setName(resourceDto.getName())
index e7c062b86f62d2a4d38e10d0e9e6cf3be1e6ef9d..c821fee9018869f34d180f302672a9e26195c2e8 100644 (file)
@@ -29,6 +29,7 @@ public class ResourceDto {
   private String name;
   private String longName;
   private Long rootId;
+  private String moduleKey;
   private String path;
   private String scope;
   private String qualifier;
@@ -93,6 +94,15 @@ public class ResourceDto {
     return this;
   }
 
+  public String getModuleKey() {
+    return moduleKey;
+  }
+
+  public ResourceDto setModuleKey(String s) {
+    this.moduleKey = s;
+    return this;
+  }
+
   public String getLongName() {
     return longName;
   }
index a9ba7ad6b0e696eab6b5ff17f104799dfd707bd7..2855efc4ddaa0f68b3ff2ca8a3c2ac1709735074 100644 (file)
@@ -44,6 +44,7 @@
     <result property="key" column="kee"/>
     <result property="deprecatedKey" column="deprecated_kee"/>
     <result property="path" column="path"/>
+    <result property="moduleKey" column="moduleKey"/>
     <result property="name" column="name"/>
     <result property="longName" column="long_name"/>
     <result property="rootId" column="root_id"/>
@@ -58,8 +59,8 @@
   </resultMap>
 
   <select id="selectResources" parameterType="map" resultMap="resourceResultMap">
-    select *
-    from projects p
+    select p.*, r.kee moduleKey
+    from projects p left outer join projects r on p.root_id=r.id
     <where>
       <if test="qualifiers != null and qualifiers.length!=0">
         and p.qualifier in
   </select>
 
   <select id="selectResource" parameterType="long" resultMap="resourceResultMap">
-    select * from projects where id=#{id}
+    select p.*, r.kee moduleKey
+    from projects p left outer join projects r on p.root_id=r.id
+    where p.id=#{id}
   </select>
 
   <select id="selectResourcesById" parameterType="map" resultMap="resourceResultMap">
-    select * from projects p where p.enabled=${_true}
+    select p.*, r.kee moduleKey
+    from projects p left outer join projects r on p.root_id=r.id
+    where p.enabled=${_true}
     and p.id in
     <foreach collection="ids" open="(" close=")" item="key" separator=",">
       #{key}
index b17d5bcbfadc42d185ea2ab770e3f247494d0fbc..448595e41c472819b923f26b8a9deb8657e59fff 100644 (file)
@@ -36,7 +36,7 @@ public class ComponentVertexTest {
     BeanGraph beanGraph = new BeanGraph(new TinkerGraph());
     ComponentVertex vertex = beanGraph.createVertex(ComponentVertex.class);
     Component file = MockSourceFile.createMain("myproject:org/Foo.java").setName("Foo.java").setQualifier(Qualifiers.FILE)
-      .setPath("src/org/Foo.java");
+      .setPath("src/org/Foo.java").setModuleKey("myproject");
 
     vertex.copyFrom(file);
 
@@ -44,6 +44,7 @@ public class ComponentVertexTest {
     assertThat(vertex.name()).isEqualTo("Foo.java");
     assertThat(vertex.qualifier()).isEqualTo(Qualifiers.FILE);
     assertThat(vertex.path()).isEqualTo("src/org/Foo.java");
+    assertThat(vertex.moduleKey()).isEqualTo("myproject");
   }
 
   @Test
index a3e87afd5b92a453a71f411114aa0968f59263e1..29cc593d31ca69a91cac19e842a641cf7691bf57 100644 (file)
@@ -19,6 +19,7 @@
  */
 package org.sonar.core.component;
 
+import org.junit.Before;
 import org.junit.Test;
 import org.sonar.api.database.model.Snapshot;
 import org.sonar.api.resources.File;
@@ -29,7 +30,13 @@ import static org.fest.assertions.Fail.fail;
 
 public class ResourceComponentTest {
 
-  Resource file = new File("foo.c").setEffectiveKey("myproject:path/to/foo.c");
+  private Resource file;
+
+  @Before
+  public void prepare() {
+    file = new File("foo.c").setEffectiveKey("myproject:path/to/foo.c");
+    file.setKey("path/to/foo.c");
+  }
 
   @Test
   public void db_ids_should_be_optional() {
@@ -54,6 +61,7 @@ public class ResourceComponentTest {
   public void should_use_effective_key() {
     ResourceComponent component = new ResourceComponent(file);
     assertThat(component.key()).isEqualTo("myproject:path/to/foo.c");
+    assertThat(component.moduleKey()).isEqualTo("myproject");
   }
 
   @Test
index 9d55f8a70a41dce75358883f1799ad1fe270e121..798e7bea7b4318e9c6fdd8390f1c5ddb5fef0443 100644 (file)
@@ -73,6 +73,7 @@ public class ResourceDaoTest extends AbstractDaoTestCase {
     ResourceDto resource = dao.getResource(1L);
 
     assertThat(resource.getPath()).isNull();
+    assertThat(resource.getModuleKey()).isNull();
     assertThat(resource.getName()).isEqualTo("Struts");
     assertThat(resource.getLongName()).isEqualTo("Apache Struts");
     assertThat(resource.getScope()).isEqualTo("PRJ");
@@ -81,6 +82,19 @@ public class ResourceDaoTest extends AbstractDaoTestCase {
     assertThat(resource.isEnabled()).isTrue();
   }
 
+  @Test
+  public void get_resource_path_and_module_key() {
+    setupData("fixture");
+
+    ResourceDto dir = dao.getResource(3L);
+    assertThat(dir.getPath()).isEqualTo("src/org/struts");
+    assertThat(dir.getModuleKey()).isEqualTo("org.struts:struts-core");
+
+    ResourceDto file = dao.getResource(4L);
+    assertThat(file.getPath()).isEqualTo("src/org/struts/RequestContext.java");
+    assertThat(file.getModuleKey()).isEqualTo("org.struts:struts-core");
+  }
+
   @Test
   public void getResource_not_found() {
     setupData("fixture");
@@ -185,10 +199,10 @@ public class ResourceDaoTest extends AbstractDaoTestCase {
   public void should_find_root_project_by_component_key() {
     setupData("fixture");
 
-    ResourceDto resource = dao.getRootProjectByComponentKey("org.struts:struts:org.struts.RequestContext");
+    ResourceDto resource = dao.getRootProjectByComponentKey("org.struts:struts-core:src/org/struts/RequestContext.java");
     assertThat(resource.getName()).isEqualTo("Struts");
 
-    resource = dao.getRootProjectByComponentKey("org.struts:struts:org.struts");
+    resource = dao.getRootProjectByComponentKey("org.struts:struts-core:src/org/struts");
     assertThat(resource.getName()).isEqualTo("Struts");
 
     resource = dao.getRootProjectByComponentKey("org.struts:struts-core");
@@ -279,8 +293,8 @@ public class ResourceDaoTest extends AbstractDaoTestCase {
 
     assertThat(dao.findAuthorizedChildrenComponentIds(newArrayList("org.struts:struts"), null, "user")).hasSize(4);
     assertThat(dao.findAuthorizedChildrenComponentIds(newArrayList("org.struts:struts-core"), null, "user")).hasSize(3);
-    assertThat(dao.findAuthorizedChildrenComponentIds(newArrayList("org.struts:struts:org.struts"), null, "user")).hasSize(2);
-    assertThat(dao.findAuthorizedChildrenComponentIds(newArrayList("org.struts:struts:org.struts.RequestContext"), null, "user")).hasSize(1);
+    assertThat(dao.findAuthorizedChildrenComponentIds(newArrayList("org.struts:struts-core:src/org/struts"), null, "user")).hasSize(2);
+    assertThat(dao.findAuthorizedChildrenComponentIds(newArrayList("org.struts:struts-core:src/org/struts/RequestContext.java"), null, "user")).hasSize(1);
 
     assertThat(dao.findAuthorizedChildrenComponentIds(newArrayList("unknown"), null, "user")).isEmpty();
     assertThat(dao.findAuthorizedChildrenComponentIds(Collections.<String>emptyList(), null, "user")).isEmpty();
@@ -317,9 +331,9 @@ public class ResourceDaoTest extends AbstractDaoTestCase {
     setupData("fixture");
 
     assertThat(dao.findByKey("org.struts:struts")).isNotNull();
-    Component<?> component = dao.findByKey("org.struts:struts:org.struts.RequestContext");
+    Component<?> component = dao.findByKey("org.struts:struts-core:src/org/struts/RequestContext.java");
     assertThat(component).isNotNull();
-    assertThat(component.path()).isEqualTo("src/main/java/RequestContext.java");
+    assertThat(component.path()).isEqualTo("src/org/struts/RequestContext.java");
     assertThat(dao.findByKey("unknown")).isNull();
   }
 
index c2e7b8638fb143f736fa845d61c31d3cc108f591..dacf468dabf949773522670bd8afc6827260bc55 100644 (file)
@@ -27,7 +27,7 @@
              depth="[null]" scope="PRJ" qualifier="TRK" created_at="2008-12-01 13:58:00.00" build_date="2008-12-01 13:58:00.00"
              version="[null]" path=""/>
 
-  <!-- project -->
+  <!-- module -->
   <projects id="2" root_id="1" kee="org.struts:struts-core" name="Struts Core"
             scope="PRJ" qualifier="BRC" long_name="Struts Core"
             description="[null]" enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]"/>
                version="[null]" path="1."/>
 
   <!-- directory -->
-  <projects long_name="org.struts" id="3" scope="DIR" qualifier="PAC" kee="org.struts:struts:org.struts"
-              name="org.struts" root_id="1"
+  <projects long_name="org.struts" id="3" scope="DIR" qualifier="DIR" kee="org.struts:struts-core:src/org/struts"
+              name="src/org/struts" root_id="2"
               description="[null]"
-              enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]"/>
+              enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" path="src/org/struts"/>
   <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]"
                version="[null]" path="1.2."/>
 
   <!-- file -->
-  <projects long_name="org.struts.RequestContext" id="4" scope="FIL" qualifier="FIL" kee="org.struts:struts:org.struts.RequestContext"
-            name="RequestContext" root_id="1"
+  <projects long_name="org.struts.RequestContext" id="4" scope="FIL" qualifier="FIL" kee="org.struts:struts-core:src/org/struts/RequestContext.java"
+            name="RequestContext.java" root_id="2"
             description="[null]"
-            enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" path="src/main/java/RequestContext.java"/>
+            enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" path="src/org/struts/RequestContext.java"/>
 
   <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]"
index 064f51f37fc3b787b541d0b119a5cd3fb4417215..1002b568043e3437112f3d11dd170d64d1693bd5 100644 (file)
  */
 package org.sonar.api.component;
 
+import javax.annotation.CheckForNull;
+
 public interface Component<C extends Component> {
   String key();
 
   /**
+   * Path of the component relative to basedir of the parent module.
+   * @return null if this component is not a child of a module
    * @since 4.2
    */
+  @CheckForNull
   String path();
 
+  /**
+   * Key of the module this component belong to.
+   * @return null for components that are module themself
+   * @since 4.2
+   */
+  @CheckForNull
+  String moduleKey();
+
   String name();
 
   String longName();
index 428c17a5a4c3ddf107cccecf370437a34a6c34d8..096f622cfea722554b7be829046b189c4394f6fb 100644 (file)
@@ -24,6 +24,7 @@ import org.sonar.api.component.SourceFile;
 public class MockSourceFile implements SourceFile {
   private String key;
   private String path;
+  private String moduleKey;
   private String qualifier;
   private String language;
   private String name;
@@ -51,6 +52,16 @@ public class MockSourceFile implements SourceFile {
     return this;
   }
 
+  @Override
+  public String moduleKey() {
+    return moduleKey;
+  }
+
+  public MockSourceFile setModuleKey(String moduleKey) {
+    this.moduleKey = moduleKey;
+    return this;
+  }
+
   public String qualifier() {
     return qualifier;
   }
index b19a32bcf7ffe8b6a5ddb22a2541d89e3643c7cc..cfc451e014f2cb4c74bfa6093748d698e78ef371 100644 (file)
@@ -492,6 +492,11 @@ public class Project extends Resource implements Component {
     return getKey();
   }
 
+  @Override
+  public String moduleKey() {
+    return null;
+  }
+
   @Override
   public String name() {
     return getName();
index 8246d73acc44a2ef225041d3b96d07832494e288..9e1ec45a97ee0ca90a88a813eec483021d14606c 100644 (file)
@@ -343,6 +343,7 @@ class Api::IssuesController < Api::ApiController
     hash[:name] = component.name if component.name
     hash[:longName] = component.longName if component.longName
     hash[:path] = component.path if component.path
+    hash[:moduleKey] = component.moduleKey if component.moduleKey
     hash
   end
 
index a348adbd9a418577e397c45db7c270af2aaddb9f..9b5f5431c6e6c6f7d605624e4807c4b194f84d27 100644 (file)
@@ -48,6 +48,14 @@ public class Component {
     return JsonUtils.getString(json, "path");
   }
 
+  /**
+   * @since 4.2
+   */
+  @CheckForNull
+  public String moduleKey() {
+    return JsonUtils.getString(json, "moduleKey");
+  }
+
   public String name() {
     return JsonUtils.getString(json, "name");
   }