aboutsummaryrefslogtreecommitdiffstats
path: root/sonar-plugin-api
diff options
context:
space:
mode:
authorJulien HENRY <julien.henry@sonarsource.com>2017-06-29 15:08:28 +0200
committerJulien HENRY <julien.henry@sonarsource.com>2017-07-04 23:47:46 +0200
commit875e23e29f4ed2d41146d8bba8b22448b23df113 (patch)
treee100819edca0bc4c2d75adce8ba760f4fef87059 /sonar-plugin-api
parentd7f436725b0172217ff8156f1425b4a4a702529c (diff)
downloadsonarqube-875e23e29f4ed2d41146d8bba8b22448b23df113.tar.gz
sonarqube-875e23e29f4ed2d41146d8bba8b22448b23df113.zip
SONAR-9478 Deprecate Settings and introduce new Configuration interface
Diffstat (limited to 'sonar-plugin-api')
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/Properties.java3
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/batch/bootstrap/ProjectDefinition.java5
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/batch/debt/DebtRemediationFunction.java1
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/batch/postjob/PostJobContext.java9
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/SensorContext.java10
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/cpd/internal/DefaultCpdTokens.java10
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/internal/SensorContextTester.java11
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/config/Configuration.java183
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/config/EmailSettings.java4
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/config/PropertyDefinition.java2
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/config/PropertyDefinitions.java1
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/config/Settings.java60
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/config/internal/ConfigurationBridge.java52
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/config/internal/MapSettings.java (renamed from sonar-plugin-api/src/main/java/org/sonar/api/config/MapSettings.java)18
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/config/internal/package-info.java23
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/scan/filesystem/FileExclusions.java6
-rw-r--r--sonar-plugin-api/src/test/java/org/sonar/api/batch/bootstrap/ProjectBuilderTest.java2
-rw-r--r--sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/cpd/internal/DefaultCpdTokensTest.java16
-rw-r--r--sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/internal/SensorContextTesterTest.java2
-rw-r--r--sonar-plugin-api/src/test/java/org/sonar/api/config/EmailSettingsTest.java1
-rw-r--r--sonar-plugin-api/src/test/java/org/sonar/api/config/internal/MapSettingsTest.java (renamed from sonar-plugin-api/src/test/java/org/sonar/api/config/MapSettingsTest.java)5
-rw-r--r--sonar-plugin-api/src/test/java/org/sonar/api/scan/filesystem/FileExclusionsTest.java17
22 files changed, 344 insertions, 97 deletions
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/Properties.java b/sonar-plugin-api/src/main/java/org/sonar/api/Properties.java
index 9efca22299a..c38f1ecc257 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/Properties.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/Properties.java
@@ -21,6 +21,7 @@ package org.sonar.api;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
+import org.sonar.api.config.Configuration;
/**
* Plugin properties. This annotation is only used on classes implementing org.sonar.api.Plugin.
@@ -28,7 +29,7 @@ import java.lang.annotation.RetentionPolicy;
* Note that {@link org.sonar.api.config.PropertyDefinition} is an alternative, programmatic and recommended approach
* to declare properties.
* <br>
- * Effective property values are accessible at runtime through the component {@link org.sonar.api.config.Settings}
+ * Effective property values are accessible at runtime through the component {@link Configuration}
*
* @since 1.10
*/
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/bootstrap/ProjectDefinition.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/bootstrap/ProjectDefinition.java
index 74cad4f2ae6..9bf8eef05b4 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/bootstrap/ProjectDefinition.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/bootstrap/ProjectDefinition.java
@@ -186,7 +186,7 @@ public class ProjectDefinition {
}
return null;
}
-
+
@CheckForNull
public String getOriginalVersion() {
return properties.get(CoreProperties.PROJECT_VERSION_PROPERTY);
@@ -199,7 +199,7 @@ public class ProjectDefinition {
}
return version;
}
-
+
@CheckForNull
public String getOriginalName() {
return properties.get(CoreProperties.PROJECT_NAME_PROPERTY);
@@ -320,6 +320,7 @@ public class ProjectDefinition {
return this;
}
+ @CheckForNull
public ProjectDefinition getParent() {
return parent;
}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/debt/DebtRemediationFunction.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/debt/DebtRemediationFunction.java
index 44917519e72..96ff255364c 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/debt/DebtRemediationFunction.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/debt/DebtRemediationFunction.java
@@ -25,6 +25,7 @@ import org.sonar.api.utils.Duration;
/**
* @since 4.3
+ * @deprecated since 6.5 debt model will soon be unavailable on batch side
*/
public class DebtRemediationFunction {
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/postjob/PostJobContext.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/postjob/PostJobContext.java
index 2baa34478d2..cfe881f2866 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/postjob/PostJobContext.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/postjob/PostJobContext.java
@@ -21,6 +21,7 @@ package org.sonar.api.batch.postjob;
import org.sonar.api.batch.AnalysisMode;
import org.sonar.api.batch.postjob.issue.PostJobIssue;
+import org.sonar.api.config.Configuration;
import org.sonar.api.config.Settings;
/**
@@ -30,10 +31,16 @@ import org.sonar.api.config.Settings;
public interface PostJobContext {
/**
- * Get settings of the current project.
+ * @deprecated since 6.5 use {@link PostJobContext#config()}
*/
Settings settings();
+ /**
+ * Get configuration of the current project.
+ * @since 6.5
+ */
+ Configuration config();
+
AnalysisMode analysisMode();
// ----------- Only available in preview mode --------------
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/SensorContext.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/SensorContext.java
index f47c408ccf0..8da60fb974e 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/SensorContext.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/SensorContext.java
@@ -24,6 +24,7 @@ import org.sonar.api.SonarRuntime;
import org.sonar.api.batch.fs.FileSystem;
import org.sonar.api.batch.fs.InputFile;
import org.sonar.api.batch.fs.InputModule;
+import org.sonar.api.batch.postjob.PostJobContext;
import org.sonar.api.batch.rule.ActiveRules;
import org.sonar.api.batch.sensor.coverage.NewCoverage;
import org.sonar.api.batch.sensor.cpd.NewCpdTokens;
@@ -36,6 +37,7 @@ import org.sonar.api.batch.sensor.measure.Measure;
import org.sonar.api.batch.sensor.measure.NewMeasure;
import org.sonar.api.batch.sensor.symbol.NewSymbolTable;
import org.sonar.api.config.Settings;
+import org.sonar.api.config.Configuration;
import org.sonar.api.utils.Version;
/**
@@ -46,11 +48,17 @@ import org.sonar.api.utils.Version;
public interface SensorContext {
/**
- * Get settings of the current module.
+ * @deprecated since 6.5 use {@link PostJobContext#config()}
*/
Settings settings();
/**
+ * Get settings of the current module, or of the project for a global Sensor.
+ * @since 6.5
+ */
+ Configuration config();
+
+ /**
* Get filesystem of the current module.
*/
FileSystem fileSystem();
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/cpd/internal/DefaultCpdTokens.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/cpd/internal/DefaultCpdTokens.java
index 3ff672988da..abdb03c9ecc 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/cpd/internal/DefaultCpdTokens.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/cpd/internal/DefaultCpdTokens.java
@@ -28,7 +28,7 @@ import org.sonar.api.batch.fs.internal.PathPattern;
import org.sonar.api.batch.sensor.cpd.NewCpdTokens;
import org.sonar.api.batch.sensor.internal.DefaultStorable;
import org.sonar.api.batch.sensor.internal.SensorStorage;
-import org.sonar.api.config.Settings;
+import org.sonar.api.config.Configuration;
import org.sonar.duplications.internal.pmd.TokensLine;
import static com.google.common.base.Preconditions.checkState;
@@ -37,7 +37,7 @@ import static java.util.Objects.requireNonNull;
public class DefaultCpdTokens extends DefaultStorable implements NewCpdTokens {
- private final Settings settings;
+ private final Configuration config;
private final ArrayList<TokensLine> result = new ArrayList<>();
private InputFile inputFile;
private int startLine = Integer.MIN_VALUE;
@@ -47,15 +47,15 @@ public class DefaultCpdTokens extends DefaultStorable implements NewCpdTokens {
private TextRange lastRange;
private boolean excluded;
- public DefaultCpdTokens(Settings settings, SensorStorage storage) {
+ public DefaultCpdTokens(Configuration config, SensorStorage storage) {
super(storage);
- this.settings = settings;
+ this.config = config;
}
@Override
public DefaultCpdTokens onFile(InputFile inputFile) {
this.inputFile = requireNonNull(inputFile, "file can't be null");
- String[] cpdExclusions = settings.getStringArray(CoreProperties.CPD_EXCLUSIONS);
+ String[] cpdExclusions = config.getStringArray(CoreProperties.CPD_EXCLUSIONS);
for (PathPattern cpdExclusion : PathPattern.create(cpdExclusions)) {
if (cpdExclusion.match(inputFile)) {
this.excluded = true;
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/internal/SensorContextTester.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/internal/SensorContextTester.java
index 4a3d60763ec..711821e7909 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/internal/SensorContextTester.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/internal/SensorContextTester.java
@@ -64,8 +64,10 @@ import org.sonar.api.batch.sensor.measure.NewMeasure;
import org.sonar.api.batch.sensor.measure.internal.DefaultMeasure;
import org.sonar.api.batch.sensor.symbol.NewSymbolTable;
import org.sonar.api.batch.sensor.symbol.internal.DefaultSymbolTable;
-import org.sonar.api.config.MapSettings;
+import org.sonar.api.config.Configuration;
import org.sonar.api.config.Settings;
+import org.sonar.api.config.internal.ConfigurationBridge;
+import org.sonar.api.config.internal.MapSettings;
import org.sonar.api.internal.ApiVersion;
import org.sonar.api.internal.SonarRuntimeImpl;
import org.sonar.api.measures.Metric;
@@ -122,6 +124,11 @@ public class SensorContextTester implements SensorContext {
return settings;
}
+ @Override
+ public Configuration config() {
+ return new ConfigurationBridge(settings);
+ }
+
public SensorContextTester setSettings(Settings settings) {
this.settings = settings;
return this;
@@ -269,7 +276,7 @@ public class SensorContextTester implements SensorContext {
@Override
public NewCpdTokens newCpdTokens() {
- return new DefaultCpdTokens(settings, sensorStorage);
+ return new DefaultCpdTokens(config(), sensorStorage);
}
@Override
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/config/Configuration.java b/sonar-plugin-api/src/main/java/org/sonar/api/config/Configuration.java
new file mode 100644
index 00000000000..f91996a0734
--- /dev/null
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/config/Configuration.java
@@ -0,0 +1,183 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info 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.api.config;
+
+import java.util.Optional;
+import org.sonar.api.batch.ScannerSide;
+import org.sonar.api.ce.ComputeEngineSide;
+import org.sonar.api.config.internal.MapSettings;
+import org.sonar.api.server.ServerSide;
+import org.sonarsource.api.sonarlint.SonarLintSide;
+
+/**
+ * Component to get effective configuration. Values of properties depend on the runtime environment:
+ * <ul>
+ * <li>immutable project or module configuration in scanner.</li>
+ * <li>global configuration in web server. It does not allow to get the settings overridden on projects.</li>
+ * <li>project configuration in Compute Engine.</li>
+ * </ul>
+ *
+ * <h3>Usage</h3>
+ * <pre>
+ * public class MyExtension {
+ *
+ * private final Configuration config;
+ *
+ * public MyExtension(Configuration config) {
+ * this.config = config;
+ * }
+ * public void doSomething() {
+ * String fooValue = config.get("sonar.foo").orElse(null);
+ * // ..
+ * }
+ * }
+ * </pre>
+ *
+ * <h3>Scanner example</h3>
+ * Scanner sensor can get the reference on Configuration directly through SensorContext,
+ * without injecting the component into constructor.
+ *
+ * <pre>
+ * public class MySensor implements Sensor {
+ * {@literal @}Override
+ * public void execute(SensorContext context) {
+ * String fooValue = context.config().get("sonar.foo").orElse(null);
+ * // ..
+ * }
+ * }
+ * </pre>
+ *
+ * <p>
+ * For testing, and only for testing, the in-memory implementation {@link MapSettings} can be used.
+ * <pre>
+ * {@literal @}Test
+ * public void my_test() {
+ * MapSettings settings = new MapSettings();
+ * settings.setProperty("foo", "bar");
+ * MyExtension underTest = new MyExtension(settings.asConfig());
+ * // ...
+ * }
+ * </pre>
+ *
+ * @see MapSettings
+ * @see PropertyDefinition
+ * @since 6.5
+ */
+@ScannerSide
+@ServerSide
+@ComputeEngineSide
+@SonarLintSide
+public interface Configuration {
+
+ /**
+ * The effective value of the specified property. Can return {@code Optional#empty()} if the property is not set and has no defined default value.
+ * <p>
+ * If the property is encrypted with a secret key, then the returned value is decrypted.
+ * </p>
+ *
+ * @throws IllegalStateException if value is encrypted but fails to be decrypted.
+ */
+ Optional<String> get(String key);
+
+ /**
+ * @return {@code true} if the property has a non-default value, else {@code false}.
+ */
+ boolean hasKey(String key);
+
+ /**
+ * Used to read multi-valued properties.
+ * <p>
+ * See {@link PropertyDefinition.Builder#multiValues(boolean)}
+ * Multi-valued properties coming from scanner are parsed as CSV lines (ie comma separator and optional double quotes to escape values).
+ * Non quoted values are trimmed.
+ * <br>
+ * Examples :
+ * <ul>
+ * <li>"one,two,three " -&gt; ["one", "two", "three"]</li>
+ * <li>" one, two, three " -&gt; ["one", "two", "three"]</li>
+ * <li>"one, , three" -&gt; ["one", "", "three"]</li>
+ * <li>"one,\"two,three\",\" four \"" -&gt; ["one", "two,three", " four "]</li>
+ * </ul>
+ */
+ String[] getStringArray(String key);
+
+ /**
+ * Effective value as boolean. It is {@code empty} if {@link #get(String)} is empty or if it
+ * does not return {@code "true"}, even if it's not a boolean representation.
+ * @return {@code true} if the effective value is {@code "true"}, {@code false} for any other non empty value.
+ * If the property does not have value nor default value, then {@code empty} is returned.
+ */
+ default Optional<Boolean> getBoolean(String key) {
+ return get(key).map(Boolean::parseBoolean);
+ }
+
+ /**
+ * Effective value as {@code int}.
+ * @return the value as {@code int}. If the property does not have value nor default value, then {@code empty} is returned.
+ * @throws NumberFormatException if value is not empty and is not a parsable integer
+ */
+ default Optional<Integer> getInt(String key) {
+ try {
+ return get(key).map(Integer::parseInt);
+ } catch (NumberFormatException e) {
+ throw new IllegalStateException(String.format("The property '%s' is not an int value: %s", key, e.getMessage()));
+ }
+ }
+
+ /**
+ * Effective value as {@code long}.
+ * @return the value as {@code long}. If the property does not have value nor default value, then {@code empty} is returned.
+ * @throws NumberFormatException if value is not empty and is not a parsable {@code long}
+ */
+ default Optional<Long> getLong(String key) {
+ try {
+ return get(key).map(Long::parseLong);
+ } catch (NumberFormatException e) {
+ throw new IllegalStateException(String.format("The property '%s' is not an long value: %s", key, e.getMessage()));
+ }
+ }
+
+ /**
+ * Effective value as {@code Float}.
+ * @return the value as {@code Float}. If the property does not have value nor default value, then {@code empty} is returned.
+ * @throws NumberFormatException if value is not empty and is not a parsable number
+ */
+ default Optional<Float> getFloat(String key) {
+ try {
+ return get(key).map(Float::valueOf);
+ } catch (NumberFormatException e) {
+ throw new IllegalStateException(String.format("The property '%s' is not an float value: %s", key, e.getMessage()));
+ }
+ }
+
+ /**
+ * Effective value as {@code Double}.
+ * @return the value as {@code Double}. If the property does not have value nor default value, then {@code empty} is returned.
+ * @throws NumberFormatException if value is not empty and is not a parsable number
+ */
+ default Optional<Double> getDouble(String key) {
+ try {
+ return get(key).map(Double::valueOf);
+ } catch (NumberFormatException e) {
+ throw new IllegalStateException(String.format("The property '%s' is not an double value: %s", key, e.getMessage()));
+ }
+ }
+
+}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/config/EmailSettings.java b/sonar-plugin-api/src/main/java/org/sonar/api/config/EmailSettings.java
index dc449884522..dae2594593a 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/config/EmailSettings.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/config/EmailSettings.java
@@ -21,7 +21,6 @@ package org.sonar.api.config;
import java.util.List;
import org.sonar.api.PropertyType;
-import org.sonar.api.batch.ScannerSide;
import org.sonar.api.ce.ComputeEngineSide;
import org.sonar.api.server.ServerSide;
@@ -34,11 +33,8 @@ import static org.sonar.api.PropertyType.INTEGER;
import static org.sonar.api.PropertyType.SINGLE_SELECT_LIST;
/**
- * If batch extensions use this component, then batch must be executed with administrator rights (see properties sonar.login and sonar.password)
- *
* @since 3.2
*/
-@ScannerSide
@ServerSide
@ComputeEngineSide
public class EmailSettings {
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/config/PropertyDefinition.java b/sonar-plugin-api/src/main/java/org/sonar/api/config/PropertyDefinition.java
index 02d64853e8e..13c407d000b 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/config/PropertyDefinition.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/config/PropertyDefinition.java
@@ -57,7 +57,7 @@ import static org.sonar.api.PropertyType.REGULAR_EXPRESSION;
import static org.sonar.api.PropertyType.SINGLE_SELECT_LIST;
/**
- * Declare a plugin property. Values are available at runtime through the component {@link Settings}.
+ * Declare a plugin property. Values are available at runtime through the components {@link Settings} or {@link org.sonar.api.Configuration.SettingsReader}.
* <br>
* It's the programmatic alternative to the annotation {@link org.sonar.api.Property}. It is more
* testable and adds new features like sub-categories and ordering.
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/config/PropertyDefinitions.java b/sonar-plugin-api/src/main/java/org/sonar/api/config/PropertyDefinitions.java
index 9a0834b62be..b0e5275674f 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/config/PropertyDefinitions.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/config/PropertyDefinitions.java
@@ -165,6 +165,7 @@ public final class PropertyDefinitions {
return byCategory;
}
+ @CheckForNull
public String getDefaultValue(String key) {
PropertyDefinition def = get(key);
if (def == null) {
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/config/Settings.java b/sonar-plugin-api/src/main/java/org/sonar/api/config/Settings.java
index 7e182dcd555..20fb15bff45 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/config/Settings.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/config/Settings.java
@@ -35,69 +35,19 @@ import org.sonar.api.batch.ScannerSide;
import org.sonar.api.ce.ComputeEngineSide;
import org.sonar.api.server.ServerSide;
import org.sonar.api.utils.DateUtils;
+import org.sonarsource.api.sonarlint.SonarLintSide;
import static java.util.Objects.requireNonNull;
import static org.apache.commons.lang.StringUtils.trim;
/**
- * Component to get effective settings. Values of properties depend on the runtime environment:
- * <ul>
- * <li>project settings in scanner.</li>
- * <li>global settings in web server. It does not allow to get the settings overridden on projects.</li>
- * <li>project settings in Compute Engine.</li>
- * </ul>
- *
- * <h3>Usage</h3>
- * <pre>
- * public class MyExtension {
- *
- * private final Settings settings;
- *
- * public MyExtension(Settings settings) {
- * this.settings = settings;
- * }
- * public void doSomething() {
- * String fooValue = settings.getString("sonar.foo");
- * // ..
- * }
- * }
- * </pre>
- *
- * <h3>Scanner example</h3>
- * Scanner sensor can get the reference on Settings directly through SensorContext,
- * without injecting the component into constructor.
- *
- * <pre>
- * public class MySensor implements Sensor {
- * {@literal @}Override
- * public void execute(SensorContext context) {
- * String fooValue = context.settings().getString("sonar.foo");
- * // ..
- * }
- * }
- * </pre>
- *
- * <p>
- * For testing, and only for testing, the in-memory implementation {@link MapSettings} can be used.
- * <pre>
- * {@literal @}Test
- * public void my_test() {
- * Settings settings = new MapSettings();
- * settings.setProperty("foo", "bar");
- * MyExtension underTest = new MyExtension(settings);
- * // ...
- * }
- * </pre>
- *
- * History - this class is abstract since 6.1.
- *
- * @see MapSettings
- * @see PropertyDefinition
- * @since 2.12
+ * @deprecated since 6.5 use {@link Configuration}
*/
-@ScannerSide
@ServerSide
@ComputeEngineSide
+@ScannerSide
+@SonarLintSide
+@Deprecated
public abstract class Settings {
private final PropertyDefinitions definitions;
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/config/internal/ConfigurationBridge.java b/sonar-plugin-api/src/main/java/org/sonar/api/config/internal/ConfigurationBridge.java
new file mode 100644
index 00000000000..4e8ef584fd3
--- /dev/null
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/config/internal/ConfigurationBridge.java
@@ -0,0 +1,52 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info 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.api.config.internal;
+
+import java.util.Optional;
+import org.sonar.api.config.Settings;
+import org.sonar.api.config.Configuration;
+
+/**
+ * Used to help migration from {@link Settings} to {@link Configuration}
+ */
+public class ConfigurationBridge implements Configuration {
+
+ private final Settings settings;
+
+ public ConfigurationBridge(Settings settings) {
+ this.settings = settings;
+ }
+
+ @Override
+ public Optional<String> get(String key) {
+ return Optional.ofNullable(settings.getString(key));
+ }
+
+ @Override
+ public boolean hasKey(String key) {
+ return settings.hasKey(key);
+ }
+
+ @Override
+ public String[] getStringArray(String key) {
+ return settings.getStringArray(key);
+ }
+
+}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/config/MapSettings.java b/sonar-plugin-api/src/main/java/org/sonar/api/config/internal/MapSettings.java
index 5a73567a808..6d45e12ddb6 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/config/MapSettings.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/config/internal/MapSettings.java
@@ -17,11 +17,15 @@
* 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.api.config;
+package org.sonar.api.config.internal;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
+import org.sonar.api.config.Configuration;
+import org.sonar.api.config.Encryption;
+import org.sonar.api.config.PropertyDefinitions;
+import org.sonar.api.config.Settings;
import static java.util.Collections.unmodifiableMap;
@@ -36,13 +40,15 @@ import static java.util.Collections.unmodifiableMap;
public class MapSettings extends Settings {
private final Map<String, String> props = new HashMap<>();
+ private final ConfigurationBridge configurationBridge;
public MapSettings() {
- super(new PropertyDefinitions(), new Encryption(null));
+ this(new PropertyDefinitions());
}
public MapSettings(PropertyDefinitions definitions) {
super(definitions, new Encryption(null));
+ configurationBridge = new ConfigurationBridge(this);
}
@Override
@@ -72,4 +78,12 @@ public class MapSettings extends Settings {
props.clear();
return this;
}
+
+ /**
+ * @return a {@link Configuration} proxy on top of this existing {@link Settings} implementation. Changes are reflected in the {@link Configuration} object.
+ * @since 6.5
+ */
+ public Configuration asConfig() {
+ return configurationBridge;
+ }
}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/config/internal/package-info.java b/sonar-plugin-api/src/main/java/org/sonar/api/config/internal/package-info.java
new file mode 100644
index 00000000000..4fb297e0a30
--- /dev/null
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/config/internal/package-info.java
@@ -0,0 +1,23 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info 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.
+ */
+@ParametersAreNonnullByDefault
+package org.sonar.api.config.internal;
+
+import javax.annotation.ParametersAreNonnullByDefault;
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/scan/filesystem/FileExclusions.java b/sonar-plugin-api/src/main/java/org/sonar/api/scan/filesystem/FileExclusions.java
index 1a071e62758..af7e9550b96 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/scan/filesystem/FileExclusions.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/scan/filesystem/FileExclusions.java
@@ -24,7 +24,7 @@ import java.util.stream.Stream;
import org.apache.commons.lang.StringUtils;
import org.sonar.api.CoreProperties;
import org.sonar.api.batch.ScannerSide;
-import org.sonar.api.config.Settings;
+import org.sonar.api.config.Configuration;
/**
* Configuration of file inclusions and exclusions.
@@ -35,9 +35,9 @@ import org.sonar.api.config.Settings;
*/
@ScannerSide
public class FileExclusions {
- private final Settings settings;
+ private final Configuration settings;
- public FileExclusions(Settings settings) {
+ public FileExclusions(Configuration settings) {
this.settings = settings;
}
diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/batch/bootstrap/ProjectBuilderTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/batch/bootstrap/ProjectBuilderTest.java
index b8b08a4e4dc..72fd4a8539c 100644
--- a/sonar-plugin-api/src/test/java/org/sonar/api/batch/bootstrap/ProjectBuilderTest.java
+++ b/sonar-plugin-api/src/test/java/org/sonar/api/batch/bootstrap/ProjectBuilderTest.java
@@ -23,7 +23,7 @@ import java.io.File;
import org.junit.Test;
import org.sonar.api.batch.bootstrap.internal.ProjectBuilderContext;
import org.sonar.api.config.Settings;
-import org.sonar.api.config.MapSettings;
+import org.sonar.api.config.internal.MapSettings;
import static org.assertj.core.api.Assertions.assertThat;
import static org.hamcrest.core.Is.is;
diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/cpd/internal/DefaultCpdTokensTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/cpd/internal/DefaultCpdTokensTest.java
index 9b20b94d700..62a268f00f7 100644
--- a/sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/cpd/internal/DefaultCpdTokensTest.java
+++ b/sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/cpd/internal/DefaultCpdTokensTest.java
@@ -24,7 +24,7 @@ import org.sonar.api.batch.fs.InputFile;
import org.sonar.api.batch.fs.internal.TestInputFileBuilder;
import org.sonar.api.batch.sensor.internal.SensorStorage;
import org.sonar.api.config.Settings;
-import org.sonar.api.config.MapSettings;
+import org.sonar.api.config.internal.MapSettings;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.fail;
@@ -44,7 +44,7 @@ public class DefaultCpdTokensTest {
@Test
public void save_no_tokens() {
SensorStorage sensorStorage = mock(SensorStorage.class);
- DefaultCpdTokens tokens = new DefaultCpdTokens(new MapSettings(), sensorStorage)
+ DefaultCpdTokens tokens = new DefaultCpdTokens(new MapSettings().asConfig(), sensorStorage)
.onFile(INPUT_FILE);
tokens.save();
@@ -57,7 +57,7 @@ public class DefaultCpdTokensTest {
@Test
public void save_one_token() {
SensorStorage sensorStorage = mock(SensorStorage.class);
- DefaultCpdTokens tokens = new DefaultCpdTokens(new MapSettings(), sensorStorage)
+ DefaultCpdTokens tokens = new DefaultCpdTokens(new MapSettings().asConfig(), sensorStorage)
.onFile(INPUT_FILE)
.addToken(INPUT_FILE.newRange(1, 2, 1, 5), "foo");
@@ -71,9 +71,9 @@ public class DefaultCpdTokensTest {
@Test
public void handle_exclusions_by_pattern() {
SensorStorage sensorStorage = mock(SensorStorage.class);
- Settings settings = new MapSettings();
+ MapSettings settings = new MapSettings();
settings.setProperty("sonar.cpd.exclusions", "src/Foo.java,another");
- DefaultCpdTokens tokens = new DefaultCpdTokens(settings, sensorStorage)
+ DefaultCpdTokens tokens = new DefaultCpdTokens(settings.asConfig(), sensorStorage)
.onFile(INPUT_FILE)
.addToken(INPUT_FILE.newRange(1, 2, 1, 5), "foo");
@@ -87,7 +87,7 @@ public class DefaultCpdTokensTest {
@Test
public void save_many_tokens() {
SensorStorage sensorStorage = mock(SensorStorage.class);
- DefaultCpdTokens tokens = new DefaultCpdTokens(new MapSettings(), sensorStorage)
+ DefaultCpdTokens tokens = new DefaultCpdTokens(new MapSettings().asConfig(), sensorStorage)
.onFile(INPUT_FILE)
.addToken(INPUT_FILE.newRange(1, 2, 1, 5), "foo")
.addToken(INPUT_FILE.newRange(1, 6, 1, 10), "bar")
@@ -108,7 +108,7 @@ public class DefaultCpdTokensTest {
@Test
public void basic_validation() {
SensorStorage sensorStorage = mock(SensorStorage.class);
- DefaultCpdTokens tokens = new DefaultCpdTokens(new MapSettings(), sensorStorage);
+ DefaultCpdTokens tokens = new DefaultCpdTokens(new MapSettings().asConfig(), sensorStorage);
try {
tokens.save();
fail("Expected exception");
@@ -138,7 +138,7 @@ public class DefaultCpdTokensTest {
@Test
public void validate_tokens_order() {
SensorStorage sensorStorage = mock(SensorStorage.class);
- DefaultCpdTokens tokens = new DefaultCpdTokens(new MapSettings(), sensorStorage)
+ DefaultCpdTokens tokens = new DefaultCpdTokens(new MapSettings().asConfig(), sensorStorage)
.onFile(INPUT_FILE)
.addToken(INPUT_FILE.newRange(1, 6, 1, 10), "bar");
diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/internal/SensorContextTesterTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/internal/SensorContextTesterTest.java
index 4893f6fdd63..566facb4a1a 100644
--- a/sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/internal/SensorContextTesterTest.java
+++ b/sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/internal/SensorContextTesterTest.java
@@ -38,8 +38,8 @@ import org.sonar.api.batch.sensor.error.NewAnalysisError;
import org.sonar.api.batch.sensor.highlighting.TypeOfText;
import org.sonar.api.batch.sensor.issue.NewIssue;
import org.sonar.api.batch.sensor.symbol.NewSymbolTable;
-import org.sonar.api.config.MapSettings;
import org.sonar.api.config.Settings;
+import org.sonar.api.config.internal.MapSettings;
import org.sonar.api.measures.CoreMetrics;
import org.sonar.api.rule.RuleKey;
import org.sonar.api.utils.SonarException;
diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/config/EmailSettingsTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/config/EmailSettingsTest.java
index b5504b5d2b3..507ab123b08 100644
--- a/sonar-plugin-api/src/test/java/org/sonar/api/config/EmailSettingsTest.java
+++ b/sonar-plugin-api/src/test/java/org/sonar/api/config/EmailSettingsTest.java
@@ -21,6 +21,7 @@ package org.sonar.api.config;
import org.junit.Test;
import org.sonar.api.CoreProperties;
+import org.sonar.api.config.internal.MapSettings;
import static org.assertj.core.api.Assertions.assertThat;
diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/config/MapSettingsTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/config/internal/MapSettingsTest.java
index 284d35ea507..e28a73cdb9c 100644
--- a/sonar-plugin-api/src/test/java/org/sonar/api/config/MapSettingsTest.java
+++ b/sonar-plugin-api/src/test/java/org/sonar/api/config/internal/MapSettingsTest.java
@@ -17,7 +17,7 @@
* 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.api.config;
+package org.sonar.api.config.internal;
import java.util.Date;
import org.assertj.core.data.Offset;
@@ -28,6 +28,9 @@ import org.junit.rules.ExpectedException;
import org.sonar.api.Properties;
import org.sonar.api.Property;
import org.sonar.api.PropertyType;
+import org.sonar.api.config.PropertyDefinitions;
+import org.sonar.api.config.Settings;
+import org.sonar.api.config.internal.MapSettings;
import org.sonar.api.utils.DateUtils;
import static org.assertj.core.api.Assertions.assertThat;
diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/scan/filesystem/FileExclusionsTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/scan/filesystem/FileExclusionsTest.java
index bd98496fdf9..bd03eec7fed 100644
--- a/sonar-plugin-api/src/test/java/org/sonar/api/scan/filesystem/FileExclusionsTest.java
+++ b/sonar-plugin-api/src/test/java/org/sonar/api/scan/filesystem/FileExclusionsTest.java
@@ -21,27 +21,26 @@ package org.sonar.api.scan.filesystem;
import org.junit.Test;
import org.sonar.api.CoreProperties;
-import org.sonar.api.config.Settings;
-import org.sonar.api.config.MapSettings;
+import org.sonar.api.config.internal.MapSettings;
import static org.assertj.core.api.Assertions.assertThat;
public class FileExclusionsTest {
@Test
public void ignore_inclusion_of_world() {
- Settings settings = new MapSettings();
+ MapSettings settings = new MapSettings();
settings.setProperty(CoreProperties.PROJECT_INCLUSIONS_PROPERTY, "**/*");
settings.setProperty(CoreProperties.PROJECT_TEST_INCLUSIONS_PROPERTY, "**/*");
- assertThat(new FileExclusions(settings).sourceInclusions()).isEmpty();
- assertThat(new FileExclusions(settings).testInclusions()).isEmpty();
+ assertThat(new FileExclusions(settings.asConfig()).sourceInclusions()).isEmpty();
+ assertThat(new FileExclusions(settings.asConfig()).testInclusions()).isEmpty();
}
@Test
public void load_inclusions() {
- Settings settings = new MapSettings();
+ MapSettings settings = new MapSettings();
settings.setProperty(CoreProperties.PROJECT_INCLUSIONS_PROPERTY, "**/*Foo.java");
settings.setProperty(CoreProperties.PROJECT_TEST_INCLUSIONS_PROPERTY, "**/*FooTest.java");
- FileExclusions moduleExclusions = new FileExclusions(settings);
+ FileExclusions moduleExclusions = new FileExclusions(settings.asConfig());
assertThat(moduleExclusions.sourceInclusions()).containsOnly("**/*Foo.java");
assertThat(moduleExclusions.testInclusions()).containsOnly("**/*FooTest.java");
@@ -49,10 +48,10 @@ public class FileExclusionsTest {
@Test
public void load_exclusions() {
- Settings settings = new MapSettings();
+ MapSettings settings = new MapSettings();
settings.setProperty(CoreProperties.PROJECT_EXCLUSIONS_PROPERTY, "**/*Foo.java");
settings.setProperty(CoreProperties.PROJECT_TEST_EXCLUSIONS_PROPERTY, "**/*FooTest.java");
- FileExclusions moduleExclusions = new FileExclusions(settings);
+ FileExclusions moduleExclusions = new FileExclusions(settings.asConfig());
assertThat(moduleExclusions.sourceInclusions()).isEmpty();
assertThat(moduleExclusions.sourceExclusions()).containsOnly("**/*Foo.java");