aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--plugins/sonar-core-plugin/src/main/resources/org/sonar/l10n/core.properties1
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/index/DefaultIndex.java2
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/issue/DeprecatedViolations.java7
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/issue/IssuePersister.java7
-rw-r--r--sonar-core/src/main/java/org/sonar/core/issue/DefaultIssue.java18
-rw-r--r--sonar-core/src/main/java/org/sonar/core/issue/DefaultIssueFinder.java6
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/issue/Issue.java3
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/utils/KeyValueFormat.java2
-rw-r--r--sonar-server/src/main/webapp/WEB-INF/app/controllers/api/issues_controller.rb8
-rw-r--r--sonar-server/src/main/webapp/WEB-INF/app/controllers/issues_controller.rb34
-rw-r--r--sonar-server/src/main/webapp/WEB-INF/app/views/issues/_list.html.erb131
-rw-r--r--sonar-server/src/main/webapp/WEB-INF/app/views/issues/index.html.erb5
-rw-r--r--sonar-server/src/main/webapp/WEB-INF/app/views/layouts/_layout.html.erb3
-rw-r--r--sonar-server/src/main/webapp/WEB-INF/config/routes.rb2
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 => /.*/ }