diff options
author | Simon Brandhof <simon.brandhof@gmail.com> | 2011-08-15 19:36:19 +0200 |
---|---|---|
committer | Simon Brandhof <simon.brandhof@gmail.com> | 2011-08-15 19:36:19 +0200 |
commit | 04cde730a288fc1dd0de91e3ee0cd0c96ed41919 (patch) | |
tree | 45345155d06fadb02c37734fc3f8eb1fe6c443ca | |
parent | 0dbee87afa49c3c5f75f045e1ac5bf1ec171e5b7 (diff) | |
download | sonarqube-04cde730a288fc1dd0de91e3ee0cd0c96ed41919.tar.gz sonarqube-04cde730a288fc1dd0de91e3ee0cd0c96ed41919.zip |
SONAR-2694 Provide a new optional 'category' attribute on the @Property annotation
9 files changed, 207 insertions, 149 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 60f7d250ba0..db162da7c70 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 @@ -48,21 +48,25 @@ import java.util.List; key = CoreProperties.ORGANIZATION, name = "Organization", description = "Identify your installation. Required to generate the server key and to benefit from licensed plugins. Server must be restarted for the change to take effect.", - global = true), + global = true, + category = "General" + ), @Property( key = CoreProperties.SERVER_BASE_URL, defaultValue = CoreProperties.SERVER_BASE_URL_DEFAULT_VALUE, name = "Server base URL", description = "HTTP address of the Sonar server, such as <i>http://yourhost.yourdomain/sonar</i>. This value is used i.e. to create links in emails and to generate server key.", project = false, - global = true), + global = true, + category = "General"), @Property( key = CoreProperties.CORE_COVERAGE_PLUGIN_PROPERTY, defaultValue = "cobertura", name = "Code coverage plugin", description = "Key of the code coverage plugin to use.", project = true, - global = true), + global = true, + category = "Coverage"), @Property( key = CoreProperties.CORE_IMPORT_SOURCES_PROPERTY, defaultValue = "" + CoreProperties.CORE_IMPORT_SOURCES_DEFAULT_VALUE, @@ -70,14 +74,16 @@ import java.util.List; description = "Set to false if sources should not be displayed, e.g. for security reasons.", project = true, module = true, - global = true), + global = true, + category = "General"), @Property( key = CoreProperties.CORE_TENDENCY_DEPTH_PROPERTY, defaultValue = "" + CoreProperties.CORE_TENDENCY_DEPTH_DEFAULT_VALUE, name = "Tendency period", description = TendencyDecorator.PROP_DAYS_DESCRIPTION, project = false, - global = true), + global = true, + category = "General"), @Property( key = CoreProperties.SKIP_TENDENCIES_PROPERTY, defaultValue = "" + CoreProperties.SKIP_TENDENCIES_DEFAULT_VALUE, @@ -85,41 +91,47 @@ import java.util.List; description = "Skip calculation of measure tendencies", project = true, module = false, - global = true), + global = true, + category = "General"), @Property( key = CoreProperties.CORE_SKIPPED_MODULES_PROPERTY, name = "Exclude modules", description = "Maven artifact ids of modules to exclude (comma-separated).", project = true, - global = false), + global = false, + category = "General"), @Property( key = CoreProperties.CORE_RULE_WEIGHTS_PROPERTY, defaultValue = CoreProperties.CORE_RULE_WEIGHTS_DEFAULT_VALUE, name = "Rules weight", description = "A weight is associated to each priority to calculate the Rules Compliance Index.", project = false, - global = true), + global = true, + category = "General"), @Property( key = CoreProperties.CORE_FORCE_AUTHENTICATION_PROPERTY, defaultValue = "" + CoreProperties.CORE_FORCE_AUTHENTICATION_DEFAULT_VALUE, name = "Force user authentication", description = "Forcing user authentication stops un-logged users to access Sonar.", project = false, - global = true), + global = true, + category = "General"), @Property( key = CoreProperties.CORE_ALLOW_USERS_TO_SIGNUP_PROPERTY, defaultValue = "" + CoreProperties.CORE_ALLOW_USERS_TO_SIGNUP_DEAULT_VALUE, name = "Allow users to sign up online", description = "Users can sign up online.", project = false, - global = true), + global = true, + category = "General"), @Property( key = CoreProperties.CORE_DEFAULT_GROUP, defaultValue = CoreProperties.CORE_DEFAULT_GROUP_DEFAULT_VALUE, name = "Default user group", description = "Any new users will automatically join this group.", project = false, - global = true + global = true, + category = "General" ), @Property( key = CoreProperties.CORE_VIOLATION_LOCALE_PROPERTY, @@ -127,7 +139,8 @@ import java.util.List; name = "Locale used for violation messages", description = "Locale to be used when generating violation messages. It's up to each rule engine to support this global internationalization property", project = true, - global = true), + global = true, + category = "General"), @Property( key = "sonar.timemachine.period1", name = "Period 1", @@ -136,7 +149,8 @@ import java.util.List; "compare to previous analysis</li><li>A version, for example 1.2</li></ul>", project = false, global = true, - defaultValue = CoreProperties.TIMEMACHINE_DEFAULT_PERIOD_1 + defaultValue = CoreProperties.TIMEMACHINE_DEFAULT_PERIOD_1, + category = "Time Machine" ), @Property( key = "sonar.timemachine.period2", @@ -144,7 +158,8 @@ import java.util.List; description = "See the property 'Period 1'", project = false, global = true, - defaultValue = CoreProperties.TIMEMACHINE_DEFAULT_PERIOD_2 + defaultValue = CoreProperties.TIMEMACHINE_DEFAULT_PERIOD_2, + category = "Time Machine" ), @Property( key = "sonar.timemachine.period3", @@ -152,7 +167,8 @@ import java.util.List; description = "See the property 'Period 1'", project = false, global = true, - defaultValue = CoreProperties.TIMEMACHINE_DEFAULT_PERIOD_3 + defaultValue = CoreProperties.TIMEMACHINE_DEFAULT_PERIOD_3, + category = "Time Machine" ), @Property( key = "sonar.timemachine.period4", @@ -162,7 +178,8 @@ import java.util.List; "for example 2010-12-25</li><li>'previous_analysis' to compare to previous analysis</li><li>A version, for example 1.2</li></ul>", project = true, global = false, - defaultValue = CoreProperties.TIMEMACHINE_DEFAULT_PERIOD_4 + defaultValue = CoreProperties.TIMEMACHINE_DEFAULT_PERIOD_4, + category = "Time Machine" ), @Property( key = "sonar.timemachine.period5", @@ -170,7 +187,8 @@ import java.util.List; description = "See the property 'Period 4'", project = true, global = false, - defaultValue = CoreProperties.TIMEMACHINE_DEFAULT_PERIOD_5 + defaultValue = CoreProperties.TIMEMACHINE_DEFAULT_PERIOD_5, + category = "Time Machine" ) }) public class CorePlugin extends SonarPlugin { diff --git a/plugins/sonar-l10n-en-plugin/src/main/resources/org/sonar/l10n/core.properties b/plugins/sonar-l10n-en-plugin/src/main/resources/org/sonar/l10n/core.properties index 6695634552d..4d5541356c2 100644 --- a/plugins/sonar-l10n-en-plugin/src/main/resources/org/sonar/l10n/core.properties +++ b/plugins/sonar-l10n-en-plugin/src/main/resources/org/sonar/l10n/core.properties @@ -416,6 +416,16 @@ dashboard.update_dashboard=Update dashboard #------------------------------------------------------------------------------ # +# SETTINGS +# +#------------------------------------------------------------------------------ +settings.save_category=Save {0} settings +settings.category.General=General + + + +#------------------------------------------------------------------------------ +# # WIDGETS # #------------------------------------------------------------------------------ diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/Property.java b/sonar-plugin-api/src/main/java/org/sonar/api/Property.java index b71fe2af2d4..02f38d19331 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/Property.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/Property.java @@ -58,6 +58,11 @@ public @interface Property { String description() default ""; /** + * @since 2.11 + */ + String category() default ""; + + /** * Is the property displayed in projet settings page ? */ boolean project() default false; diff --git a/sonar-server/src/main/webapp/WEB-INF/app/controllers/project_controller.rb b/sonar-server/src/main/webapp/WEB-INF/app/controllers/project_controller.rb index 79ae8f0ed59..d5c5bceae45 100644 --- a/sonar-server/src/main/webapp/WEB-INF/app/controllers/project_controller.rb +++ b/sonar-server/src/main/webapp/WEB-INF/app/controllers/project_controller.rb @@ -71,6 +71,19 @@ class ProjectController < ApplicationController if !@project.project? && !@project.module? redirect_to :action => 'index', :id => params[:id] end + + @category=params[:category] ||= 'General' + @properties_per_category={} + java_facade.getPluginsMetadata().each do |plugin| + properties=java_facade.getPluginProperties(plugin).select { |property| + (@project.module? && property.module()) || (@project.project? && property.project()) + } + properties.each do |property| + category = (property.category().present? ? property.category() : plugin.name()) + @properties_per_category[category]||=[] + @properties_per_category[category]<<property + end + end end diff --git a/sonar-server/src/main/webapp/WEB-INF/app/controllers/settings_controller.rb b/sonar-server/src/main/webapp/WEB-INF/app/controllers/settings_controller.rb index 854c5f746db..a936793ac29 100644 --- a/sonar-server/src/main/webapp/WEB-INF/app/controllers/settings_controller.rb +++ b/sonar-server/src/main/webapp/WEB-INF/app/controllers/settings_controller.rb @@ -21,25 +21,28 @@ class SettingsController < ApplicationController SECTION=Navigation::SECTION_CONFIGURATION - verify :method => :post, :only => ['update'], :redirect_to => { :action => :index } + verify :method => :post, :only => ['update'], :redirect_to => {:action => :index} def index - return access_denied unless is_admin? + return access_denied unless is_admin? + load_properties() + @category ||= 'General' end def update if params[:resource_id] project=Project.by_key(params[:resource_id]) - return access_denied unless is_admin?(project) + return access_denied unless (project && is_admin?(project)) resource_id=project.id else return access_denied unless is_admin? + resource_id=nil end - plugins = java_facade.getPluginsMetadata() - plugins.each do |plugin| - properties=java_facade.getPluginProperties(plugin) - properties.each do |property| + load_properties() + + if @category && @properties_per_category[@category] + @properties_per_category[@category].each do |property| value=params[property.key()] persisted_property = Property.find(:first, :conditions => {:prop_key=> property.key(), :resource_id => resource_id, :user_id => nil}) @@ -48,20 +51,34 @@ class SettingsController < ApplicationController Property.delete_all('prop_key' => property.key(), 'resource_id' => resource_id, 'user_id' => nil) elsif persisted_property.text_value != value.to_s persisted_property.text_value = value.to_s - persisted_property.save + persisted_property.save! end - elsif !value.blank? + elsif !value.blank? Property.create(:prop_key => property.key(), :text_value => value.to_s, :resource_id => resource_id) end end + java_facade.reloadConfiguration() + flash[:notice] = 'Parameters updated' end - java_facade.reloadConfiguration() - flash[:notice] = 'Parameters updated.' if resource_id - redirect_to :controller => 'project', :action => 'settings', :id => resource_id + redirect_to :controller => 'project', :action => 'settings', :id => resource_id, :category => @category else - redirect_to :action => 'index' + redirect_to :controller => 'settings', :action => 'index', :category => @category + end + end + + private + + def load_properties + @category=params[:category] + @properties_per_category={} + java_facade.getPluginsMetadata().each do |plugin| + java_facade.getPluginProperties(plugin).select { |property| property.global }.each do |property| + category = (property.category().present? ? property.category() : plugin.name()) + @properties_per_category[category]||=[] + @properties_per_category[category]<<property + end end end end diff --git a/sonar-server/src/main/webapp/WEB-INF/app/views/project/settings/_delete_project.html.erb b/sonar-server/src/main/webapp/WEB-INF/app/views/project/settings/_delete_project.html.erb index 7e89d570273..282a23c7627 100644 --- a/sonar-server/src/main/webapp/WEB-INF/app/views/project/settings/_delete_project.html.erb +++ b/sonar-server/src/main/webapp/WEB-INF/app/views/project/settings/_delete_project.html.erb @@ -1,5 +1,5 @@ <% if @snapshot.root? %> -<h2>Delete project</h2> +<h1>Delete project</h1> <div class="yui-g widget" id="widget_delete_project"> <div class="warning"> This operation can not be undone. diff --git a/sonar-server/src/main/webapp/WEB-INF/app/views/project/settings/_exclusions.html.erb b/sonar-server/src/main/webapp/WEB-INF/app/views/project/settings/_exclusions.html.erb index 2e315bc8248..b2208db0f2b 100644 --- a/sonar-server/src/main/webapp/WEB-INF/app/views/project/settings/_exclusions.html.erb +++ b/sonar-server/src/main/webapp/WEB-INF/app/views/project/settings/_exclusions.html.erb @@ -1,4 +1,4 @@ -<h2>Exclude sources from code analysis</h2> +<h1>Exclude sources from code analysis</h1> <div class="yui-g widget" id="widget_exclusions"> diff --git a/sonar-server/src/main/webapp/WEB-INF/app/views/project/settings/_links.html.erb b/sonar-server/src/main/webapp/WEB-INF/app/views/project/settings/_links.html.erb index 4ae38c09f8d..8f79d83807e 100644 --- a/sonar-server/src/main/webapp/WEB-INF/app/views/project/settings/_links.html.erb +++ b/sonar-server/src/main/webapp/WEB-INF/app/views/project/settings/_links.html.erb @@ -1,4 +1,4 @@ -<h2>Project links</h2> +<h1>Project links</h1> <div class="yui-g widget" id="widget_links"> <% form_for( 'set_links', :url => { :action => 'set_links', :project_id => @project.id } ) do |form| diff --git a/sonar-server/src/main/webapp/WEB-INF/app/views/settings/_plugins.html.erb b/sonar-server/src/main/webapp/WEB-INF/app/views/settings/_plugins.html.erb index d0d7ad83c44..59e305d9573 100644 --- a/sonar-server/src/main/webapp/WEB-INF/app/views/settings/_plugins.html.erb +++ b/sonar-server/src/main/webapp/WEB-INF/app/views/settings/_plugins.html.erb @@ -1,130 +1,125 @@ <style type="text/css"> -#plugins .plugin { + #plugins .plugin { padding: 5px; border: 1px solid #ddd; background-color: #fff; - } -#plugins .plugin h2 { - margin-left: 10px; - font-size: 122%; - color: #333; -} -#plugins .plugin h3 { - margin-left: 5px; -} -#plugins .plugin p { - padding: 5px 5px; - } -#plugins .plugin img { - padding: 5px 0 0 5px; - } -</style> -<div id="plugins"> - <% form_tag :controller => :settings, :action => :update do - plugins = controller.java_facade.getPluginsMetadata().sort {|p1,p2| p1.getName() <=> p2.getName()} - plugin_properties={} - plugins.each do |plugin| - properties = controller.java_facade.getPluginProperties(plugin).select do |property| - (project && project.module? && property.module()) or (project && project.project? && property.project()) or (project.nil? && property.global) - end - plugin_properties[plugin]=properties - end - - %> - <% if project %> - <input type="hidden" name="resource_id" value="<%= project.id -%>" ></input> - <% end %> - <table width="100%"> - <tr> - <td width="1%" nowrap class="column first"> - <table class="data selector"> - <thead><tr><th> - <span>Select plugin</span> - </th></tr></thead> - <tbody> - <% plugins.each do |plugin| - if plugin_properties[plugin].empty? - # we display only plugins with properties - next - end - %> - <tr class="select <%= cycle('even', 'odd', :name => 'plugins') -%>" id="select_<%= plugin.getKey() -%>"> - <td><a href="#" onclick="showPlugin('<%= plugin.getKey() -%>')"><%= h(plugin.getName()) -%></a></td> - </tr> - <% end %> - </tbody> - </table> - <br/> - <%= submit_tag('Save parameters') %> - </td> - <td class="column"> - - <% - values = Property.hash(project ? project.id : nil) - plugins.each do |plugin| - properties = plugin_properties[plugin] - %> - <div class="plugin" id="plugin_<%= plugin.getKey() -%>" style="display: none;"> - <table class="spaced"> - <% unless plugin.getDescription().blank? %> - <tr><td class="odd"> - <p><%= plugin.getDescription() %></p> - </td></tr> - <% end %> + } + #plugins .plugin h2 { + margin-left: 10px; + font-size: 122%; + color: #333; + } - <% properties.each do |property| - value= values[property.key()] || '' - css = cycle('even', 'odd', :name => plugin.getKey()) - %> - <tr class="<%= css -%>"> - <td> - <h3><%= property.name() %> <% if property.project() %><span class="note">[<%= property.key() -%>]</span><% end %></h3> - <p><%= property.description() %></p> - <p> - <% span_id = "text_" + property.key().gsub('.', '_') %> - <% textfield = text_field_tag property.key(), value, :size => '20' %> - <% textfield += link_to_function(image_tag("zoom.png"), "replaceTextField('#{span_id}', '#{property.key()}')", :id => "toggle_text", :class => 'nolink') %> - <% textarea = text_area_tag property.key(), value, :size => "100x10" %> - <span id="<%= span_id %>"><%= (value.length < 50) ? textfield : textarea %></span> + #plugins .plugin h3 { + margin-left: 5px; + } - <% unless property.defaultValue().blank? %> - <% if project.nil? %> - <span class="note">Default : <%= h property.defaultValue() -%></span> - <% else %> - <span class="note">Default : <%= h Property.value(property.key(), nil, property.defaultValue()) -%></span> - <% end %> - <% end %> - </p> - </td> - </tr> - - <% end %> - </table> - </div> - <% end %> - </td> - </tr> - </table> - <% end %> -</div> + #plugins .plugin p { + padding: 5px 5px; + } + #plugins .plugin img { + padding: 5px 0 0 5px; + } +</style> <script type="text/javascript"> function replaceTextField(span_id, key) { var text_field_value = $F(key); var text_area = '<textarea cols="100" id="' + key + '" name="' + key + '" rows="10">' + text_field_value + '</textarea>'; $(span_id).replace(text_area); } - function showPlugin(id) { - $$('.plugin').each(function(element) { - element.hide(); - }); - $$('.select').each(function(element) { - element.removeClassName('selected'); - }); - $('plugin_' + id).show(); - $('select_' + id).addClassName('selected'); - return false; - } - showPlugin('core'); -</script>
\ No newline at end of file +</script> +<div id="plugins"> + <table width="100%"> + <tr> + <td width="1%" nowrap class="column first"> + <table class="data selector"> + <thead> + <tr> + <th> + <span>Category</span> + </th> + </tr> + </thead> + <tbody> + <% + @properties_per_category.keys.sort.each do |category| + unless @properties_per_category[category].empty? + %> + <tr class="select <%= cycle('even', 'odd', :name => 'category') -%> <%= 'selected' if @category==category -%>" id="select_<%= category -%>"> + <td><%= link_to h(category), :overwrite_params => {:category => category} -%></td> + </tr> + <% end + end + %> + </tbody> + </table> + <br/> + </td> + + <td class="column"> + <% if @category + category_name = message("settings.category.#{@category}", :default => @category) + %> + + <% form_tag :controller => :settings, :action => :update do %> + <%= hidden_field_tag('category', @category) -%> + <% if @project %> + <input type="hidden" name="resource_id" value="<%= @project.id -%>"/> + <% end %> + <table class="data marginbottom10"> + <thead> + <tr> + <th> + <span><%= h(category_name) -%></span> + </th> + </tr> + </thead> + <tbody> + <% + if @properties_per_category[@category] + @properties_per_category[@category].each do |property| + value = Property.value(property.key(), (@project ? @project.id : nil), '') + %> + <tr class="<%= cycle('even', 'odd', :name => 'properties') -%>"> + <td style="padding: 10px"> + <h3> + <%= h(property.name()) -%> + <% if property.project() %> + <br/><span class="note"><%= property.key() -%></span> + <% end %> + </h3> + <% if property.description.present? %> + <p class="marginbottom10"><%= property.description -%></p> + <% end %> + <p> + <% span_id = "text_" + property.key().gsub('.', '_') %> + <% textfield = text_field_tag property.key(), value, :size => '20' %> + <% textfield += link_to_function(image_tag("zoom.png"), "replaceTextField('#{span_id}', '#{property.key()}')", :id => "toggle_text", :class => 'nolink') %> + <% textarea = text_area_tag property.key(), value, :size => "100x10" %> + <span id="<%= span_id %>"><%= (value.length < 50) ? textfield : textarea %></span> + + <% unless property.defaultValue().blank? %> + <% if @project %> + <span class="note">Default : <%= h Property.value(property.key(), nil, property.defaultValue()) -%></span> + <% else %> + <span class="note">Default : <%= h property.defaultValue() -%></span> + <% end %> + <% end %> + </p> + </td> + </tr> + <% end + end + %> + </tbody> + </table> + <% save_message=message('settings.save_category', :params => [category_name]) %> + <%= submit_tag(save_message, :disable_with => save_message, :id => 'save') -%> + <% end %> + <% end %> + </td> + </tr> + </table> +</div> |