]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-3825 fix loading of qualifiers in the form
authorSimon Brandhof <simon.brandhof@gmail.com>
Sat, 24 Nov 2012 23:00:50 +0000 (00:00 +0100)
committerSimon Brandhof <simon.brandhof@gmail.com>
Mon, 26 Nov 2012 12:55:54 +0000 (13:55 +0100)
13 files changed:
plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/DefaultResourceTypes.java
plugins/sonar-core-plugin/src/main/resources/org/sonar/l10n/core.properties
sonar-core/src/main/java/org/sonar/core/measure/MeasureFilter.java
sonar-core/src/main/java/org/sonar/core/measure/MeasureFilterExecutor.java
sonar-plugin-api/src/main/java/org/sonar/api/resources/ResourceType.java
sonar-plugin-api/src/main/java/org/sonar/api/resources/ResourceTypes.java
sonar-plugin-api/src/test/java/org/sonar/api/resources/ResourceTypeTest.java
sonar-plugin-api/src/test/java/org/sonar/api/resources/ResourceTypesTest.java
sonar-server/src/main/webapp/WEB-INF/app/models/measure_filter.rb
sonar-server/src/main/webapp/WEB-INF/app/views/layouts/_layout.html.erb
sonar-server/src/main/webapp/WEB-INF/app/views/layouts/_tools.html.erb
sonar-server/src/main/webapp/WEB-INF/app/views/measures/_display_list.html.erb
sonar-server/src/main/webapp/WEB-INF/app/views/measures/search.html.erb

index e2b9328d31fcf0a2d7d7decb3bd408ce8bb8a62e..bc3125b2d07d8b97a357638338d2dbc955d0569e 100644 (file)
@@ -38,15 +38,28 @@ public final class DefaultResourceTypes extends ExtensionProvider implements Bat
             .setProperty("modifiable_history", true)
             .setProperty("hasRolePolicy", true)
             .setProperty("updatable_key", true)
+            .setProperty("supports_measure_filters", true)
             .build())
         .addType(ResourceType.builder(Qualifiers.MODULE)
             .setProperty("updatable_key", true)
+            .setProperty("supports_measure_filters", true)
             .build())
-        .addType(ResourceType.builder(Qualifiers.DIRECTORY).build())
-        .addType(ResourceType.builder(Qualifiers.PACKAGE).build())
-        .addType(ResourceType.builder(Qualifiers.FILE).hasSourceCode().build())
-        .addType(ResourceType.builder(Qualifiers.CLASS).hasSourceCode().build())
-        .addType(ResourceType.builder(Qualifiers.UNIT_TEST_FILE).hasSourceCode().build())
+        .addType(ResourceType.builder(Qualifiers.DIRECTORY)
+          .setProperty("supports_measure_filters", true)
+          .build())
+        .addType(ResourceType.builder(Qualifiers.PACKAGE)
+          .build())
+        .addType(ResourceType.builder(Qualifiers.FILE)
+          .hasSourceCode()
+          .setProperty("supports_measure_filters", true)
+          .build())
+        .addType(ResourceType.builder(Qualifiers.CLASS)
+          .hasSourceCode()
+          .build())
+        .addType(ResourceType.builder(Qualifiers.UNIT_TEST_FILE)
+          .hasSourceCode()
+          .setProperty("supports_measure_filters", true)
+          .build())
 
         .addRelations(Qualifiers.PROJECT, Qualifiers.MODULE)
         .addRelations(Qualifiers.MODULE, Qualifiers.DIRECTORY, Qualifiers.PACKAGE)
index 0a352ace85a37be5ec21a5bd436021f6c3007568..a0a87406463110f11eaf5bbeab90d36287c8188e 100644 (file)
@@ -381,6 +381,17 @@ session.flash_notice.logged_out=You have been logged out.
 # MEASURE FILTERS
 #
 #------------------------------------------------------------------------------
+measure_filter.col.date=Date
+measure_filter.col.description=Description
+measure_filter.col.key=Key
+measure_filter.col.language=Language
+measure_filter.col.links=Links
+measure_filter.col.name=Name
+measure_filter.col.short_name=Name
+measure_filter.col.version=Version
+measure_filter.missing_name=Name is missing
+measure_filter.name_too_long=Name is too long
+
 
 #------------------------------------------------------------------------------
 #
index 5c4d247a6d63db23a9ce8fd97ca9c4aacd59313e..41f987dd57944a1c8b38f4e3ac0ee7cfcad55a6a 100644 (file)
@@ -23,8 +23,8 @@ import com.google.common.annotations.VisibleForTesting;
 import com.google.common.base.Strings;
 import com.google.common.collect.Lists;
 import org.apache.commons.lang.builder.ReflectionToStringBuilder;
-import org.apache.commons.lang.builder.ToStringStyle;
 import org.sonar.api.measures.Metric;
+import org.sonar.api.resources.Qualifiers;
 
 import javax.annotation.Nullable;
 
@@ -76,6 +76,12 @@ public class MeasureFilter {
 
   public MeasureFilter setResourceQualifiers(@Nullable List<String> list) {
     this.resourceQualifiers = sanitize(list);
+    if (resourceQualifiers.contains(Qualifiers.FILE)) {
+      resourceQualifiers.add(Qualifiers.CLASS);
+    }
+    if (resourceQualifiers.contains(Qualifiers.DIRECTORY)) {
+      resourceQualifiers.add(Qualifiers.PACKAGE);
+    }
     return this;
   }
 
index 6b1bf54b3b81d293e9e14c16622dda5f8210966f..0de8fad5f27764c99796f7da27da6120e1c80e34 100644 (file)
@@ -19,6 +19,7 @@
  */
 package org.sonar.core.measure;
 
+import com.google.common.base.Strings;
 import org.apache.ibatis.session.SqlSession;
 import org.sonar.api.ServerComponent;
 import org.sonar.core.persistence.Database;
@@ -75,7 +76,8 @@ public class MeasureFilterExecutor implements ServerComponent {
   }
 
   static boolean isValid(MeasureFilter filter, MeasureFilterContext context) {
-    boolean valid = !(filter.isOnBaseResourceChildren() && context.getBaseSnapshot() == null);
+    boolean valid = (Strings.isNullOrEmpty(filter.getBaseResourceKey()) || context.getBaseSnapshot()!=null);
+    valid &= !(filter.isOnBaseResourceChildren() && context.getBaseSnapshot() == null);
     valid &= !(filter.isOnFavourites() && context.getUserId() == null);
     valid &= validateMeasureConditions(filter);
     valid &= validateSort(filter);
index fc0d8b0041ede12375cc6dbc4ff81679b13d4c9a..bab797e764b319abe0748a8df1066841fcb2ea1f 100644 (file)
@@ -40,7 +40,7 @@ import java.util.Map;
  * </p>
  * <ul>
  * <li>"deletable": if set to "true", then this resource can be deleted/purged.</li>
- * <li>"availableForFilters": if set to "true", then this resource can be displayed in the filters results</li>
+ * <li>"supports_measure_filters": if set to "true", then this resource can be displayed in measure filters</li>
  * <li>"modifiable_history": if set to "true", then the history of this resource may be modified (deletion of snapshots, modification of events, ...)</li>
  * <li>"updatable_key" (since 3.2): if set to "true", then it is possible to update the key of this resource</li>
  * <li>"supportsGlobalDashboards" (since 3.2): if true, this resource can be displayed in global dashboards</li>
@@ -82,11 +82,11 @@ public final class ResourceType {
     }
 
     /**
-     * @deprecated since 3.0. Use {@link #setProperty(String, String)} with "availableForFilters" set to "true".
+     * @deprecated since 3.0. Use {@link #setProperty(String, String)} with "supports_measure_filters" set to "true".
      */
     @Deprecated
     public Builder availableForFilters() {
-      setProperty("availableForFilters", "true");
+      setProperty("supports_measure_filters", "true");
       return this;
     }
 
@@ -107,6 +107,11 @@ public final class ResourceType {
       Preconditions.checkNotNull(key);
       Preconditions.checkNotNull(value);
       properties.put(key, value);
+
+      // for backward-compatibility since version 3.4
+      if (key.equals("availableForFilters")) {
+        properties.put("supports_measure_filters", value);
+      }
       return this;
     }
 
index 4821187385fd4919230829b5301b5173ec82d7e4..f3494e963c2653a2fe162d37e065f41400ef1a0b 100644 (file)
@@ -45,7 +45,7 @@ public final class ResourceTypes implements BatchComponent, ServerComponent {
 
   public static final Predicate<ResourceType> AVAILABLE_FOR_FILTERS = new Predicate<ResourceType>() {
     public boolean apply(@Nullable ResourceType input) {
-      return input != null && input.getBooleanProperty("availableForFilters");
+      return input != null && input.getBooleanProperty("supports_measure_filters");
     }
   };
 
index 5d3559e9100eabd6dc14b4e13f23a74416abfb65..98e11c609d3eb30a297894f803ac47e07e4e98a5 100644 (file)
@@ -40,13 +40,13 @@ public class ResourceTypeTest {
     ResourceType def = ResourceType.builder("qualifier")
       .setIconPath("/custom-icon.png")
       .hasSourceCode()
-      .setProperty("availableForFilters", "true")
+      .setProperty("supports_measure_filters", "true")
       .setProperty("anotherProperty", "foo")
       .build();
     assertThat(def.getQualifier()).isEqualTo("qualifier");
     assertThat(def.getIconPath()).isEqualTo("/custom-icon.png");
     assertThat(def.hasSourceCode()).isTrue();
-    assertThat(def.getBooleanProperty("availableForFilters")).isTrue();
+    assertThat(def.getBooleanProperty("supports_measure_filters")).isTrue();
     assertThat(def.getStringProperty("anotherProperty")).isEqualTo("foo");
   }
 
@@ -71,32 +71,32 @@ public class ResourceTypeTest {
   @Test
   public void testDeprecatedIsAvailableForFiltesCompatibility() {
     ResourceType def = ResourceType.builder("qualifier").build();
-    assertThat(def.getBooleanProperty("availableForFilters")).isFalse();
+    assertThat(def.getBooleanProperty("supports_measure_filters")).isFalse();
 
     def = ResourceType.builder("qualifier").availableForFilters().build();
-    assertThat(def.getBooleanProperty("availableForFilters")).isTrue();
+    assertThat(def.getBooleanProperty("supports_measure_filters")).isTrue();
   }
 
   @Test
   public void getBooleanProperty_is_set() {
     // set with boolean parameter
-    ResourceType def = ResourceType.builder("qualifier").setProperty("availableForFilters", true).build();
-    assertThat(def.getBooleanProperty("availableForFilters")).isTrue();
+    ResourceType def = ResourceType.builder("qualifier").setProperty("supports_measure_filters", true).build();
+    assertThat(def.getBooleanProperty("supports_measure_filters")).isTrue();
 
-    def = ResourceType.builder("qualifier").setProperty("availableForFilters", false).build();
-    assertThat(def.getBooleanProperty("availableForFilters")).isFalse();
+    def = ResourceType.builder("qualifier").setProperty("supports_measure_filters", false).build();
+    assertThat(def.getBooleanProperty("supports_measure_filters")).isFalse();
 
-    def = ResourceType.builder("qualifier").setProperty("availableForFilters", "true").build();
-    assertThat(def.getBooleanProperty("availableForFilters")).isTrue();
+    def = ResourceType.builder("qualifier").setProperty("supports_measure_filters", "true").build();
+    assertThat(def.getBooleanProperty("supports_measure_filters")).isTrue();
 
-    def = ResourceType.builder("qualifier").setProperty("availableForFilters", "false").build();
-    assertThat(def.getBooleanProperty("availableForFilters")).isFalse();
+    def = ResourceType.builder("qualifier").setProperty("supports_measure_filters", "false").build();
+    assertThat(def.getBooleanProperty("supports_measure_filters")).isFalse();
   }
 
   @Test
   public void getBooleanProperty_is_not_set() {
     ResourceType def = ResourceType.builder("qualifier").build();
-    assertThat(def.getBooleanProperty("availableForFilters")).isFalse();
+    assertThat(def.getBooleanProperty("supports_measure_filters")).isFalse();
   }
 
   @Test
index eeb96d7402fefd1b81064b4dc623bb22d8e00944..1d73ddcc550fa23b98294e5be1c55f7fbe3b5389 100644 (file)
@@ -30,14 +30,14 @@ import static org.fest.assertions.Assertions.assertThat;
 public class ResourceTypesTest {
 
   private ResourceTypeTree viewsTree = ResourceTypeTree.builder()
-    .addType(ResourceType.builder(Qualifiers.VIEW).setProperty("availableForFilters", "true").build())
+    .addType(ResourceType.builder(Qualifiers.VIEW).setProperty("supports_measure_filters", "true").build())
     .addType(ResourceType.builder(Qualifiers.SUBVIEW).build())
     .addRelations(Qualifiers.VIEW, Qualifiers.SUBVIEW)
     .addRelations(Qualifiers.SUBVIEW, Qualifiers.PROJECT)
     .build();
 
   private ResourceTypeTree defaultTree = ResourceTypeTree.builder()
-    .addType(ResourceType.builder(Qualifiers.PROJECT).setProperty("availableForFilters", "true").build())
+    .addType(ResourceType.builder(Qualifiers.PROJECT).setProperty("supports_measure_filters", "true").build())
     .addType(ResourceType.builder(Qualifiers.DIRECTORY).build())
     .addType(ResourceType.builder(Qualifiers.FILE).build())
     .addRelations(Qualifiers.PROJECT, Qualifiers.DIRECTORY)
@@ -67,14 +67,14 @@ public class ResourceTypesTest {
 
   @Test
   public void getAllWithPropertyKey() {
-    assertThat(qualifiers(types.getAllWithPropertyKey("availableForFilters"))).containsOnly(Qualifiers.VIEW, Qualifiers.PROJECT);
+    assertThat(qualifiers(types.getAllWithPropertyKey("supports_measure_filters"))).containsOnly(Qualifiers.VIEW, Qualifiers.PROJECT);
   }
 
   @Test
   public void getAllWithPropertyValue() {
-    assertThat(qualifiers(types.getAllWithPropertyValue("availableForFilters", "true"))).containsOnly(Qualifiers.VIEW, Qualifiers.PROJECT);
-    assertThat(qualifiers(types.getAllWithPropertyValue("availableForFilters", true))).containsOnly(Qualifiers.VIEW, Qualifiers.PROJECT);
-    assertThat(qualifiers(types.getAllWithPropertyValue("availableForFilters", false))).containsOnly(Qualifiers.SUBVIEW, Qualifiers.DIRECTORY, Qualifiers.FILE);
+    assertThat(qualifiers(types.getAllWithPropertyValue("supports_measure_filters", "true"))).containsOnly(Qualifiers.VIEW, Qualifiers.PROJECT);
+    assertThat(qualifiers(types.getAllWithPropertyValue("supports_measure_filters", true))).containsOnly(Qualifiers.VIEW, Qualifiers.PROJECT);
+    assertThat(qualifiers(types.getAllWithPropertyValue("supports_measure_filters", false))).containsOnly(Qualifiers.SUBVIEW, Qualifiers.DIRECTORY, Qualifiers.FILE);
   }
 
   @Test
index 27dfc7c129b953e0e594113c8dc02b2e8ae57e0f..e123375ea171777c7d11e8057f099c6cc0217164 100644 (file)
@@ -58,7 +58,7 @@ class MeasureFilter < ActiveRecord::Base
       if @metric
         Api::Utils.message("metric.#{@metric.key}.name", :default => @metric.short_name)
       else
-        Api::Utils.message("filters.col.#{@key}", :default => @key)
+        Api::Utils.message("measure_filter.col.#{@key}", :default => @key)
       end
     end
 
@@ -96,7 +96,7 @@ class MeasureFilter < ActiveRecord::Base
     KEY = :list
 
     def initialize(filter)
-      filter.set_criteria_default_value('columns', ['name', 'short_name', 'description', 'links', 'date', 'language', 'version', 'alert', 'metric:ncloc', 'metric:violations'])
+      filter.set_criteria_default_value('columns', ['metric:alert_status', 'name', 'date', 'metric:ncloc', 'metric:violations', 'links'])
       filter.set_criteria_default_value('sort', 'name')
       filter.set_criteria_default_value('asc', 'true')
       filter.set_criteria_default_value('pageSize', '30')
@@ -117,6 +117,7 @@ class MeasureFilter < ActiveRecord::Base
 
     def initialize(filter)
       filter.set_criteria_default_value('columns', ['metric:ncloc', 'metric:violations'])
+      @columns = filter.criteria['columns'].map { |column_key| Column.new(column_key) }
       @metric_ids = @columns.map { |column| column.metric.id if column.metric }.compact.uniq
     end
   end
@@ -129,11 +130,11 @@ class MeasureFilter < ActiveRecord::Base
   CRITERIA_SEPARATOR = '|'
   CRITERIA_KEY_VALUE_SEPARATOR = ','
 
-# Configuration available after call to execute()
+  # Configuration available after call to execute()
   attr_reader :pagination, :security_exclusions, :columns
 
-# Results : sorted array of Result
-  attr_reader :results
+  # Results : sorted array of Result
+  attr_reader :base_result, :results
 
   belongs_to :user
   validates_presence_of :name, :message => Api::Utils.message('measure_filter.missing_name')
@@ -223,7 +224,7 @@ class MeasureFilter < ActiveRecord::Base
     self
   end
 
-# API used by Displays
+  # API used by Displays
   def set_criteria_value(key, value)
     if value
       @criteria[key.to_s]=value
@@ -232,7 +233,7 @@ class MeasureFilter < ActiveRecord::Base
     end
   end
 
-# API used by Displays
+  # API used by Displays
   def set_criteria_default_value(key, value)
     set_criteria_value(key, value) unless criteria.has_key?(key)
   end
@@ -297,6 +298,20 @@ class MeasureFilter < ActiveRecord::Base
         end
       end
     end
+    if criteria['base'].present?
+      base_snapshot = Snapshot.find(:first, :include => 'project', :conditions => ['projects.kee=? and islast=?', criteria['base'], true])
+      if base_snapshot
+        @base_result = Result.new(base_snapshot)
+        if display.metric_ids && !display.metric_ids.empty?
+          base_measures = ProjectMeasure.find(:all, :conditions =>
+              ['rule_priority is null and rule_id is null and characteristic_id is null and person_id is null and snapshot_id=? and metric_id in (?)', base_snapshot.id, display.metric_ids]
+          )
+          base_measures.each do |base_measure|
+            @base_result.add_measure(base_measure)
+          end
+        end
+      end
+    end
   end
 
   def validate
index 4f6cd3877607f4b26a77a16d34a15ded9db5b933..63c220d9ad5964e8d7e0e6f57f9a468cf424eb0f 100644 (file)
             </li>
           <% end %>
 
-          <li class="<%= 'selected' if controller.controller_path=='reviews' -%>">
-          <a href="<%= ApplicationController.root_context -%>/reviews/index"><%= message('reviews.page') -%></a>
-          </li>
-
           <% controller.java_facade.getPages(Navigation::SECTION_HOME, nil, nil, nil, nil).each do |page|
             page_url = (page.isController() ? page.getId() : "/plugins/home/#{page.getId()}")
             selected=request.request_uri.include?("/plugins/home/#{page_url}")
index 83fe4265a22fd8241315c0a8f791919e13de043b..b1bca085e65e1fc1b46fb7494c713878b58173eb 100644 (file)
@@ -4,6 +4,7 @@
   <div id="tools-menu" class="dropdown-menu" style="display: none">
     <ul>
       <li><a href="<%= ApplicationController.root_context -%>/dependencies/index"><%= message('dependencies.page') -%></a></li>
+      <li><a href="<%= ApplicationController.root_context -%>/reviews/index"><%= message('reviews.page') -%></a></li>
     </ul>
   </div>
 </li>
\ No newline at end of file
index ee642f3c0c90d9f04299bbc4e7f8614cb6693753..900431e003b24eb995b051faf5480684db0f21d4 100644 (file)
   </tr>
   </thead>
   <tbody>
+
+  <% if @filter.base_result %>
+    <tr class="highlight">
+      <% if display_favourites %>
+        <td class="thin"><%= link_to_favourite(@filter.base_result.snapshot.resource) -%></td>
+      <% end %>
+      <% @filter.display.columns.each do |column| %>
+        <td class="<%= column.align -%>">
+          <%= list_cell_html(column, @filter.base_result) -%>
+        </td>
+      <% end %>
+    </tr>
+  <% end %>
+
   <% @filter.results.each do |result| %>
     <tr class="<%= cycle 'even', 'odd' -%>">
       <% if display_favourites %>
         <td class="thin"><%= link_to_favourite(result.snapshot.resource) -%></td>
       <% end %>
       <% @filter.display.columns.each do |column| %>
-        <td class="<%= column.align -%>" >
+        <td class="<%= column.align -%>">
           <%= list_cell_html(column, result) -%>
         </td>
       <% end %>
     </tr>
   <% end %>
+
   <% if @filter.results.empty? %>
     <tr class="even">
       <td colspan="<%= colspan -%>"><%= message 'no_data' -%></td>
     </tr>
   <% end %>
+
   </tbody>
   <%= render :partial => 'utils/tfoot_pagination', :locals => {:pagination => @filter.pagination, :colspan => colspan} %>
 </table>
\ No newline at end of file
index 4905680ff25ebbca0aa2523ac34684f17bae6b1c..90fc6f7d804fdb0adce05421b5e1ac07c2304456 100644 (file)
         <tr>
           <td>
             Qualifiers:<br>
-            <%= select_tag 'qualifiers[]', options_for_select([['Any', ''], ['Project', 'TRK'], ['Sub-project', 'BRC'], ['Directory/Package', 'PAC'], ['File', 'CLA']], @filter.criteria['qualifiers']||''), :size => 5, :multiple => true -%>
+            <%
+              qualifiers = Api::Utils.java_facade.getResourceTypesForFilter().map do |resource_type|
+                [message("qualifiers.#{resource_type.getQualifier()}"), resource_type.getQualifier()]
+              end
+            %>
+            <%= select_tag 'qualifiers[]', options_for_select([[message('any'), '']].concat(qualifiers), @filter.criteria['qualifiers']||''), :size => 5, :multiple => true -%>
           </td>
         </tr>
         <tr>
           <td>
             Language:<br>
-            <% languages = [['Any', '']].concat(Api::Utils.languages.map { |lang| [lang.name, lang.key] }) %>
+            <% languages = [[message('any'), '']].concat(Api::Utils.languages.map { |lang| [lang.name, lang.key] }) %>
             <%= select_tag 'languages[]', options_for_select(languages, @filter.criteria['languages']||''), :size => 5, :multiple => true -%>
           </td>
         </tr>
         <tr>
           <td>
             Name:<br>
-            <input type="text" name="nameRegexp"></td>
+            <input type="text" name="nameRegexp" value="<%= h @filter.criteria['nameRegexp'] -%>"></td>
         </tr>
         <tr>
           <td>
             Key:<br>
-            <input type="text" name="keyRegexp"></td>
+            <input type="text" name="keyRegexp" value="<%= h @filter.criteria['keyRegexp'] -%>"></td>
         </tr>
         <tr>
           <td>
             Favourites only:<br>
-            <%= check_box_tag 'onFavourites', 'true', params['onFavourites']=='true' %>
+            <%= check_box_tag 'onFavourites', 'true', @filter.criteria['onFavourites']=='true' %>
           </td>
         </tr>
         <tr>
           <td>
             From date:<br>
-            <input type="text" name="fromDate" value="<%= params['fromDate'] -%>">
+            <input type="text" name="fromDate" value="<%= @filter.criteria['fromDate'] -%>">
           </td>
         </tr>
         <tr>
           <td>
             To date:<br>
-            <input type="text" name="toDate" value="<%= params['toDate'] -%>">
+            <input type="text" name="toDate" value="<%= @filter.criteria['toDate'] -%>">
           </td>
         </tr>
         <tr>
           <td>
-            Before:<br>
-            <input type="text" name="beforeDays" value="<%= params['beforeDays'] -%>" size="4"> days
+            More than:<br>
+            <input type="text" name="beforeDays" value="<%= @filter.criteria['beforeDays'] -%>" size="4"> days ago
           </td>
         </tr>
         <tr>
-          <td>After:<br>
-            <input type="text" name="afterDays" value="<%= params['afterDays'] -%>" size="4"> days
+          <td>Within the last:<br>
+            <input type="text" name="afterDays" value="<%= @filter.criteria['afterDays'] -%>" size="4"> days
           </td>
         </tr>
         <tr>