reviews.each do |review|
xml.review do
xml.id(review.id.to_i)
+ xml.createdAt(format_datetime(review.created_at))
xml.updatedAt(format_datetime(review.updated_at))
xml.user(review.user.login)
- xml.assignee(review.assignee.login)
+ xml.assignee(review.assignee.login) if review.assignee
xml.title(review.title)
xml.type(review.review_type)
xml.status(review.status)
xml.severity(review.severity)
xml.resource(review.resource.kee) if review.resource
- xml.line(review.resource_line) if review.resource_line
-
- # Continue here with resource + comments
+ xml.line(review.resource_line) if review.resource_line > 0
+ xml.comments do
+ review.review_comments.each do |comment|
+ xml.comment do
+ xml.author(comment.user.login)
+ xml.updatedAt(format_datetime(comment.updated_at))
+ xml.text(convert_markdown ? markdown_to_html(comment.review_text): comment.review_text)
+ end
+ end
+ end
end
end
end
def review_to_json(review, html=false)
json = {}
json['id'] = review.id.to_i
- json['updatedAt'] = review.updated_at
+ json['createdAt'] = format_datetime(review.created_at)
+ json['updatedAt'] = format_datetime(review.updated_at)
json['author'] = review.user.login
json['assignee'] = review.assignee.login if review.assignee
json['title'] = review.title if review.title
json['type'] = review.review_type
json['status'] = review.status
json['severity'] = review.severity
+ json['resource'] = review.resource.kee if review.resource
+ json['line'] = review.resource_line if review.resource_line > 0
comments = []
review.review_comments.each do |comment|
comments << {
'author' => comment.user.login,
'updatedAt' => format_datetime(comment.updated_at),
- 'comment' => (html ? markdown_to_html(comment.review_text): comment.review_text)
+ 'text' => (html ? markdown_to_html(comment.review_text): comment.review_text)
}
end
json['comments'] = comments
- json['line'] = review.resource_line if review.resource_line
- json['resource'] = review.resource.kee if review.resource
json
end
conditions << "status in (:statuses)"
values[:statuses]=@statuses
end
+ unless @projects == [""]
+ conditions << "project_id in (:projects)"
+ values[:projects]=@projects
+ end
unless @severities == [""]
conditions << "severity in (:severities)"
values[:severities]=@severities
end
def self.search(options={})
- conditions=['review_type<>:not_type']
- values={:not_type => Review::TYPE_FALSE_POSITIVE}
-
+ conditions=[]
+ values={}
+
+ review_type = options['review_type']
+ if review_type
+ conditions << "review_type=:type"
+ values[:type] = review_type.upcase
+ else
+ conditions=['review_type<>:not_type']
+ values={:not_type => Review::TYPE_FALSE_POSITIVE}
+ end
+
ids=options['ids']
if options[:id]
conditions << "id=:id"
values[:statuses]=statuses
end
+ projects=options['projects']
+ if projects && projects.size>0 && !projects[0].blank?
+ conditions << "project_id in (:projects)"
+ values[:projects]=projects
+ end
+
+ resources=options['resources']
+ if resources && resources.size>0 && !resources[0].blank?
+ conditions << "resource_id in (:resources)"
+ values[:resources]=resources
+ end
+
severities=options['severities']
if severities && severities.size>0 && !severities[0].blank?
conditions << "severity in (:severities)"
values[:assignees]=User.logins_to_ids(assignees)
end
- Review.find(:all, :order => "created_at DESC", :conditions => [conditions.join(" AND "), values], :limit => 200)
+ Review.find(:all, :include => [ 'review_comments' ], :order => "created_at DESC", :conditions => [conditions.join(" AND "), values], :limit => 200)
end
private
<h3><%= title -%></h3>
<textarea id="commentText<%= params[:id] -%>" rows="8" name="comment" style="width: 100%" onkeyup="if (this.value=='') $('submit_btn').disabled='true'; else $('submit_btn').disabled='';"></textarea>
<%= submit_to_remote "submit_btn", button, :url => { :action => 'violation_flag_as_false_positive' }, :html => { :id => "submit_btn", :disabled => "true" }, :update => 'vId'+params[:id] -%>
+
<%= link_to_remote 'Cancel', :url => {:action => 'display_violation', :id => params[:id]}, :update => 'vId' + params[:id] -%>
</form>
--- /dev/null
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2008-2011 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
+ */
+package org.sonar.wsclient.services;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * @since 2.8
+ */
+public class Review extends Model {
+
+ private Long id;
+ private Date createdAt = null;
+ private Date updatedAt = null;
+ private String authorLogin = null;
+ private String assigneeLogin = null;
+ private String title = null;
+ private String type = null;
+ private String status = null;
+ private String severity = null;
+ private String resourceKee = null;
+ private Integer line = null;
+ private List<Review.Comment> comments = new ArrayList<Review.Comment>();
+
+ /**
+ * @return the id
+ */
+ public Long getId() {
+ return id;
+ }
+
+ /**
+ * @param id
+ * the id to set
+ */
+ public void setId(Long id) {
+ this.id = id;
+ }
+
+ /**
+ * @return the createdAt
+ */
+ public Date getCreatedAt() {
+ return createdAt;
+ }
+
+ /**
+ * @param createdAt
+ * the createdAt to set
+ */
+ public void setCreatedAt(Date createdAt) {
+ this.createdAt = createdAt;
+ }
+
+ /**
+ * @return the updatedAt
+ */
+ public Date getUpdatedAt() {
+ return updatedAt;
+ }
+
+ /**
+ * @param updatedAt
+ * the updatedAt to set
+ */
+ public void setUpdatedAt(Date updatedAt) {
+ this.updatedAt = updatedAt;
+ }
+
+ /**
+ * @return the authorLogin
+ */
+ public String getAuthorLogin() {
+ return authorLogin;
+ }
+
+ /**
+ * @param authorLogin
+ * the authorLogin to set
+ */
+ public void setAuthorLogin(String authorLogin) {
+ this.authorLogin = authorLogin;
+ }
+
+ /**
+ * @return the assigneeLogin
+ */
+ public String getAssigneeLogin() {
+ return assigneeLogin;
+ }
+
+ /**
+ * @param assigneeLogin
+ * the assigneeLogin to set
+ */
+ public void setAssigneeLogin(String assigneeLogin) {
+ this.assigneeLogin = assigneeLogin;
+ }
+
+ /**
+ * @return the title
+ */
+ public String getTitle() {
+ return title;
+ }
+
+ /**
+ * @param title
+ * the title to set
+ */
+ public void setTitle(String title) {
+ this.title = title;
+ }
+
+ /**
+ * @return the type
+ */
+ public String getType() {
+ return type;
+ }
+
+ /**
+ * @param type
+ * the type to set
+ */
+ public void setType(String type) {
+ this.type = type;
+ }
+
+ /**
+ * @return the status
+ */
+ public String getStatus() {
+ return status;
+ }
+
+ /**
+ * @param status
+ * the status to set
+ */
+ public void setStatus(String status) {
+ this.status = status;
+ }
+
+ /**
+ * @return the severity
+ */
+ public String getSeverity() {
+ return severity;
+ }
+
+ /**
+ * @param severity
+ * the severity to set
+ */
+ public void setSeverity(String severity) {
+ this.severity = severity;
+ }
+
+ /**
+ * @return the resourceKee
+ */
+ public String getResourceKee() {
+ return resourceKee;
+ }
+
+ /**
+ * @param resourceKee
+ * the resourceKee to set
+ */
+ public void setResourceKee(String resourceKee) {
+ this.resourceKee = resourceKee;
+ }
+
+ /**
+ * @return the line
+ */
+ public Integer getLine() {
+ return line;
+ }
+
+ /**
+ * @param line
+ * the line to set
+ */
+ public void setLine(Integer line) {
+ this.line = line;
+ }
+
+ /**
+ * @return the comments
+ */
+ public List<Review.Comment> getComments() {
+ return comments;
+ }
+
+ /**
+ * @param comments
+ * the comments to set
+ */
+ public void addComments(Date updatedAt, String authorLogin, String text) {
+ this.comments.add(new Review.Comment(updatedAt, authorLogin, text));
+ }
+
+ /**
+ * @since 2.8
+ */
+ public class Comment extends Model {
+
+ private String authorLogin = null;
+ private Date updatedAt = null;
+ private String text = null;
+
+ private Comment(Date updatedAt, String authorLogin, String text) {
+ this.updatedAt = updatedAt;
+ this.authorLogin = authorLogin;
+ this.text = text;
+ }
+
+ /**
+ * @return the authorLogin
+ */
+ public String getAuthorLogin() {
+ return authorLogin;
+ }
+
+ /**
+ * @return the updatedAt
+ */
+ public Date getUpdatedAt() {
+ return updatedAt;
+ }
+
+ /**
+ * @return the text
+ */
+ public String getText() {
+ return text;
+ }
+ }
+
+}
--- /dev/null
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2008-2011 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
+ */
+package org.sonar.wsclient.services;
+
+/**
+ * @since 2.8
+ */
+public class ReviewQuery extends Query<Review> {
+
+ public static final String BASE_URL = "/api/reviews";
+
+ private String reviewType;
+ private Long id;
+ private Long[] ids;
+ private String[] statuses;
+ private String[] severities;
+ private Long[] projects;
+ private Long[] resources;
+ private Long[] authors;
+ private Long[] assignees;
+ private Boolean html;
+
+ public ReviewQuery() {
+ }
+
+ /**
+ * @return the reviewType
+ */
+ public String getReviewType() {
+ return reviewType;
+ }
+
+ /**
+ * @param reviewType
+ * the reviewType to set
+ */
+ public ReviewQuery setReviewType(String reviewType) {
+ this.reviewType = reviewType;
+ return this;
+ }
+
+ /**
+ * @return the id
+ */
+ public Long getId() {
+ return id;
+ }
+
+ /**
+ * @param id
+ * the id to set
+ */
+ public ReviewQuery setId(Long id) {
+ this.id = id;
+ return this;
+ }
+
+ /**
+ * @return the ids
+ */
+ public Long[] getIds() {
+ return ids;
+ }
+
+ /**
+ * @param ids
+ * the ids to set
+ */
+ public ReviewQuery setIds(Long... ids) {
+ this.ids = ids;
+ return this;
+ }
+
+ /**
+ * @return the statuses
+ */
+ public String[] getStatuses() {
+ return statuses;
+ }
+
+ /**
+ * @param statuses
+ * the statuses to set
+ */
+ public ReviewQuery setStatuses(String... statuses) {
+ this.statuses = statuses;
+ return this;
+ }
+
+ /**
+ * @return the severities
+ */
+ public String[] getSeverities() {
+ return severities;
+ }
+
+ /**
+ * @param severities
+ * the severities to set
+ */
+ public ReviewQuery setSeverities(String... severities) {
+ this.severities = severities;
+ return this;
+ }
+
+ /**
+ * @return the projects
+ */
+ public Long[] getProjects() {
+ return projects;
+ }
+
+ /**
+ * Specify the IDs of the projects.
+ *
+ * @param projects
+ * the project IDs to set
+ */
+ public ReviewQuery setProjects(Long... projects) {
+ this.projects = projects;
+ return this;
+ }
+
+ /**
+ * @return the resources
+ */
+ public Long[] getResources() {
+ return resources;
+ }
+
+ /**
+ * Specify the IDs of the resources.
+ *
+ * @param resources
+ * the resource IDs to set
+ */
+ public ReviewQuery setResources(Long... resources) {
+ this.resources = resources;
+ return this;
+ }
+
+ /**
+ * @return the authors
+ */
+ public Long[] getAuthors() {
+ return authors;
+ }
+
+ /**
+ * Specify the IDs of the authors.
+ *
+ * @param authors
+ * the author IDs to set
+ */
+ public ReviewQuery setAuthors(Long... authors) {
+ this.authors = authors;
+ return this;
+ }
+
+ /**
+ * @return the assignees
+ */
+ public Long[] getAssignees() {
+ return assignees;
+ }
+
+ /**
+ * Specify the IDs of the assignees.
+ *
+ * @param assignees
+ * the assignee IDs to set
+ */
+ public ReviewQuery setAssignees(Long... assignees) {
+ this.assignees = assignees;
+ return this;
+ }
+
+ /**
+ * @return the html
+ */
+ public Boolean getHtml() {
+ return html;
+ }
+
+ /**
+ * If true, the comments will be generated in HTML. Otherwise, they will be in raw text.
+ *
+ * @param html the html to set
+ */
+ public ReviewQuery setHtml(Boolean html) {
+ this.html = html;
+ return this;
+ }
+
+ @Override
+ public String getUrl() {
+ StringBuilder url = new StringBuilder(BASE_URL);
+ url.append('?');
+ if (id != null) {
+ appendUrlParameter(url, "id", id);
+ } else if (ids != null) {
+ appendUrlParameter(url, "ids", ids);
+ }
+ appendUrlParameter(url, "review_type", reviewType);
+ appendUrlParameter(url, "statuses", statuses);
+ appendUrlParameter(url, "severities", severities);
+ appendUrlParameter(url, "projects", projects);
+ appendUrlParameter(url, "resources", resources);
+ appendUrlParameter(url, "authors", authors);
+ appendUrlParameter(url, "assignees", assignees);
+ appendUrlParameter(url, "html", html);
+
+ return url.toString();
+ }
+
+ @Override
+ public Class<Review> getModelClass() {
+ return Review.class;
+ }
+
+ public static ReviewQuery createForResource(Resource resource) {
+ return new ReviewQuery().setId(new Long(resource.getId()));
+ }
+
+}
return switchedOff;
}
+ /**
+ * @since 2.8
+ */
public Long getReviewId() {
return reviewId;
}
+ /**
+ * @since 2.8
+ */
public Violation setReviewId(Long l) {
this.reviewId = l;
return this;
--- /dev/null
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2008-2011 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
+ */
+package org.sonar.wsclient.unmarshallers;
+
+import org.sonar.wsclient.services.Review;
+import org.sonar.wsclient.services.WSUtils;
+
+/**
+ * @since 2.8
+ */
+public class ReviewUnmarshaller extends AbstractUnmarshaller<Review> {
+
+ @Override
+ protected Review parse(Object json) {
+ WSUtils utils = WSUtils.getINSTANCE();
+
+ Review review = new Review();
+ review.setId(utils.getLong(json, "id"));
+ review.setCreatedAt(utils.getDateTime(json, "createdAt"));
+ review.setUpdatedAt(utils.getDateTime(json, "updatedAt"));
+ review.setAuthorLogin(utils.getString(json, "author"));
+ review.setAssigneeLogin(utils.getString(json, "assignee"));
+ review.setTitle(utils.getString(json, "title"));
+ review.setType(utils.getString(json, "type"));
+ review.setStatus(utils.getString(json, "status"));
+ review.setSeverity(utils.getString(json, "severity"));
+ review.setResourceKee(utils.getString(json, "resource"));
+ review.setLine(utils.getInteger(json, "line"));
+
+ Object comments = utils.getField(json, "comments");
+ if (comments != null) {
+ for (int i = 0; i < utils.getArraySize(comments); i++) {
+ Object comment = utils.getArrayElement(comments, i);
+ review.addComments(utils.getDateTime(comment, "updatedAt"), utils.getString(comment, "author"), utils.getString(comment, "text"));
+ }
+ }
+
+ return review;
+ }
+}
--- /dev/null
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2008-2011 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
+ */
+package org.sonar.wsclient.services;
+
+import static org.hamcrest.Matchers.is;
+import static org.junit.Assert.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import org.junit.Test;
+
+public class ReviewQueryTest extends QueryTestCase {
+
+ @Test
+ public void testSimpleQueryForResource() {
+ Resource resource = mock(Resource.class);
+ when(resource.getId()).thenReturn(69);
+ ReviewQuery query = ReviewQuery.createForResource(resource);
+ assertThat(query.getUrl(), is("/api/reviews?id=69&"));
+ assertThat(query.getModelClass().getName(), is(Review.class.getName()));
+ }
+
+ @Test
+ public void resourceTreeViolations() {
+ ReviewQuery query = new ReviewQuery();
+ query.setIds(10L, 11L);
+ query.setReviewType("FALSE_POSITIVE");
+ query.setStatuses("OPEN");
+ query.setSeverities("MINOR", "INFO");
+ query.setProjects(1L);
+ query.setResources(2L, 3L);
+ query.setAuthors(20L);
+ query.setAssignees(21L);
+ query.setHtml(Boolean.TRUE);
+ assertThat(
+ query.getUrl(),
+ is("/api/reviews?ids=10,11&review_type=FALSE_POSITIVE&statuses=OPEN&severities=MINOR,INFO&projects=1&resources=2,3&authors=20&assignees=21&html=true&"));
+ }
+}
--- /dev/null
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2008-2011 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
+ */
+package org.sonar.wsclient.unmarshallers;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.CoreMatchers.nullValue;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertThat;
+
+import java.util.List;
+
+import org.junit.Test;
+import org.sonar.wsclient.services.Review;
+import org.sonar.wsclient.services.Review.Comment;
+
+public class ReviewUnmarshallerTest extends UnmarshallerTestCase {
+
+ @Test
+ public void testToModels() {
+ Review review = new ReviewUnmarshaller().toModel("[]");
+ assertThat(review, nullValue());
+
+ List<Review> reviews = new ReviewUnmarshaller().toModels(loadFile("/reviews/reviews.json"));
+ assertThat(reviews.size(), is(2));
+
+ review = reviews.get(0);
+ assertThat(review.getAssigneeLogin(), nullValue());
+
+ review = reviews.get(1);
+ assertThat(review.getId(), is(3L));
+ assertNotNull(review.getCreatedAt());
+ assertNotNull(review.getUpdatedAt());
+ assertThat(review.getAuthorLogin(), is("admin"));
+ assertThat(review.getAssigneeLogin(), is("admin"));
+ assertThat(review.getTitle(), is("'static' modifier out of order with the JLS suggestions."));
+ assertThat(review.getType(), is("VIOLATION"));
+ assertThat(review.getStatus(), is("OPEN"));
+ assertThat(review.getSeverity(), is("MINOR"));
+ assertThat(review.getResourceKee(), is("org.codehaus.sonar:sonar-channel:org.sonar.channel.CodeReaderConfiguration"));
+ assertThat(review.getLine(), is(33));
+ List<Comment> comments = review.getComments();
+ assertThat(comments.size(), is(4));
+ Comment comment = comments.get(0);
+ assertNotNull(comment.getUpdatedAt());
+ assertThat(comment.getAuthorLogin(), is("admin"));
+ assertThat(comment.getText(), is("This is a review.<br/>And this is on multiple lines...<br/><br/><code>Wouhou!!!!!</code>"));
+ }
+
+}
--- /dev/null
+[{"id":9,"createdAt":"2011-04-27T14:37:20+0200","updatedAt":"2011-04-27T14:37:20+0200","author":"admin","title":"New exception is thrown in catch block, original stack trace may be lost","type":"VIOLATION","status":"OPEN","severity":"MAJOR","resource":"org.codehaus.sonar:sonar-channel:org.sonar.channel.CodeReader","line":84,"comments":[{"author":"admin","updatedAt":"2011-04-27T14:37:20+0200","text":"Wazzaaaa"}]},{"id":3,"createdAt":"2011-04-26T15:44:42+0200","updatedAt":"2011-04-26T15:44:42+0200","author":"admin","assignee":"admin","title":"'static' modifier out of order with the JLS suggestions.","type":"VIOLATION","status":"OPEN","severity":"MINOR","resource":"org.codehaus.sonar:sonar-channel:org.sonar.channel.CodeReaderConfiguration","line":33,"comments":[{"author":"admin","updatedAt":"2011-04-26T15:44:42+0200","text":"This is a review.<br/>And this is on multiple lines...<br/><br/><code>Wouhou!!!!!</code>"},{"author":"admin","updatedAt":"2011-04-26T17:10:19+0200","text":"<em>Bold on multiple line?</em>"},{"author":"admin","updatedAt":"2011-04-26T17:11:02+0200","text":"And the bullets:<br/><ul><li>1 bullet</li>\n<li>2 bullets</li></ul>"},{"author":"admin","updatedAt":"2011-04-26T17:27:37+0200","text":"Wazzaa"}]}]
\ No newline at end of file