From a2b30ecfa4c12cb28adc61ff3013b09fc998a40c Mon Sep 17 00:00:00 2001 From: Julien Lancelot Date: Wed, 1 Mar 2017 12:04:32 +0100 Subject: [PATCH] SONAR-8460 Simplify creation of BadRequestException with one message --- .../sonar/server/batch/ProjectDataLoader.java | 7 ++---- .../server/component/ComponentUpdater.java | 14 ++++------- .../java/org/sonar/server/es/Sorting.java | 8 +++---- .../exceptions/BadRequestException.java | 10 ++++---- .../org/sonar/server/issue/IssueService.java | 7 +++--- .../measure/custom/ws/CreateAction.java | 13 ++++------- .../server/measure/ws/ComponentTreeSort.java | 2 +- .../sonar/server/metric/ws/CreateAction.java | 20 +++++----------- .../sonar/server/metric/ws/UpdateAction.java | 18 ++++++--------- .../ApplyPermissionTemplateQuery.java | 12 ++++------ .../permission/GroupPermissionChanger.java | 8 ++----- .../permission/UserPermissionChanger.java | 6 ++--- .../ws/PermissionRequestValidator.java | 2 +- .../server/plugins/PluginDownloader.java | 7 ++---- .../QualityGateConditionsUpdater.java | 10 ++++---- .../qualitygate/ws/ProjectStatusAction.java | 2 +- .../server/qualitygate/ws/QualityGatesWs.java | 2 +- .../server/qualitygate/ws/ShowAction.java | 4 ++-- .../qualityprofile/QProfileExporters.java | 8 +++---- .../qualityprofile/QProfileFactory.java | 12 ++++------ .../server/qualityprofile/QProfileReset.java | 6 ++--- .../server/qualityprofile/RuleActivator.java | 9 +++----- .../qualityprofile/RuleActivatorContext.java | 20 ++++++---------- .../RuleActivatorContextFactory.java | 15 ++++-------- .../sonar/server/root/ws/UnsetRootAction.java | 7 ++---- .../sonar/server/setting/ws/SetAction.java | 4 ++-- .../server/setting/ws/SettingValidations.java | 2 +- .../org/sonar/server/user/UserUpdater.java | 10 +++----- .../server/user/ws/DeactivateAction.java | 23 +++++++++---------- .../server/usergroups/ws/GroupWsSupport.java | 7 ++---- .../usergroups/ws/RemoveUserAction.java | 6 ++--- .../server/util/BooleanTypeValidation.java | 8 +++---- .../server/util/FloatTypeValidation.java | 2 +- .../server/util/IntegerTypeValidation.java | 2 +- .../sonar/server/util/LongTypeValidation.java | 2 +- .../util/MetricLevelTypeValidation.java | 2 +- .../server/util/StringListTypeValidation.java | 8 ++----- .../sonar/server/util/TypeValidations.java | 9 ++++---- .../org/sonar/server/util/Validation.java | 18 --------------- .../java/org/sonar/server/ws/WsUtils.java | 9 +++++++- .../exceptions/BadRequestExceptionTest.java | 9 +++++++- .../server/project/ws/CreateActionTest.java | 2 +- .../sonar/server/ws/WebServiceEngineTest.java | 2 +- 43 files changed, 136 insertions(+), 218 deletions(-) diff --git a/server/sonar-server/src/main/java/org/sonar/server/batch/ProjectDataLoader.java b/server/sonar-server/src/main/java/org/sonar/server/batch/ProjectDataLoader.java index fab76d2bb55..875ac417f1b 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/batch/ProjectDataLoader.java +++ b/server/sonar-server/src/main/java/org/sonar/server/batch/ProjectDataLoader.java @@ -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); diff --git a/server/sonar-server/src/main/java/org/sonar/server/component/ComponentUpdater.java b/server/sonar-server/src/main/java/org/sonar/server/component/ComponentUpdater.java index 06a12193f57..65d9355f812 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/component/ComponentUpdater.java +++ b/server/sonar-server/src/main/java/org/sonar/server/component/ComponentUpdater.java @@ -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) { diff --git a/server/sonar-server/src/main/java/org/sonar/server/es/Sorting.java b/server/sonar-server/src/main/java/org/sonar/server/es/Sorting.java index 81381855c0b..082664fec0f 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/es/Sorting.java +++ b/server/sonar-server/src/main/java/org/sonar/server/es/Sorting.java @@ -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 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); } diff --git a/server/sonar-server/src/main/java/org/sonar/server/exceptions/BadRequestException.java b/server/sonar-server/src/main/java/org/sonar/server/exceptions/BadRequestException.java index 523c35e73ea..6212ad56571 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/exceptions/BadRequestException.java +++ b/server/sonar-server/src/main/java/org/sonar/server/exceptions/BadRequestException.java @@ -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); diff --git a/server/sonar-server/src/main/java/org/sonar/server/issue/IssueService.java b/server/sonar-server/src/main/java/org/sonar/server/issue/IssueService.java index 4d205912acc..61d65a33449 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/issue/IssueService.java +++ b/server/sonar-server/src/main/java/org/sonar/server/issue/IssueService.java @@ -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)) { diff --git a/server/sonar-server/src/main/java/org/sonar/server/measure/custom/ws/CreateAction.java b/server/sonar-server/src/main/java/org/sonar/server/measure/custom/ws/CreateAction.java index bf630ef1b75..e7e606deff1 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/measure/custom/ws/CreateAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/measure/custom/ws/CreateAction.java @@ -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) { diff --git a/server/sonar-server/src/main/java/org/sonar/server/measure/ws/ComponentTreeSort.java b/server/sonar-server/src/main/java/org/sonar/server/measure/ws/ComponentTreeSort.java index a501e9542f1..50a42682c5b 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/measure/ws/ComponentTreeSort.java +++ b/server/sonar-server/src/main/java/org/sonar/server/measure/ws/ComponentTreeSort.java @@ -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 numericalMetricOrdering(boolean isAscending, @Nullable MetricDto metric, diff --git a/server/sonar-server/src/main/java/org/sonar/server/metric/ws/CreateAction.java b/server/sonar-server/src/main/java/org/sonar/server/metric/ws/CreateAction.java index c25a164b95e..59b37d16fa1 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/metric/ws/CreateAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/metric/ws/CreateAction.java @@ -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 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()); } } diff --git a/server/sonar-server/src/main/java/org/sonar/server/metric/ws/UpdateAction.java b/server/sonar-server/src/main/java/org/sonar/server/metric/ws/UpdateAction.java index cbd0ff6342e..2cefd31a725 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/metric/ws/UpdateAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/metric/ws/UpdateAction.java @@ -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 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) { diff --git a/server/sonar-server/src/main/java/org/sonar/server/permission/ApplyPermissionTemplateQuery.java b/server/sonar-server/src/main/java/org/sonar/server/permission/ApplyPermissionTemplateQuery.java index 451e527098e..ee7d2189720 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/permission/ApplyPermissionTemplateQuery.java +++ b/server/sonar-server/src/main/java/org/sonar/server/permission/ApplyPermissionTemplateQuery.java @@ -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."); } } diff --git a/server/sonar-server/src/main/java/org/sonar/server/permission/GroupPermissionChanger.java b/server/sonar-server/src/main/java/org/sonar/server/permission/GroupPermissionChanger.java index 1a4de6d5c98..1b2e4ab27d8 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/permission/GroupPermissionChanger.java +++ b/server/sonar-server/src/main/java/org/sonar/server/permission/GroupPermissionChanger.java @@ -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); } } diff --git a/server/sonar-server/src/main/java/org/sonar/server/permission/UserPermissionChanger.java b/server/sonar-server/src/main/java/org/sonar/server/permission/UserPermissionChanger.java index ed862bbbab9..3d0d4ac9787 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/permission/UserPermissionChanger.java +++ b/server/sonar-server/src/main/java/org/sonar/server/permission/UserPermissionChanger.java @@ -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); } } } diff --git a/server/sonar-server/src/main/java/org/sonar/server/permission/ws/PermissionRequestValidator.java b/server/sonar-server/src/main/java/org/sonar/server/permission/ws/PermissionRequestValidator.java index fbf13b732f2..15dfb603cd4 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/permission/ws/PermissionRequestValidator.java +++ b/server/sonar-server/src/main/java/org/sonar/server/permission/ws/PermissionRequestValidator.java @@ -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)); } } } diff --git a/server/sonar-server/src/main/java/org/sonar/server/plugins/PluginDownloader.java b/server/sonar-server/src/main/java/org/sonar/server/plugins/PluginDownloader.java index 784809e702d..0e5f752e7ea 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/plugins/PluginDownloader.java +++ b/server/sonar-server/src/main/java/org/sonar/server/plugins/PluginDownloader.java @@ -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 = updateCenterMatrixFactory.getUpdateCenter(true); if (updateCenter.isPresent()) { List 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); diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/QualityGateConditionsUpdater.java b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/QualityGateConditionsUpdater.java index 831d88dcb22..c1e3f9753d0 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/QualityGateConditionsUpdater.java +++ b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/QualityGateConditionsUpdater.java @@ -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) { diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/ProjectStatusAction.java b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/ProjectStatusAction.java index 6b220b99300..a51d6b199c4 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/ProjectStatusAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/ProjectStatusAction.java @@ -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) { diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QualityGatesWs.java b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QualityGatesWs.java index de5b991e075..3353d93c21e 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QualityGatesWs.java +++ b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QualityGatesWs.java @@ -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"); } } diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/ShowAction.java b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/ShowAction.java index bd4f608cdee..a90201257a9 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/ShowAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/ShowAction.java @@ -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."); } } diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/QProfileExporters.java b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/QProfileExporters.java index f5fa40c4402..15b3e1d20b3 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/QProfileExporters.java +++ b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/QProfileExporters.java @@ -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()); } diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/QProfileFactory.java b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/QProfileFactory.java index 1d8a778af9b..43a5eedc283 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/QProfileFactory.java +++ b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/QProfileFactory.java @@ -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(); diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/QProfileReset.java b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/QProfileReset.java index 45ade78c687..9f37b9d2aa7 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/QProfileReset.java +++ b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/QProfileReset.java @@ -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()); } } diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/RuleActivator.java b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/RuleActivator.java index faeae921d82..ed7917e5331 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/RuleActivator.java +++ b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/RuleActivator.java @@ -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 diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/RuleActivatorContext.java b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/RuleActivatorContext.java index 74de29a6e5d..649800a21f3 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/RuleActivatorContext.java +++ b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/RuleActivatorContext.java @@ -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 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()); } } diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/RuleActivatorContextFactory.java b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/RuleActivatorContextFactory.java index 97e20180a11..282dde9bef4 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/RuleActivatorContextFactory.java +++ b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/RuleActivatorContextFactory.java @@ -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 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(); diff --git a/server/sonar-server/src/main/java/org/sonar/server/root/ws/UnsetRootAction.java b/server/sonar-server/src/main/java/org/sonar/server/root/ws/UnsetRootAction.java index 050795c0095..3b7b404ebae 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/root/ws/UnsetRootAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/root/ws/UnsetRootAction.java @@ -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(); diff --git a/server/sonar-server/src/main/java/org/sonar/server/setting/ws/SetAction.java b/server/sonar-server/src/main/java/org/sonar/server/setting/ws/SetAction.java index bdcfee1f6a3..4138e2d9d16 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/setting/ws/SetAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/setting/ws/SetAction.java @@ -286,9 +286,9 @@ public class SetAction implements SettingsWsAction { }.getType(); Gson gson = GsonHelper.create(); try { - return (Map) 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)); } } diff --git a/server/sonar-server/src/main/java/org/sonar/server/setting/ws/SettingValidations.java b/server/sonar-server/src/main/java/org/sonar/server/setting/ws/SettingValidations.java index 9a6940d7bbd..0da91cde788 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/setting/ws/SettingValidations.java +++ b/server/sonar-server/src/main/java/org/sonar/server/setting/ws/SettingValidations.java @@ -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(", "))))); }); } diff --git a/server/sonar-server/src/main/java/org/sonar/server/user/UserUpdater.java b/server/sonar-server/src/main/java/org/sonar/server/user/UserUpdater.java index 47c6ddf3ced..59cfd640a83 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/user/UserUpdater.java +++ b/server/sonar-server/src/main/java/org/sonar/server/user/UserUpdater.java @@ -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; } diff --git a/server/sonar-server/src/main/java/org/sonar/server/user/ws/DeactivateAction.java b/server/sonar-server/src/main/java/org/sonar/server/user/ws/DeactivateAction.java index 1dfbb350a72..f7b0014fac4 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/user/ws/DeactivateAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/user/ws/DeactivateAction.java @@ -118,19 +118,18 @@ public class DeactivateAction implements UsersWsAction { private void ensureNotLastAdministrator(DbSession dbSession, UserDto user) { List 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 selectOrganizationsWithNoMoreAdministrators(DbSession dbSession, UserDto user) { diff --git a/server/sonar-server/src/main/java/org/sonar/server/usergroups/ws/GroupWsSupport.java b/server/sonar-server/src/main/java/org/sonar/server/usergroups/ws/GroupWsSupport.java index 5bebf0cfc74..c526356f7fd 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/usergroups/ws/GroupWsSupport.java +++ b/server/sonar-server/src/main/java/org/sonar/server/usergroups/ws/GroupWsSupport.java @@ -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) { diff --git a/server/sonar-server/src/main/java/org/sonar/server/usergroups/ws/RemoveUserAction.java b/server/sonar-server/src/main/java/org/sonar/server/usergroups/ws/RemoveUserAction.java index dc0e2b5da57..abcc7a39883 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/usergroups/ws/RemoveUserAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/usergroups/ws/RemoveUserAction.java @@ -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) { diff --git a/server/sonar-server/src/main/java/org/sonar/server/util/BooleanTypeValidation.java b/server/sonar-server/src/main/java/org/sonar/server/util/BooleanTypeValidation.java index fbb5d0ddb69..eccbdb14620 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/util/BooleanTypeValidation.java +++ b/server/sonar-server/src/main/java/org/sonar/server/util/BooleanTypeValidation.java @@ -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 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); } } diff --git a/server/sonar-server/src/main/java/org/sonar/server/util/FloatTypeValidation.java b/server/sonar-server/src/main/java/org/sonar/server/util/FloatTypeValidation.java index dfa2bbc30a4..670bf228c08 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/util/FloatTypeValidation.java +++ b/server/sonar-server/src/main/java/org/sonar/server/util/FloatTypeValidation.java @@ -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)); } } diff --git a/server/sonar-server/src/main/java/org/sonar/server/util/IntegerTypeValidation.java b/server/sonar-server/src/main/java/org/sonar/server/util/IntegerTypeValidation.java index 311b7791b1d..b159c0cd005 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/util/IntegerTypeValidation.java +++ b/server/sonar-server/src/main/java/org/sonar/server/util/IntegerTypeValidation.java @@ -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)); } } diff --git a/server/sonar-server/src/main/java/org/sonar/server/util/LongTypeValidation.java b/server/sonar-server/src/main/java/org/sonar/server/util/LongTypeValidation.java index 682d6cbc08a..1fdb458a267 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/util/LongTypeValidation.java +++ b/server/sonar-server/src/main/java/org/sonar/server/util/LongTypeValidation.java @@ -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)); } } } diff --git a/server/sonar-server/src/main/java/org/sonar/server/util/MetricLevelTypeValidation.java b/server/sonar-server/src/main/java/org/sonar/server/util/MetricLevelTypeValidation.java index 84079e338f1..86db49c95c2 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/util/MetricLevelTypeValidation.java +++ b/server/sonar-server/src/main/java/org/sonar/server/util/MetricLevelTypeValidation.java @@ -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)); } } } diff --git a/server/sonar-server/src/main/java/org/sonar/server/util/StringListTypeValidation.java b/server/sonar-server/src/main/java/org/sonar/server/util/StringListTypeValidation.java index cd8f1b1c28c..7984fe460b8 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/util/StringListTypeValidation.java +++ b/server/sonar-server/src/main/java/org/sonar/server/util/StringListTypeValidation.java @@ -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 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, ", ")); } } diff --git a/server/sonar-server/src/main/java/org/sonar/server/util/TypeValidations.java b/server/sonar-server/src/main/java/org/sonar/server/util/TypeValidations.java index 4b988d5a25c..edf0f651e75 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/util/TypeValidations.java +++ b/server/sonar-server/src/main/java/org/sonar/server/util/TypeValidations.java @@ -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; } diff --git a/server/sonar-server/src/main/java/org/sonar/server/util/Validation.java b/server/sonar-server/src/main/java/org/sonar/server/util/Validation.java index 48e6247ffa1..574bee4fd4a 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/util/Validation.java +++ b/server/sonar-server/src/main/java/org/sonar/server/util/Validation.java @@ -19,11 +19,6 @@ */ 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)); - } - } - } diff --git a/server/sonar-server/src/main/java/org/sonar/server/ws/WsUtils.java b/server/sonar-server/src/main/java/org/sonar/server/ws/WsUtils.java index 4225a1c10e1..e0daec42ac1 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/ws/WsUtils.java +++ b/server/sonar-server/src/main/java/org/sonar/server/ws/WsUtils.java @@ -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 messages) { + if (!expression) { + throw BadRequestException.create(messages); } } diff --git a/server/sonar-server/src/test/java/org/sonar/server/exceptions/BadRequestExceptionTest.java b/server/sonar-server/src/test/java/org/sonar/server/exceptions/BadRequestExceptionTest.java index 1d8d84ee1aa..920cb09d2a2 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/exceptions/BadRequestExceptionTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/exceptions/BadRequestExceptionTest.java @@ -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")); diff --git a/server/sonar-server/src/test/java/org/sonar/server/project/ws/CreateActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/project/ws/CreateActionTest.java index 452b25618d7..57f2228d989 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/project/ws/CreateActionTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/project/ws/CreateActionTest.java @@ -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); diff --git a/server/sonar-server/src/test/java/org/sonar/server/ws/WebServiceEngineTest.java b/server/sonar-server/src/test/java/org/sonar/server/ws/WebServiceEngineTest.java index b1bb4b0d7be..32c931f262b 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/ws/WebServiceEngineTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/ws/WebServiceEngineTest.java @@ -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") -- 2.39.5