import org.sonar.server.user.UserSession;
import org.sonarqube.ws.client.setting.ResetRequest;
+import static java.util.Collections.emptyList;
import static org.sonar.server.setting.ws.SettingsWsComponentParameters.addComponentParameters;
import static org.sonarqube.ws.client.ce.CeWsParameters.PARAM_COMPONENT_KEY;
import static org.sonarqube.ws.client.setting.SettingsWsParameters.ACTION_RESET;
Optional<ComponentDto> component = getComponent(dbSession, resetRequest);
checkPermissions(component);
resetRequest.getKeys().forEach(key -> {
- SettingData data = new SettingData(key, component.orElse(null));
+ SettingData data = new SettingData(key, emptyList(), component.orElse(null));
ImmutableList.of(validations.scope(), validations.qualifier())
.forEach(validation -> validation.validate(data));
});
import java.lang.reflect.Type;
import java.util.Collections;
import java.util.List;
-import java.util.Locale;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
String value;
- commonChecks(request, definition, component);
+ commonChecks(request, component);
if (!request.getFieldValues().isEmpty()) {
value = doHandlePropertySet(dbSession, request, definition, component);
List<String> fieldValues = request.getFieldValues();
IntStream.of(fieldIds).boxed()
.flatMap(i -> readOneFieldValues(fieldValues.get(i - 1), request.getKey()).entrySet().stream()
- .map(entry -> new KeyValue(key + "." + i + "." + entry.getKey(), entry.getValue())))
+ .map(entry -> new KeyValue(key + "." + i + "." + entry.getKey(), entry.getValue())))
.forEach(keyValue -> dbClient.propertiesDao().saveProperty(dbSession, toFieldProperty(keyValue, componentId)));
return inlinedFieldKeys;
}
}
- private void commonChecks(SetRequest request, @Nullable PropertyDefinition definition, Optional<ComponentDto> component) {
+ private void commonChecks(SetRequest request, Optional<ComponentDto> component) {
checkValueIsSet(request);
- SettingData settingData = new SettingData(request.getKey(), component.orElse(null));
- ImmutableList.of(validations.scope(), validations.qualifier()).stream()
+ SettingData settingData = new SettingData(request.getKey(), valuesFromRequest(request), component.orElse(null));
+ ImmutableList.of(validations.scope(), validations.qualifier(), validations.valueType())
.forEach(validation -> validation.validate(settingData));
}
return;
}
- checkType(request, definition);
checkSingleOrMultiValue(request, definition);
}
"Parameter '%s' must be used for single value setting. Parameter '%s' must be used for multi value setting.", PARAM_VALUE, PARAM_VALUES);
}
- private void checkType(SetRequest request, PropertyDefinition definition) {
- List<String> values = valuesFromRequest(request);
- Optional<PropertyDefinition.Result> failingResult = values.stream()
- .map(definition::validate)
- .filter(result -> !result.isValid())
- .findAny();
- String errorKey = failingResult.isPresent() ? failingResult.get().getErrorKey() : null;
- checkRequest(errorKey == null,
- i18n.message(Locale.ENGLISH, "property.error." + errorKey, "Error when validating setting with key '%s' and value '%s'"),
- request.getKey(), request.getValue());
- }
-
private static void checkValueIsSet(SetRequest request) {
checkRequest(!isNullOrEmpty(request.getValue())
^ !request.getValues().isEmpty()
package org.sonar.server.setting.ws;
+import java.util.Collections;
+import java.util.List;
import java.util.Locale;
+import java.util.Optional;
+import java.util.stream.Collectors;
import javax.annotation.CheckForNull;
import javax.annotation.Nullable;
import org.sonar.api.config.PropertyDefinition;
import org.sonar.api.config.PropertyDefinitions;
import org.sonar.api.i18n.I18n;
import org.sonar.db.component.ComponentDto;
+import org.sonarqube.ws.client.setting.SetRequest;
+import static java.util.Objects.requireNonNull;
import static org.sonar.server.ws.WsUtils.checkRequest;
public class SettingValidations {
};
}
+ public SettingValidation valueType() {
+ return data -> {
+ PropertyDefinition definition = definitions.get(data.key);
+ if (definition == null) {
+ return;
+ }
+ Optional<PropertyDefinition.Result> failingResult = data.values.stream()
+ .map(definition::validate)
+ .filter(result -> !result.isValid())
+ .findAny();
+ String errorKey = failingResult.isPresent() ? failingResult.get().getErrorKey() : null;
+ checkRequest(errorKey == null,
+ i18n.message(Locale.ENGLISH, "property.error." + errorKey, "Error when validating setting with key '%s' and value [%s]"),
+ data.key, data.values.stream().collect(Collectors.joining(", ")));
+ };
+ }
+
+ private static List<String> valuesFromRequest(SetRequest request) {
+ return request.getValue() == null ? request.getValues() : Collections.singletonList(request.getValue());
+ }
+
private static boolean isGlobal(PropertyDefinition definition) {
return !definition.global() && definition.qualifiers().isEmpty();
}
public static class SettingData {
private final String key;
+ private final List<String> values;
@CheckForNull
private final ComponentDto component;
- public SettingData(String key, @Nullable ComponentDto component) {
- this.key = key;
+ public SettingData(String key, List<String> values, @Nullable ComponentDto component) {
+ this.key = requireNonNull(key);
+ this.values = requireNonNull(values);
this.component = component;
}
.defaultValue("default")
.build());
expectedException.expect(BadRequestException.class);
- expectedException.expectMessage("Error when validating setting with key 'my.key' and value 'My Value'");
+ expectedException.expectMessage("Error when validating setting with key 'my.key' and value [My Value, My Other Value]");
- callForGlobalSetting("my.key", "My Value");
+ callForMultiValueGlobalSetting("my.key", newArrayList("My Value", "My Other Value"));
}
@Test
import org.sonarsource.api.sonarlint.SonarLintSide;
import static com.google.common.base.Preconditions.checkArgument;
+import static org.apache.commons.lang.StringUtils.isBlank;
import static org.sonar.api.PropertyType.PROPERTY_SET;
/**
}
public static Result validate(PropertyType type, @Nullable String value, List<String> options) {
- if (StringUtils.isNotBlank(value)) {
- if (type == PropertyType.BOOLEAN) {
+ if (isBlank(value)) {
+ return Result.SUCCESS;
+ }
+
+ switch (type) {
+ case BOOLEAN:
return validateBoolean(value);
- } else if (type == PropertyType.INTEGER) {
+ case INTEGER:
+ case LONG:
return validateInteger(value);
- } else if (type == PropertyType.FLOAT) {
+ case FLOAT:
return validateFloat(value);
- } else if (type == PropertyType.SINGLE_SELECT_LIST && !options.contains(value)) {
- return Result.newError("notInOptions");
- }
+ case SINGLE_SELECT_LIST:
+ if (!options.contains(value)) {
+ return Result.newError("notInOptions");
+ }
+ default:
+ return Result.SUCCESS;
}
- return Result.SUCCESS;
}
private static Result validateBoolean(String value) {
assertThat(def.validate("foo").getErrorKey()).isEqualTo("notInteger");
}
+ @Test
+ public void should_validate_long() {
+ PropertyDefinition def = PropertyDefinition.builder("foo").name("foo").type(PropertyType.LONG).build();
+
+ assertThat(def.validate(null).isValid()).isTrue();
+ assertThat(def.validate("").isValid()).isTrue();
+ assertThat(def.validate(" ").isValid()).isTrue();
+ assertThat(def.validate("123456").isValid()).isTrue();
+
+ assertThat(def.validate("foo").isValid()).isFalse();
+ assertThat(def.validate("foo").getErrorKey()).isEqualTo("notInteger");
+ }
+
@Test
public void should_validate_float() {
PropertyDefinition def = PropertyDefinition.builder("foo").name("foo").type(PropertyType.FLOAT).build();