aboutsummaryrefslogtreecommitdiffstats
path: root/sonar-server
diff options
context:
space:
mode:
authorFabrice Bellingard <bellingard@gmail.com>2012-05-13 22:41:21 +0200
committerFabrice Bellingard <bellingard@gmail.com>2012-05-14 15:11:01 +0200
commitb4d82de23fc414353dace746378fc8ec8e33b7a5 (patch)
tree69b3e363ed1cedd8924232db4af926a48ee7a265 /sonar-server
parentebab45f85888753e69b5acab3a26124cc1fc9c07 (diff)
downloadsonarqube-b4d82de23fc414353dace746378fc8ec8e33b7a5.tar.gz
sonarqube-b4d82de23fc414353dace746378fc8ec8e33b7a5.zip
SONAR-2706 / SONAR-2541 Refactoring
Diffstat (limited to 'sonar-server')
-rw-r--r--sonar-server/src/main/java/org/sonar/server/platform/Platform.java4
-rw-r--r--sonar-server/src/main/java/org/sonar/server/reviews/ReviewActionsManager.java73
-rw-r--r--sonar-server/src/main/java/org/sonar/server/reviews/ReviewManager.java97
-rw-r--r--sonar-server/src/main/java/org/sonar/server/ui/JRubyFacade.java23
-rw-r--r--sonar-server/src/main/webapp/WEB-INF/app/controllers/resource_controller.rb1
-rw-r--r--sonar-server/src/main/webapp/WEB-INF/app/controllers/reviews_controller.rb8
-rw-r--r--sonar-server/src/main/webapp/WEB-INF/app/models/api/review_context.rb50
-rw-r--r--sonar-server/src/main/webapp/WEB-INF/app/models/review.rb35
-rw-r--r--sonar-server/src/main/webapp/WEB-INF/app/views/resource/_violation.html.erb4
-rw-r--r--sonar-server/src/main/webapp/WEB-INF/app/views/reviews/_violation_comment_form.html.erb12
-rw-r--r--sonar-server/src/main/webapp/javascripts/resource.js4
-rw-r--r--sonar-server/src/test/java/org/sonar/server/reviews/ReviewActionsManagerTest.java82
-rw-r--r--sonar-server/src/test/java/org/sonar/server/reviews/ReviewManagerTest.java175
13 files changed, 374 insertions, 194 deletions
diff --git a/sonar-server/src/main/java/org/sonar/server/platform/Platform.java b/sonar-server/src/main/java/org/sonar/server/platform/Platform.java
index 76cb88f4c70..9c8c2b01ec0 100644
--- a/sonar-server/src/main/java/org/sonar/server/platform/Platform.java
+++ b/sonar-server/src/main/java/org/sonar/server/platform/Platform.java
@@ -72,7 +72,7 @@ import org.sonar.server.plugins.ServerExtensionInstaller;
import org.sonar.server.plugins.UpdateCenterClient;
import org.sonar.server.plugins.UpdateCenterMatrixFactory;
import org.sonar.server.qualitymodel.DefaultModelManager;
-import org.sonar.server.reviews.ReviewActionsManager;
+import org.sonar.server.reviews.ReviewManager;
import org.sonar.server.rules.ProfilesConsole;
import org.sonar.server.rules.RulesConsole;
import org.sonar.server.startup.ActivateDefaultProfiles;
@@ -241,7 +241,7 @@ public final class Platform {
servicesContainer.addSingleton(ReviewsNotificationManager.class);
// Reviews
- servicesContainer.addSingleton(ReviewActionsManager.class);
+ servicesContainer.addSingleton(ReviewManager.class);
servicesContainer.startComponents();
}
diff --git a/sonar-server/src/main/java/org/sonar/server/reviews/ReviewActionsManager.java b/sonar-server/src/main/java/org/sonar/server/reviews/ReviewActionsManager.java
deleted file mode 100644
index c7090952e05..00000000000
--- a/sonar-server/src/main/java/org/sonar/server/reviews/ReviewActionsManager.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Sonar, open source software quality management 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
- */
-package org.sonar.server.reviews;
-
-import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
-import org.sonar.api.reviews.ReviewAction;
-import org.sonar.api.utils.SonarException;
-
-import java.util.Collection;
-import java.util.Map;
-
-/**
- * @since 3.1
- */
-public class ReviewActionsManager {
-
- private Map<String, ReviewAction> idToAction = Maps.newHashMap();
- private Map<String, Collection<ReviewAction>> interfaceToAction = Maps.newHashMap();
-
- public ReviewActionsManager(ReviewAction[] reviewActions) {
- for (ReviewAction reviewAction : reviewActions) {
- idToAction.put(reviewAction.getId(), reviewAction);
- }
- }
-
- public ReviewActionsManager() {
- this(new ReviewAction[0]);
- }
-
- public ReviewAction getAction(String actionId) {
- return idToAction.get(actionId);
- }
-
- @SuppressWarnings({"unchecked", "rawtypes"})
- public Collection<ReviewAction> getActions(String interfaceName) {
- Collection<ReviewAction> result = interfaceToAction.get(interfaceName);
- if (result == null) {
- result = Lists.newArrayList();
- interfaceToAction.put(interfaceName, result);
- try {
- Class interfaceClass = Class.forName(interfaceName);
- for (ReviewAction reviewAction : idToAction.values()) {
- if (interfaceClass.isAssignableFrom(reviewAction.getClass())) {
- result.add(reviewAction);
- }
- }
- } catch (ClassNotFoundException e) {
- throw new SonarException("The following interface for review actions does not exist: " + interfaceName);
- }
-
- }
- return result;
- }
-
-}
diff --git a/sonar-server/src/main/java/org/sonar/server/reviews/ReviewManager.java b/sonar-server/src/main/java/org/sonar/server/reviews/ReviewManager.java
new file mode 100644
index 00000000000..d6ee862db3e
--- /dev/null
+++ b/sonar-server/src/main/java/org/sonar/server/reviews/ReviewManager.java
@@ -0,0 +1,97 @@
+/*
+ * Sonar, open source software quality management 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
+ */
+package org.sonar.server.reviews;
+
+import com.google.common.base.Preconditions;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import org.apache.commons.lang.StringUtils;
+import org.sonar.api.reviews.ReviewAction;
+import org.sonar.api.reviews.ReviewCommand;
+import org.sonar.api.reviews.ReviewContext;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @since 3.1
+ */
+public class ReviewManager {
+
+ private Map<String, ReviewCommand> idToCommand = Maps.newLinkedHashMap();
+
+ public ReviewManager(ReviewCommand[] reviewCommands) {
+ for (ReviewCommand reviewCommand : reviewCommands) {
+ idToCommand.put(reviewCommand.getId(), reviewCommand);
+ }
+ }
+
+ public ReviewManager() {
+ this(new ReviewCommand[0]);
+ }
+
+ public Collection<ReviewCommand> getAvailableCommandsFor(ReviewContext reviewContext) {
+ Preconditions.checkNotNull(reviewContext, "The review context must not be NULL when searching for available commands.");
+ List<ReviewCommand> commands = Lists.newArrayList();
+ for (ReviewCommand reviewCommand : idToCommand.values()) {
+ if (reviewCommand.isAvailableFor(reviewContext)) {
+ commands.add(reviewCommand);
+ }
+ }
+ return commands;
+ }
+
+ @SuppressWarnings({"unchecked", "rawtypes"})
+ public Collection<ReviewCommand> filterCommands(Collection<ReviewCommand> initialCommands, ReviewContext reviewContext, String interfaceName) {
+ Preconditions.checkNotNull(initialCommands, "The list of review commands must not be NULL when filtering commands.");
+ Preconditions.checkState(StringUtils.isNotBlank(interfaceName), "The interface name must not be blank when searching for available commands.");
+
+ Class interfaceClass = null;
+ try {
+ interfaceClass = Class.forName(interfaceName);
+ } catch (ClassNotFoundException e) {
+ throw new IllegalArgumentException("The following interface for review commands does not exist: " + interfaceName);
+ }
+
+ List<ReviewCommand> commands = Lists.newArrayList();
+ for (ReviewCommand reviewCommand : initialCommands) {
+ if (interfaceClass.isAssignableFrom(reviewCommand.getClass()) && reviewCommand.isAvailableFor(reviewContext)) {
+ commands.add(reviewCommand);
+ }
+ }
+ return commands;
+ }
+
+ public void executeCommandActions(String commandId, ReviewContext reviewContext) {
+ Preconditions.checkNotNull(reviewContext, "The review context must not be NULL when executing the actions of a command.");
+ ReviewCommand command = getCommand(commandId);
+ Preconditions.checkState(command != null, "The command with the following ID does not exist: " + commandId);
+
+ for (ReviewAction reviewAction : command.getActions()) {
+ reviewAction.execute(reviewContext);
+ }
+ }
+
+ public ReviewCommand getCommand(String commandId) {
+ return idToCommand.get(commandId);
+ }
+
+}
diff --git a/sonar-server/src/main/java/org/sonar/server/ui/JRubyFacade.java b/sonar-server/src/main/java/org/sonar/server/ui/JRubyFacade.java
index 5e726fbc4f3..108bf021e62 100644
--- a/sonar-server/src/main/java/org/sonar/server/ui/JRubyFacade.java
+++ b/sonar-server/src/main/java/org/sonar/server/ui/JRubyFacade.java
@@ -33,7 +33,8 @@ import org.sonar.api.profiles.ProfileImporter;
import org.sonar.api.resources.Language;
import org.sonar.api.resources.ResourceType;
import org.sonar.api.resources.ResourceTypes;
-import org.sonar.api.reviews.ReviewAction;
+import org.sonar.api.reviews.ReviewCommand;
+import org.sonar.api.reviews.ReviewContext;
import org.sonar.api.rules.RulePriority;
import org.sonar.api.rules.RuleRepository;
import org.sonar.api.utils.ValidationMessages;
@@ -62,7 +63,7 @@ import org.sonar.server.plugins.PluginDeployer;
import org.sonar.server.plugins.PluginDownloader;
import org.sonar.server.plugins.UpdateCenterMatrix;
import org.sonar.server.plugins.UpdateCenterMatrixFactory;
-import org.sonar.server.reviews.ReviewActionsManager;
+import org.sonar.server.reviews.ReviewManager;
import org.sonar.server.rules.ProfilesConsole;
import org.sonar.server.rules.RulesConsole;
import org.sonar.updatecenter.common.Version;
@@ -73,6 +74,7 @@ import java.net.InetAddress;
import java.sql.Connection;
import java.util.Collection;
import java.util.List;
+import java.util.Map;
import java.util.Set;
public final class JRubyFacade {
@@ -478,12 +480,21 @@ public final class JRubyFacade {
// REVIEWS ------------------------------------------------------------------
- public Collection<ReviewAction> getReviewActions(String interfaceName) {
- return getContainer().getComponentByType(ReviewActionsManager.class).getActions(interfaceName);
+ public Collection<ReviewCommand> getAvailableCommandsFor(Map<String, Map<String, String>> reviewContextPropertiesMap) {
+ return getContainer().getComponentByType(ReviewManager.class).getAvailableCommandsFor(ReviewContext.createFromMap(reviewContextPropertiesMap));
}
- public ReviewAction getReviewAction(String actionId) {
- return getContainer().getComponentByType(ReviewActionsManager.class).getAction(actionId);
+ public Collection<ReviewCommand> filterCommands(Collection<ReviewCommand> reviewCommands, Map<String, Map<String, String>> reviewContextPropertiesMap,
+ String interfaceName) {
+ return getContainer().getComponentByType(ReviewManager.class).filterCommands(reviewCommands, ReviewContext.createFromMap(reviewContextPropertiesMap), interfaceName);
+ }
+
+ public void executeCommandActions(String commandId, Map<String, Map<String, String>> reviewContextPropertiesMap) {
+ getContainer().getComponentByType(ReviewManager.class).executeCommandActions(commandId, ReviewContext.createFromMap(reviewContextPropertiesMap));
+ }
+
+ public ReviewCommand getCommand(String commandId) {
+ return getContainer().getComponentByType(ReviewManager.class).getCommand(commandId);
}
}
diff --git a/sonar-server/src/main/webapp/WEB-INF/app/controllers/resource_controller.rb b/sonar-server/src/main/webapp/WEB-INF/app/controllers/resource_controller.rb
index 330fbeeeeb8..81f52ab562f 100644
--- a/sonar-server/src/main/webapp/WEB-INF/app/controllers/resource_controller.rb
+++ b/sonar-server/src/main/webapp/WEB-INF/app/controllers/resource_controller.rb
@@ -332,6 +332,7 @@ class ResourceController < ApplicationController
@global_violations=[]
@expandable=(@lines!=nil)
@filtered=!@expanded
+ @review_commands= Review.available_commands_for( Api::ReviewContext.new(:project => @resource.root) )
if params[:rule].blank?
metric = Metric.by_id(params[:metric])
diff --git a/sonar-server/src/main/webapp/WEB-INF/app/controllers/reviews_controller.rb b/sonar-server/src/main/webapp/WEB-INF/app/controllers/reviews_controller.rb
index 928c04ae9ec..788ad12341c 100644
--- a/sonar-server/src/main/webapp/WEB-INF/app/controllers/reviews_controller.rb
+++ b/sonar-server/src/main/webapp/WEB-INF/app/controllers/reviews_controller.rb
@@ -138,8 +138,8 @@ class ReviewsController < ApplicationController
if !params[:comment_id].blank? && @violation.review
@comment = @violation.review.comments.find(params[:comment_id])
end
- unless params[:review_action_id].blank?
- @review_action = Review.getAction(params[:review_action_id])
+ unless params[:review_command_id].blank?
+ @review_command = Review.get_command(params[:review_command_id])
end
render :partial => 'reviews/violation_comment_form'
end
@@ -160,11 +160,11 @@ class ReviewsController < ApplicationController
:user => current_user)
end
- if !params[:text].blank? || !params[:review_action_id].blank?
+ if !params[:text].blank? || !params[:review_command_id].blank?
if params[:comment_id]
violation.review.edit_comment(current_user, params[:comment_id].to_i, params[:text])
else
- violation.review.create_comment({:user => current_user, :text => params[:text]}, params[:review_action_id])
+ violation.review.create_comment({:user => current_user, :text => params[:text]}, params[:review_command_id])
end
end
diff --git a/sonar-server/src/main/webapp/WEB-INF/app/models/api/review_context.rb b/sonar-server/src/main/webapp/WEB-INF/app/models/api/review_context.rb
new file mode 100644
index 00000000000..cb46e1df612
--- /dev/null
+++ b/sonar-server/src/main/webapp/WEB-INF/app/models/api/review_context.rb
@@ -0,0 +1,50 @@
+#
+# 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 Api::ReviewContext
+ def initialize(options={})
+ @review = options[:review]
+ @project = options[:project]
+ @user = options[:user]
+ @params = options[:params]
+ end
+
+ def to_string_map
+ result = {}
+ result['review'] = create_string_map_from_attributes @review if @review
+ result['project'] = create_string_map_from_attributes @project if @project
+ result['user'] = create_string_map_from_attributes @user if @user
+ result['params'] = ensure_key_and_values_as_strings @params if @params
+ result
+ end
+
+ def create_string_map_from_attributes(object)
+ ensure_key_and_values_as_strings(object.attributes)
+ end
+
+ def ensure_key_and_values_as_strings(params)
+ map = {}
+ params.each do |key, value|
+ map[key.to_s] = value.to_s
+ end
+ map
+ end
+
+end
diff --git a/sonar-server/src/main/webapp/WEB-INF/app/models/review.rb b/sonar-server/src/main/webapp/WEB-INF/app/models/review.rb
index 2d2b148e96f..18253223c3e 100644
--- a/sonar-server/src/main/webapp/WEB-INF/app/models/review.rb
+++ b/sonar-server/src/main/webapp/WEB-INF/app/models/review.rb
@@ -75,14 +75,12 @@ class Review < ActiveRecord::Base
# - :user
# - :text
#
- # param review_action_id is optional (=> specifies an action to
- # trigger instead of creating a simple comment)
- def create_comment(comment_values={}, review_action_id=nil)
- if review_action_id
- action = Review.getAction(review_action_id)
- if action
- action.execute({"review.id" => id.to_s, "user.login" => comment_values[:user].login, "comment.text" => comment_values[:text]})
- end
+ # param review_command_id is optional (=> specifies which command was
+ # triggered instead of creating a simple comment)
+ def create_comment(comment_values={}, review_command_id=nil)
+ if review_command_id
+ review_context = Api::ReviewContext.new(:review => self, :user => User.new(:login => comment_values[:user].login), :params => {"comment.text" => comment_values[:text]})
+ Java::OrgSonarServerUi::JRubyFacade.getInstance().executeCommandActions(review_command_id, review_context.to_string_map)
else
# simple comment
comment = comments.create!(comment_values)
@@ -263,18 +261,21 @@ class Review < ActiveRecord::Base
action_plans[0]
end
- def self.available_link_actions(current_review=nil)
-
- link_actions = Java::OrgSonarServerUi::JRubyFacade.getInstance().getReviewActions("org.sonar.api.reviews.LinkReviewAction")
- if current_review && current_review.data
- link_actions.reject {|action| current_review.data.include? (action.getId())}
- else
- link_actions
+ def self.available_commands_for(review_context)
+ Java::OrgSonarServerUi::JRubyFacade.getInstance().getAvailableCommandsFor(review_context.to_string_map)
+ end
+
+ def self.filter_commands(commands, violation, user=nil)
+ unless commands
+ commands= Review.available_commands_for( Api::ReviewContext.new(:project => violation.snapshot.root_project) )
end
+
+ review_context = Api::ReviewContext.new(:review => violation.review, :user => user)
+ actions = Java::OrgSonarServerUi::JRubyFacade.getInstance().filterCommands(commands, review_context.to_string_map, "org.sonar.api.reviews.LinkReviewCommand")
end
- def self.getAction(actionId)
- Java::OrgSonarServerUi::JRubyFacade.getInstance().getReviewAction(actionId)
+ def self.get_command(command_id)
+ Java::OrgSonarServerUi::JRubyFacade.getInstance().getCommand(command_id)
end
#
diff --git a/sonar-server/src/main/webapp/WEB-INF/app/views/resource/_violation.html.erb b/sonar-server/src/main/webapp/WEB-INF/app/views/resource/_violation.html.erb
index 0463ec16202..11f12198248 100644
--- a/sonar-server/src/main/webapp/WEB-INF/app/views/resource/_violation.html.erb
+++ b/sonar-server/src/main/webapp/WEB-INF/app/views/resource/_violation.html.erb
@@ -130,8 +130,8 @@
<li><%= link_to_function message('reviews.change_severity'), "sCSF(#{violation.id})", :name => 'bChangeSeverity' -%></li>
<li><%= link_to_function message('reviews.link_to_action_plan'), "sAPF(#{violation.id})", :name => 'bLinkActionPlan' -%></li>
- <% Review.available_link_actions(violation.review).each do |action| %>
- <li><%= link_to_function action.getName(), "sCF(#{violation.id}, '#{action.getId()}')", :name => 'bComment' -%></li>
+ <% Review.filter_commands(@review_commands, violation, current_user).each do |command| %>
+ <li><%= link_to_function command.getName(), "sCF(#{violation.id}, '#{command.getId()}')", :name => 'bComment' -%></li>
<% end %>
<% end %>
diff --git a/sonar-server/src/main/webapp/WEB-INF/app/views/reviews/_violation_comment_form.html.erb b/sonar-server/src/main/webapp/WEB-INF/app/views/reviews/_violation_comment_form.html.erb
index 8c6c899a03c..fcf463c4d9e 100644
--- a/sonar-server/src/main/webapp/WEB-INF/app/views/reviews/_violation_comment_form.html.erb
+++ b/sonar-server/src/main/webapp/WEB-INF/app/views/reviews/_violation_comment_form.html.erb
@@ -1,6 +1,6 @@
<%
- if @review_action
- button_label = @review_action.getName()
+ if @review_command
+ button_label = @review_command.getName()
else
button_label=(@comment ? message('reviews.update_comment_submit') : message('reviews.comment_submit'))
end
@@ -11,15 +11,15 @@
<% if @comment %>
<input type="hidden" name="comment_id" value="<%= @comment.id -%>"/>
<% end %>
- <% if @review_action %>
- <input type="hidden" name="review_action_id" value="<%= @review_action.getId() -%>"/>
+ <% if @review_command %>
+ <input type="hidden" name="review_command_id" value="<%= @review_command.getId() -%>"/>
<% end %>
<table class="width100">
<tr>
<td style="vertical-align:top">
<textarea id="commentText<%= params[:id] -%>"
- <% unless @review_action -%>
+ <% unless @review_command -%>
onkeyup="if (this.value=='') $('submit_btn<%= params[:id] -%>').disabled='true'; else $('submit_btn<%= params[:id] -%>').disabled='';"
<% end %>
rows="4" name="text" style="width: 100%"><%= @comment.text if @comment -%></textarea>
@@ -36,7 +36,7 @@
<%= submit_to_remote "submit_btn"+params[:id],
button_label,
:url => {:action => 'violation_save_comment'},
- :html => {:id => "submit_btn"+params[:id]}.merge(@review_action ? {} : {:disabled => "true"}),
+ :html => {:id => "submit_btn"+params[:id]}.merge(@review_command ? {} : {:disabled => "true"}),
:update => 'vId'+params[:id] -%>
&nbsp;
<%= link_to_function message('cancel'), "cancelViolationAction(#{params[:id]})" -%>
diff --git a/sonar-server/src/main/webapp/javascripts/resource.js b/sonar-server/src/main/webapp/javascripts/resource.js
index 7b64d3a74a3..148a9a110a3 100644
--- a/sonar-server/src/main/webapp/javascripts/resource.js
+++ b/sonar-server/src/main/webapp/javascripts/resource.js
@@ -40,11 +40,11 @@ function hideMoreViolationActions(violation_id) {
}
// show the form to comment violation
-function sCF(violation_id, review_action_id) {
+function sCF(violation_id, review_command_id) {
hideMoreViolationActions(violation_id);
new Ajax.Updater('reviewForm' + violation_id,
baseUrl + '/reviews/violation_comment_form/' + violation_id
- + (review_action_id==null ? "" : "?review_action_id=" + review_action_id),
+ + (review_command_id==null ? "" : "?review_command_id=" + review_command_id),
{
asynchronous:true,
evalScripts:true,
diff --git a/sonar-server/src/test/java/org/sonar/server/reviews/ReviewActionsManagerTest.java b/sonar-server/src/test/java/org/sonar/server/reviews/ReviewActionsManagerTest.java
deleted file mode 100644
index 47148fca9bb..00000000000
--- a/sonar-server/src/test/java/org/sonar/server/reviews/ReviewActionsManagerTest.java
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Sonar, open source software quality management 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
- */
-package org.sonar.server.reviews;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.sonar.api.reviews.LinkReviewAction;
-import org.sonar.api.reviews.ReviewAction;
-
-import java.util.Collection;
-import java.util.Map;
-
-import static org.hamcrest.Matchers.hasItem;
-import static org.hamcrest.Matchers.is;
-import static org.junit.Assert.assertThat;
-
-public class ReviewActionsManagerTest {
-
- private ReviewAction fakeLinkReviewAction = new FakeLinkReviewAction();
- private ReviewAction simpleReviewAction = new SimpleReviewAction();
- private ReviewActionsManager manager;
-
- @Before
- public void init() throws Exception {
- manager = new ReviewActionsManager(new ReviewAction[] {fakeLinkReviewAction, simpleReviewAction});
- }
-
- @Test
- public void shouldReturnActionsById() throws Exception {
- assertThat(manager.getAction("fake-link-review"), is(fakeLinkReviewAction));
- assertThat(manager.getAction("simple-review-action"), is(simpleReviewAction));
- }
-
- @Test
- public void shouldReturnActionsByInterfaceName() throws Exception {
- Collection<ReviewAction> reviewActions = manager.getActions("org.sonar.api.reviews.LinkReviewAction");
- assertThat(reviewActions.size(), is(1));
- assertThat(reviewActions, hasItem(fakeLinkReviewAction));
- }
-
- class FakeLinkReviewAction implements LinkReviewAction {
- public String getId() {
- return "fake-link-review";
- }
-
- public String getName() {
- return "Fake action";
- }
-
- public void execute(Map<String, String> reviewContext) {
- }
- }
- class SimpleReviewAction implements ReviewAction {
- public String getId() {
- return "simple-review-action";
- }
-
- public String getName() {
- return "Simple action";
- }
-
- public void execute(Map<String, String> reviewContext) {
- }
- }
-}
diff --git a/sonar-server/src/test/java/org/sonar/server/reviews/ReviewManagerTest.java b/sonar-server/src/test/java/org/sonar/server/reviews/ReviewManagerTest.java
new file mode 100644
index 00000000000..2d6bacfea6d
--- /dev/null
+++ b/sonar-server/src/test/java/org/sonar/server/reviews/ReviewManagerTest.java
@@ -0,0 +1,175 @@
+/*
+ * Sonar, open source software quality management 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
+ */
+package org.sonar.server.reviews;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.sonar.api.reviews.LinkReviewCommand;
+import org.sonar.api.reviews.ReviewAction;
+import org.sonar.api.reviews.ReviewCommand;
+import org.sonar.api.reviews.ReviewContext;
+import org.sonar.api.test.ReviewContextTestUtils;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+
+import static org.hamcrest.Matchers.hasItem;
+import static org.hamcrest.Matchers.is;
+import static org.junit.Assert.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+
+public class ReviewManagerTest {
+
+ @Rule
+ public ExpectedException thrown = ExpectedException.none();
+
+ private ReviewManager manager;
+ private ReviewAction action1;
+ private ReviewAction action2;
+ private ReviewAction action3;
+ private FakeLinkReviewCommand fakeLinkReviewCommand;
+ private SimpleReviewCommand simpleReviewCommand;
+
+ @Before
+ public void init() throws Exception {
+ action1 = mock(ReviewAction.class);
+ action2 = mock(ReviewAction.class);
+ action3 = mock(ReviewAction.class);
+ fakeLinkReviewCommand = new FakeLinkReviewCommand();
+ simpleReviewCommand = new SimpleReviewCommand();
+
+ manager = new ReviewManager(new ReviewCommand[] {fakeLinkReviewCommand, simpleReviewCommand});
+ }
+
+ @Test
+ public void testGetCommandById() throws Exception {
+ assertThat(manager.getCommand("simple-review-action"), is((ReviewCommand) simpleReviewCommand));
+ }
+
+ @Test
+ public void shouldGetAvailableCommandForReviewContext() throws Exception {
+ Map<String, String> reviewMap = Maps.newHashMap();
+ reviewMap.put("fake", "bar");
+ Map<String, Map<String, String>> contextMap = Maps.newHashMap();
+ contextMap.put("review", reviewMap);
+
+ ReviewContext context = ReviewContext.createFromMap(contextMap);
+ Collection<ReviewCommand> availableCommands = manager.getAvailableCommandsFor(context);
+ assertThat(availableCommands.size(), is(1));
+ assertThat(availableCommands, hasItem((ReviewCommand) fakeLinkReviewCommand));
+ }
+
+ @Test
+ public void shouldFilterCommands() throws Exception {
+ ReviewContext context = ReviewContextTestUtils.createReviewContext("review={fake=bar}");
+ Collection<ReviewCommand> filteredCommands = manager.filterCommands(Lists.newArrayList(fakeLinkReviewCommand, simpleReviewCommand), context,
+ "org.sonar.api.reviews.LinkReviewCommand");
+ assertThat(filteredCommands.size(), is(1));
+ assertThat(filteredCommands, hasItem((ReviewCommand) fakeLinkReviewCommand));
+ }
+
+ @Test
+ public void shouldFilterCommandsButNoMatch() throws Exception {
+ ReviewContext context = ReviewContextTestUtils.createReviewContext("review={simple=foo}");
+ Collection<ReviewCommand> filteredCommands = manager.filterCommands(Lists.newArrayList(fakeLinkReviewCommand, simpleReviewCommand), context,
+ "org.sonar.api.reviews.LinkReviewCommand");
+ assertThat(filteredCommands.size(), is(0));
+ }
+
+ @Test
+ public void shouldFailFilterCommandsIfUnknownInterface() throws Exception {
+ ReviewContext context = ReviewContextTestUtils.createReviewContext("review={fake=bar}");
+
+ thrown.expect(IllegalArgumentException.class);
+ thrown.expectMessage("The following interface for review commands does not exist: org.sonar.api.reviews.UnkonwnReviewCommand");
+
+ manager.filterCommands(Lists.newArrayList(fakeLinkReviewCommand, simpleReviewCommand), context, "org.sonar.api.reviews.UnkonwnReviewCommand");
+ }
+
+ @Test
+ public void shouldExecuteCommandActions() throws Exception {
+ ReviewContext reviewContext = ReviewContext.createFromMap(new HashMap<String, Map<String, String>>());
+ manager.executeCommandActions("fake-link-review", reviewContext);
+ verify(action1).execute(reviewContext);
+ verify(action2).execute(reviewContext);
+ verify(action3, never()).execute(reviewContext);
+ }
+
+ @Test
+ public void shouldFailExecuteCommandActionsIfCommandDoesNotExist() throws Exception {
+ ReviewContext reviewContext = ReviewContext.createFromMap(new HashMap<String, Map<String, String>>());
+
+ thrown.expect(IllegalStateException.class);
+ thrown.expectMessage("The command with the following ID does not exist: unexisting-command");
+
+ manager.executeCommandActions("unexisting-command", reviewContext);
+ }
+
+ class FakeLinkReviewCommand extends ReviewCommand implements LinkReviewCommand {
+ @Override
+ public String getId() {
+ return "fake-link-review";
+ }
+
+ @Override
+ public String getName() {
+ return "Fake action";
+ }
+
+ @Override
+ public boolean isAvailableFor(ReviewContext reviewContext) {
+ return reviewContext.getReviewProperty("fake") != null;
+ }
+
+ @Override
+ public Collection<ReviewAction> getActions() {
+ return Lists.newArrayList(action1, action2);
+ }
+ }
+
+ class SimpleReviewCommand extends ReviewCommand {
+ @Override
+ public String getId() {
+ return "simple-review-action";
+ }
+
+ @Override
+ public String getName() {
+ return "Simple action";
+ }
+
+ @Override
+ public boolean isAvailableFor(ReviewContext reviewContext) {
+ return reviewContext.getReviewProperty("simple") != null;
+ }
+
+ @Override
+ public Collection<ReviewAction> getActions() {
+ return Lists.newArrayList(action3);
+ }
+ }
+}