]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-2547 validate values
authorSimon Brandhof <simon.brandhof@gmail.com>
Wed, 27 Jul 2011 14:33:10 +0000 (16:33 +0200)
committerSimon Brandhof <simon.brandhof@gmail.com>
Wed, 27 Jul 2011 14:33:17 +0000 (16:33 +0200)
13 files changed:
sonar-server/src/main/webapp/WEB-INF/app/controllers/manual_measures_controller.rb
sonar-server/src/main/webapp/WEB-INF/app/helpers/application_helper.rb
sonar-server/src/main/webapp/WEB-INF/app/models/api/utils.rb
sonar-server/src/main/webapp/WEB-INF/app/models/filter_column.rb
sonar-server/src/main/webapp/WEB-INF/app/models/manual_measure.rb
sonar-server/src/main/webapp/WEB-INF/app/models/metric.rb
sonar-server/src/main/webapp/WEB-INF/app/models/project_link.rb
sonar-server/src/main/webapp/WEB-INF/app/models/project_measure.rb
sonar-server/src/main/webapp/WEB-INF/app/models/rule.rb
sonar-server/src/main/webapp/WEB-INF/app/models/rules_parameter.rb
sonar-server/src/main/webapp/WEB-INF/app/models/sonar/rule_priority.rb
sonar-server/src/main/webapp/WEB-INF/app/views/manual_measures/index.html.erb
sonar-server/src/main/webapp/WEB-INF/app/views/manual_measures/new.html.erb

index c30fa98c1ad48956b2b6fc63c6bd500fc1b6f817..b7d85bac9512f2f268d2acaaa2dbc22f1ed3bd47 100644 (file)
@@ -39,19 +39,22 @@ class ManualMeasuresController < ApplicationController
   end
 
   def save
-    metric=Metric.by_key(params[:metric])
-    measure=ManualMeasure.find(:first, :conditions => ['resource_id=? and metric_id=?', @resource.id, metric.id])
-    if measure.nil?
-      measure=ManualMeasure.new(:resource => @resource, :user_login => current_user.login, :metric_id => metric.id)
+    @metric=Metric.by_key(params[:metric])
+    @measure=ManualMeasure.find(:first, :conditions => ['resource_id=? and metric_id=?', @resource.id, @metric.id])
+    if @measure.nil?
+      @measure=ManualMeasure.new(:resource => @resource, :user_login => current_user.login, :metric_id => @metric.id)
     end
-    # TODO use measure.text_value if string metric
-    measure.value = params[:val]
-    measure.description = params[:desc]
-    measure.save!
-    if (params[:redirect_to_new]=='true')
-      redirect_to :action => 'new', :id => params[:id]
+    @measure.typed_value=params[:val]
+    @measure.description=params[:desc]
+    if @measure.valid?
+      @measure.save
+      if (params[:redirect_to_new]=='true')
+        redirect_to :action => 'new', :id => params[:id]
+      else
+        redirect_to :action => 'index', :id => params[:id], :metric => params[:metric]
+      end
     else
-      redirect_to :action => 'index', :id => params[:id], :metric => params[:metric]
+      render :action => :new, :metric => @metric.id, :id => params[:id]
     end
   end
 
index fffd7a91f253c94a3c516b840b86d10fae926602..935a7231d3353fe3fdc8c8de57d0e416a51668ee 100644 (file)
@@ -57,12 +57,7 @@ module ApplicationHelper
 
   # i18n
   def message(key, options={})
-    default = options[:default]
-    params = options[:params]
-    if params.nil? 
-      params=[]
-    end
-    Java::OrgSonarServerUi::JRubyFacade.getInstance().getI18nMessage(I18n.locale, key, default, params.to_java)    
+    Api::Utils.message(key, options)
   end
 
   # deprecated since 2.5. Use trend_icon() instead
index 5a196ca16b7eca57a35ab60f74aa42a544de492f..7ff974147af5619e516e82bebfffcfcb000969bf 100644 (file)
@@ -57,4 +57,16 @@ class Api::Utils
     # See http://jira.codehaus.org/browse/SONAR-2571
     split_newlines(input).join("\n")
   end
+
+  #
+  # i18n
+  # Since 2.10
+  def self.message(key, options={})
+    default = options[:default]
+    params = options[:params]
+    if params.nil?
+      params=[]
+    end
+    Java::OrgSonarServerUi::JRubyFacade.getInstance().getI18nMessage(I18n.locale, key, default, params.to_java)
+  end
 end
index fe9d8cd678acbd8e7309e939baf4d879d622885c..0694e37d8bd0eb49f1ba860e12f673bfddfdb251 100644 (file)
@@ -39,9 +39,9 @@ class FilterColumn < ActiveRecord::Base
 
   def name
     if on_metric?
-      Java::OrgSonarServerUi::JRubyFacade.getInstance().getI18nMessage(I18n.locale, "metric." + kee + ".name", metric.short_name, [].to_java)
+      Api::Utils.message("metric." + kee + ".name", :default => metric.short_name)
     else
-      Java::OrgSonarServerUi::JRubyFacade.getInstance().getI18nMessage(I18n.locale, family, kee, [].to_java)
+      Api::Utils.message(family, :default => kee)
     end
   end
 
index f8a6cc5a02b126f1973984f7a2ef7ccab634522a..158892608253e2fef587c5068335588886247119 100644 (file)
 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02
 #
 class ManualMeasure < ActiveRecord::Base
+  include ActionView::Helpers::NumberHelper
+  
   belongs_to :resource, :class_name => 'Project'
   validates_uniqueness_of :metric_id, :scope => :resource_id
   validates_length_of :text_value, :maximum => 4000, :allow_nil => true, :allow_blank => true
   validates_length_of :description, :maximum => 4000, :allow_nil => true, :allow_blank => true
-  validate :validate_metric
+  validate :validate_metric, :validate_value
 
   def metric
     @metric ||=
@@ -47,6 +49,64 @@ class ManualMeasure < ActiveRecord::Base
     write_attribute(:metric_id, m.id) if m.id
   end
 
+  def typed_value=(v)
+    if metric && metric.numeric?
+      self.value=v
+    else
+      self.text_value=v
+    end
+  end
+
+  def pending?(snapshot=nil)
+    if snapshot.nil?
+      snapshot=resource.last_snapshot
+    end
+    snapshot && updated_at && snapshot.created_at<updated_at
+  end
+
+  def formatted_value
+    if metric.nil?
+      return value.to_s
+    end
+
+    case metric().val_type
+      when Metric::VALUE_TYPE_INT
+        number_with_precision(value(), :precision => 0)
+      when Metric::VALUE_TYPE_FLOAT
+        number_with_precision(value(), :precision => 1)
+      when Metric::VALUE_TYPE_PERCENT
+        number_to_percentage(value(), {:precision => 1})
+      when Metric::VALUE_TYPE_MILLISEC
+        millisecs_formatted_value(value())
+      when Metric::VALUE_TYPE_BOOLEAN
+        value() == 1 ? 'Yes' : 'No'
+      when Metric::VALUE_TYPE_LEVEL
+        Sonar::RulePriority.to_s(value)
+      when Metric::VALUE_TYPE_STRING
+        text_value
+      when Metric::VALUE_TYPE_RATING
+        text_value || value.to_i.to_s
+      else
+        value().to_s
+    end
+  end
+
+  def editable_value
+    if metric.nil?
+      return ''
+    end
+
+    if metric.numeric?
+      value ? value.to_s : ''
+    elsif metric.value_type==Metric::VALUE_TYPE_BOOLEAN
+      value ? (value==1 ? 'Yes' : 'No') : ''
+    elsif metric.value_type==Metric::VALUE_TYPE_LEVEL
+      text_value ? Sonar::RulePriority.to_s(text_value) : ''
+    else
+      text_value
+    end
+  end
+
   def validate_metric
     if metric.nil? || !metric.enabled?
       errors.add_to_base("Unknown metric")
@@ -55,10 +115,29 @@ class ManualMeasure < ActiveRecord::Base
     end
   end
 
-  def pending?(snapshot=nil)
-    if snapshot.nil?
-      snapshot=resource.last_snapshot
+  def validate_value
+    if metric
+      case metric.value_type
+        when Metric::VALUE_TYPE_INT
+          errors.add('value', "An integer value must be provided") if value_before_type_cast.nil? || !Api::Utils.is_integer?(value_before_type_cast)
+        when Metric::VALUE_TYPE_FLOAT
+          errors.add('value', "A numerical value must be provided") if value_before_type_cast.nil? || !Api::Utils.is_number?(value_before_type_cast)
+        when Metric::VALUE_TYPE_PERCENT
+          errors.add('value', "A numerical value must be provided") if value_before_type_cast.nil? || !Api::Utils.is_number?(value_before_type_cast)
+        when Metric::VALUE_TYPE_MILLISEC
+          errors.add('value', "Value must equal or be greater than 0") if value_before_type_cast.nil? || !Api::Utils.is_number?(value_before_type_cast) || value<0
+        when Metric::VALUE_TYPE_BOOLEAN
+          raw_value = text_value.downcase
+          errors.add('value', "Value must be 'No' or 'Yes'") if raw_value != "yes" && raw_value != "no"
+          write_attribute("value", 1.0) if raw_value == "yes"
+          write_attribute("value", 0.0) if raw_value == "no"
+        when Metric::VALUE_TYPE_LEVEL
+          raw_value = text_value.upcase
+          errors.add('value', "Value must be BLOCKER, CRITICAL, MAJOR, MINOR or INFO") if !['BLOCKER', 'CRITICAL', 'MAJOR', 'MINOR', 'INFO'].include?(raw_value)
+          write_attribute("value", Sonar::RulePriority.id(raw_value))
+          write_attribute("text_value", raw_value)
+      end
     end
-    snapshot && updated_at && snapshot.created_at<updated_at
   end
+
 end
\ No newline at end of file
index 45bb9cad720a861360e8eea985e34750da4c7024..614d6b218248b0f97000b70b74c8a178a69f5ec0 100644 (file)
@@ -77,8 +77,8 @@ class Metric < ActiveRecord::Base
     return localeMap[locale] if not localeMap.nil? and localeMap.has_key?(locale)
     
     i18n_key = 'domain.' + to_translate
-    result = Java::OrgSonarServerUi::JRubyFacade.getInstance().getI18nMessage(I18n.locale, i18n_key, to_translate, [].to_java) 
-    localeMap[locale] = result if not localeMap.nil? 
+    result = Api::Utils.message(i18n_key, :default => to_translate)
+    localeMap[locale] = result if localeMap
     result
   end
  
@@ -109,7 +109,7 @@ class Metric < ActiveRecord::Base
     return localeMap[locale] if localeMap && localeMap.has_key?(locale)
     
     i18n_key = 'metric.' + metric_key + '.name'
-    result = Java::OrgSonarServerUi::JRubyFacade.getInstance().getI18nMessage(I18n.locale, i18n_key, default_string, [].to_java) 
+    result = Api::Utils.message(i18n_key, :default => default_string)
     localeMap[locale] = result if localeMap
     result
   end
@@ -127,7 +127,7 @@ class Metric < ActiveRecord::Base
     return nil if metric_name.nil?
     
     i18n_key = 'metric.' + metric_name + '.description'
-    result = Java::OrgSonarServerUi::JRubyFacade.getInstance().getI18nMessage(I18n.locale, i18n_key, default_string, [].to_java)
+    result = Api::Utils.message(i18n_key, :default => default_string)
     result
   end
 
index d5079f420c466da88b5ec01de283ce89c8ce1c51..f00e819f839d77745a84e9f80ef41580fb6ae82a 100644 (file)
@@ -46,7 +46,7 @@ class ProjectLink < ActiveRecord::Base
     return default_string unless translate
     
     i18n_key = 'project_links.' + read_attribute(:link_type)
-    Java::OrgSonarServerUi::JRubyFacade.getInstance().getI18nMessage(I18n.locale, i18n_key, default_string, [].to_java)
+    Api::Utils.message(i18n_key, :default => default_string)
   end
 
   def self.name_to_key(s)
index 1921ddfe8c3f4ca8ded0de500847536ff71236e3..0532898a30c57cbf029bc5e81beac73b111e4e93 100644 (file)
@@ -31,9 +31,6 @@ class ProjectMeasure < ActiveRecord::Base
   belongs_to :characteristic
   has_one :measure_data, :class_name => 'MeasureData', :foreign_key => 'measure_id'
 
-  validates_numericality_of :value, :if => :numerical_metric?
-  validate :validate_date, :validate_value
-
   def metric
     @metric ||=
       begin
@@ -263,7 +260,7 @@ class ProjectMeasure < ActiveRecord::Base
   end
 
   def <=>(other)
-    return value<=>other.value
+    value<=>other.value
   end
 
   private
@@ -272,39 +269,5 @@ class ProjectMeasure < ActiveRecord::Base
     [Metric::VALUE_TYPE_INT, Metric::VALUE_TYPE_FLOAT, Metric::VALUE_TYPE_PERCENT, Metric::VALUE_TYPE_MILLISEC].include?(metric.val_type)
   end
 
-  def validate_date
-    if measure_date.nil?
-      errors.add_to_base('A valid date must be provided')
-    else
-      last_snasphot_date = project.last_snapshot.created_at
-      if project.last_snapshot.created_at < measure_date
-        errors.add_to_base("The date should not be after #{last_snasphot_date.strftime('%Y-%m-%d')}")
-      end
-    end
-  end
-
-  def validate_value
-    case metric.value_type
-    when Metric::VALUE_TYPE_INT
-      errors.add_to_base("A numerical value must be provided") if value.nil?
-    when Metric::VALUE_TYPE_FLOAT
-      errors.add_to_base("A numerical value must be provided") if value.nil?
-    when Metric::VALUE_TYPE_PERCENT
-      errors.add_to_base("A numerical value must be provided") if value.nil?
-    when Metric::VALUE_TYPE_MILLISEC
-      errors.add_to_base("Value must be greater than 0") if value < 0
-    when Metric::VALUE_TYPE_BOOLEAN
-      raw_value = send("value_before_type_cast")
-      if raw_value.instance_of?(String)
-        raw_value = raw_value.downcase
-        errors.add_to_base("Value must be 'No' or 'Yes'") if raw_value != "yes" && raw_value != "no"
-        write_attribute( "value", 1.0) if raw_value == "yes"
-        write_attribute( "value", 0.0) if raw_value == "no"
-      end
-    when Metric::VALUE_TYPE_STRING
-      errors.add_to_base("A text value must be provided") if text_value.blank?
-    end
-  end
-
 
 end
\ No newline at end of file
index cbb737680943c2d3ff13a63f47f9731dbe68b979..0fbb2e788232514cc499c8162ca2105eaafdf390 100644 (file)
@@ -68,7 +68,7 @@ class Rule < ActiveRecord::Base
     return nil if (rule_plugin_name.nil? or rule_plugin_rule_key.nil?)
     
     i18n_key = 'rule.' + rule_plugin_name + '.' + rule_plugin_rule_key + '.name'   
-    result = Java::OrgSonarServerUi::JRubyFacade.getInstance().getI18nMessage(I18n.locale, i18n_key, default_string, [].to_java)     
+    result = Api::Utils.message(i18n_key, :default => default_string)
     result
   end
   
@@ -86,7 +86,7 @@ class Rule < ActiveRecord::Base
     return nil if (rule_plugin_name.nil? or rule_plugin_rule_key.nil?)
     
     i18n_key = 'rule.' + rule_plugin_name + '.' + rule_plugin_rule_key + '.description'   
-    result = Java::OrgSonarServerUi::JRubyFacade.getInstance().getI18nMessage(I18n.locale, i18n_key, default_string, [].to_java)     
+    result = Api::Utils.message(i18n_key, :default => default_string)
     result
   end
 
index acd78c8ecf21214f5cba86e12a802d54b886fe09..efe684b8c586062678f9bc0c552ab4a3db2bcaca 100644 (file)
@@ -50,7 +50,7 @@ class RulesParameter < ActiveRecord::Base
     return nil if (rule_plugin_name.nil? or rule_plugin_rule_key.nil?)
     
     i18n_key = 'rule.' + rule_plugin_name + '.' + rule_plugin_rule_key + '.param.' + read_attribute(:name)
-    result = Java::OrgSonarServerUi::JRubyFacade.getInstance().getI18nMessage(I18n.locale, i18n_key, default_string, [].to_java)     
+    result = Api::Utils.message(i18n_key, :default => default_string)
     result
   end
   
index b2767214303ca0399e1c662834aba6c83e388164..c13f215fe3bf75674e9632f5f8069253d32ca9d2 100644 (file)
@@ -52,7 +52,7 @@ class Sonar::RulePriority
     return text unless translate
     
     i18n_key = 'severity.' + text
-    result = Java::OrgSonarServerUi::JRubyFacade.getInstance().getI18nMessage(I18n.locale, i18n_key, as_text_map[text], [].to_java)
+    result = Api::Utils.message(i18n_key, :default => as_text_map[text])
     result
   end
   
@@ -64,7 +64,7 @@ class Sonar::RulePriority
       nil
     end
   end
-  
+
   def self.as_array
     @@priorities_a ||= []
     return @@priorities_a if @@priorities_a.size > 0
index 634dc52890172ffa7f3e81f6e104d8dcb9596275..b6d5665f784e4a472660718e0e90fe68b9c73093 100644 (file)
@@ -26,9 +26,9 @@
   <thead>
   <tr>
     <th style="padding: 0; margin: 0" class="nosort"></th>
-    <th class="thin nowrap sortfirstasc"><%= message('manual_measures.col.domain') -%></th>
-    <th class="thin nowrap"><%= message('manual_measures.col.metric') -%></th>
-    <th class="thin nowrap" style="text-align: right"><%= message('manual_measures.col.value') -%></th>
+    <th class="thin nowrap"><%= message('manual_measures.col.domain') -%></th>
+    <th class="thin nowrap sortfirstasc"><%= message('manual_measures.col.metric') -%></th>
+    <th class="thin nowrap nosort" style="text-align: right"><%= message('manual_measures.col.value') -%></th>
     <th><%= message('manual_measures.col.description') -%></th>
     <th style="text-align: right"><%= message('manual_measures.col.author') -%></th>
     <th style="text-align: right"><%= message('manual_measures.col.date') -%></th>
@@ -51,7 +51,7 @@
       <% end %>
       <td class="thin nowrap"><%= measure.metric.domain -%></td>
       <td class="thin nowrap"><%= measure.metric.short_name -%></td>
-      <td class="thin nowrap" align="right"><%= measure.value -%></td>
+      <td class="thin nowrap" align="right"><%= measure.formatted_value -%></td>
       <td id="desc"><%= measure.description -%></td>
       <td align="right"><%= measure.username -%>
       </td>
index 6ba201f4bfef5d80665f7934123413ae14206c4d..ab98dee404f55fc8370d7261fec378d67f61f3f8 100644 (file)
@@ -9,13 +9,21 @@
   }
 </script>
 <h1 class="marginbottom10"><%= message('manual_measures.add_measure_title') -%></h1>
+
+<% if @measure && @measure.errors.on_base
+     @measure.errors.on_base.each do |error| %>
+  <div class="error"><%= error -%></div>
+<%   end
+   end
+%>
+
 <form action="<%= url_for :action => (@measure ? 'save' : 'new') -%>" method="POST" id="createForm">
   <input type="hidden" name="id" value="<%= @resource.id -%>"/>
   <table class="width100 form">
     <tbody>
     <tr>
       <td class="keyCell">
-        Metric:
+        <%= message('manual_measures.col.metric') -%>:
       </td>
       <td>
         <select name="metric" onchange="changeMetric();" id="metricSelect">
           <%= message('manual_measures.col.value') -%>:
         </td>
         <td>
-          <input type="text" name="val" id="valueText" value="<%= @measure.value -%>"/>
+          <input type="text" name="val" id="valueText" value="<%= @measure ? @measure.editable_value : '' -%>"/>
+          <%= '%' if @metric && @metric.value_type==Metric::VALUE_TYPE_PERCENT -%>
+          <% if @measure.errors.on('value')
+               @measure.errors.on('value').each do |error| %>
+            <span class="error"><%= error -%></span>
+          <%   end
+             end %>
         </td>
       </tr>
       <tr>
         </td>
         <td>
           <textarea rows="5" cols="80" name="desc" class="width100"><%= @measure.description -%></textarea>
+          <% if @measure.errors.on('description')
+               @measure.errors.on('description').each do |error| %>
+            <span class="error"><%= error -%></span>
+          <%   end
+             end %>
         </td>
       </tr>
       <% unless @measure.new_record?() %>