# # SonarQube, open source software quality management tool. # Copyright (C) 2008-2013 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 Api::ProjectsController < Api::ApiController before_filter :admin_required, :only => [ :destroy ] # PARAMETERS # subprojects [true|false] : load sub-projects ? Default is false. Ignored if the parameter key is set. # views [true|false] : load views and sub-views ? Default is false. Ignored if the parameter key is set. # libs [true|false] : load libraries ? Default is false. Ignored if the parameter key is set. # langs (comma-separated list) : filter results by language. Default is empty. # desc [true|false] : load project description ? Default is false. # key : id or key of the project (0 or 1 result) # search : substring of project name, case insensitive # versions [true,false,last]. Default is false. # TODO # - SQL pagination (LIMIT + OFFSET) def index begin @show_description=(params[:desc]=='true') @projects=load_projects @snapshots_by_pid=load_snapshots_by_project respond_to do |format| format.json{ render :json => jsonp(to_json) } format.xml { render :xml => to_xml } format.text { render :text => text_not_supported } end rescue Exception => e logger.error("Fails to execute #{request.url} : #{e.message}") render_error(e.message) end end # # DELETE /api/projects/ # curl -X DELETE http://localhost:9000/api/projects/ -v -u admin:admin # def destroy bad_request("Missing project key") unless params[:id].present? project = Project.by_key(params[:id]) bad_request("Not valid project") unless project access_denied unless is_admin?(project) bad_request("Not valid project") unless java_facade.getResourceTypeBooleanProperty(project.qualifier, 'deletable') Project.delete_resource_tree(project) render_success("Project deleted") end # # POST /api/projects/create?key=&name= # # -- Example # curl -v -u admin:admin -X POST 'http://localhost:9000/api/projects/create?key=project1&name=Project%20One' # # since 4.0 # def create verify_post_request require_parameters :key, :name access_denied unless has_role?("provisioning") key = params[:key] name = params[:name] Internal.component_api.createComponent(key, name, 'TRK') Internal.permissions.applyDefaultPermissionTemplate(key) result = Project.by_key(key) respond_to do |format| format.json { render :json => jsonp(to_json_hash(result)) } format.xml { render :xml => to_xml_hash(result) } end end private def load_projects conditions=['enabled=:enabled'] values={:enabled => true} if !params[:langs].blank? conditions<<'language in (:langs)' values[:langs]=params[:langs].split(',') end if !params[:key].blank? begin id=Integer(params[:key]) conditions<<'id=:id' values[:id]=id rescue conditions<<'kee=:key' values[:key]=params[:key] end else if !params[:search].blank? conditions<<"UPPER(name) like :name" values[:name]='%' + params[:search].upcase + '%' end scopes=['PRJ'] qualifiers=['TRK'] if params[:views]=='true' qualifiers<<'VW'<<'SVW' end if params[:subprojects]=='true' qualifiers<<'BRC' end if params[:libs]=='true' qualifiers<<'LIB' end conditions<<'scope in (:scopes) AND qualifier in (:qualifiers)' values[:scopes]=scopes values[:qualifiers]=qualifiers end # this is really an advanced optimization ! select_columns='id,kee,name,language,long_name,scope,qualifier,root_id' select_columns += ',description' if @show_description projects=Project.find(:all, :select => select_columns, :conditions => [conditions.join(' AND '), values], :order => 'name') select_authorized(:user, projects) end def load_snapshots_by_project select_columns='id,project_id,version,islast,created_at' if params[:versions]=='true' snapshots=Snapshot.find_by_sql(["SELECT #{select_columns} FROM snapshots s1 WHERE s1.status=? AND s1.project_id IN (?) AND NOT EXISTS(SELECT * FROM snapshots s2 WHERE s2.project_id=s1.project_id AND s2.created_at>s1.created_at AND s2.version=s1.version)", 'P', @projects.map{|p| p.id}]) elsif params[:versions]=='last' snapshots=Snapshot.find_by_sql(["SELECT #{select_columns} FROM snapshots s1 WHERE s1.status=? AND islast=? AND s1.project_id IN (?) AND NOT EXISTS(SELECT * FROM snapshots s2 WHERE s2.project_id=s1.project_id AND s2.created_at>s1.created_at AND s2.version=s1.version)", 'P', true, @projects.map{|p| p.id}]) else snapshots=[] end snapshots_by_project_id={} snapshots.each do |s| snapshots_by_project_id[s.project_id]||=[] snapshots_by_project_id[s.project_id]< s1.version}.each do |snapshot| version={:sid => snapshot.id.to_s} version[:d]=Api::Utils.format_datetime(snapshot.created_at) if snapshot.created_at if snapshot.last? hash[:lv]=snapshot.version end versions[snapshot.version]=version end hash[:v]=versions end json< project.id.nil? ? nil : project.id.to_s, :k => project.key, :nm => project.name(true), :sc => project.scope, :qu => project.qualifier, :ds => @show_description && project.description ? project.description : nil }.reject!{|k,v| v.nil?} end def to_xml xml = Builder::XmlMarkup.new(:indent => 0) xml.projects do @projects.each do |project| to_xml_hash(project, xml) end end end def to_xml_hash(project, xml=Builder::XmlMarkup.new(:indent => 0)) xml.project(:id => project.id.to_s, :key => project.key) do xml.name(project.name(true)) xml.scope(project.scope) xml.qualifier(project.qualifier) xml.desc(project.description) if @show_description && project.description if @snapshots_by_pid && @snapshots_by_pid[project.id] @snapshots_by_pid[project.id].sort{|s1,s2| s2.version <=> s1.version}.each do |snapshot| attributes={:sid => snapshot.id.to_s, :last => snapshot.last?} attributes[:date]=Api::Utils.format_datetime(snapshot.created_at) if snapshot.created_at xml.version(snapshot.version, attributes) end end end end end