diff options
author | David Gageot <david@gageot.net> | 2012-05-09 10:31:33 +0200 |
---|---|---|
committer | David Gageot <david@gageot.net> | 2012-05-09 11:22:55 +0200 |
commit | c90a83404de632683567072a5dd75a70d1a15594 (patch) | |
tree | c7e07a2fe11727f7b27c9dadc9c1b8b207b6f6c0 | |
parent | 882dab818134eca6353509d7ab92f80bcabbac5d (diff) | |
download | sonarqube-c90a83404de632683567072a5dd75a70d1a15594.tar.gz sonarqube-c90a83404de632683567072a5dd75a70d1a15594.zip |
SONAR-1927 Implement a Global Widget that can display Complexity of a given project
8 files changed, 215 insertions, 1 deletions
diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/CorePlugin.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/CorePlugin.java index 2541173c051..e9ac361baa9 100644 --- a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/CorePlugin.java +++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/CorePlugin.java @@ -249,6 +249,7 @@ public final class CorePlugin extends SonarPlugin { extensions.add(CommentsDuplicationsWidget.class); extensions.add(DescriptionWidget.class); extensions.add(ComplexityWidget.class); + extensions.add(TestComplexityWidget.class); extensions.add(RulesWidget.class); extensions.add(SizeWidget.class); extensions.add(EventsWidget.class); diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/widgets/TestComplexityWidget.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/widgets/TestComplexityWidget.java new file mode 100644 index 00000000000..1a5865a9e0d --- /dev/null +++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/widgets/TestComplexityWidget.java @@ -0,0 +1,47 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2008-2012 SonarSource + * mailto:contact AT sonarsource DOT com + * + * Sonar 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. + * + * Sonar 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 Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.plugins.core.widgets; + +import org.sonar.api.web.AbstractRubyTemplate; +import org.sonar.api.web.RubyRailsWidget; +import org.sonar.api.web.WidgetGlobal; +import org.sonar.api.web.WidgetProperties; +import org.sonar.api.web.WidgetProperty; +import org.sonar.api.web.WidgetPropertyType; + +@WidgetGlobal +@WidgetProperties({ + @WidgetProperty(key = "project", type = WidgetPropertyType.PROJECT, defaultValue = "1") +}) +public class TestComplexityWidget extends AbstractRubyTemplate implements RubyRailsWidget { + + public String getId() { + return "testComplexity"; + } + + public String getTitle() { + return "TestComplexity"; + } + + @Override + protected String getTemplatePath() { + return "/org/sonar/plugins/core/widgets/test_complexity.html.erb"; + } +}
\ No newline at end of file diff --git a/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/widgets/test_complexity.html.erb b/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/widgets/test_complexity.html.erb new file mode 100644 index 00000000000..3eb807b0847 --- /dev/null +++ b/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/widgets/test_complexity.html.erb @@ -0,0 +1,118 @@ +<% + file_complexity=measure('file_complexity') + function_complexity=measure('function_complexity') + class_complexity=measure('class_complexity') + paragraph_complexity=measure('paragraph_complexity') + + if file_complexity || function_complexity || class_complexity || paragraph_complexity +complexity=measure('complexity') +%> +<table class="width100"> + <tbody> + <tr> + <td valign="top" width="50%"> + <div class="dashbox" > + <h3><%= message('widget.complexity.name') -%></h3> + <% if function_complexity %> + <p> + <span class="big"><%= format_measure(function_complexity, :suffix => '', :url => url_for_drilldown(function_complexity)) %></span><%= message('widget.complexity.per_method.suffix') -%> + <%= dashboard_configuration.selected_period? ? format_variation(function_complexity) : trend_icon(function_complexity) -%> + </p> + <% end %> + <% if paragraph_complexity %> + <p> + <span class="big"><%= format_measure(paragraph_complexity, :suffix => '', :url => url_for_drilldown(paragraph_complexity)) %></span><%= message('widget.complexity.per_paragraph.suffix') -%> + <%= dashboard_configuration.selected_period? ? format_variation(paragraph_complexity) : trend_icon(paragraph_complexity) -%> + </p> + <% end %> + <% if class_complexity %> + <p> + <span class="big"><%= format_measure(class_complexity, :suffix => '', :url => url_for_drilldown(class_complexity)) %></span></span><%= message('widget.complexity.per_class.suffix') -%> + <%= dashboard_configuration.selected_period? ? format_variation(class_complexity) : trend_icon(class_complexity) -%> + </p> + <% end %> + <% if file_complexity %> + <p> + <span class="big"><%= format_measure(file_complexity, :suffix => '', :url => url_for_drilldown(file_complexity)) %></span></span><%= message('widget.complexity.per_file.suffix') -%> + <%= dashboard_configuration.selected_period? ? format_variation(file_complexity) : trend_icon(file_complexity) -%> + </p> + <% end %> + <% if complexity %> + <p> + <%= message('widget.complexity.total') -%>: <%= format_measure(complexity, :url => url_for_drilldown(complexity)) -%> <%= dashboard_configuration.selected_period? ? format_variation(complexity) : trend_icon(complexity) -%> + </p> + <% end %> + </div> + </td> + <td valign="top" width="50%" nowrap> +<% + function_distribution=measure('function_complexity_distribution') + paragraph_distribution=measure('paragraph_complexity_distribution') + class_distribution=measure('class_complexity_distribution') + file_distribution=measure('file_complexity_distribution') + distributions=[function_distribution,paragraph_distribution,class_distribution,file_distribution].compact + selected_distribution=nil + if distributions.size>0 + selected_distribution=distributions.first + end + if selected_distribution +%> +<div class="dashbox" id="cmp_charts"> + <script type='text/javascript'> + //<![CDATA[ + function selectComplexity(metric) { + $$('#cmp_charts .chart').each(function(chart) { + chart.hide(); + }); + $('chart_' + metric).show(); + } + </script> + <style> + #cmp_charts form { + font-size: 93%;padding-left: 30px; + } +#cmp_charts form label { + padding-right: 5px; + } + </style> + <% distributions.each do |distribution_measure| %> + <%= render :partial => 'project/widgets/complexity_chart', :locals => { :metric => distribution_measure.metric.key, :title => distribution_measure.metric.description, :visible => (selected_distribution==distribution_measure) } %> + <% end %> + + <form> + <% + count_dist=0 + if function_distribution + count_dist+=1 + %> +<input type="radio" name="cmp_dist" value="function_complexity_distribution" id="cmp_dist_function_complexity_distribution" onClick="selectComplexity('function_complexity_distribution');" <%= 'checked' if function_distribution==selected_distribution -%>></input> <label for="cmp_dist_function_complexity_distribution"><%= message('metric.functions.name') -%></label> +<% +end +if paragraph_distribution + count_dist+=1 +%> +<input type="radio" name="cmp_dist" value="paragraph_complexity_distribution" id="cmp_dist_paragraph_complexity_distribution" onClick="selectComplexity('paragraph_complexity_distribution');" <%= 'checked' if paragraph_distribution==selected_distribution -%>></input> <label for="cmp_dist_paragraph_complexity_distribution"><%= message('metric.paragraphs.name') -%></label><%= '<br/>' if count_dist==2 %> +<% +end +if class_distribution + count_dist+=1 +%> +<input type="radio" name="cmp_dist" value="class_complexity_distribution" id="cmp_dist_class_complexity_distribution" onClick="selectComplexity('class_complexity_distribution');" <%= 'checked' if class_distribution==selected_distribution -%>></input> <label for="cmp_dist_class_complexity_distribution"><%= message('metric.classes.name') -%></label><%= '<br/>' if count_dist==2 %> +<% +end +if file_distribution + count_dist+=1 +%> +<input type="radio" name="cmp_dist" value="file_complexity_distribution" id="cmp_dist_file_complexity_distribution" onClick="selectComplexity('file_complexity_distribution');" <%= 'checked' if file_distribution==selected_distribution -%>></input> <label for="cmp_dist_file_complexity_distribution"><%= message('metric.files.name') -%></label> +<% end %> + + </form> + +</div> +<% end %> + </td> + </tr> + </tbody> + </table> +<div class="clear"></div> +<% end %> diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/web/WidgetPropertyType.java b/sonar-plugin-api/src/main/java/org/sonar/api/web/WidgetPropertyType.java index 7be2caf8b2c..a514287a388 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/web/WidgetPropertyType.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/web/WidgetPropertyType.java @@ -25,5 +25,6 @@ public enum WidgetPropertyType { FLOAT, STRING, METRIC, // @since 2.10 - FILTER // @since 3.1 + FILTER, // @since 3.1 + PROJECT // @since 3.1 } diff --git a/sonar-server/src/main/webapp/WEB-INF/app/helpers/widget_properties_helper.rb b/sonar-server/src/main/webapp/WEB-INF/app/helpers/widget_properties_helper.rb index 277209e5b87..bf1e4792e4d 100644 --- a/sonar-server/src/main/webapp/WEB-INF/app/helpers/widget_properties_helper.rb +++ b/sonar-server/src/main/webapp/WEB-INF/app/helpers/widget_properties_helper.rb @@ -39,6 +39,9 @@ module WidgetPropertiesHelper elsif definition.type.name()==WidgetProperty::TYPE_FILTER select_tag definition.key(), ::Filter.all.sort_by(&:id).collect { |f| "<option value='#{f.id}'>#{f.name}</option>" } + elsif definition.type.name()==WidgetProperty::TYPE_PROJECT + select_tag definition.key(), Project.all(:conditions => {:scope => 'PRJ', :qualifier => 'TRK'}).collect { |f| "<option value='#{f.id}'>#{f.name}</option>" } + else hidden_field_tag definition.key() end diff --git a/sonar-server/src/main/webapp/WEB-INF/app/models/widget_property.rb b/sonar-server/src/main/webapp/WEB-INF/app/models/widget_property.rb index a26e8e5dfcb..114b1440263 100644 --- a/sonar-server/src/main/webapp/WEB-INF/app/models/widget_property.rb +++ b/sonar-server/src/main/webapp/WEB-INF/app/models/widget_property.rb @@ -24,6 +24,7 @@ class WidgetProperty < ActiveRecord::Base TYPE_STRING = 'STRING' TYPE_METRIC = 'METRIC' TYPE_FILTER = 'FILTER' + TYPE_PROJECT = 'PROJECT' belongs_to :widget @@ -84,6 +85,8 @@ class WidgetProperty < ActiveRecord::Base Metric.by_key(text) when TYPE_FILTER text.to_i + when TYPE_PROJECT + text.to_i else text end diff --git a/sonar-server/src/main/webapp/WEB-INF/app/views/dashboard/_configure_widget.html.erb b/sonar-server/src/main/webapp/WEB-INF/app/views/dashboard/_configure_widget.html.erb index 61d45160038..812e15e3d99 100644 --- a/sonar-server/src/main/webapp/WEB-INF/app/views/dashboard/_configure_widget.html.erb +++ b/sonar-server/src/main/webapp/WEB-INF/app/views/dashboard/_configure_widget.html.erb @@ -1,4 +1,17 @@ <% + @backup_resource=@resource + @backup_project=@project + @backup_snapshot=@snapshot + @backup_dashboard_configuration=@dashboard_configuration + + if widget.property_value('project') + @project = @resource = Project.find(widget.property_value('project')) + @snapshot=@resource.last_snapshot + @dashboard_configuration=Api::DashboardConfiguration.new(@dashboard, :period_index => params[:period], :snapshot => @snapshot) + end +%> + +<% begin widget_body=render :inline => widget.java_definition.getTarget().getTemplate(), :locals => {:widget_properties => widget.properties_as_hash, :widget => widget, :dashboard_configuration => @dashboard_configuration} rescue => error @@ -51,3 +64,11 @@ <div style="clear: both;"></div> </div> +<% + @resource=@backup_resource + @project=@backup_project + @snapshot=@backup_snapshot + @dashboard_configuration=@backup_dashboard_configuration +%> + + diff --git a/sonar-server/src/main/webapp/WEB-INF/app/views/dashboard/_widget.html.erb b/sonar-server/src/main/webapp/WEB-INF/app/views/dashboard/_widget.html.erb index 035b4a87c94..474737e744b 100644 --- a/sonar-server/src/main/webapp/WEB-INF/app/views/dashboard/_widget.html.erb +++ b/sonar-server/src/main/webapp/WEB-INF/app/views/dashboard/_widget.html.erb @@ -1,3 +1,16 @@ +<% + @backup_resource=@resource + @backup_project=@project + @backup_snapshot=@snapshot + @backup_dashboard_configuration=@dashboard_configuration + + if widget.property_value('project') + @project = @resource = Project.find(widget.property_value('project')) + @snapshot=@resource.last_snapshot + @dashboard_configuration=Api::DashboardConfiguration.new(@dashboard, :period_index => params[:period], :snapshot => @snapshot) + end +%> + <div class="<%= h widget.key -%>" style="height:100%;"> <% if widget.configured begin @@ -29,3 +42,10 @@ <% end %> <div style="clear: both;"></div> </div> + +<% + @resource=@backup_resource + @project=@backup_project + @snapshot=@backup_snapshot + @dashboard_configuration=@backup_dashboard_configuration +%> |