@@ -29,7 +29,6 @@ import org.sonar.api.server.ws.Request; | |||
import org.sonar.api.server.ws.Response; | |||
import org.sonar.api.server.ws.WebService; | |||
import org.sonar.server.exceptions.BadRequestException; | |||
import org.sonar.server.exceptions.Message; | |||
import org.sonar.server.notification.email.EmailNotificationChannel; | |||
import org.sonar.server.user.UserSession; | |||
@@ -83,12 +82,12 @@ public class SendAction implements EmailsWsAction { | |||
} | |||
private static BadRequestException createBadRequestException(EmailException emailException) { | |||
List<Message> messages = Throwables.getCausalChain(emailException) | |||
List<String> messages = Throwables.getCausalChain(emailException) | |||
.stream() | |||
.map(e -> Message.of(e.getMessage())) | |||
.map(Throwable::getMessage) | |||
.collect(Collectors.toList()); | |||
Collections.reverse(messages); | |||
return new BadRequestException(messages); | |||
return BadRequestException.create(messages); | |||
} | |||
} |
@@ -21,8 +21,9 @@ package org.sonar.server.exceptions; | |||
import com.google.common.base.MoreObjects; | |||
import java.util.List; | |||
import org.sonar.api.utils.ValidationMessages; | |||
import java.util.stream.Collectors; | |||
import static com.google.common.base.Preconditions.checkArgument; | |||
import static java.net.HttpURLConnection.HTTP_BAD_REQUEST; | |||
/** | |||
@@ -32,46 +33,34 @@ public class BadRequestException extends ServerException { | |||
private final transient Errors errors; | |||
public BadRequestException(String format, Object... arguments) { | |||
super(HTTP_BAD_REQUEST); | |||
this.errors = new Errors().add(Message.of(format, arguments)); | |||
public BadRequestException(String message) { | |||
super(HTTP_BAD_REQUEST, message); | |||
this.errors = new Errors().add(Message.of(message)); | |||
} | |||
public BadRequestException(List<Message> messages) { | |||
super(HTTP_BAD_REQUEST); | |||
this.errors = new Errors().add(messages); | |||
private BadRequestException(Errors e) { | |||
super(HTTP_BAD_REQUEST, e.messages().get(0).getMessage()); | |||
this.errors = e; | |||
} | |||
public BadRequestException(Errors e) { | |||
super(HTTP_BAD_REQUEST); | |||
this.errors = e; | |||
public static BadRequestException create(List<String> errorMessages) { | |||
return create(new Errors().add(errorMessages.stream().map(Message::of).collect(Collectors.toList()))); | |||
} | |||
public BadRequestException(ValidationMessages validationMessages) { | |||
super(HTTP_BAD_REQUEST); | |||
this.errors = new Errors(); | |||
for (String s : validationMessages.getErrors()) { | |||
errors.add(Message.of(s)); | |||
} | |||
public static BadRequestException create(Errors e) { | |||
checkArgument(!e.messages().isEmpty(), "At least one error message is required"); | |||
return new BadRequestException(e); | |||
} | |||
public Errors errors() { | |||
return errors; | |||
} | |||
public Message firstError() { | |||
return errors.messages().get(0); | |||
} | |||
@Override | |||
public String getMessage() { | |||
return firstError().getMessage(); | |||
} | |||
@Override | |||
public String toString() { | |||
return MoreObjects.toStringHelper(this) | |||
.add("errors", errors) | |||
.toString(); | |||
} | |||
} |
@@ -19,6 +19,9 @@ | |||
*/ | |||
package org.sonar.server.exceptions; | |||
import com.google.common.base.Preconditions; | |||
import static com.google.common.base.Strings.isNullOrEmpty; | |||
import static java.lang.String.format; | |||
public class Message { | |||
@@ -26,6 +29,7 @@ public class Message { | |||
private final String msg; | |||
private Message(String format, Object... params) { | |||
Preconditions.checkArgument(!isNullOrEmpty(format), "Message cannot be empty"); | |||
this.msg = format(format, params); | |||
} | |||
@@ -19,6 +19,8 @@ | |||
*/ | |||
package org.sonar.server.exceptions; | |||
import static java.util.Objects.requireNonNull; | |||
public class ServerException extends RuntimeException { | |||
private final int httpCode; | |||
@@ -27,7 +29,7 @@ public class ServerException extends RuntimeException { | |||
} | |||
public ServerException(int httpCode, String message) { | |||
super(message); | |||
super(requireNonNull(message, "Error message cannot be null")); | |||
this.httpCode = httpCode; | |||
} | |||
@@ -1,33 +0,0 @@ | |||
/* | |||
* SonarQube | |||
* Copyright (C) 2009-2016 SonarSource SA | |||
* mailto:contact AT sonarsource DOT com | |||
* | |||
* This program is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
package org.sonar.server.exceptions; | |||
public class Verifications { | |||
private Verifications() { | |||
// only static stuff | |||
} | |||
public static void check(boolean expression, String format, Object... arguments) { | |||
if (!expression) { | |||
throw new BadRequestException(format, arguments); | |||
} | |||
} | |||
} |
@@ -137,7 +137,7 @@ public class QualityGateConditionsUpdater { | |||
checkPeriod(metric, period, errors); | |||
checkRatingMetric(metric, warningThreshold, errorThreshold, period, errors); | |||
if (!errors.isEmpty()) { | |||
throw new BadRequestException(errors); | |||
throw BadRequestException.create(errors); | |||
} | |||
} | |||
@@ -54,7 +54,7 @@ public class QualityGateUpdater { | |||
checkQualityGateDoesNotAlreadyExist(qGateId, name, errors); | |||
} | |||
if (!errors.isEmpty()) { | |||
throw new BadRequestException(errors); | |||
throw BadRequestException.create(errors); | |||
} | |||
} | |||
@@ -233,7 +233,7 @@ public class QualityGates { | |||
checkQgateNotAlreadyExists(updatingQgateId, name, errors); | |||
} | |||
if (!errors.isEmpty()) { | |||
throw new BadRequestException(errors); | |||
throw BadRequestException.create(errors); | |||
} | |||
} | |||
@@ -172,7 +172,7 @@ public class QProfileExporters { | |||
private static void processValidationMessages(ValidationMessages messages, QProfileResult result) { | |||
if (!messages.getErrors().isEmpty()) { | |||
throw new BadRequestException(messages); | |||
throw BadRequestException.create(messages.getErrors()); | |||
} | |||
result.addWarnings(messages.getWarnings()); | |||
result.addInfos(messages.getInfos()); |
@@ -35,10 +35,10 @@ import org.sonar.db.qualityprofile.ActiveRuleDto; | |||
import org.sonar.db.qualityprofile.QualityProfileDto; | |||
import org.sonar.server.exceptions.BadRequestException; | |||
import org.sonar.server.exceptions.NotFoundException; | |||
import org.sonar.server.exceptions.Verifications; | |||
import static org.sonar.server.qualityprofile.ActiveRuleChange.Type.DEACTIVATED; | |||
import static org.sonar.server.ws.WsUtils.checkFound; | |||
import static org.sonar.server.ws.WsUtils.checkRequest; | |||
/** | |||
* Create, delete, rename and set as default profile. | |||
@@ -140,7 +140,7 @@ public class QProfileFactory { | |||
} | |||
void setDefault(DbSession dbSession, String profileKey) { | |||
Verifications.check(StringUtils.isNotBlank(profileKey), "Profile key must be set"); | |||
checkRequest(StringUtils.isNotBlank(profileKey), "Profile key must be set"); | |||
QualityProfileDto profile = db.qualityProfileDao().selectByKey(dbSession, profileKey); | |||
if (profile == null) { | |||
throw new NotFoundException("Quality profile not found: " + profileKey); | |||
@@ -198,8 +198,8 @@ public class QProfileFactory { | |||
// ------------- RENAME | |||
public boolean rename(String key, String newName) { | |||
Verifications.check(StringUtils.isNotBlank(newName), "Name must be set"); | |||
Verifications.check(newName.length() < 100, String.format("Name is too long (>%d characters)", 100)); | |||
checkRequest(StringUtils.isNotBlank(newName), "Name must be set"); | |||
checkRequest(newName.length() < 100, String.format("Name is too long (>%d characters)", 100)); | |||
DbSession dbSession = db.openSession(false); | |||
try { | |||
QualityProfileDto profile = db.qualityProfileDao().selectByKey(dbSession, key); |
@@ -172,7 +172,7 @@ public class QProfileReset { | |||
private void processValidationMessages(ValidationMessages messages) { | |||
if (!messages.getErrors().isEmpty()) { | |||
throw new BadRequestException(messages); | |||
throw BadRequestException.create(messages.getErrors()); | |||
} | |||
} | |||
} |
@@ -119,7 +119,7 @@ public class RuleCreator { | |||
} | |||
if (!errors.isEmpty()) { | |||
throw new BadRequestException(errors); | |||
throw BadRequestException.create(errors); | |||
} | |||
} | |||
@@ -42,7 +42,6 @@ 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.Message; | |||
import org.sonar.server.exceptions.ServerException; | |||
import org.sonar.server.organization.DefaultOrganizationProvider; | |||
import org.sonar.server.user.index.UserIndexer; | |||
@@ -51,6 +50,7 @@ import org.sonar.server.util.Validation; | |||
import static com.google.common.base.Preconditions.checkArgument; | |||
import static com.google.common.base.Strings.isNullOrEmpty; | |||
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; | |||
@@ -140,7 +140,7 @@ public class UserUpdater { | |||
private UserDto createNewUserDto(DbSession dbSession, NewUser newUser) { | |||
UserDto userDto = new UserDto(); | |||
List<Message> messages = newArrayList(); | |||
List<String> messages = newArrayList(); | |||
String login = newUser.login(); | |||
if (validateLoginFormat(login, messages)) { | |||
@@ -170,25 +170,25 @@ public class UserUpdater { | |||
setExternalIdentity(userDto, newUser.externalIdentity()); | |||
if (!messages.isEmpty()) { | |||
throw new BadRequestException(messages); | |||
throw BadRequestException.create(messages); | |||
} | |||
return userDto; | |||
} | |||
private boolean updateUserDto(DbSession dbSession, UpdateUser updateUser, UserDto userDto) { | |||
List<Message> messages = newArrayList(); | |||
List<String> messages = newArrayList(); | |||
boolean changed = updateName(updateUser, userDto, messages); | |||
changed |= updateEmail(updateUser, userDto, messages); | |||
changed |= updateExternalIdentity(updateUser, userDto); | |||
changed |= updatePassword(updateUser, userDto, messages); | |||
changed |= updateScmAccounts(dbSession, updateUser, userDto, messages); | |||
if (!messages.isEmpty()) { | |||
throw new BadRequestException(messages); | |||
throw BadRequestException.create(messages); | |||
} | |||
return changed; | |||
} | |||
private static boolean updateName(UpdateUser updateUser, UserDto userDto, List<Message> messages) { | |||
private static boolean updateName(UpdateUser updateUser, UserDto userDto, List<String> messages) { | |||
String name = updateUser.name(); | |||
if (updateUser.isNameChanged() && validateNameFormat(name, messages) && !Objects.equals(userDto.getName(), name)) { | |||
userDto.setName(name); | |||
@@ -197,7 +197,7 @@ public class UserUpdater { | |||
return false; | |||
} | |||
private static boolean updateEmail(UpdateUser updateUser, UserDto userDto, List<Message> messages) { | |||
private static boolean updateEmail(UpdateUser updateUser, UserDto userDto, List<String> messages) { | |||
String email = updateUser.email(); | |||
if (updateUser.isEmailChanged() && validateEmailFormat(email, messages) && !Objects.equals(userDto.getEmail(), email)) { | |||
userDto.setEmail(email); | |||
@@ -217,7 +217,7 @@ public class UserUpdater { | |||
return false; | |||
} | |||
private static boolean updatePassword(UpdateUser updateUser, UserDto userDto, List<Message> messages) { | |||
private static boolean updatePassword(UpdateUser updateUser, UserDto userDto, List<String> messages) { | |||
String password = updateUser.password(); | |||
if (!updateUser.isExternalIdentityChanged() && updateUser.isPasswordChanged() && validatePasswords(password, messages) && checkPasswordChangeAllowed(userDto, messages)) { | |||
setEncryptedPassWord(password, userDto); | |||
@@ -226,7 +226,7 @@ public class UserUpdater { | |||
return false; | |||
} | |||
private boolean updateScmAccounts(DbSession dbSession, UpdateUser updateUser, UserDto userDto, List<Message> messages) { | |||
private boolean updateScmAccounts(DbSession dbSession, UpdateUser updateUser, UserDto userDto, List<String> messages) { | |||
String email = updateUser.email(); | |||
List<String> scmAccounts = sanitizeScmAccounts(updateUser.scmAccounts()); | |||
List<String> existingScmAccounts = userDto.getScmAccountsAsList(); | |||
@@ -263,70 +263,70 @@ public class UserUpdater { | |||
} | |||
} | |||
private static boolean checkNotEmptyParam(@Nullable String value, String param, List<Message> messages) { | |||
private static boolean checkNotEmptyParam(@Nullable String value, String param, List<String> messages) { | |||
if (isNullOrEmpty(value)) { | |||
messages.add(Message.of(Validation.CANT_BE_EMPTY_MESSAGE, param)); | |||
messages.add(format(Validation.CANT_BE_EMPTY_MESSAGE, param)); | |||
return false; | |||
} | |||
return true; | |||
} | |||
private static boolean validateLoginFormat(@Nullable String login, List<Message> messages) { | |||
private static boolean validateLoginFormat(@Nullable String login, List<String> messages) { | |||
boolean isValid = checkNotEmptyParam(login, LOGIN_PARAM, messages); | |||
if (!isNullOrEmpty(login)) { | |||
if (login.length() < LOGIN_MIN_LENGTH) { | |||
messages.add(Message.of(Validation.IS_TOO_SHORT_MESSAGE, LOGIN_PARAM, LOGIN_MIN_LENGTH)); | |||
messages.add(format(Validation.IS_TOO_SHORT_MESSAGE, LOGIN_PARAM, LOGIN_MIN_LENGTH)); | |||
return false; | |||
} else if (login.length() > LOGIN_MAX_LENGTH) { | |||
messages.add(Message.of(Validation.IS_TOO_LONG_MESSAGE, LOGIN_PARAM, LOGIN_MAX_LENGTH)); | |||
messages.add(format(Validation.IS_TOO_LONG_MESSAGE, LOGIN_PARAM, LOGIN_MAX_LENGTH)); | |||
return false; | |||
} else if (!login.matches("\\A\\w[\\w\\.\\-_@]+\\z")) { | |||
messages.add(Message.of("Use only letters, numbers, and .-_@ please.")); | |||
messages.add("Use only letters, numbers, and .-_@ please."); | |||
return false; | |||
} | |||
} | |||
return isValid; | |||
} | |||
private static boolean validateNameFormat(@Nullable String name, List<Message> messages) { | |||
private static boolean validateNameFormat(@Nullable String name, List<String> messages) { | |||
boolean isValid = checkNotEmptyParam(name, NAME_PARAM, messages); | |||
if (name != null && name.length() > NAME_MAX_LENGTH) { | |||
messages.add(Message.of(Validation.IS_TOO_LONG_MESSAGE, NAME_PARAM, 200)); | |||
messages.add(format(Validation.IS_TOO_LONG_MESSAGE, NAME_PARAM, 200)); | |||
return false; | |||
} | |||
return isValid; | |||
} | |||
private static boolean validateEmailFormat(@Nullable String email, List<Message> messages) { | |||
private static boolean validateEmailFormat(@Nullable String email, List<String> messages) { | |||
if (email != null && email.length() > EMAIL_MAX_LENGTH) { | |||
messages.add(Message.of(Validation.IS_TOO_LONG_MESSAGE, EMAIL_PARAM, 100)); | |||
messages.add(format(Validation.IS_TOO_LONG_MESSAGE, EMAIL_PARAM, 100)); | |||
return false; | |||
} | |||
return true; | |||
} | |||
private static boolean checkPasswordChangeAllowed(UserDto userDto, List<Message> messages) { | |||
private static boolean checkPasswordChangeAllowed(UserDto userDto, List<String> messages) { | |||
if (!userDto.isLocal()) { | |||
messages.add(Message.of("Password cannot be changed when external authentication is used")); | |||
messages.add("Password cannot be changed when external authentication is used"); | |||
return false; | |||
} | |||
return true; | |||
} | |||
private static boolean validatePasswords(@Nullable String password, List<Message> messages) { | |||
private static boolean validatePasswords(@Nullable String password, List<String> messages) { | |||
if (password == null || password.length() == 0) { | |||
messages.add(Message.of(Validation.CANT_BE_EMPTY_MESSAGE, PASSWORD_PARAM)); | |||
messages.add(format(Validation.CANT_BE_EMPTY_MESSAGE, PASSWORD_PARAM)); | |||
return false; | |||
} | |||
return true; | |||
} | |||
private boolean validateScmAccounts(DbSession dbSession, List<String> scmAccounts, @Nullable String login, @Nullable String email, @Nullable UserDto existingUser, | |||
List<Message> messages) { | |||
List<String> messages) { | |||
boolean isValid = true; | |||
for (String scmAccount : scmAccounts) { | |||
if (scmAccount.equals(login) || scmAccount.equals(email)) { | |||
messages.add(Message.of("Login and email are automatically considered as SCM accounts")); | |||
messages.add("Login and email are automatically considered as SCM accounts"); | |||
isValid = false; | |||
} else { | |||
List<UserDto> matchingUsers = dbClient.userDao().selectByScmAccountOrLoginOrEmail(dbSession, scmAccount); | |||
@@ -338,7 +338,7 @@ public class UserUpdater { | |||
matchingUsersWithoutExistingUser.add(matchingUser.getName() + " (" + matchingUser.getLogin() + ")"); | |||
} | |||
if (!matchingUsersWithoutExistingUser.isEmpty()) { | |||
messages.add(Message.of("The scm account '%s' is already used by user(s) : '%s'", scmAccount, Joiner.on(", ").join(matchingUsersWithoutExistingUser))); | |||
messages.add(format("The scm account '%s' is already used by user(s) : '%s'", scmAccount, Joiner.on(", ").join(matchingUsersWithoutExistingUser))); | |||
isValid = false; | |||
} | |||
} | |||
@@ -399,7 +399,7 @@ public class UserUpdater { | |||
Optional<GroupDto> groupDto = dbClient.groupDao().selectByName(dbSession, defOrgUuid, defaultGroupName); | |||
if (!groupDto.isPresent()) { | |||
throw new ServerException(HttpURLConnection.HTTP_INTERNAL_ERROR, | |||
String.format("The default group '%s' for new users does not exist. Please update the general security settings to fix this issue.", | |||
format("The default group '%s' for new users does not exist. Please update the general security settings to fix this issue.", | |||
defaultGroupName)); | |||
} | |||
dbClient.userGroupDao().insert(dbSession, new UserGroupDto().setUserId(userDto.getId()).setGroupId(groupDto.get().getId())); |
@@ -25,6 +25,8 @@ import org.apache.commons.lang.StringUtils; | |||
import org.sonar.api.PropertyType; | |||
import org.sonar.server.exceptions.BadRequestException; | |||
import static java.lang.String.format; | |||
public class BooleanTypeValidation implements TypeValidation { | |||
@Override | |||
@@ -35,7 +37,7 @@ 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("Value '%s' must be one of \"true\" or \"false\".", value); | |||
throw new BadRequestException(format("Value '%s' must be one of \"true\" or \"false\".", value)); | |||
} | |||
} | |||
@@ -24,6 +24,8 @@ import javax.annotation.Nullable; | |||
import org.sonar.api.PropertyType; | |||
import org.sonar.server.exceptions.BadRequestException; | |||
import static java.lang.String.format; | |||
public class FloatTypeValidation implements TypeValidation { | |||
@Override | |||
@@ -36,7 +38,7 @@ public class FloatTypeValidation implements TypeValidation { | |||
try { | |||
Double.parseDouble(value); | |||
} catch (NumberFormatException e) { | |||
throw new BadRequestException("Value '%s' must be an floating point number.", value); | |||
throw new BadRequestException(format("Value '%s' must be an floating point number.", value)); | |||
} | |||
} | |||
@@ -24,6 +24,8 @@ import javax.annotation.Nullable; | |||
import org.sonar.api.PropertyType; | |||
import org.sonar.server.exceptions.BadRequestException; | |||
import static java.lang.String.format; | |||
public class IntegerTypeValidation implements TypeValidation { | |||
@Override | |||
@@ -36,7 +38,7 @@ public class IntegerTypeValidation implements TypeValidation { | |||
try { | |||
Integer.parseInt(value); | |||
} catch (NumberFormatException e) { | |||
throw new BadRequestException("Value '%s' must be an integer.", value); | |||
throw new BadRequestException(format("Value '%s' must be an integer.", value)); | |||
} | |||
} | |||
@@ -24,6 +24,8 @@ import javax.annotation.Nullable; | |||
import org.sonar.api.PropertyType; | |||
import org.sonar.server.exceptions.BadRequestException; | |||
import static java.lang.String.format; | |||
public class LongTypeValidation implements TypeValidation { | |||
@Override | |||
public String key() { | |||
@@ -35,7 +37,7 @@ public class LongTypeValidation implements TypeValidation { | |||
try { | |||
Long.parseLong(value); | |||
} catch (NumberFormatException e) { | |||
throw new BadRequestException("Value '%s' must be a long.", value); | |||
throw new BadRequestException(format("Value '%s' must be a long.", value)); | |||
} | |||
} | |||
} |
@@ -25,6 +25,8 @@ import org.sonar.api.PropertyType; | |||
import org.sonar.api.measures.Metric; | |||
import org.sonar.server.exceptions.BadRequestException; | |||
import static java.lang.String.format; | |||
public class MetricLevelTypeValidation implements TypeValidation { | |||
@Override | |||
public String key() { | |||
@@ -36,7 +38,7 @@ public class MetricLevelTypeValidation implements TypeValidation { | |||
try { | |||
Metric.Level.valueOf(value); | |||
} catch (IllegalArgumentException e) { | |||
throw new BadRequestException("Value '%s' must be one of \"OK\", \"WARN\", \"ERROR\".", value); | |||
throw new BadRequestException(format("Value '%s' must be one of \"OK\", \"WARN\", \"ERROR\".", value)); | |||
} | |||
} | |||
} |
@@ -25,6 +25,8 @@ import org.apache.commons.lang.StringUtils; | |||
import org.sonar.api.PropertyType; | |||
import org.sonar.server.exceptions.BadRequestException; | |||
import static java.lang.String.format; | |||
public class StringListTypeValidation implements TypeValidation { | |||
@Override | |||
@@ -36,7 +38,7 @@ public class StringListTypeValidation implements TypeValidation { | |||
public void validate(String value, @Nullable List<String> options) { | |||
if (options != null && !options.contains(value)) { | |||
String optionsAsString = StringUtils.join(options, ", "); | |||
throw new BadRequestException("Value '%s' must be one of : %s.", value, optionsAsString); | |||
throw new BadRequestException(format("Value '%s' must be one of : %s.", value, optionsAsString)); | |||
} | |||
} | |||
@@ -22,6 +22,8 @@ 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,14 +37,14 @@ public class Validation { | |||
public static void checkMandatoryParameter(String value, String paramName) { | |||
if (Strings.isNullOrEmpty(value)) { | |||
throw new BadRequestException(Validation.CANT_BE_EMPTY_MESSAGE, paramName); | |||
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(Validation.IS_TOO_LONG_MESSAGE, paramName, size); | |||
throw new BadRequestException(format(Validation.IS_TOO_LONG_MESSAGE, paramName, size)); | |||
} | |||
} | |||
@@ -19,16 +19,68 @@ | |||
*/ | |||
package org.sonar.server.exceptions; | |||
import java.util.Collections; | |||
import org.junit.Rule; | |||
import org.junit.Test; | |||
import org.junit.rules.ExpectedException; | |||
import static java.util.Arrays.asList; | |||
import static org.assertj.core.api.Assertions.assertThat; | |||
public class BadRequestExceptionTest { | |||
@Rule | |||
public ExpectedException expectedException = ExpectedException.none(); | |||
@Test | |||
public void text_error() { | |||
BadRequestException exception = new BadRequestException("error"); | |||
assertThat(exception.getMessage()).isEqualTo("error"); | |||
} | |||
@Test | |||
public void create_exception_from_list() throws Exception { | |||
BadRequestException underTest = BadRequestException.create(asList("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")); | |||
BadRequestException underTest = BadRequestException.create(errors); | |||
assertThat(underTest.errors().messages().stream().map(Message::getMessage)).containsOnly("error1", "error2"); | |||
} | |||
@Test | |||
public void getMessage_return_first_error() throws Exception { | |||
BadRequestException underTest = BadRequestException.create(asList("error1", "error2")); | |||
assertThat(underTest.getMessage()).isEqualTo("error1"); | |||
} | |||
@Test | |||
public void fail_when_creating_exception_with_empty_list() throws Exception { | |||
expectedException.expect(IllegalArgumentException.class); | |||
expectedException.expectMessage("At least one error message is required"); | |||
BadRequestException.create(Collections.emptyList()); | |||
} | |||
@Test | |||
public void fail_when_creating_exception_with_one_empty_element() throws Exception { | |||
expectedException.expect(IllegalArgumentException.class); | |||
expectedException.expectMessage("Message cannot be empty"); | |||
BadRequestException.create(asList("error", "")); | |||
} | |||
@Test | |||
public void fail_when_creating_exception_with_one_null_element() throws Exception { | |||
expectedException.expect(IllegalArgumentException.class); | |||
expectedException.expectMessage("Message cannot be empty"); | |||
BadRequestException.create(asList("error", null)); | |||
} | |||
} |
@@ -19,12 +19,17 @@ | |||
*/ | |||
package org.sonar.server.exceptions; | |||
import org.junit.Rule; | |||
import org.junit.Test; | |||
import org.junit.rules.ExpectedException; | |||
import static org.assertj.core.api.Assertions.assertThat; | |||
public class MessageTest { | |||
@Rule | |||
public ExpectedException expectedException = ExpectedException.none(); | |||
@Test | |||
public void create_message() { | |||
Message message = Message.of("key1 %s", "param1"); | |||
@@ -37,6 +42,20 @@ public class MessageTest { | |||
assertThat(message.getMessage()).isEqualTo("key1"); | |||
} | |||
@Test | |||
public void fail_when_message_is_null() throws Exception { | |||
expectedException.expect(IllegalArgumentException.class); | |||
Message.of(null); | |||
} | |||
@Test | |||
public void fail_when_message_is_empty() throws Exception { | |||
expectedException.expect(IllegalArgumentException.class); | |||
Message.of(""); | |||
} | |||
@Test | |||
public void test_equals_and_hashcode() throws Exception { | |||
Message message1 = Message.of("key1%s", "param1"); |
@@ -27,7 +27,7 @@ public class ServerExceptionTest { | |||
@Test | |||
public void should_create_exception_with_status() { | |||
ServerException exception = new ServerException(400); | |||
ServerException exception = new ServerException(400, "error!"); | |||
assertThat(exception.httpCode()).isEqualTo(400); | |||
} | |||
@@ -1,44 +0,0 @@ | |||
/* | |||
* SonarQube | |||
* Copyright (C) 2009-2016 SonarSource SA | |||
* mailto:contact AT sonarsource DOT com | |||
* | |||
* This program is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
package org.sonar.server.exceptions; | |||
import org.junit.Rule; | |||
import org.junit.Test; | |||
import org.junit.rules.ExpectedException; | |||
public class VerificationsTest { | |||
@Rule | |||
public ExpectedException expectedException = ExpectedException.none(); | |||
@Test | |||
public void check() { | |||
// no exception | |||
Verifications.check(true, "Error on %s and %s", "foo", "bar"); | |||
} | |||
@Test | |||
public void fail() throws Exception { | |||
expectedException.expect(BadRequestException.class); | |||
expectedException.expectMessage("Error on foo and bar"); | |||
Verifications.check(false, "Error on %s and %s", "foo", "bar"); | |||
} | |||
} |
@@ -65,7 +65,7 @@ public class TypeValidationsTest { | |||
} catch (Exception e) { | |||
assertThat(e).isInstanceOf(BadRequestException.class); | |||
BadRequestException badRequestException = (BadRequestException) e; | |||
assertThat(badRequestException.firstError().getMessage()).isEqualTo("Type 'Unknown' is not valid."); | |||
assertThat(badRequestException.getMessage()).isEqualTo("Type 'Unknown' is not valid."); | |||
} | |||
} | |||
@@ -39,6 +39,7 @@ import org.sonar.server.exceptions.Errors; | |||
import org.sonar.server.exceptions.Message; | |||
import org.sonarqube.ws.MediaTypes; | |||
import static java.util.Collections.singletonList; | |||
import static org.assertj.core.api.Assertions.assertThat; | |||
import static org.mockito.Matchers.any; | |||
import static org.mockito.Mockito.doThrow; | |||
@@ -291,7 +292,7 @@ public class WebServiceEngineTest { | |||
DumbResponse response = new DumbResponse(); | |||
expectedException.expect(IllegalArgumentException.class); | |||
expectedException.expectMessage("Error!"); | |||
expectedException.expectMessage("error writing json"); | |||
underTest.execute(request, response); | |||
} | |||
@@ -355,14 +356,15 @@ public class WebServiceEngineTest { | |||
for (int count = 0; count < Integer.valueOf(request.param("count")); count++) { | |||
errors.add(Message.of("Bad request reason #" + count)); | |||
} | |||
throw new BadRequestException(errors); | |||
throw BadRequestException.create(errors); | |||
}); | |||
createNewDefaultAction(newController, "fail_to_write_errors") | |||
.setHandler((request, response) -> { | |||
Errors errors = mock(Errors.class); | |||
when(errors.messages()).thenReturn(singletonList(Message.of("invalid argument"))); | |||
// Try to simulate an error when generating JSON errors | |||
doThrow(new IllegalArgumentException("Error!")).when(errors).writeJson(any(JsonWriter.class)); | |||
throw new BadRequestException(errors); | |||
doThrow(new IllegalArgumentException("error writing json")).when(errors).writeJson(any(JsonWriter.class)); | |||
throw BadRequestException.create(errors); | |||
}); | |||
createNewDefaultAction(newController, "alive") | |||
.setHandler((request, response) -> response.noContent()); |