diff options
14 files changed, 216 insertions, 13 deletions
diff --git a/plugins/sonar-core-plugin/src/main/resources/org/sonar/l10n/core.properties b/plugins/sonar-core-plugin/src/main/resources/org/sonar/l10n/core.properties index 1ef95924f91..df523ff6627 100644 --- a/plugins/sonar-core-plugin/src/main/resources/org/sonar/l10n/core.properties +++ b/plugins/sonar-core-plugin/src/main/resources/org/sonar/l10n/core.properties @@ -346,6 +346,7 @@ project_links.page=Links project_history.page=History quality_profiles.page=Quality Profiles reviews.page=Reviews +issues.page=Issues settings.page=General Settings source.page=Source system_info.page=System Info diff --git a/sonar-batch/src/main/java/org/sonar/batch/index/DefaultIndex.java b/sonar-batch/src/main/java/org/sonar/batch/index/DefaultIndex.java index 44055904fdf..ea0746d6b47 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/index/DefaultIndex.java +++ b/sonar-batch/src/main/java/org/sonar/batch/index/DefaultIndex.java @@ -367,8 +367,8 @@ public class DefaultIndex extends SonarIndex { } violation.setResource(bucket.getResource()); - deprecatedViolations.add(violation); addViolation(violation, bucket, force); + deprecatedViolations.add(violation); } private void addViolation(Violation violation, Bucket bucket, boolean force) { diff --git a/sonar-batch/src/main/java/org/sonar/batch/issue/DeprecatedViolations.java b/sonar-batch/src/main/java/org/sonar/batch/issue/DeprecatedViolations.java index 9841207f8c4..d83c1bccb3e 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/issue/DeprecatedViolations.java +++ b/sonar-batch/src/main/java/org/sonar/batch/issue/DeprecatedViolations.java @@ -56,10 +56,9 @@ public class DeprecatedViolations implements BatchComponent { .setCost(violation.getCost()) .setLine(violation.getLineId()) .setMessage(violation.getMessage()) - .setStatus(Issue.STATUS_OPEN); - if (violation.getSeverity() != null) { - issue.setSeverity(violation.getSeverity().name()); - } + .setStatus(Issue.STATUS_OPEN) + .setSeverity(violation.getSeverity() != null ? violation.getSeverity().name() : null); + // FIXME //issue.setPerson(violation.getPersonId()); return issue; diff --git a/sonar-batch/src/main/java/org/sonar/batch/issue/IssuePersister.java b/sonar-batch/src/main/java/org/sonar/batch/issue/IssuePersister.java index 8722358f488..55333446f62 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/issue/IssuePersister.java +++ b/sonar-batch/src/main/java/org/sonar/batch/issue/IssuePersister.java @@ -23,6 +23,7 @@ import org.sonar.api.database.model.Snapshot; import org.sonar.api.issue.Issue; import org.sonar.api.rules.Rule; import org.sonar.api.rules.RuleFinder; +import org.sonar.api.utils.KeyValueFormat; import org.sonar.batch.index.ScanPersister; import org.sonar.batch.index.SnapshotCache; import org.sonar.core.issue.DefaultIssue; @@ -76,6 +77,7 @@ public class IssuePersister implements ScanPersister { .setCost(issue.cost()) .setResolution(issue.resolution()) .setStatus(issue.status()) + .setSeverity(issue.severity()) .setChecksum(issue.getChecksum()) .setManualIssue(issue.isManual()) .setManualSeverity(issue.isManualSeverity()) @@ -86,9 +88,8 @@ public class IssuePersister implements ScanPersister { .setClosedAt(issue.closedAt()) .setRuleId(ruleId) .setResourceId(componentId) - - // TODO -// .setData(null) + .setData(issue.attributes() != null ? KeyValueFormat.format(issue.attributes()) : null) + // TODO // .setPersonId() ; } diff --git a/sonar-core/src/main/java/org/sonar/core/issue/DefaultIssue.java b/sonar-core/src/main/java/org/sonar/core/issue/DefaultIssue.java index 77598dacc51..a3066d96ca7 100644 --- a/sonar-core/src/main/java/org/sonar/core/issue/DefaultIssue.java +++ b/sonar-core/src/main/java/org/sonar/core/issue/DefaultIssue.java @@ -20,8 +20,11 @@ package org.sonar.core.issue; import com.google.common.base.Preconditions; +import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; import com.google.common.collect.Maps; +import org.apache.commons.lang.builder.ToStringBuilder; +import org.apache.commons.lang.builder.ToStringStyle; import org.sonar.api.issue.Issue; import javax.annotation.Nullable; @@ -259,6 +262,15 @@ public class DefaultIssue implements Issue { return this; } + public Map<String, String> attributes() { + return attributes == null ? null : ImmutableMap.copyOf(attributes); + } + + public DefaultIssue setAttributes(Map<String, String> attributes){ + this.attributes = attributes; + return this; + } + @Override public boolean equals(Object o) { if (this == o) { @@ -278,4 +290,10 @@ public class DefaultIssue implements Issue { public int hashCode() { return key != null ? key.hashCode() : 0; } + + @Override + public String toString() { + return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE); + } + } diff --git a/sonar-core/src/main/java/org/sonar/core/issue/DefaultIssueFinder.java b/sonar-core/src/main/java/org/sonar/core/issue/DefaultIssueFinder.java index 5cd06de4759..0e6c8f83b5c 100644 --- a/sonar-core/src/main/java/org/sonar/core/issue/DefaultIssueFinder.java +++ b/sonar-core/src/main/java/org/sonar/core/issue/DefaultIssueFinder.java @@ -32,6 +32,7 @@ import org.sonar.api.issue.IssueFinder; import org.sonar.api.issue.IssueQuery; import org.sonar.api.rules.Rule; import org.sonar.api.rules.RuleFinder; +import org.sonar.api.utils.KeyValueFormat; import org.sonar.core.resource.ResourceDao; import org.sonar.core.resource.ResourceDto; @@ -120,8 +121,9 @@ public class DefaultIssueFinder implements IssueFinder { issue.setUserLogin(dto.getUserLogin()); issue.setAssigneeLogin(dto.getAssigneeLogin()); issue.setCreatedAt(dto.getCreatedAt()); - issue.setUpdatedAt(dto.getCreatedAt()); - issue.setClosedAt(dto.getUpdatedAt()); + issue.setUpdatedAt(dto.getUpdatedAt()); + issue.setClosedAt(dto.getClosedAt()); + issue.setAttributes(KeyValueFormat.parse(dto.getData())); if (resource != null) { issue.setComponentKey(resource.getKey()); } diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/issue/Issue.java b/sonar-plugin-api/src/main/java/org/sonar/api/issue/Issue.java index 652ed9cd9bd..619ea22f776 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/issue/Issue.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/issue/Issue.java @@ -20,6 +20,7 @@ package org.sonar.api.issue; import java.util.Date; +import java.util.Map; /** * @since 3.6 @@ -77,6 +78,8 @@ public interface Issue { String attribute(String key); + Map<String, String> attributes(); + /** * Used only during project scan. */ diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/utils/KeyValueFormat.java b/sonar-plugin-api/src/main/java/org/sonar/api/utils/KeyValueFormat.java index 158caf22e18..c0c4cd47b42 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/utils/KeyValueFormat.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/utils/KeyValueFormat.java @@ -227,7 +227,7 @@ public final class KeyValueFormat { return map; } - public static Map parse(String data) { + public static Map<String, String> parse(String data) { return parse(data, newStringConverter(), newStringConverter()); } diff --git a/sonar-server/src/main/webapp/WEB-INF/app/controllers/api/issues_controller.rb b/sonar-server/src/main/webapp/WEB-INF/app/controllers/api/issues_controller.rb index cf005721f21..408ba110f37 100644 --- a/sonar-server/src/main/webapp/WEB-INF/app/controllers/api/issues_controller.rb +++ b/sonar-server/src/main/webapp/WEB-INF/app/controllers/api/issues_controller.rb @@ -32,6 +32,14 @@ class Api::IssuesController < Api::ApiController Api.issues.find(map) end + def issues_to_json(issues) + json = [] + issues.each do |issue| + json << issue_to_json(issue) if issue + end + json + end + def issue_to_json(issue) json = { :key => issue.key, diff --git a/sonar-server/src/main/webapp/WEB-INF/app/controllers/issues_controller.rb b/sonar-server/src/main/webapp/WEB-INF/app/controllers/issues_controller.rb new file mode 100644 index 00000000000..3b87bffa64f --- /dev/null +++ b/sonar-server/src/main/webapp/WEB-INF/app/controllers/issues_controller.rb @@ -0,0 +1,34 @@ +# +# Sonar, entreprise quality control 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 +# + +class IssuesController < ApplicationController + + def index + @issues = find_issues({}).issues + end + + + protected + + def find_issues(map) + Api.issues.find(map) + end + +end
\ No newline at end of file diff --git a/sonar-server/src/main/webapp/WEB-INF/app/views/issues/_list.html.erb b/sonar-server/src/main/webapp/WEB-INF/app/views/issues/_list.html.erb new file mode 100644 index 00000000000..a4d40056d61 --- /dev/null +++ b/sonar-server/src/main/webapp/WEB-INF/app/views/issues/_list.html.erb @@ -0,0 +1,131 @@ +<% + if @issues && !@issues.empty? +%> + <table id="issues-list" class="data width100"> + <thead> + <tr> + <th width="1%" nowrap> + <%= message('identifier_abbreviated') -%> + </th> + <th width="1%" nowrap> + <%= message('status_abbreviated') -%> + </th> + <th width="1%" nowrap> + <%= message('severity_abbreviated') -%> + </th> + <th> + Resolution + </th> + <th> + <%= message('title') -%> + </th> + <th> + Message + </th> + <th width="1%"> + <%= message('project') -%> + </th> + <th> + Rule + </th> + <th width="1%"> + Line + </th> + <th width="1%"> + Cost + </th> + <th> + User + </th> + <th> + Assignee + </th> + <th> + Attr + </th> + <th> + Created at + </th> + <th> + Updated at + </th> + <th> + Closed at + </th> + </tr> + </thead> + <tfoot> + <tr> + <td colspan="6"> + <%= paginate(@issues) -%> + </td> + </tr> + </tfoot> + <tbody> + <% + @issues.each do |issue| + %> + <tr class="<%= cycle('even', 'odd') -%>"> + <td> + <%= h(issue.key) %> + </td> + <td> + <img src="<%= ApplicationController.root_context -%>/images/status/<%= issue.status -%>.png" title="<%= message(issue.status.downcase).capitalize -%>"/> + </td> + <td> + <% if issue.severity %> + <img src="<%= ApplicationController.root_context -%>/images/priority/<%= issue.severity -%>.png" title="<%= message(issue.severity.downcase).capitalize -%>"/> + <% end %> + </td> + <td> + <%= h(issue.resolution) %> + </td> + <td> + <%= h(issue.title) %> + </td> + <td> + <%= h(issue.message) %> + </td> + <td> + <span class="nowrap"><%= h issue.component_key -%></span> + </td> + <td> + <%= issue.rule_repository_key + ":" + issue.rule_key %> + </td> + <td> + <%= issue.cost -%> + </td> + <td> + <%= issue.cost -%> + </td> + <td> + <%= issue.user_login -%> + </td> + <td> + <%= issue.assignee_login -%> + </td> + <td> + <%= issue.attributes -%> + </td> + <td> + <%= issue.created_at -%> + </td> + <td> + <%= issue.updated_at -%> + </td> + <td> + <%= issue.closed_at -%> + </td> + </tr> + <% + end + %> + </tbody> + </table> +<% + elsif @issues +%> + <p><%= message('no_results') -%></p> +<% + end +%> diff --git a/sonar-server/src/main/webapp/WEB-INF/app/views/issues/index.html.erb b/sonar-server/src/main/webapp/WEB-INF/app/views/issues/index.html.erb new file mode 100644 index 00000000000..4b0572b9dc7 --- /dev/null +++ b/sonar-server/src/main/webapp/WEB-INF/app/views/issues/index.html.erb @@ -0,0 +1,5 @@ +<div id="reviews-search"> + <div id="content"> + <%= render :partial => "list" -%> + </div> +</div>
\ No newline at end of file diff --git a/sonar-server/src/main/webapp/WEB-INF/app/views/layouts/_layout.html.erb b/sonar-server/src/main/webapp/WEB-INF/app/views/layouts/_layout.html.erb index 9bb70302df7..893c67f9053 100644 --- a/sonar-server/src/main/webapp/WEB-INF/app/views/layouts/_layout.html.erb +++ b/sonar-server/src/main/webapp/WEB-INF/app/views/layouts/_layout.html.erb @@ -21,6 +21,9 @@ <li> <a href="<%= ApplicationController.root_context -%>/reviews/index"><%= message('reviews.page') -%></a> </li> + <li> + <a href="<%= ApplicationController.root_context -%>/issues/index"><%= message('issues.page') -%></a> + </li> </ul> </div> <div id="nav"> diff --git a/sonar-server/src/main/webapp/WEB-INF/config/routes.rb b/sonar-server/src/main/webapp/WEB-INF/config/routes.rb index 70d2d26d103..01707eb4f4a 100644 --- a/sonar-server/src/main/webapp/WEB-INF/config/routes.rb +++ b/sonar-server/src/main/webapp/WEB-INF/config/routes.rb @@ -26,8 +26,6 @@ ActionController::Routing::Routes.draw do |map| map.connect 'api/resoures', :controller => 'api/resources', :action => 'index' map.connect 'api/sources', :controller => 'api/sources', :action => 'index' map.connect 'api/violations', :controller => 'api/violations', :action => 'index' - map.connect 'api/issues', :controller => 'api/issues', :action => 'index', :conditions => { :method => :get } - map.connect 'api/issues/:key', :controller => 'api/issues', :action => 'show', :conditions => { :method => :get } map.resources 'rules', :path_prefix => 'api', :controller => 'api/rules' map.resources 'properties', :path_prefix => 'api', :controller => 'api/properties', :requirements => { :id => /.*/ } |