+++ /dev/null
-#
-# SonarQube, open source software quality management tool.
-# Copyright (C) 2008-2014 SonarSource
-# mailto:contact AT sonarsource DOT com
-#
-# SonarQube 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.
-#
-# SonarQube 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 this program; if not, write to the Free Software Foundation,
-# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-#
-class AllProjectsController < ApplicationController
-
- SECTION=Navigation::SECTION_HOME
-
- def index
- @qualifier = params[:qualifier]||'TRK'
- bad_request("The 'qualifier' parameter is not valid. It must reference a root type.") unless Project.root_qualifiers.include?(@qualifier)
-
- @filter = MeasureFilter.new
- @filter.criteria={:qualifiers => @qualifier, :sort => 'name', :asc => (params[:asc]!='false'), :pageSize=>200, :page => params[:page]}
- @filter.require_links=true
- @filter.execute(self, :user => current_user)
- end
-
-end
Api::Utils.message(key, options)
end
- # deprecated since 2.5. Use trend_icon() instead
- def tendency_icon(metric_or_measure, small=true, no_tendency_img=true)
- trend_icon(nil, {:empty => !no_tendency_img})
- end
-
- def boolean_icon(boolean_value, options={})
- if boolean_value
- "<i class='icon-check'></i>"
- elsif options[:display_false]
- image_tag('cross.png', options)
- else
- nil
- end
- end
-
def configuring?
params['configuring']=='true'
end
Metric.by_key(key)
end
- # URL to static resource.
- #
- # === Optional parameters
- #
- # * <tt>:plugin</tt> - key of plugin, from where this resource should be loaded.
- #
- # === Examples
- #
- # url_for_static(:path => 'images/sonarqube-24x100.png')
- # url_for_static(:plugin => 'myplugin', :path => 'image.png')
- def url_for_static(options={})
- if options[:plugin]
- "#{ApplicationController.root_context}/static/#{options[:plugin]}/#{options[:path]}"
- else
- "#{ApplicationController.root_context}/#{options[:path]}"
- end
- end
-
- # URL to measures drilldown page for a given metric.
- #
- # === Optional parameters
- #
- # * <tt>:resource</tt> - id or key of the selected resource
- # * <tt>:highlight</tt> - key of the metric to highlight, different than the metric to drilldown.
- # * <tt>:period</tt> - period index
- #
- # === Examples
- #
- # url_for_drilldown('ncloc')
- # url_for_drilldown('ncloc', {:resource => 'org.apache.struts:struts-parent', :highlight => 'lines'})
- # url_for_drilldown('ncloc', {:resource => 'org.apache.struts:struts-parent'})
- #
- def url_for_drilldown(metric_or_measure, options={})
- if options[:resource].nil? && !@resource
- return ''
- end
-
- if metric_or_measure.is_a? ProjectMeasure
- metric_key = metric_or_measure.metric.key
- elsif metric_or_measure.is_a? Metric
- metric_key = metric_or_measure.key
- else
- metric_key = metric_or_measure
- end
-
- issues_metrics = get_issue_metrics
-
- if issues_metrics.include? metric_key
- resource = options[:resource]||@resource.key
- url = url_for({:controller => 'component_issues', :action => 'index'}) + '?id=' + url_encode(resource) + '#'
- if options[:period] && @snapshot
- snapshot_datetime = @snapshot.period_datetime(options[:period])
- if snapshot_datetime
- date = snapshot_datetime.strftime('%FT%T%z')
- url += "createdAfter=#{date}|"
- end
- end
- case metric_key
- when 'blocker_violations', 'new_blocker_violations'
- url += 'resolved=false|severities=BLOCKER'
- when 'critical_violations', 'new_critical_violations'
- url += 'resolved=false|severities=CRITICAL'
- when 'major_violations', 'new_major_violations'
- url += 'resolved=false|severities=MAJOR'
- when 'minor_violations', 'new_minor_violations'
- url += 'resolved=false|severities=MINOR'
- when 'info_violations', 'new_info_violations'
- url += 'resolved=false|severities=INFO'
- when 'open_issues'
- url += 'resolved=false|statuses=OPEN'
- when 'reopened_issues'
- url += 'resolved=false|statuses=REOPENED'
- when 'confirmed_issues'
- url += 'resolved=false|statuses=CONFIRMED'
- when 'false_positive_issues'
- url += 'resolutions=FALSE-POSITIVE'
- else
- url += 'resolved=false'
- end
- else
- url = url_for(options.merge({:controller => 'drilldown', :action => 'measures', :metric => metric_key, :id => options[:resource]||@resource.id}))
- end
-
- url
- end
-
- #
- # Display a measure
- #
- # === Optional parameters
- # * <tt>:skip_span_id</tt> - skip the generation of the html attribute 'id'. Default is false
- # * <tt>:url</tt> - add an url on the measure.
- # * <tt>:prefix</tt> - add a prefix. Default is ''.
- # * <tt>:suffix</tt> - add a suffix. Default is ''.
- # * <tt>:period</tt> - period index, from 1 to 5. Optional. Default is nil.
- # * <tt>:default</tt> - text to return if metric or measure not found. Default is blank string.
- #
- # === Examples
- #
- # format_measure('ncloc')
- # format_measure('ncloc', {:suffix => '', :url => url_for_drilldown('ncloc'), :default => '-'})
- #
- def format_measure(metric_or_measure, options={})
- html=''
- m=nil
- if metric_or_measure.is_a? ProjectMeasure
- m = metric_or_measure
- elsif @snapshot
- m = @snapshot.measure(metric_or_measure)
- end
-
- if m.nil?
- return options[:default] || ''
- end
-
- if m && m.metric
- link_rel=''
- show_link= !options[:url].blank?
-
- if options[:period]
- html=m.format_numeric_value(m.variation(options[:period].to_i))
- elsif m.metric.val_type==Metric::VALUE_TYPE_LEVEL
- if m.alert_status.blank?
- html = m.formatted_value
- else
- html = "<i class=\"icon-alert-#{m.alert_status.downcase}\"></i>"
- end
- elsif m.metric.val_type == Metric::VALUE_TYPE_RATING
- html = m.formatted_value
- if html.ord < 65 || html.ord > 69
- html = (Integer(html) + 64).chr
- end
- else
- html = m.formatted_value
- end
-
- alert_class=''
- style = ''
- if !(m.alert_status.blank?)
- alert_class="class='alert_#{m.alert_status}'" unless m.metric.val_type==Metric::VALUE_TYPE_LEVEL
- link_rel=h(m.alert_text)
- elsif m.metric.val_type==Metric::VALUE_TYPE_RATING
- alert_class="class='rating rating-" + html + "'"
- end
-
- span_id=''
- unless options[:skip_span_id]
- span_id="id='m_#{m.key}'"
- end
- html="<span #{span_id} #{alert_class} #{style}>#{html}</span>"
- if options[:prefix]
- html="#{options[:prefix]}#{html}"
- end
- if options[:suffix]
- html="#{html}#{options[:suffix]}"
- end
-
- if show_link
- if options[:url].blank?
- url='#'
- link_class='nolink'
- else
- url=options[:url]
- link_class=''
- end
- # Do not put url between simple quotes to prevent problem if url contain simple quote
- html='<a href="'+ url +'"'+ " class='widget-link #{link_class}' rel='#{link_rel}' title='#{link_rel}'>#{html}</a>"
- end
- end
- html
- end
-
-
- #
- #
- # link to the current page with the given resource. If file, then open a popup to display resource viewers.
- #
- #
- def link_to_resource(resource, name=nil, options={})
- period_index=options[:period]
- period_index=nil if period_index && period_index<=0
- if resource.display_dashboard?
- if options[:dashboard]
- root = "#{ApplicationController.root_context}/dashboard/index?"
- else
- # stay on the same page (for example components)
- root = "#{ApplicationController.root_context}/#{u params[:controller]}/#{u params[:action]}?"
- end
- path = ''
- query = request.query_parameters
- query[:id] = resource.id
- query[:metric] = options[:metric] if options[:metric]
- query[:period] = period_index if period_index
- query.each do |key, value|
- path += '&' unless path.empty?
- path += "#{u key}=#{u value}"
- end
- "<a class='#{options[:class]}' title='#{options[:title]}' href='#{root + path}'>#{name || resource.name}</a>"
- else
- url = "#{ApplicationController.root_context}/dashboard/index?id=#{u resource.key}"
- url += "&period=#{u period_index}" if period_index
- url += "&metric=#{u options[:metric]}" if options[:metric]
- "<a class='#{options[:class]}' title='#{options[:title]}' " +
- "onclick='window.open(this.href,\"resource-#{resource.key.parameterize}\",\"\");return false;' " +
- "href='#{url}'>#{name || resource.name}</a>"
- end
- end
-
-
- #
- #
- # Piechart for a distribution string or measure (foo=1;bar=2)
- #
- #
- def piechart(distribution, options={})
- chart = ""
- data=nil
- if distribution
- data=(distribution.kind_of? ProjectMeasure) ? distribution.data : distribution
- end
-
- if data && data.size > 0
- labels = []
- values = []
- skipZeros = options[:skipZeros].nil? ? true : options[:skipZeros]
- options[:skipZeros] = nil
- data.split(';').each do |pair|
- splitted = pair.split('=')
- value = splitted[1]
- next if skipZeros && value.to_i == 0
- labels << splitted[0]
- values << value
- end
- if labels.size > 0
- options[:alt] ||= ""
- chart = gchart("chs=#{options[:size] || '250x90'}&chd=t:#{values.join(',')}&cht=p&chl=#{labels.join('|')}", options)
- end
- end
- chart
- end
-
- #
- #
- # Draw a HTML/CSS bar
- #
- # === Optional parameters
- # * width: container width in pixels. Default is 150.
- # * percent: integer between -100 and 100. Size of the bar inside the container. Default is 100. Bar is aligned to right if the value is negative.
- # * color: the bar HTML color. Default value is '#777'
- # * tooltip: tooltip to display on the bar
- #
- def barchart(options)
- percent = (options[:percent] || 100).to_i
- width=(options[:width] || 150).to_i
- if options[:positive_color] && percent>0
- color = options[:positive_color]
- elsif options[:negative_color] && percent<0
- color = options[:negative_color]
- else
- color = options[:color]||'#236a97'
- end
-
- align=(percent<0 ? 'float: right;' : nil)
- "<div class='barchart' style='width: #{width}px' title='#{options[:tooltip]}'><div style='width: #{percent.abs}%;background-color:#{color};#{align}'></div></div>"
- end
-
- def chart(parameters, options={})
- image_tag("#{ApplicationController.root_context}/chart?#{parameters}", options)
- end
-
- def link_to_favourite(resource, deprecated_options=nil)
- return '' unless (logged_in?)
- return '' if resource.nil?
- resource_id=(resource.is_a?(Fixnum) ? resource : resource.permanent_id)
-
- if current_user.favourite?(resource_id)
- css='icon-favorite'
- title=message('click_to_remove_from_favorites')
- else
- css='icon-not-favorite'
- title=message('click_to_add_to_favorites')
- end
- link_to_function '', "toggleFav(#{resource_id}, this)", :class => css, :title => title
- end
-
- #
- # Unsupported since version 5.2
- #
- def trend_icon(metric_or_measure, options={})
- return options[:empty] ? "<i class=\"icon-trend-0\"></i>" : nil
- end
-
#
#
# Numeric value of variation
+++ /dev/null
-#
-# SonarQube, open source software quality management tool.
-# Copyright (C) 2008-2014 SonarSource
-# mailto:contact AT sonarsource DOT com
-#
-# SonarQube 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.
-#
-# SonarQube 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 this program; if not, write to the Free Software Foundation,
-# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-#
-module ComponentsHelper
- include ActionView::Helpers::UrlHelper
-
- def get_header_content(column, snapshot)
- get_column_content(column, snapshot, {snapshot => snapshot.measures}, 'th')
- end
-
- def get_column_content(column, snapshot, measures_by_snapshot, html_node='td')
- project = snapshot.project
- content = ''
- nowrap = true
- measure_param = '0'
-
- if column.language_column?
- content = project.language || ''
-
- elsif column.version_column?
- content = snapshot.version || ''
-
- elsif column.links_column?
- links = links_by_project_uuid[project.uuid]
- if links
- links.each do |link|
- content << link_to("<i class='icon-#{link.link_type}' alt='#{link.name}'></i>", link.href, :popup => true) unless link.custom?
- content << ' '
- end
- end
- elsif column.build_time_column?
- measure_param = snapshot.created_at.tv_sec
- content = human_short_date( snapshot.created_at )
-
- elsif column.metric_column?
- measure = item_by_metric_id(measures_by_snapshot[snapshot], column.id )
- measure_param = measure.value if measure
- content = format_measure(measure)
- end
-
- "<#{html_node} #{"nowrap='nowrap'" if nowrap} #{"x='#{measure_param}'" if measure_param} class='right'><span class='no-transform'>" + content + "</span></#{html_node}>"
- end
-
-
- def search_measure(measures, metric_key)
- item_by_metric_id(measures, metric_key )
- end
-
- private
-
- def item_by_metric_id(items, metric_name)
- return nil if items.nil?
- items.each do |item|
- metric = Metric.by_name(metric_name)
- return item if (item && metric && item.metric_id==metric.id && item.person_id.nil?)
- end
- nil
- end
-
- def links_by_project_uuid
- @links_by_project_uuid ||= {}
- if @links_by_project_uuid.empty?
- ProjectLink.find(:all, :order => 'link_type').each do |link|
- @links_by_project_uuid[link.component_uuid] ||= []
- @links_by_project_uuid[link.component_uuid]<<link
- end
- end
- @links_by_project_uuid
- end
-
-end
+++ /dev/null
-#
-# SonarQube, open source software quality management tool.
-# Copyright (C) 2008-2014 SonarSource
-# mailto:contact AT sonarsource DOT com
-#
-# SonarQube 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.
-#
-# SonarQube 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 this program; if not, write to the Free Software Foundation,
-# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-#
-module MeasuresHelper
-
- def list_column_html(filter, column, widget_id)
- if column.sort?
- html = link_to_function(h(column.title_label), "refreshList#{widget_id}('#{h escape_javascript column.key}',#{!filter.sort_asc?}, '#{h(escape_javascript(filter.criteria[:page])) || 1}')", :title => h(column.tooltip))
- else
- html=h(column.title_label)
- end
- if column.period
- html += "<br><span class='note'>#{Api::Utils.period_abbreviation(column.period)}</small>"
- end
- if column.sort? && filter.sort_key==column.key
- html << (filter.sort_asc? ? ' <i class="icon-sort-asc"></i>' : ' <i class="icon-sort-desc"></i>')
- end
- "<th class='#{column.align} #{column.title_css}'>#{html}</th>"
- end
-
- def list_cell_html(column, row)
- if column.metric
- measure = row.measure(column.metric)
- if column.period
- if measure && measure.metric.on_new_code?
- format_new_metric_measure(measure, column.period)
- else
- format_variation(measure, :index => column.period, :style => 'light')
- end
- else
- format_measure(measure) + ' '
- end
-
- elsif column.key=='name'
- "#{qualifier_icon(row.resource)} #{link_to(h(row.resource.name(true)), {:controller => 'dashboard', :id => row.resource.id}, {:title => h(row.resource.key)})}"
- elsif column.key=='short_name'
- "#{qualifier_icon(row.resource)} #{link_to(h(row.resource.name(false)), {:controller => 'dashboard', :id => row.resource.id}, {:title => h(row.resource.key)})}"
- elsif column.key=='date'
- human_short_date(row.analysis.created_at) if row.analysis
- elsif column.key=='project_creation_date'
- human_short_date(row.resource.created_at) if row.resource.created_at
- elsif column.key=='key'
- "<span class='small'>#{row.resource.kee}</span>"
- elsif column.key=='description'
- h row.resource.description
- elsif column.key=='version'
- h row.analysis.version if row.analysis
- elsif column.key=='language'
- Api::Utils.language_name(row.resource.language)
- elsif column.key=='links' && row.links
- html = ''
- row.links.select { |link| link.href.start_with?('http') }.each do |link|
- html += "<a target='_blank' href='#{link.href}' class='icon-#{link.link_type}'></a> " unless link.custom?
- end
- html
- end
- end
-
- def measure_filter_star(filter, is_favourite)
- if is_favourite
- style='icon-favorite'
- title=message('click_to_remove_from_favorites')
- else
- style='icon-not-favorite'
- title=message('click_to_add_to_favorites')
- end
-
- "<a href='#' id='star-#{filter.name.parameterize}' class='measure-filter-star #{style}' filter-id='#{filter.id}' title='#{title}'></a>"
- end
-
- def period_labels
- [Api::Utils.period_label(1), Api::Utils.period_label(2), Api::Utils.period_label(3)]
- end
-
- def more_criteria_options(filter)
- more_criteria_options = [['', '']]
- more_criteria_options << [message('measure_filter.criteria.metric'), 'metric']
- more_criteria_options << [message('measure_filter.criteria.age'), 'age'] unless filter.criteria('ageMinDays') || filter.criteria('ageMaxDays')
- more_criteria_options << [message('measure_filter.criteria.date'), 'date'] unless filter.criteria('fromDate') || filter.criteria('toDate')
- more_criteria_options << [message('measure_filter.criteria.only_favorites'), 'fav'] unless filter.criteria('onFavourites')
- more_criteria_options << [message('measure_filter.criteria.key'), 'key'] unless filter.criteria('keySearch')
- more_criteria_options << [message('measure_filter.criteria.language'), 'lang'] unless filter.criteria('languages')
- more_criteria_options << [message('measure_filter.criteria.name'), 'name'] unless filter.criteria('nameSearch')
- more_criteria_options << [message('measure_filter.criteria.components_of_project'), 'project'] unless filter.base_resource
- more_criteria_options << [message('measure_filter.criteria.alert'), 'alert'] unless filter.criteria('alertLevels')
- # SONAR-4508 sort criterias
- Api::Utils.insensitive_sort(more_criteria_options){|option| option[0]}
- end
-
-
- private
-
- #
- # This method is a inspired by ApplicationHelper#format_variation for measure where metrics key begin with 'new_'
- # It will display measure in color, without operand (+/-), and prefix with a %.
- #
- def format_new_metric_measure(metric_or_measure, index)
- if metric_or_measure.is_a?(ProjectMeasure)
- m = metric_or_measure
- elsif @snapshot
- m = @snapshot.measure(metric_or_measure)
- end
- html=nil
- if m
- val=variation_value(m, :index => index)
- if val
- formatted_val = m.format_numeric_value(val, :variation => false)
- html = "<span>#{formatted_val}</span>"
- end
- end
- html
- end
-
-end
size = options[:size] || 50
text_field_tag name, value, {:size => size}.update(html_options)
- when PropertyType::TYPE_FILTER
- user_filters = options_id(value, current_user.measure_filters)
- shared_filters = options_id(value, MeasureFilter.find(:all, :conditions => ['(user_id<>? or user_id is null) and shared=?', current_user.id, true]).sort_by(&:name))
-
- filters_combo = select_tag name, option_group('My Filters', user_filters) + option_group('Shared Filters', shared_filters), html_options
- filter_link = link_to message('widget.filter.edit'), {:controller => 'measures', :action => 'manage'}, :class => 'link-action'
-
- "#{filters_combo} #{filter_link}"
-
when PropertyType::TYPE_ISSUE_FILTER
user_filters = options_id(value, Internal.issues.findIssueFiltersForCurrentUser())
shared_filters = options_id(value, Internal.issues.findSharedFiltersForCurrentUser())
- #user_filters = options_id(value, current_user.measure_filters)
- #shared_filters = options_id(value, MeasureFilter.find(:all, :conditions => ['(user_id<>? or user_id is null) and shared=?', current_user.id, true]).sort_by(&:name))
-
filters_combo = select_tag name, option_group('My Filters', user_filters) + option_group('Shared Filters', shared_filters), html_options
filter_link = link_to message('widget.filter.edit'), {:controller => 'issues', :action => 'manage'}, :class => 'link-action'
+++ /dev/null
-#
-# SonarQube, open source software quality management tool.
-# Copyright (C) 2008-2014 SonarSource
-# mailto:contact AT sonarsource DOT com
-#
-# SonarQube 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.
-#
-# SonarQube 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 this program; if not, write to the Free Software Foundation,
-# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-#
-require 'set'
-class MeasureFilter < ActiveRecord::Base
-
- # Row in the table of results
- class Row
- attr_reader :component, :measures_by_metric, :links, :analysis
-
- def initialize(component)
- @component = component
- @measures_by_metric = {}
- @links = nil
- end
-
- def resource
- component
- end
-
- # For internal use
- def add_measure(measure)
- @measures_by_metric[measure.metric] = measure
- end
-
- # For internal use
- def set_analysis(analysis)
- @analysis=analysis
- end
-
- # For internal use
- def add_link(link)
- @links ||= []
- @links << link
- end
-
- def measure(metric)
- @measures_by_metric[metric]
- end
-
- def measures
- @measures_by_metric.values
- end
- end
-
- CRITERIA_SEPARATOR = '|'
- CRITERIA_KEY_VALUE_SEPARATOR = ','
-
- belongs_to :user
- has_many :measure_filter_favourites, :dependent => :delete_all
-
- validates_length_of :description, :allow_nil => true, :maximum => 4000
- validate :validate_name
-
- attr_reader :pagination, :security_exclusions, :base_row, :rows, :display
-
- def validate_name
- if name.nil? || name.empty?
- errors.add :name, Api::Utils.message('measure_filter.missing_name')
- elsif name.size > 100
- errors.add :name, Api::Utils.message('measure_filter.name_too_long')
- end
- end
-
- def sort_key
- criteria['sort']
- end
-
- def sort_asc?
- criteria['asc']!='false'
- end
-
- # array of the metrics to use when loading measures
- def metrics
- @metrics ||= []
- end
-
- # Set the metrics of the result measures to load. Array of Metric or String.
- def metrics=(array=[])
- @metrics = array.map { |m| m.is_a?(Metric) ? m : Metric.by_key(m) }.compact
- end
-
- # Enable the loading of result links. False by default
- def require_links=(flag)
- @require_links=flag
- end
-
- # boolean flag that indicates if project links should be loaded
- def require_links?
- @require_links
- end
-
- def require_authentication?
- criteria[:onFavourites]=='true'
- end
-
- def can_be_reassigned_by(user)
- user.has_role?(:admin) && shared
- end
-
- def criteria(key=nil)
- @criteria ||= HashWithIndifferentAccess.new
- if key
- @criteria[key]
- else
- @criteria
- end
- end
-
- def criteria=(hash)
- @criteria = HashWithIndifferentAccess.new
- hash.each_pair do |k, v|
- set_criteria_value(k, v)
- end
- end
-
- def override_criteria(hash)
- @criteria ||= HashWithIndifferentAccess.new
- hash.each_pair do |k, v|
- set_criteria_value(k, v)
- end
- end
-
- # API used by Displays
- def set_criteria_value(key, value)
- @criteria ||= HashWithIndifferentAccess.new
- if key
- if value!=nil && value!='' && value!=['']
- value = (value.kind_of?(Array) ? value : value.to_s)
- @criteria[key]=value
- else
- @criteria.delete(key)
- end
- end
- end
-
- # API used by Displays
- def set_criteria_default_value(key, value)
- @criteria ||= HashWithIndifferentAccess.new
- unless @criteria.has_key?(key)
- if key
- if value!=nil && value!='' && value!=['']
- value = (value.kind_of?(Array) ? value : value.to_s)
- @criteria[key]=value
- else
- @criteria.delete(key)
- end
- end
- end
- end
-
- def load_criteria_from_data
- if self.data
- @criteria = self.data.split(CRITERIA_SEPARATOR).inject(HashWithIndifferentAccess.new) do |h, s|
- k, v=s.split('=')
- if k && v
- # nameSearch can contains comma, in this case we should not split the value
- if k != 'nameSearch'
- # Empty values are removed
- v=v.split(CRITERIA_KEY_VALUE_SEPARATOR).select{|v| !v.empty?} if v.include?(CRITERIA_KEY_VALUE_SEPARATOR)
- end
- h[k]=v
- end
- h
- end
- else
- @criteria = HashWithIndifferentAccess.new
- end
- end
-
- def convert_criteria_to_data
- string_data = []
- if @criteria
- @criteria.each_pair do |k, v|
- string_value = (v.is_a?(String) ? v : v.join(CRITERIA_KEY_VALUE_SEPARATOR))
- string_data << "#{k}=#{string_value}"
- end
- end
- self.data = string_data.join(CRITERIA_SEPARATOR)
- end
-
- def enable_default_display
- set_criteria_default_value('display', 'list')
- end
-
- def base_resource
- if criteria('base')
- Project.first(:conditions => ['kee=? and copy_component_uuid is null and developer_uuid is null', criteria('base')])
- end
- end
-
- def system?
- user_id == nil
- end
-
- # ==== Options
- # :user : the authenticated user
- def execute(controller, options={})
- init_results
- init_display(options)
- user = options[:user]
- result = Api::Utils.java_facade.executeMeasureFilter(criteria, (user && user.id))
- if result.error
- errors.add_to_base(Api::Utils.message("measure_filter.error.#{result.error}"))
- else
- rows = result.getRows()
- component_uuids = filter_authorized_component_uuids(rows, controller)
- base_project = filter_authorized_base_project(base_resource, controller)
- load_results(component_uuids, base_project)
- end
- self
- end
-
- def owner?(user)
- return false if user==nil || user.id==nil
- (self.id==nil) || (self.user_id==user.id) || (self.user_id==nil && user.has_role?(:admin))
- end
-
- private
-
- def init_results
- @pagination = nil
- @security_exclusions = nil
- @rows = nil
- @base_row = nil
- self
- end
-
- def init_display(options)
- @display = MeasureFilterDisplay.create(self, options)
- end
-
- def filter_authorized_base_project(base_resource, controller)
- # SONAR-4793
- # Verify that user has browse permission on base project
- controller.has_role?(:user, base_resource) ? base_resource : nil
- end
-
- def filter_authorized_component_uuids(rows, controller)
- project_uuids = rows.map { |row| row.getRootComponentUuid() }.compact.uniq
- authorized_project_uuids = controller.select_authorized(:user, project_uuids)
- component_uuids = rows.map { |row| row.getComponentUuid() if authorized_project_uuids.include?(row.getRootComponentUuid()) }.compact
- @security_exclusions = (component_uuids.size<rows.size)
- @pagination = Api::Pagination.new
- @pagination.per_page=(criteria(:pageSize)||999999).to_i
- @pagination.page=(criteria(:page)||1).to_i
- @pagination.count = component_uuids.size
- component_uuids[@pagination.offset ... (@pagination.offset+@pagination.limit)] || []
- end
-
- def load_results(component_uuids, base_resource)
- @rows = []
- metric_ids = metrics.map(&:id)
-
- if !component_uuids.empty?
- rows_by_component_uuid = {}
-
- components = []
- component_uuids.each_slice(999) do |safe_for_oracle_uuids|
- components.concat(Project.find(:all, :conditions => ['uuid in (?)', safe_for_oracle_uuids]))
- end
- project_uuids = []
- components.each do |component|
- row = Row.new(component)
- rows_by_component_uuid[component.uuid] = row
- project_uuids << component.project_uuid
- end
- project_uuids.uniq!
-
- analysis_by_project_uuid = Snapshot.all(:conditions => ['component_uuid in (?) and islast=?', project_uuids, true]).inject({}) do |hash, analysis|
- hash[analysis.component_uuid] = analysis
- hash
- end
-
- components.each do |component|
- analysis = analysis_by_project_uuid[component.project_uuid]
- rows_by_component_uuid[component.uuid].set_analysis(analysis) if analysis
- end
-
- # @rows must be in the same order as the component uuids
- component_uuids.each do |uuid|
- @rows << rows_by_component_uuid[uuid]
- end
-
- unless metric_ids.empty?
- measures = []
- component_uuids.each_slice(999) do |safe_for_oracle_uuids|
- measures.concat(ProjectMeasure.all(:include => :analysis, :conditions =>
- ['project_measures.person_id is null and project_measures.component_uuid in (?) and project_measures.metric_id in (?) and snapshots.islast=?', safe_for_oracle_uuids, metric_ids, true]
- ))
- end
- measures.each do |measure|
- row = rows_by_component_uuid[measure.component_uuid]
- row.add_measure(measure)
- end
- end
-
- if require_links?
- uuids_for_links = components.map { |c| c.uuid if c.scope=='PRJ'}.compact.uniq
-
- uuids_for_links.each_slice(999) do |safe_for_oracle_uuids|
- ProjectLink.all(:conditions => {:component_uuid => safe_for_oracle_uuids}, :order => 'link_type').each do |link|
- rows_by_component_uuid[link.component_uuid].add_link(link)
- end
- end
- end
- end
- if base_resource
- base_snapshot = base_resource.last_snapshot
- if base_snapshot
- @base_row = Row.new(base_resource)
- unless metric_ids.empty?
- base_measures = ProjectMeasure.all(:include => :analysis, :conditions =>
- ['project_measures.person_id is null and project_measures.component_uuid=? and project_measures.metric_id in (?) and snapshots.islast=?', base_resource.uuid, metric_ids, true]
- )
- base_measures.each do |base_measure|
- @base_row.add_measure(base_measure)
- end
- end
- end
- end
- end
-
- def validate
- # validate uniqueness of name
- if id
- # update existing filter
- if user_id
- count = MeasureFilter.count('id', :conditions => ['name=? and user_id=? and id<>?', name, user_id, id])
- else
- count = MeasureFilter.count('id', :conditions => ['name=? and user_id is null and id<>?', name, id])
- end
- else
- # new filter
- count = MeasureFilter.count('id', :conditions => ['name=? and user_id=?', name, user_id])
- end
- errors.add_to_base('Name already exists') if count>0
-
- if shared
- if id
- count = MeasureFilter.count('id', :conditions => ['name=? and shared=? and (user_id is null or user_id<>?) and id<>?', name, true, user_id, id])
- else
- count = MeasureFilter.count('id', :conditions => ['name=? and shared=? and (user_id is null or user_id<>?)', name, true, user_id])
- end
- errors.add_to_base('Other users already share filters with the same name') if count>0
-
- # Verify filter owner has sharing permission
- if !user
- errors.add(:user, "cannot own this filter because of insufficient rights")
- end
- elsif system?
- errors.add_to_base("System filters can't be unshared")
- end
- end
-
-end
+++ /dev/null
-#
-# SonarQube, open source software quality management tool.
-# Copyright (C) 2008-2014 SonarSource
-# mailto:contact AT sonarsource DOT com
-#
-# SonarQube 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.
-#
-# SonarQube 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 this program; if not, write to the Free Software Foundation,
-# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-#
-class MeasureFilterDisplay
-
- def self.create(filter, options)
- # Do not init a MeasureFilterDisplayList when we want to completely control the render (column to return, pagination, etc.) of the filter
- # For instance, the /measures/search_filter manage by itself the column and the pagination
- MeasureFilterDisplayList.new(filter, options) if filter.criteria('display') == 'list'
- end
-
- def key
- self.class::KEY
- end
-
- attr_reader :filter, :options
-
- def initialize(filter, options)
- @filter = filter
- @options = options
-
- if filter.base_resource
- qualifiers = filter.criteria(:qualifiers)
- filter.set_criteria_value(:onBaseComponents, 'true') unless qualifiers && !qualifiers.empty?
- end
- end
-
- # sorted array of parameters :
- # [[key1,value1], [key2,value2]]
- def url_params
- []
- end
-end
+++ /dev/null
-#
-# SonarQube, open source software quality management tool.
-# Copyright (C) 2008-2014 SonarSource
-# mailto:contact AT sonarsource DOT com
-#
-# SonarQube 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.
-#
-# SonarQube 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 this program; if not, write to the Free Software Foundation,
-# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-#
-require 'set'
-class MeasureFilterDisplayList < MeasureFilterDisplay
- KEY = :list
- MAX_PAGE_SIZE = 250
-
- class Column
- attr_reader :key, :metric, :period
-
- def initialize(key)
- @key = key
- fields = @key.split(':')
- if fields.size>=2 && fields[0]=='metric'
- @metric = Metric.by_key(fields[1])
- @period = fields[2].to_i if fields.size>=3
- end
- end
-
- def title_label
- if @metric
- label = @metric.abbreviation
- else
- label = Api::Utils.message("measure_filter.abbr.#{@key}", :default => @key)
- end
- label
- end
-
- def tooltip
- if @metric
- tooltip = @metric.description
- else
- tooltip = Api::Utils.message("measure_filter.col.#{@key}", :default => @key)
- end
- tooltip
- end
-
- def align
- @align ||=
- begin
- # by default is table cells are left-aligned
- (@key=='name' || @key=='short_name' || @key=='description') ? '' : 'right'
- end
- end
-
- def title_css
- 'thin' if @metric && @metric.val_type==Metric::VALUE_TYPE_LEVEL
- end
-
- def row_css
- 'nowrap' unless (@metric && !@metric.numeric?) || @key=='description'
- end
-
- def sort?
- !links?
- end
-
- def links?
- @key == 'links'
- end
-
- end
-
- attr_reader :columns
-
- def initialize(filter, options)
- super(filter, options)
-
- # default values
- filter.set_criteria_default_value(:cols, ['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, 100)
- filter.set_criteria_value(:pageSize, MAX_PAGE_SIZE) if filter.criteria(:pageSize).to_i>MAX_PAGE_SIZE
-
- @columns = []
- metrics = []
- filter.criteria(:cols).each do |column_key|
- column = Column.new(column_key)
- @columns << column
- metrics << column.metric if column.metric
- filter.require_links=true if column.links?
- end
- filter.metrics=(metrics)
- end
-
- PROPERTY_KEYS = Set.new([:cols, :sort, :asc, :pageSize])
-
- def url_params
- @filter.criteria.select { |k, v| PROPERTY_KEYS.include?(k.to_sym) }
- end
-end
+++ /dev/null
-#
-# SonarQube, open source software quality management tool.
-# Copyright (C) 2008-2014 SonarSource
-# mailto:contact AT sonarsource DOT com
-#
-# SonarQube 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.
-#
-# SonarQube 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 this program; if not, write to the Free Software Foundation,
-# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-#
-class MeasureFilterFavourite < ActiveRecord::Base
- belongs_to :user
- belongs_to :measure_filter
-
- validates_uniqueness_of :measure_filter_id, :scope => :user_id
-end
TYPE_LICENSE = 'LICENSE'
TYPE_REGULAR_EXPRESSION = 'REGULAR_EXPRESSION'
- TYPE_FILTER = 'FILTER'
# Since 3.7
TYPE_ISSUE_FILTER = 'ISSUE_FILTER'
TYPE_USER_LOGIN = 'USER_LOGIN'
has_and_belongs_to_many :groups
has_many :properties, :foreign_key => 'user_id', :dependent => :delete_all
- has_many :active_dashboards, :dependent => :destroy, :order => 'order_index'
- has_many :dashboards, :dependent => :destroy
- has_many :measure_filters, :class_name => 'MeasureFilter', :dependent => :delete_all, :order => 'name asc'
-
- # measure filters that are marked as favourites
- has_many :favourited_measure_filters, :class_name => 'MeasureFilter', :through => :measure_filter_favourites, :source => :measure_filter, :order => 'name asc'
-
- # the join table MEASURE_FILTER_FAVOURITES
- has_many :measure_filter_favourites, :class_name => 'MeasureFilterFavourite', :dependent => :delete_all
include Authentication
include Authentication::ByPassword
+++ /dev/null
-<% if @filter.rows %>
- <div class="page">
- <header class="page-header">
- <h1 class="page-title"><%= message('qualifiers.all.' + @qualifier) -%></h1>
- </header>
-
- <div id="all-projects">
-
- <% if @filter.security_exclusions %>
- <p class="notes"><%= message('all-projects.results_not_display_due_to_security') -%></p>
- <% end %>
-
- <%
- display_favourites = logged_in?
- colspan = 5
- colspan += 1 if display_favourites
- %>
-
- <table class="data" id="all-projects-table">
- <thead>
- <tr>
- <% if display_favourites %>
- <th class="thin" style></th>
- <% end %>
- <th class="thin nowrap">
- <%= link_to message('all-projects.cols.name'), {:action => 'index', :qualifier => params[:qualifier], :asc => (!@filter.sort_asc?).to_s} -%>
- <%= @filter.sort_asc? ? '<i class="icon-sort-asc"></i>' : '<i class="icon-sort-desc"></i>' -%>
- </th>
- <th></th>
- <th></th>
- <th></th>
- <th></th>
- </tr>
- </thead>
-
- <tbody>
- <% @filter.rows.each do |row| %>
- <tr class="thin <%= cycle 'even', 'odd' -%>">
- <% if display_favourites %>
- <td class="thin"><%= link_to_favourite(row.resource) -%></td>
- <% end %>
- <td class="nowrap">
- <%= qualifier_icon(row.resource) -%> <%= link_to(h(row.resource.name(true)), {:controller => 'dashboard', :id => row.resource.id}, :title => h(row.resource.key)) -%>
- </td>
- <td class="sep"></td>
- <td>
- <%= h row.resource.description -%>
- </td>
- <td class="sep"></td>
- <td class="nowrap text-right">
- <%
- if row.links
- row.links.select { |link| link.href.start_with?('http') }.each do |link|
- %>
- <a target="_blank" href="<%= link.href -%>" class="icon-<%= link.link_type -%>"></a>
- <%
- end
- end
- %>
- </td>
- </tr>
- <% end %>
-
- <% if @filter.rows.empty? %>
- <tr class="even">
- <td colspan="<%= colspan -%>"><%= message 'no_data' -%></td>
- </tr>
- <% end %>
- </tbody>
-
- <%= table_pagination(@filter.pagination, :colspan => colspan) { |label, page_id|
- link_to(label, :action => 'index', :qualifier => h(@qualifier), :asc => h(@filter.criteria[:asc]), :page => page_id)
- }
- -%>
-
- </table>
- </div>
-
- </div>
-
-<% end %>
session.flash_notice.authentication_failed=Authentication failed.
session.flash_notice.logged_out=You have been logged out.
-#------------------------------------------------------------------------------
-#
-# MEASURES & MEASURE FILTERS
-#
-#------------------------------------------------------------------------------
-measures.select_components=Please select "Components", "Components of" or "Favorites only" filter to see results.
-measure_filter.delete_column=Delete column
-measure_filter.no_filters=No filters
-measure_filter.display_as=Display as
-measure_filter.shared_with_all_users=Shared with all users
-measure_filter.private=Private
-measure_filter.manage.shared_filters=Shared Measures Filters
-measure_filter.manage.my_filters=My Measures Filters
-measure_filter.criteria.what=What? Projects, files...
-measure_filter.criteria.components=Components
-measure_filter.criteria.age=Age
-measure_filter.criteria.date=Date
-measure_filter.criteria.only_favorites=Favorites only
-measure_filter.criteria.key=Key
-measure_filter.criteria.name=Name
-measure_filter.criteria.key_contains=Key contains
-measure_filter.criteria.name_contains=Name contains
-measure_filter.criteria.language=Language
-measure_filter.criteria.last_analysis=Last analysis
-measure_filter.criteria.metric=Metric
-measure_filter.criteria.metric.not_set=Not set
-measure_filter.criteria.project=Project
-measure_filter.criteria.alert=Quality Gate
-measure_filter.criteria.alert.error=Error
-measure_filter.criteria.alert.warn=Warning
-measure_filter.criteria.alert.ok=Ok
-measure_filter.criteria.from_date=Inspected since
-measure_filter.criteria.to_date=Inspected before
-measure_filter.criteria.date_format=year-month-day (2013-01-31)
-measure_filter.criteria.age.more_than=Inspected more than
-measure_filter.criteria.age.within_last=Inspected within the last
-measure_filter.criteria.age.days_ago=days ago
-measure_filter.criteria.age.days=days
-measure_filter.criteria.components_of=Components of
-measure_filter.criteria.components_of_project=Components of project
-measure_filter.new_search=New Search
-measure_filter.favourite_filters=Favourite Filters
-measure_filter.more_criteria=+ More Criteria
-measure_filter.languages=Languages
-measure_filter.filter_list=Measures Filters
-measure_filter.col.date=Last Analysis
-measure_filter.col.description=Description
-measure_filter.col.key=Key
-measure_filter.col.links=Links
-measure_filter.col.name=Name
-measure_filter.col.short_name=Short Name
-measure_filter.col.version=Version
-measure_filter.col.project_creation_date=First Analysis
-measure_filter.abbr.date=Last Analysis
-measure_filter.abbr.description=Description
-measure_filter.abbr.key=Key
-measure_filter.abbr.links=Links
-measure_filter.abbr.name=Name
-measure_filter.abbr.short_name=Name
-measure_filter.abbr.version=Version
-measure_filter.abbr.project_creation_date=First Analysis
-measure_filter.missing_name=Name is missing
-measure_filter.name_too_long=Name is too long
-measure_filter.sharing=Sharing
-measure_filter.delete_confirm_title=Delete Filter
-measure_filter.are_you_sure_want_delete_filter_x=Are you sure that you want to delete the filter "{0}"?
-measure_filter.title_shared_filters=Shared Filters
-measure_filter.key_contains=Key contains
-measure_filter.name_contains=Name contains
-measure_filter.manage_filters=Manage Filters
-measure_filter.display.list=List
-measure_filter.display.treemap=Treemap
-measure_filter.list.change=Change Columns
-measure_filter.treemap.change=Change Treemap
-measure_filter.add_column_button=Add Column
-measure_filter.widget.unknown_filter_warning=This widget is configured to display a measure filter that does not exist anymore.
-measure_filter.error.UNKNOWN=Unexpected error. Please contact the administrator.
-measure_filter.error.TOO_MANY_RESULTS=Too many results. Please refine your search.
-measure_filter.error.VALUE_SHOULD_BE_A_NUMBER=Value used for metric should be a number.
-
#------------------------------------------------------------------------------
#
my_account.favorite_components=Favorite Components
my_account.no_favorite_components=You do not have favorite components yet.
my_account.no_favorite_issue_filters=You do not have favorite issue filters yet.
-my_account.favorite_measure_filters=Favorite Measure Filters
-my_account.no_favorite_measure_filters=You do not have favorite measure filters yet.
my_account.notifications=Notifications
my_account.no_project_notifications=You have not set project notifications yet.
my_account.profile=Profile