]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-8460 Simplify creation of BadRequestException with one message
authorJulien Lancelot <julien.lancelot@sonarsource.com>
Wed, 1 Mar 2017 11:04:32 +0000 (12:04 +0100)
committerJulien Lancelot <julien.lancelot@sonarsource.com>
Thu, 2 Mar 2017 08:26:10 +0000 (09:26 +0100)
43 files changed:
server/sonar-server/src/main/java/org/sonar/server/batch/ProjectDataLoader.java
server/sonar-server/src/main/java/org/sonar/server/component/ComponentUpdater.java
server/sonar-server/src/main/java/org/sonar/server/es/Sorting.java
server/sonar-server/src/main/java/org/sonar/server/exceptions/BadRequestException.java
server/sonar-server/src/main/java/org/sonar/server/issue/IssueService.java
server/sonar-server/src/main/java/org/sonar/server/measure/custom/ws/CreateAction.java
server/sonar-server/src/main/java/org/sonar/server/measure/ws/ComponentTreeSort.java
server/sonar-server/src/main/java/org/sonar/server/metric/ws/CreateAction.java
server/sonar-server/src/main/java/org/sonar/server/metric/ws/UpdateAction.java
server/sonar-server/src/main/java/org/sonar/server/permission/ApplyPermissionTemplateQuery.java
server/sonar-server/src/main/java/org/sonar/server/permission/GroupPermissionChanger.java
server/sonar-server/src/main/java/org/sonar/server/permission/UserPermissionChanger.java
server/sonar-server/src/main/java/org/sonar/server/permission/ws/PermissionRequestValidator.java
server/sonar-server/src/main/java/org/sonar/server/plugins/PluginDownloader.java
server/sonar-server/src/main/java/org/sonar/server/qualitygate/QualityGateConditionsUpdater.java
server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/ProjectStatusAction.java
server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QualityGatesWs.java
server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/ShowAction.java
server/sonar-server/src/main/java/org/sonar/server/qualityprofile/QProfileExporters.java
server/sonar-server/src/main/java/org/sonar/server/qualityprofile/QProfileFactory.java
server/sonar-server/src/main/java/org/sonar/server/qualityprofile/QProfileReset.java
server/sonar-server/src/main/java/org/sonar/server/qualityprofile/RuleActivator.java
server/sonar-server/src/main/java/org/sonar/server/qualityprofile/RuleActivatorContext.java
server/sonar-server/src/main/java/org/sonar/server/qualityprofile/RuleActivatorContextFactory.java
server/sonar-server/src/main/java/org/sonar/server/root/ws/UnsetRootAction.java
server/sonar-server/src/main/java/org/sonar/server/setting/ws/SetAction.java
server/sonar-server/src/main/java/org/sonar/server/setting/ws/SettingValidations.java
server/sonar-server/src/main/java/org/sonar/server/user/UserUpdater.java
server/sonar-server/src/main/java/org/sonar/server/user/ws/DeactivateAction.java
server/sonar-server/src/main/java/org/sonar/server/usergroups/ws/GroupWsSupport.java
server/sonar-server/src/main/java/org/sonar/server/usergroups/ws/RemoveUserAction.java
server/sonar-server/src/main/java/org/sonar/server/util/BooleanTypeValidation.java
server/sonar-server/src/main/java/org/sonar/server/util/FloatTypeValidation.java
server/sonar-server/src/main/java/org/sonar/server/util/IntegerTypeValidation.java
server/sonar-server/src/main/java/org/sonar/server/util/LongTypeValidation.java
server/sonar-server/src/main/java/org/sonar/server/util/MetricLevelTypeValidation.java
server/sonar-server/src/main/java/org/sonar/server/util/StringListTypeValidation.java
server/sonar-server/src/main/java/org/sonar/server/util/TypeValidations.java
server/sonar-server/src/main/java/org/sonar/server/util/Validation.java
server/sonar-server/src/main/java/org/sonar/server/ws/WsUtils.java
server/sonar-server/src/test/java/org/sonar/server/exceptions/BadRequestExceptionTest.java
server/sonar-server/src/test/java/org/sonar/server/project/ws/CreateActionTest.java
server/sonar-server/src/test/java/org/sonar/server/ws/WebServiceEngineTest.java

index fab76d2bb5524e192638582c800934f134a1c75f..875ac417f1b17b353b31ee8f4beb708418096ed9 100644 (file)
@@ -36,16 +36,15 @@ import org.sonar.db.component.FilePathWithHashDto;
 import org.sonar.db.property.PropertyDto;
 import org.sonar.scanner.protocol.input.FileData;
 import org.sonar.scanner.protocol.input.ProjectRepositories;
-import org.sonar.server.exceptions.BadRequestException;
 import org.sonar.server.exceptions.ForbiddenException;
 import org.sonar.server.user.UserSession;
 
 import static com.google.common.collect.Lists.newArrayList;
 import static com.google.common.collect.Maps.newHashMap;
-import static java.lang.String.format;
 import static org.sonar.api.web.UserRole.USER;
 import static org.sonar.core.permission.GlobalPermissions.SCAN_EXECUTION;
 import static org.sonar.server.ws.WsUtils.checkFoundWithOptional;
+import static org.sonar.server.ws.WsUtils.checkRequest;
 
 @ServerSide
 public class ProjectDataLoader {
@@ -63,9 +62,7 @@ public class ProjectDataLoader {
       ProjectRepositories data = new ProjectRepositories();
       ComponentDto module = checkFoundWithOptional(dbClient.componentDao().selectByKey(session, query.getModuleKey()),
         "Project or module with key '%s' is not found", query.getModuleKey());
-      if (!isProjectOrModule(module)) {
-        throw new BadRequestException(format("Key '%s' belongs to a component which is not a Project", query.getModuleKey()));
-      }
+      checkRequest(isProjectOrModule(module), "Key '%s' belongs to a component which is not a Project", query.getModuleKey());
 
       boolean hasScanPerm = userSession.hasComponentPermission(SCAN_EXECUTION, module) ||
         userSession.hasOrganizationPermission(module.getOrganizationUuid(), SCAN_EXECUTION);
index 06a12193f573b99ed2774b0d655463fc8e9d3714..65d9355f812b279b5973ecc21ce15bc6701494ff 100644 (file)
@@ -34,7 +34,6 @@ import org.sonar.db.DbSession;
 import org.sonar.db.component.ComponentDto;
 import org.sonar.server.es.ProjectIndexer;
 import org.sonar.server.es.ProjectIndexer.Cause;
-import org.sonar.server.exceptions.BadRequestException;
 import org.sonar.server.favorite.FavoriteUpdater;
 import org.sonar.server.permission.PermissionTemplateService;
 
@@ -82,9 +81,8 @@ public class ComponentUpdater {
   private ComponentDto createRootComponent(DbSession session, NewComponent newComponent) {
     checkBranchFormat(newComponent.qualifier(), newComponent.branch());
     String keyWithBranch = ComponentKeys.createKey(newComponent.key(), newComponent.branch());
-    if (dbClient.componentDao().selectByKey(session, keyWithBranch).isPresent()) {
-      throw new BadRequestException(formatMessage("Could not create %s, key already exists: %s", newComponent.qualifier(), keyWithBranch));
-    }
+    checkRequest(!dbClient.componentDao().selectByKey(session, keyWithBranch).isPresent(),
+      formatMessage("Could not create %s, key already exists: %s", newComponent.qualifier(), keyWithBranch));
 
     String uuid = Uuids.create();
     ComponentDto component = new ComponentDto()
@@ -122,7 +120,7 @@ public class ComponentUpdater {
   private void handlePermissionTemplate(DbSession dbSession, ComponentDto componentDto, String organizationUuid, @Nullable Long userId) {
     permissionTemplateService.applyDefault(dbSession, organizationUuid, componentDto, userId);
     if (componentDto.qualifier().equals(PROJECT)
-        && permissionTemplateService.hasDefaultTemplateWithPermissionOnProjectCreator(dbSession, organizationUuid, componentDto)) {
+      && permissionTemplateService.hasDefaultTemplateWithPermissionOnProjectCreator(dbSession, organizationUuid, componentDto)) {
       favoriteUpdater.add(dbSession, componentDto, userId);
     }
   }
@@ -133,10 +131,8 @@ public class ComponentUpdater {
   }
 
   private void checkBranchFormat(String qualifier, @Nullable String branch) {
-    if (branch != null && !ComponentKeys.isValidBranch(branch)) {
-      throw new BadRequestException(formatMessage("Malformed branch for %s: %s. Allowed characters are alphanumeric, '-', '_', '.' and '/', with at least one non-digit.",
-        qualifier, branch));
-    }
+    checkRequest(branch == null || ComponentKeys.isValidBranch(branch),
+      formatMessage("Malformed branch for %s: %s. Allowed characters are alphanumeric, '-', '_', '.' and '/', with at least one non-digit.", qualifier, branch));
   }
 
   private String formatMessage(String message, String qualifier, String key) {
index 81381855c0b6f8fdec8b2f8a8e5ac6e6c0aefe14..082664fec0f294cd3f77e19955d4748edb4cadaa 100644 (file)
@@ -22,13 +22,13 @@ package org.sonar.server.es;
 import com.google.common.collect.ArrayListMultimap;
 import com.google.common.collect.ListMultimap;
 import com.google.common.collect.Lists;
+import java.util.List;
 import org.elasticsearch.action.search.SearchRequestBuilder;
 import org.elasticsearch.search.sort.FieldSortBuilder;
 import org.elasticsearch.search.sort.SortBuilders;
 import org.elasticsearch.search.sort.SortOrder;
-import org.sonar.server.exceptions.BadRequestException;
 
-import java.util.List;
+import static org.sonar.server.ws.WsUtils.checkRequest;
 
 /**
  * Construct sorting criteria of ES requests. Sortable fields must be previously
@@ -63,9 +63,7 @@ public class Sorting {
 
   public void fill(SearchRequestBuilder request, String name, boolean asc) {
     List<Field> list = fields.get(name);
-    if (list.isEmpty()) {
-      throw new BadRequestException("Bad sort field: " + name);
-    }
+    checkRequest(!list.isEmpty(), "Bad sort field: %s", name);
     doFill(request, list, asc);
   }
 
index 523c35e73ea4f7c18b2a5fed9f2f28d1b2151309..6212ad56571f236ab88ab067513e6d0368aeca7c 100644 (file)
@@ -25,6 +25,7 @@ import java.util.stream.Collectors;
 
 import static com.google.common.base.Preconditions.checkArgument;
 import static java.net.HttpURLConnection.HTTP_BAD_REQUEST;
+import static java.util.Arrays.asList;
 
 /**
  * Request is not valid and can not be processed.
@@ -33,11 +34,6 @@ public class BadRequestException extends ServerException {
 
   private final transient Errors errors;
 
-  public BadRequestException(String message) {
-    super(HTTP_BAD_REQUEST, message);
-    this.errors = new Errors().add(Message.of(message));
-  }
-
   private BadRequestException(Errors e) {
     super(HTTP_BAD_REQUEST, e.messages().get(0).getMessage());
     this.errors = e;
@@ -47,6 +43,10 @@ public class BadRequestException extends ServerException {
     return create(new Errors().add(errorMessages.stream().map(Message::of).collect(Collectors.toList())));
   }
 
+  public static BadRequestException create(String... errorMessages) {
+    return create(asList(errorMessages));
+  }
+
   public static BadRequestException create(Errors e) {
     checkArgument(!e.messages().isEmpty(), "At least one error message is required");
     return new BadRequestException(e);
index 4d205912acc63c076f0db2683f736f0a81951e48..61d65a33449ae7bcd36ab336a205e255f7c8f072 100644 (file)
@@ -33,10 +33,11 @@ import org.sonar.core.issue.DefaultIssue;
 import org.sonar.core.issue.IssueChangeContext;
 import org.sonar.db.DbClient;
 import org.sonar.db.DbSession;
-import org.sonar.server.exceptions.BadRequestException;
 import org.sonar.server.issue.index.IssueIndex;
 import org.sonar.server.user.UserSession;
 
+import static org.sonar.server.ws.WsUtils.checkRequest;
+
 @ServerSide
 @ComputeEngineSide
 public class IssueService {
@@ -70,9 +71,7 @@ public class IssueService {
       User user = null;
       if (!Strings.isNullOrEmpty(assignee)) {
         user = userFinder.findByLogin(assignee);
-        if (user == null) {
-          throw new BadRequestException("Unknown user: " + assignee);
-        }
+        checkRequest(user != null, "Unknown user: %s", assignee);
       }
       IssueChangeContext context = IssueChangeContext.createUser(new Date(), userSession.getLogin());
       if (issueFieldsSetter.assign(issue, user, context)) {
index bf630ef1b75cb17cce0621f08b770bc5b5c5011f..e7e606deff1f6b5e6ee36f8200773cdfc2c0d3cd 100644 (file)
@@ -32,7 +32,6 @@ import org.sonar.db.measure.custom.CustomMeasureDto;
 import org.sonar.db.metric.MetricDto;
 import org.sonar.db.user.UserDto;
 import org.sonar.server.component.ComponentFinder;
-import org.sonar.server.exceptions.BadRequestException;
 import org.sonar.server.user.UserSession;
 
 import static com.google.common.base.Preconditions.checkArgument;
@@ -40,6 +39,7 @@ import static org.sonar.server.component.ComponentFinder.ParamNames.PROJECT_ID_A
 import static org.sonar.server.measure.custom.ws.CustomMeasureValidator.checkPermissions;
 import static org.sonar.server.measure.custom.ws.CustomMeasureValueDescription.measureValueDescription;
 import static org.sonar.server.ws.KeyExamples.KEY_PROJECT_EXAMPLE_001;
+import static org.sonar.server.ws.WsUtils.checkRequest;
 
 public class CreateAction implements CustomMeasuresWsAction {
   public static final String ACTION = "create";
@@ -137,17 +137,14 @@ public class CreateAction implements CustomMeasuresWsAction {
   }
 
   private static void checkIsProjectOrModule(ComponentDto component) {
-    if (!Scopes.PROJECT.equals(component.scope())) {
-      throw new BadRequestException(String.format("Component '%s' (id: %s) must be a project or a module.", component.key(), component.uuid()));
-    }
+    checkRequest(Scopes.PROJECT.equals(component.scope()), "Component '%s' (id: %s) must be a project or a module.", component.key(), component.uuid());
   }
 
   private void checkMeasureDoesNotExistAlready(DbSession dbSession, ComponentDto component, MetricDto metric) {
     int nbMeasuresOnSameMetricAndMeasure = dbClient.customMeasureDao().countByComponentIdAndMetricId(dbSession, component.uuid(), metric.getId());
-    if (nbMeasuresOnSameMetricAndMeasure > 0) {
-      throw new BadRequestException(String.format("A measure already exists for project '%s' (id: %s) and metric '%s' (id: '%d')",
-        component.key(), component.uuid(), metric.getKey(), metric.getId()));
-    }
+    checkRequest(nbMeasuresOnSameMetricAndMeasure == 0,
+      "A measure already exists for project '%s' (id: %s) and metric '%s' (id: '%d')",
+      component.key(), component.uuid(), metric.getKey(), metric.getId());
   }
 
   private MetricDto searchMetric(DbSession dbSession, Request request) {
index a501e9542f1de8d7827f7e04cccdae5f08b4f313..50a42682c5ba6f0b47c02e12888691221111ec78 100644 (file)
@@ -148,7 +148,7 @@ public class ComponentTreeSort {
       return numericalMetricPeriodOrdering(wsRequest, metric, measuresByComponentUuidAndMetric);
     }
 
-    throw new BadRequestException(format("Impossible to sort metric '%s' by measure period.", metric.getKey()));
+    throw BadRequestException.create(format("Impossible to sort metric '%s' by measure period.", metric.getKey()));
   }
 
   private static Ordering<ComponentDto> numericalMetricOrdering(boolean isAscending, @Nullable MetricDto metric,
index c25a164b95e8de87a3c9f205fb61542af80a18fa..59b37d16fa1c2965edfdd80bd1479eaa37dcc527 100644 (file)
@@ -30,10 +30,11 @@ import org.sonar.db.DbClient;
 import org.sonar.db.DbSession;
 import org.sonar.db.measure.custom.CustomMeasureDto;
 import org.sonar.db.metric.MetricDto;
-import org.sonar.server.exceptions.BadRequestException;
 import org.sonar.server.user.UserSession;
 
+import static com.google.common.base.Preconditions.checkArgument;
 import static org.sonar.server.util.MetricKeyValidator.checkMetricKeyFormat;
+import static org.sonar.server.ws.WsUtils.checkRequest;
 
 public class CreateAction implements MetricsWsAction {
   private static final String ACTION = "create";
@@ -165,24 +166,15 @@ public class CreateAction implements MetricsWsAction {
   }
 
   private void checkMetricInDbAndTemplate(DbSession dbSession, @Nullable MetricDto metricInDb, MetricDto template) {
-    if (areOneOfTheMandatoryArgumentsEmpty(template)) {
-      throw new IllegalArgumentException(String.format("The mandatory arguments '%s','%s' and '%s' must not be empty", PARAM_KEY, PARAM_NAME, PARAM_TYPE));
-    }
+    checkArgument(!areOneOfTheMandatoryArgumentsEmpty(template), "The mandatory arguments '%s','%s' and '%s' must not be empty", PARAM_KEY, PARAM_NAME, PARAM_TYPE);
     if (metricIsNotInDb(metricInDb)) {
       return;
     }
-    if (isMetricEnabled(metricInDb)) {
-      throw new BadRequestException("An active metric already exist with key: " + metricInDb.getKey());
-    }
-    if (isMetricNonCustom(metricInDb)) {
-      throw new BadRequestException("An non custom metric already exist with key: " + metricInDb.getKey());
-    }
+    checkRequest(!isMetricEnabled(metricInDb), "An active metric already exist with key: " + metricInDb.getKey());
+    checkRequest(!isMetricNonCustom(metricInDb), "An non custom metric already exist with key: %s", metricInDb.getKey());
     if (hasMetricTypeChanged(metricInDb, template)) {
       List<CustomMeasureDto> customMeasures = dbClient.customMeasureDao().selectByMetricId(dbSession, metricInDb.getId());
-      if (hasAssociatedCustomMeasures(customMeasures)) {
-        throw new BadRequestException(String.format("You're trying to change the type '%s' while there are associated measures.",
-          metricInDb.getValueType()));
-      }
+      checkRequest(!hasAssociatedCustomMeasures(customMeasures), "You're trying to change the type '%s' while there are associated measures.", metricInDb.getValueType());
     }
   }
 
index cbd0ff6342ed8beaf382ed18c923b8a6a9337e67..2cefd31a72501be85a40f0cd2f365157bdda7676 100644 (file)
@@ -30,10 +30,11 @@ import org.sonar.db.DbClient;
 import org.sonar.db.DbSession;
 import org.sonar.db.measure.custom.CustomMeasureDto;
 import org.sonar.db.metric.MetricDto;
-import org.sonar.server.exceptions.BadRequestException;
 import org.sonar.server.user.UserSession;
 import org.sonar.server.util.MetricKeyValidator;
 
+import static org.sonar.server.ws.WsUtils.checkRequest;
+
 public class UpdateAction implements MetricsWsAction {
   private static final String ACTION = "update";
 
@@ -166,25 +167,20 @@ public class UpdateAction implements MetricsWsAction {
   }
 
   private void checkMetricInDbAndTemplate(DbSession dbSession, @Nullable MetricDto metricInDb, MetricDto template) {
-    if (!isMetricFoundInDb(metricInDb) || isMetricDisabled(metricInDb) || !isMetricCustom(metricInDb)) {
-      throw new BadRequestException(String.format("No active custom metric has been found for id '%d'.", template.getId()));
-    }
+    checkRequest(isMetricFoundInDb(metricInDb) && !isMetricDisabled(metricInDb) && isMetricCustom(metricInDb),
+      "No active custom metric has been found for id '%d'.", template.getId());
     checkNoOtherMetricWithTargetKey(dbSession, metricInDb, template);
     if (haveMetricTypeChanged(metricInDb, template)) {
       List<CustomMeasureDto> customMeasures = dbClient.customMeasureDao().selectByMetricId(dbSession, metricInDb.getId());
-      if (haveAssociatedCustomMeasures(customMeasures)) {
-        throw new BadRequestException(String.format("You're trying to change the type '%s' while there are associated custom measures.",
-          metricInDb.getValueType()));
-      }
+      checkRequest(!haveAssociatedCustomMeasures(customMeasures), "You're trying to change the type '%s' while there are associated custom measures.", metricInDb.getValueType());
     }
   }
 
   private void checkNoOtherMetricWithTargetKey(DbSession dbSession, MetricDto metricInDb, MetricDto template) {
     String targetKey = template.getKey();
     MetricDto metricWithTargetKey = dbClient.metricDao().selectByKey(dbSession, targetKey);
-    if (isMetricFoundInDb(metricWithTargetKey) && !metricInDb.getId().equals(metricWithTargetKey.getId())) {
-      throw new BadRequestException(String.format("The key '%s' is already used by an existing metric.", targetKey));
-    }
+    checkRequest(!isMetricFoundInDb(metricWithTargetKey) || metricInDb.getId().equals(metricWithTargetKey.getId()),
+      "The key '%s' is already used by an existing metric.", targetKey);
   }
 
   private static void writeMetric(JsonWriter json, MetricDto metric) {
index 451e527098e109862b227d8366219ab452835fe4..ee7d21897207506219e180190aac84461abe53e2 100644 (file)
@@ -20,9 +20,9 @@
 package org.sonar.server.permission;
 
 import java.util.List;
-import org.sonar.server.exceptions.BadRequestException;
 
-import static com.google.common.base.CharMatcher.WHITESPACE;
+import static org.apache.commons.lang.StringUtils.isNotBlank;
+import static org.sonar.server.ws.WsUtils.checkRequest;
 
 public class ApplyPermissionTemplateQuery {
 
@@ -48,11 +48,7 @@ public class ApplyPermissionTemplateQuery {
   }
 
   private void validate() {
-    if (templateUuid == null || WHITESPACE.trimFrom(templateUuid).isEmpty()) {
-      throw new BadRequestException("Permission template is mandatory");
-    }
-    if (componentKeys == null || componentKeys.isEmpty()) {
-      throw new BadRequestException("No project provided. Please provide at least one project.");
-    }
+    checkRequest(isNotBlank(templateUuid), "Permission template is mandatory");
+    checkRequest(componentKeys != null && !componentKeys.isEmpty(), "No project provided. Please provide at least one project.");
   }
 }
index 1a4de6d5c98e45e7040aa15e077c673650c6affe..1b2e4ab27d84c3ca54b2ab47ee655e67b83fb18e 100644 (file)
@@ -24,11 +24,10 @@ import java.util.Optional;
 import org.sonar.db.DbClient;
 import org.sonar.db.DbSession;
 import org.sonar.db.permission.GroupPermissionDto;
-import org.sonar.server.exceptions.BadRequestException;
 
-import static java.lang.String.format;
 import static org.sonar.core.permission.GlobalPermissions.SYSTEM_ADMIN;
 import static org.sonar.server.permission.ws.PermissionRequestValidator.validateNotAnyoneAndAdminPermission;
+import static org.sonar.server.ws.WsUtils.checkRequest;
 
 public class GroupPermissionChanger {
 
@@ -97,10 +96,7 @@ public class GroupPermissionChanger {
       // removing global admin permission from group
       int remaining = dbClient.authorizationDao().countUsersWithGlobalPermissionExcludingGroup(dbSession,
         change.getOrganizationUuid(), SYSTEM_ADMIN, change.getGroupIdOrAnyone().getId());
-
-      if (remaining == 0) {
-        throw new BadRequestException(format("Last group with permission '%s'. Permission cannot be removed.", SYSTEM_ADMIN));
-      }
+      checkRequest(remaining > 0, "Last group with permission '%s'. Permission cannot be removed.", SYSTEM_ADMIN);
     }
   }
 
index ed862bbbab97a16981575b72dce5c9a3ffbb4d8c..3d0d4ac9787a26f39735edbee0a0a4d4e4a1f473 100644 (file)
@@ -24,9 +24,9 @@ import java.util.Optional;
 import org.sonar.db.DbClient;
 import org.sonar.db.DbSession;
 import org.sonar.db.permission.UserPermissionDto;
-import org.sonar.server.exceptions.BadRequestException;
 
 import static org.sonar.core.permission.GlobalPermissions.SYSTEM_ADMIN;
+import static org.sonar.server.ws.WsUtils.checkRequest;
 
 /**
  * Adds and removes user permissions. Both global and project scopes are supported.
@@ -89,9 +89,7 @@ public class UserPermissionChanger {
     if (SYSTEM_ADMIN.equals(change.getPermission()) && !change.getProjectId().isPresent()) {
       int remaining = dbClient.authorizationDao().countUsersWithGlobalPermissionExcludingUserPermission(dbSession,
         change.getOrganizationUuid(), change.getPermission(), change.getUserId().getId());
-      if (remaining == 0) {
-        throw new BadRequestException(String.format("Last user with permission '%s'. Permission cannot be removed.", SYSTEM_ADMIN));
-      }
+      checkRequest(remaining > 0, "Last user with permission '%s'. Permission cannot be removed.", SYSTEM_ADMIN);
     }
   }
 }
index fbf13b732f2d8e39fd01ead8bfb8d645420c7f04..15dfb603cd421bfb4f72050155e20823f7c3ad90 100644 (file)
@@ -91,7 +91,7 @@ public class PermissionRequestValidator {
     try {
       Pattern.compile(projectPattern);
     } catch (PatternSyntaxException e) {
-      throw new BadRequestException(format("The '%s' parameter must be a valid Java regular expression. '%s' was passed", PARAM_PROJECT_KEY_PATTERN, projectPattern));
+      throw BadRequestException.create(format("The '%s' parameter must be a valid Java regular expression. '%s' was passed", PARAM_PROJECT_KEY_PATTERN, projectPattern));
     }
   }
 }
index 784809e702d4ac9f624c17e3213297e5e30f1cdd..0e5f752e7ea1bd5805c1f1d9189f12610816a5d7 100644 (file)
@@ -34,7 +34,6 @@ import org.sonar.api.utils.SonarException;
 import org.sonar.api.utils.log.Logger;
 import org.sonar.api.utils.log.Loggers;
 import org.sonar.core.platform.PluginInfo;
-import org.sonar.server.exceptions.BadRequestException;
 import org.sonar.server.platform.ServerFileSystem;
 import org.sonar.updatecenter.common.Release;
 import org.sonar.updatecenter.common.UpdateCenter;
@@ -49,6 +48,7 @@ import static org.apache.commons.io.FileUtils.toFile;
 import static org.apache.commons.lang.StringUtils.substringAfterLast;
 import static org.sonar.core.platform.PluginInfo.jarToPluginInfo;
 import static org.sonar.core.util.FileUtils.deleteQuietly;
+import static org.sonar.server.ws.WsUtils.checkRequest;
 
 /**
  * Downloads plugins from update center. Files are copied in the directory extensions/downloads and then
@@ -124,10 +124,7 @@ public class PluginDownloader implements Startable {
     Optional<UpdateCenter> updateCenter = updateCenterMatrixFactory.getUpdateCenter(true);
     if (updateCenter.isPresent()) {
       List<Release> installablePlugins = updateCenter.get().findInstallablePlugins(pluginKey, version);
-      if (installablePlugins.isEmpty()) {
-        throw new BadRequestException(String.format("Error while downloading plugin '%s' with version '%s'. No compatible plugin found.", pluginKey,
-          version.getName()));
-      }
+      checkRequest(!installablePlugins.isEmpty(), "Error while downloading plugin '%s' with version '%s'. No compatible plugin found.", pluginKey, version.getName());
       for (Release release : installablePlugins) {
         try {
           downloadRelease(release);
index 831d88dcb2205d586e621761a84bb9de07ff7264..c1e3f9753d0148a63b631ca24b394153f0f097de 100644 (file)
@@ -48,6 +48,7 @@ import static org.sonar.api.measures.Metric.ValueType.valueOf;
 import static org.sonar.db.qualitygate.QualityGateConditionDto.isOperatorAllowed;
 import static org.sonar.server.computation.task.projectanalysis.qualitymodel.RatingGrid.Rating.E;
 import static org.sonar.server.qualitygate.ValidRatingMetrics.isCoreRatingMetric;
+import static org.sonar.server.ws.WsUtils.checkRequest;
 
 public class QualityGateConditionsUpdater {
 
@@ -175,12 +176,9 @@ public class QualityGateConditionsUpdater {
     }
 
     boolean conditionExists = conditions.stream().anyMatch(c -> c.getMetricId() == metric.getId() && ObjectUtils.equals(c.getPeriod(), period));
-    if (conditionExists) {
-      String errorMessage = period == null
-        ? format("Condition on metric '%s' already exists.", metric.getShortName())
-        : format("Condition on metric '%s' over leak period already exists.", metric.getShortName());
-      throw new BadRequestException(errorMessage);
-    }
+    checkRequest(!conditionExists, period == null
+      ? format("Condition on metric '%s' already exists.", metric.getShortName())
+      : format("Condition on metric '%s' over leak period already exists.", metric.getShortName()));
   }
 
   private static void checkRatingMetric(MetricDto metric, @Nullable String warningThreshold, @Nullable String errorThreshold, @Nullable Integer period, Errors errors) {
index 6b220b99300b0d4ef8df208d6fadbe35cfe3e120..a51d6b199c4c6752bf41a3027658e8642f5a8e5d 100644 (file)
@@ -133,7 +133,7 @@ public class ProjectStatusAction implements QualityGatesWsAction {
       return getProjectThenSnapshot(dbSession, request);
     }
 
-    throw new BadRequestException(MSG_ONE_PARAMETER_ONLY);
+    throw BadRequestException.create(MSG_ONE_PARAMETER_ONLY);
   }
 
   private ProjectAndSnapshot getProjectThenSnapshot(DbSession dbSession, ProjectStatusWsRequest request) {
index de5b991e0759d8804013b9de5a5e254c09eb1a63..3353d93c21e1bfcea5d4813194042ff52b31aac0 100644 (file)
@@ -90,7 +90,7 @@ public class QualityGatesWs implements WebService {
     try {
       return Long.valueOf(request.mandatoryParam(paramName));
     } catch (NumberFormatException badFormat) {
-      throw new BadRequestException(paramName + " must be a valid long value");
+      throw BadRequestException.create(paramName + " must be a valid long value");
     }
   }
 
index bd4f608cdee211b1a2823073239acaac0c61a6e0..a90201257a9b919b71dd3955cada478e739eb4b4 100644 (file)
@@ -82,9 +82,9 @@ public class ShowAction implements QualityGatesWsAction {
 
   private static void checkOneOfIdOrNamePresent(@Nullable Long qGateId, @Nullable String qGateName) {
     if (qGateId == null && qGateName == null) {
-      throw new BadRequestException("Either one of 'id' or 'name' is required.");
+      throw BadRequestException.create("Either one of 'id' or 'name' is required.");
     } else if (qGateId != null && qGateName != null) {
-      throw new BadRequestException("Only one of 'id' or 'name' must be provided.");
+      throw BadRequestException.create("Only one of 'id' or 'name' must be provided.");
     }
   }
 
index f5fa40c44026547d0fe7530b96577bed026bab08..15b3e1d20b3c4eac2baec358e618357c47e87167 100644 (file)
@@ -48,6 +48,8 @@ import org.sonar.db.qualityprofile.QualityProfileDto;
 import org.sonar.server.exceptions.BadRequestException;
 import org.sonar.server.exceptions.NotFoundException;
 
+import static org.sonar.server.ws.WsUtils.checkRequest;
+
 @ServerSide
 public class QProfileExporters {
 
@@ -167,13 +169,11 @@ public class QProfileExporters {
         return importer;
       }
     }
-    throw new BadRequestException("No such importer : " + importerKey);
+    throw BadRequestException.create("No such importer : " + importerKey);
   }
 
   private static void processValidationMessages(ValidationMessages messages, QProfileResult result) {
-    if (!messages.getErrors().isEmpty()) {
-      throw BadRequestException.create(messages.getErrors());
-    }
+    checkRequest(messages.getErrors().isEmpty(), messages.getErrors());
     result.addWarnings(messages.getWarnings());
     result.addInfos(messages.getInfos());
   }
index 1d8a778af9b192153cad8175fd737e7f7c4438e1..43a5eedc283815dd17eac74764d65caa722ef8a9 100644 (file)
@@ -63,15 +63,13 @@ public class QProfileFactory {
 
   public QualityProfileDto create(DbSession dbSession, QProfileName name) {
     QualityProfileDto dto = db.qualityProfileDao().selectByNameAndLanguage(name.getName(), name.getLanguage(), dbSession);
-    if (dto != null) {
-      throw new BadRequestException("Quality profile already exists: " + name);
-    }
+    checkRequest(dto == null, "Quality profile already exists: %s", name);
     return doCreate(dbSession, name);
   }
 
   private QualityProfileDto doCreate(DbSession dbSession, QProfileName name) {
     if (StringUtils.isEmpty(name.getName())) {
-      throw new BadRequestException("quality_profiles.profile_name_cant_be_blank");
+      throw BadRequestException.create("quality_profiles.profile_name_cant_be_blank");
     }
     Date now = new Date();
     for (int i = 0; i < 20; i++) {
@@ -191,7 +189,7 @@ public class QProfileFactory {
 
   private static void checkNotDefault(QualityProfileDto p) {
     if (p.isDefault()) {
-      throw new BadRequestException("The profile marked as default can not be deleted: " + p.getKey());
+      throw BadRequestException.create("The profile marked as default can not be deleted: " + p.getKey());
     }
   }
 
@@ -207,9 +205,7 @@ public class QProfileFactory {
         throw new NotFoundException("Quality profile not found: " + key);
       }
       if (!StringUtils.equals(newName, profile.getName())) {
-        if (db.qualityProfileDao().selectByNameAndLanguage(newName, profile.getLanguage(), dbSession) != null) {
-          throw new BadRequestException("Quality profile already exists: " + newName);
-        }
+        checkRequest(db.qualityProfileDao().selectByNameAndLanguage(newName, profile.getLanguage(), dbSession) == null, "Quality profile already exists: %s", newName);
         profile.setName(newName);
         db.qualityProfileDao().update(dbSession, profile);
         dbSession.commit();
index 45ade78c687d5354b1055973942dd0843134aee3..9f37b9d2aa7741716f0f60f00f99577b00dc6210 100644 (file)
@@ -45,6 +45,8 @@ import org.sonar.db.rule.RuleParamDto;
 import org.sonar.server.exceptions.BadRequestException;
 import org.sonar.server.qualityprofile.index.ActiveRuleIndexer;
 
+import static org.sonar.server.ws.WsUtils.checkRequest;
+
 @ServerSide
 public class QProfileReset {
 
@@ -171,8 +173,6 @@ public class QProfileReset {
   }
 
   private void processValidationMessages(ValidationMessages messages) {
-    if (!messages.getErrors().isEmpty()) {
-      throw BadRequestException.create(messages.getErrors());
-    }
+    checkRequest(messages.getErrors().isEmpty(), messages.getErrors());
   }
 }
index faeae921d826ed49c3cbe84d88e50c48ca1300a2..ed7917e5331cb36f4c009ac129d2b92af37a250d 100644 (file)
@@ -49,6 +49,7 @@ import org.sonar.server.user.UserSession;
 import org.sonar.server.util.TypeValidations;
 
 import static com.google.common.collect.Lists.newArrayList;
+import static org.sonar.server.ws.WsUtils.checkRequest;
 
 /**
  * Activation and deactivation of rules in Quality profiles
@@ -368,9 +369,7 @@ public class RuleActivator {
     if (activeRuleDto == null) {
       return changes;
     }
-    if (!force && !isCascade && activeRuleDto.getInheritance() != null) {
-      throw new BadRequestException("Cannot deactivate inherited rule '" + key.ruleKey() + "'");
-    }
+    checkRequest(force || isCascade || activeRuleDto.getInheritance() == null, "Cannot deactivate inherited rule '%s'", key.ruleKey());
     change = ActiveRuleChange.createFor(ActiveRuleChange.Type.DEACTIVATED, key);
     changes.add(change);
     persist(change, context, dbSession);
@@ -471,9 +470,7 @@ public class RuleActivator {
 
     } else if (profile.getParentKee() == null || !parentKey.equals(profile.getParentKee())) {
       QualityProfileDto parentProfile = db.qualityProfileDao().selectOrFailByKey(dbSession, parentKey);
-      if (isDescendant(dbSession, profile, parentProfile)) {
-        throw new BadRequestException(String.format("Descendant profile '%s' can not be selected as parent of '%s'", parentKey, profileKey));
-      }
+      checkRequest(!isDescendant(dbSession, profile, parentProfile), "Descendant profile '%s' can not be selected as parent of '%s'", parentKey, profileKey);
       changes.addAll(removeParent(dbSession, profile));
 
       // set new parent
index 74de29a6e5d7992311064f807c90c985e4541846..649800a21f3270b99154fc3bee1f9dd12bbe14bc 100644 (file)
@@ -33,7 +33,8 @@ import org.sonar.db.qualityprofile.ActiveRuleParamDto;
 import org.sonar.db.qualityprofile.QualityProfileDto;
 import org.sonar.db.rule.RuleDto;
 import org.sonar.db.rule.RuleParamDto;
-import org.sonar.server.exceptions.BadRequestException;
+
+import static org.sonar.server.ws.WsUtils.checkRequest;
 
 class RuleActivatorContext {
 
@@ -217,10 +218,10 @@ class RuleActivatorContext {
     }
     for (Map.Entry<String, String> changeParam : change.getParameters().entrySet()) {
       ActiveRuleParamDto param = activeRuleParams.get(changeParam.getKey());
-      if (changeParam.getValue()==null && param != null && param.getValue()!=null) {
+      if (changeParam.getValue() == null && param != null && param.getValue() != null) {
         return false;
       }
-      if (changeParam.getValue()!=null && (param == null || !StringUtils.equals(changeParam.getValue(), param.getValue()))) {
+      if (changeParam.getValue() != null && (param == null || !StringUtils.equals(changeParam.getValue(), param.getValue()))) {
         return false;
       }
     }
@@ -228,15 +229,8 @@ class RuleActivatorContext {
   }
 
   void verifyForActivation() {
-    if (RuleStatus.REMOVED == rule.getStatus()) {
-      throw new BadRequestException("Rule was removed: " + rule.getKey());
-    }
-    if (rule.isTemplate()) {
-      throw new BadRequestException("Rule template can't be activated on a Quality profile: " + rule.getKey());
-    }
-    if (!profile.getLanguage().equals(rule.getLanguage())) {
-      throw new BadRequestException(String.format("Rule %s and profile %s have different languages", rule.getKey(), profile.getKey()));
-    }
-
+    checkRequest(RuleStatus.REMOVED != rule.getStatus(), "Rule was removed: %s", rule.getKey());
+    checkRequest(!rule.isTemplate(), "Rule template can't be activated on a Quality profile: %s", rule.getKey());
+    checkRequest(profile.getLanguage().equals(rule.getLanguage()), "Rule %s and profile %s have different languages", rule.getKey(), profile.getKey());
   }
 }
index 97e20180a11483b2e373a32aaee6b9709eed0099..282dde9bef40dee756e73efb5d3f9eb9d5b5765f 100644 (file)
@@ -30,7 +30,8 @@ import org.sonar.db.qualityprofile.ActiveRuleKey;
 import org.sonar.db.qualityprofile.ActiveRuleParamDto;
 import org.sonar.db.qualityprofile.QualityProfileDto;
 import org.sonar.db.rule.RuleDto;
-import org.sonar.server.exceptions.BadRequestException;
+
+import static org.sonar.server.ws.WsUtils.checkRequest;
 
 @ServerSide
 public class RuleActivatorContextFactory {
@@ -44,9 +45,7 @@ public class RuleActivatorContextFactory {
   RuleActivatorContext create(String profileKey, RuleKey ruleKey, DbSession session) {
     RuleActivatorContext context = new RuleActivatorContext();
     QualityProfileDto profile = db.qualityProfileDao().selectByKey(session, profileKey);
-    if (profile == null) {
-      throw new BadRequestException("Quality profile not found: " + profileKey);
-    }
+    checkRequest(profile != null, "Quality profile not found: %s", profileKey);
     context.setProfile(profile);
     return create(ruleKey, session, context);
   }
@@ -54,9 +53,7 @@ public class RuleActivatorContextFactory {
   RuleActivatorContext create(QProfileName profileName, RuleKey ruleKey, DbSession session) {
     RuleActivatorContext context = new RuleActivatorContext();
     QualityProfileDto profile = db.qualityProfileDao().selectByNameAndLanguage(profileName.getName(), profileName.getLanguage(), session);
-    if (profile == null) {
-      throw new BadRequestException("Quality profile not found: " + profileName);
-    }
+    checkRequest(profile != null, "Quality profile not found: %s", profileName);
     context.setProfile(profile);
     return create(ruleKey, session, context);
   }
@@ -77,9 +74,7 @@ public class RuleActivatorContextFactory {
 
   private RuleDto initRule(RuleKey ruleKey, RuleActivatorContext context, DbSession dbSession) {
     Optional<RuleDto> rule = db.ruleDao().selectByKey(dbSession, ruleKey);
-    if (!rule.isPresent()) {
-      throw new BadRequestException("Rule not found: " + ruleKey);
-    }
+    checkRequest(rule.isPresent(), "Rule not found: %s", ruleKey);
     context.setRule(rule.get());
     context.setRuleParams(db.ruleDao().selectRuleParamsByRuleKey(dbSession, rule.get().getKey()));
     return rule.get();
index 050795c0095a1810832a85c5897236cbec809a22..3b7b404ebaee2bc8ced5bfa2d14d3cc033636ad3 100644 (file)
@@ -25,12 +25,12 @@ import org.sonar.api.server.ws.WebService;
 import org.sonar.db.DbClient;
 import org.sonar.db.DbSession;
 import org.sonar.db.user.UserDto;
-import org.sonar.server.exceptions.BadRequestException;
 import org.sonar.server.exceptions.NotFoundException;
 import org.sonar.server.user.UserSession;
 
 import static java.lang.String.format;
 import static org.sonar.server.user.AbstractUserSession.insufficientPrivilegesException;
+import static org.sonar.server.ws.WsUtils.checkRequest;
 
 public class UnsetRootAction implements RootsWsAction {
   private static final String PARAM_LOGIN = "login";
@@ -70,10 +70,7 @@ public class UnsetRootAction implements RootsWsAction {
       if (userDto == null || !userDto.isActive()) {
         throw new NotFoundException(format("User with login '%s' not found", login));
       }
-
-      if (dbClient.userDao().countRootUsersButLogin(dbSession, login) == 0) {
-        throw new BadRequestException("Last root can't be unset");
-      }
+      checkRequest(dbClient.userDao().countRootUsersButLogin(dbSession, login) > 0, "Last root can't be unset");
       if (userDto.isRoot()) {
         dbClient.userDao().setRoot(dbSession, login, false);
         dbSession.commit();
index bdcfee1f6a3093d557925a7072e68eb8bb23aaa4..4138e2d9d16b468ab1fbfccd9546d23477bc6d3c 100644 (file)
@@ -286,9 +286,9 @@ public class SetAction implements SettingsWsAction {
     }.getType();
     Gson gson = GsonHelper.create();
     try {
-      return (Map<String, String>) gson.fromJson(json, type);
+      return gson.fromJson(json, type);
     } catch (JsonSyntaxException e) {
-      throw new BadRequestException(String.format("JSON '%s' does not respect expected format for setting '%s'. Ex: {\"field1\":\"value1\", \"field2\":\"value2\"}", json, key));
+      throw BadRequestException.create(String.format("JSON '%s' does not respect expected format for setting '%s'. Ex: {\"field1\":\"value1\", \"field2\":\"value2\"}", json, key));
     }
   }
 
index 9a6940d7bbd0278d096d9d3bbffb917efe06cfd7..0da91cde788266659d9cbbd7628c5bed604776f7 100644 (file)
@@ -112,7 +112,7 @@ public class SettingValidations {
         .filter(result -> !result.isValid())
         .findAny()
         .ifPresent(result -> {
-          throw new BadRequestException(i18n.message(Locale.ENGLISH, "property.error." + result.getErrorKey(),
+          throw BadRequestException.create(i18n.message(Locale.ENGLISH, "property.error." + result.getErrorKey(),
             format("Error when validating setting with key '%s' and value [%s]", data.key, data.values.stream().collect(Collectors.joining(", ")))));
         });
     }
index 47c6ddf3ced9ea781e81b2d4474685566c1d9a5b..59cfd640a8335a3df127d17263f7e72f3402f0a6 100644 (file)
@@ -41,7 +41,6 @@ import org.sonar.db.DbSession;
 import org.sonar.db.user.GroupDto;
 import org.sonar.db.user.UserDto;
 import org.sonar.db.user.UserGroupDto;
-import org.sonar.server.exceptions.BadRequestException;
 import org.sonar.server.exceptions.ServerException;
 import org.sonar.server.organization.DefaultOrganizationProvider;
 import org.sonar.server.organization.OrganizationCreation;
@@ -54,6 +53,7 @@ import static com.google.common.collect.Lists.newArrayList;
 import static java.lang.String.format;
 import static org.sonar.db.user.UserDto.encryptPassword;
 import static org.sonar.server.ws.WsUtils.checkFound;
+import static org.sonar.server.ws.WsUtils.checkRequest;
 
 @ServerSide
 public class UserUpdater {
@@ -171,9 +171,7 @@ public class UserUpdater {
 
     setExternalIdentity(userDto, newUser.externalIdentity());
 
-    if (!messages.isEmpty()) {
-      throw BadRequestException.create(messages);
-    }
+    checkRequest(messages.isEmpty(), messages);
     return userDto;
   }
 
@@ -184,9 +182,7 @@ public class UserUpdater {
     changed |= updateExternalIdentity(updateUser, userDto);
     changed |= updatePassword(updateUser, userDto, messages);
     changed |= updateScmAccounts(dbSession, updateUser, userDto, messages);
-    if (!messages.isEmpty()) {
-      throw BadRequestException.create(messages);
-    }
+    checkRequest(messages.isEmpty(), messages);
     return changed;
   }
 
index 1dfbb350a72b947f3ceea1ef5947b297daa8c34e..f7b0014fac414cd1c308258b3459c8f250e4ef8d 100644 (file)
@@ -118,19 +118,18 @@ public class DeactivateAction implements UsersWsAction {
 
   private void ensureNotLastAdministrator(DbSession dbSession, UserDto user) {
     List<String> problematicOrgs = selectOrganizationsWithNoMoreAdministrators(dbSession, user);
-    if (!problematicOrgs.isEmpty()) {
-      if (problematicOrgs.size() == 1 && defaultOrganizationProvider.get().getUuid().equals(problematicOrgs.get(0))) {
-        throw new BadRequestException("User is last administrator, and cannot be deactivated");
-      }
-      String keys = problematicOrgs
-        .stream()
-        .map(orgUuid -> selectOrganizationByUuid(dbSession, orgUuid, user))
-        .map(OrganizationDto::getKey)
-        .sorted()
-        .collect(Collectors.joining(", "));
-      throw new BadRequestException(format("User is last administrator of organizations [%s], and cannot be deactivated", keys));
-
+    if (problematicOrgs.isEmpty()) {
+      return;
     }
+    checkRequest(problematicOrgs.size() != 1 || !defaultOrganizationProvider.get().getUuid().equals(problematicOrgs.get(0)),
+      "User is last administrator, and cannot be deactivated");
+    String keys = problematicOrgs
+      .stream()
+      .map(orgUuid -> selectOrganizationByUuid(dbSession, orgUuid, user))
+      .map(OrganizationDto::getKey)
+      .sorted()
+      .collect(Collectors.joining(", "));
+    throw BadRequestException.create(format("User is last administrator of organizations [%s], and cannot be deactivated", keys));
   }
 
   private List<String> selectOrganizationsWithNoMoreAdministrators(DbSession dbSession, UserDto user) {
index 5bebf0cfc74d8fcc9708e404a6b41307157aafaf..c526356f7fd75ed0223b681fe767d4b823b977f6 100644 (file)
@@ -29,15 +29,14 @@ import org.sonar.db.DbClient;
 import org.sonar.db.DbSession;
 import org.sonar.db.organization.OrganizationDto;
 import org.sonar.db.user.GroupDto;
-import org.sonar.server.exceptions.BadRequestException;
 import org.sonar.server.exceptions.NotFoundException;
 import org.sonar.server.organization.DefaultOrganizationProvider;
 import org.sonarqube.ws.WsUserGroups;
 
 import static com.google.common.base.Preconditions.checkArgument;
-import static java.lang.String.format;
 import static org.sonar.server.ws.WsUtils.checkFound;
 import static org.sonar.server.ws.WsUtils.checkFoundWithOptional;
+import static org.sonar.server.ws.WsUtils.checkRequest;
 
 /**
  * Factorizes code about user groups between web services
@@ -149,9 +148,7 @@ public class GroupWsSupport {
     // There is no database constraint on column groups.name
     // because MySQL cannot create a unique index
     // on a UTF-8 VARCHAR larger than 255 characters on InnoDB
-    if (dbClient.groupDao().selectByName(dbSession, organizationUuid, name).isPresent()) {
-      throw new BadRequestException(format("Group '%s' already exists", name));
-    }
+    checkRequest(!dbClient.groupDao().selectByName(dbSession, organizationUuid, name).isPresent(), "Group '%s' already exists", name);
   }
 
   static WsUserGroups.Group.Builder toProtobuf(OrganizationDto organization, GroupDto group, int membersCount) {
index dc0e2b5da576cfc479736c0f0fc63f46836f60f1..abcc7a39883c943f30c747b9663dd0d4f724bed8 100644 (file)
@@ -26,7 +26,6 @@ import org.sonar.api.server.ws.WebService.NewController;
 import org.sonar.db.DbClient;
 import org.sonar.db.DbSession;
 import org.sonar.db.user.UserDto;
-import org.sonar.server.exceptions.BadRequestException;
 import org.sonar.server.user.UserSession;
 
 import static java.lang.String.format;
@@ -37,6 +36,7 @@ import static org.sonar.server.usergroups.ws.GroupWsSupport.PARAM_LOGIN;
 import static org.sonar.server.usergroups.ws.GroupWsSupport.defineGroupWsParameters;
 import static org.sonar.server.usergroups.ws.GroupWsSupport.defineLoginWsParameter;
 import static org.sonar.server.ws.WsUtils.checkFound;
+import static org.sonar.server.ws.WsUtils.checkRequest;
 
 public class RemoveUserAction implements UserGroupsWsAction {
 
@@ -91,9 +91,7 @@ public class RemoveUserAction implements UserGroupsWsAction {
   private void ensureLastAdminIsNotRemoved(DbSession dbSession, GroupId group, UserDto user) {
     int remainingAdmins = dbClient.authorizationDao().countUsersWithGlobalPermissionExcludingGroupMember(dbSession,
       group.getOrganizationUuid(), SYSTEM_ADMIN, group.getId(), user.getId());
-    if (remainingAdmins == 0) {
-      throw new BadRequestException("The last administrator user cannot be removed");
-    }
+    checkRequest(remainingAdmins > 0, "The last administrator user cannot be removed");
   }
 
   private UserDto getUser(DbSession dbSession, String userLogin) {
index fbb5d0ddb693c3d895936c5b5ded46ad6f132369..eccbdb14620920745c9f1abac4b77886b0a8145a 100644 (file)
@@ -23,9 +23,8 @@ import java.util.List;
 import javax.annotation.Nullable;
 import org.apache.commons.lang.StringUtils;
 import org.sonar.api.PropertyType;
-import org.sonar.server.exceptions.BadRequestException;
 
-import static java.lang.String.format;
+import static org.sonar.server.ws.WsUtils.checkRequest;
 
 public class BooleanTypeValidation implements TypeValidation {
 
@@ -36,9 +35,8 @@ public class BooleanTypeValidation implements TypeValidation {
 
   @Override
   public void validate(String value, @Nullable List<String> options) {
-    if (!StringUtils.equalsIgnoreCase(value, "true") && !StringUtils.equalsIgnoreCase(value, "false")) {
-      throw new BadRequestException(format("Value '%s' must be one of \"true\" or \"false\".", value));
-    }
+    checkRequest(StringUtils.equalsIgnoreCase(value, "true") || StringUtils.equalsIgnoreCase(value, "false"),
+      "Value '%s' must be one of \"true\" or \"false\".", value);
   }
 
 }
index dfa2bbc30a4cfdc411ba93a81267e9c6a97bb5d8..670bf228c082fc53ba3eb888354e562546c69db3 100644 (file)
@@ -38,7 +38,7 @@ public class FloatTypeValidation implements TypeValidation {
     try {
       Double.parseDouble(value);
     } catch (NumberFormatException e) {
-      throw new BadRequestException(format("Value '%s' must be an floating point number.", value));
+      throw BadRequestException.create(format("Value '%s' must be an floating point number.", value));
     }
   }
 
index 311b7791b1d70fb0e607609a1f0be4573a91ae0f..b159c0cd0058303537ab8013e176e1d67aebfe93 100644 (file)
@@ -38,7 +38,7 @@ public class IntegerTypeValidation implements TypeValidation {
     try {
       Integer.parseInt(value);
     } catch (NumberFormatException e) {
-      throw new BadRequestException(format("Value '%s' must be an integer.", value));
+      throw BadRequestException.create(format("Value '%s' must be an integer.", value));
     }
   }
 
index 682d6cbc08a0ff2f9d85444d88859e97d0628450..1fdb458a267e188fdd78afcc205faaccc19c4c6b 100644 (file)
@@ -37,7 +37,7 @@ public class LongTypeValidation implements TypeValidation {
     try {
       Long.parseLong(value);
     } catch (NumberFormatException e) {
-      throw new BadRequestException(format("Value '%s' must be a long.", value));
+      throw BadRequestException.create(format("Value '%s' must be a long.", value));
     }
   }
 }
index 84079e338f1f936de869e615624a73fe8735165f..86db49c95c233b97fac45782b59a61b7981569fb 100644 (file)
@@ -38,7 +38,7 @@ public class MetricLevelTypeValidation implements TypeValidation {
     try {
       Metric.Level.valueOf(value);
     } catch (IllegalArgumentException e) {
-      throw new BadRequestException(format("Value '%s' must be one of \"OK\", \"WARN\", \"ERROR\".", value));
+      throw BadRequestException.create(format("Value '%s' must be one of \"OK\", \"WARN\", \"ERROR\".", value));
     }
   }
 }
index cd8f1b1c28c2c4a2a6d2a5a255d87b11adb72a11..7984fe460b874eb101e4f433603321253a1ec86c 100644 (file)
@@ -23,9 +23,8 @@ import java.util.List;
 import javax.annotation.Nullable;
 import org.apache.commons.lang.StringUtils;
 import org.sonar.api.PropertyType;
-import org.sonar.server.exceptions.BadRequestException;
 
-import static java.lang.String.format;
+import static org.sonar.server.ws.WsUtils.checkRequest;
 
 public class StringListTypeValidation implements TypeValidation {
 
@@ -36,10 +35,7 @@ public class StringListTypeValidation implements TypeValidation {
 
   @Override
   public void validate(String value, @Nullable List<String> options) {
-    if (options != null && !options.contains(value)) {
-      String optionsAsString = StringUtils.join(options, ", ");
-      throw new BadRequestException(format("Value '%s' must be one of : %s.", value, optionsAsString));
-    }
+    checkRequest(options == null || options.contains(value), "Value '%s' must be one of : %s.", value, StringUtils.join(options, ", "));
   }
 
 }
index 4b988d5a25c8e75b856d99a32c7f6b087b1d5884..edf0f651e75580e958be19cd39105ec86f078eb5 100644 (file)
@@ -25,7 +25,8 @@ import java.util.List;
 import javax.annotation.Nonnull;
 import javax.annotation.Nullable;
 import org.sonar.api.server.ServerSide;
-import org.sonar.server.exceptions.BadRequestException;
+
+import static org.sonar.server.ws.WsUtils.checkRequest;
 
 @ServerSide
 public class TypeValidations {
@@ -48,11 +49,9 @@ public class TypeValidations {
     typeValidation.validate(value, options);
   }
 
-  private TypeValidation findByKey(final String key) {
+  private TypeValidation findByKey(String key) {
     TypeValidation typeValidation = Iterables.find(typeValidationList, new TypeValidationMatchKey(key), null);
-    if (typeValidation == null) {
-      throw new BadRequestException(String.format("Type '%s' is not valid.", key));
-    }
+    checkRequest(typeValidation != null, "Type '%s' is not valid.", key);
     return typeValidation;
   }
 
index 48e6247ffa1bba548bc0c1052b1b86f7ab6434e5..574bee4fd4ac50372508d18257c9ae7cfee2ed90 100644 (file)
  */
 package org.sonar.server.util;
 
-import com.google.common.base.Strings;
-import org.sonar.server.exceptions.BadRequestException;
-
-import static java.lang.String.format;
-
 public class Validation {
 
   public static final String CANT_BE_EMPTY_MESSAGE = "%s can't be empty";
@@ -35,17 +30,4 @@ public class Validation {
     // only static methods
   }
 
-  public static void checkMandatoryParameter(String value, String paramName) {
-    if (Strings.isNullOrEmpty(value)) {
-      throw new BadRequestException(format(Validation.CANT_BE_EMPTY_MESSAGE, paramName));
-    }
-  }
-
-  public static void checkMandatorySizeParameter(String value, String paramName, Integer size) {
-    checkMandatoryParameter(value, paramName);
-    if (!Strings.isNullOrEmpty(value) && value.length() > size) {
-      throw new BadRequestException(format(Validation.IS_TOO_LONG_MESSAGE, paramName, size));
-    }
-  }
-
 }
index 4225a1c10e1f4b61509c39573f68861ed123aa17..e0daec42ac1b1fba62cb8dc82a37bc4c0892e9dd 100644 (file)
@@ -24,6 +24,7 @@ import com.google.protobuf.Message;
 import java.io.OutputStream;
 import java.io.OutputStreamWriter;
 import java.nio.charset.StandardCharsets;
+import java.util.List;
 import javax.annotation.Nullable;
 import org.apache.commons.io.IOUtils;
 import org.sonar.api.server.ws.Request;
@@ -67,7 +68,13 @@ public class WsUtils {
    */
   public static void checkRequest(boolean expression, String message, Object... messageArguments) {
     if (!expression) {
-      throw new BadRequestException(format(message, messageArguments));
+      throw BadRequestException.create(format(message, messageArguments));
+    }
+  }
+
+  public static void checkRequest(boolean expression, List<String> messages) {
+    if (!expression) {
+      throw BadRequestException.create(messages);
     }
   }
 
index 1d8d84ee1aaa527eef585414e02589fc84cd13da..920cb09d2a218315a981d5a69785a7853e970b36 100644 (file)
@@ -34,7 +34,7 @@ public class BadRequestExceptionTest {
 
   @Test
   public void text_error() {
-    BadRequestException exception = new BadRequestException("error");
+    BadRequestException exception = BadRequestException.create("error");
     assertThat(exception.getMessage()).isEqualTo("error");
   }
 
@@ -45,6 +45,13 @@ public class BadRequestExceptionTest {
     assertThat(underTest.errors().messages().stream().map(Message::getMessage)).containsOnly("error1", "error2");
   }
 
+  @Test
+  public void create_exception_from_var_args() throws Exception {
+    BadRequestException underTest = BadRequestException.create("error1", "error2");
+
+    assertThat(underTest.errors().messages().stream().map(Message::getMessage)).containsOnly("error1", "error2");
+  }
+
   @Test
   public void create_exception_from_errors() throws Exception {
     Errors errors = new Errors().add(Message.of("error1"), Message.of("error2"));
index 452b25618d77badaccce085f7e00f86c92cf2f44..57f2228d989982ccf14cf5842dd54776ce0cc830 100644 (file)
@@ -133,7 +133,7 @@ public class CreateActionTest {
   @Test
   public void fail_when_project_already_exists() throws Exception {
     OrganizationDto organization = db.organizations().insert();
-    when(componentUpdater.create(any(DbSession.class), any(NewComponent.class), anyLong())).thenThrow(new BadRequestException("already exists"));
+    when(componentUpdater.create(any(DbSession.class), any(NewComponent.class), anyLong())).thenThrow(BadRequestException.create("already exists"));
     userSession.addOrganizationPermission(organization, PROVISIONING);
 
     expectedException.expect(BadRequestException.class);
index b1bb4b0d7bebf067573b504818d7d07bf422967b..32c931f262bfaed487f5676ffa017ef0ef47ca48 100644 (file)
@@ -345,7 +345,7 @@ public class WebServiceEngineTest {
         });
       createNewDefaultAction(newController, "fail_bad_request")
         .setHandler((request, response) -> {
-          throw new BadRequestException("Bad request !");
+          throw BadRequestException.create("Bad request !");
         });
       createNewDefaultAction(newController, "fail_with_multiple_messages")
         .createParam("count", "Number of error messages to generate")