@@ -131,6 +131,7 @@ public class SensorContextTester implements SensorContext { | |||
return new SensorContextTester(moduleBaseDir); | |||
} | |||
@Override | |||
public MapSettings settings() { | |||
return settings; | |||
} |
@@ -31,27 +31,17 @@ import javax.annotation.CheckForNull; | |||
import javax.annotation.Nullable; | |||
import org.apache.commons.lang.ArrayUtils; | |||
import org.apache.commons.lang.StringUtils; | |||
import org.sonar.api.ce.ComputeEngineSide; | |||
import org.sonar.api.config.Configuration; | |||
import org.sonar.api.config.PropertyDefinition; | |||
import org.sonar.api.config.PropertyDefinitions; | |||
import org.sonar.api.scanner.ScannerSide; | |||
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; | |||
/** | |||
* @deprecated since 6.5 use {@link Configuration} | |||
* Implementation of the deprecated Settings interface | |||
*/ | |||
@ServerSide | |||
@ComputeEngineSide | |||
@ScannerSide | |||
@SonarLintSide | |||
@Deprecated | |||
public abstract class Settings { | |||
public abstract class Settings extends org.sonar.api.config.Settings { | |||
private final PropertyDefinitions definitions; | |||
private final Encryption encryption; | |||
@@ -118,6 +108,7 @@ public abstract class Settings { | |||
/** | |||
* @return {@code true} if the property has a non-default value, else {@code false}. | |||
*/ | |||
@Override | |||
public boolean hasKey(String key) { | |||
return getRawString(key).isPresent(); | |||
} | |||
@@ -143,6 +134,7 @@ public abstract class Settings { | |||
* @throws IllegalStateException if value is encrypted but fails to be decrypted. | |||
*/ | |||
@CheckForNull | |||
@Override | |||
public String getString(String key) { | |||
String effectiveKey = definitions.validKey(key); | |||
Optional<String> value = getRawString(effectiveKey); | |||
@@ -166,6 +158,7 @@ public abstract class Settings { | |||
* | |||
* @return {@code true} if the effective value is {@code "true"}, else {@code false}. | |||
*/ | |||
@Override | |||
public boolean getBoolean(String key) { | |||
String value = getString(key); | |||
return StringUtils.isNotEmpty(value) && Boolean.parseBoolean(value); | |||
@@ -177,6 +170,7 @@ public abstract class Settings { | |||
* @return the value as {@code int}. If the property does not have value nor default value, then {@code 0} is returned. | |||
* @throws NumberFormatException if value is not empty and is not a parsable integer | |||
*/ | |||
@Override | |||
public int getInt(String key) { | |||
String value = getString(key); | |||
if (StringUtils.isNotEmpty(value)) { | |||
@@ -191,6 +185,7 @@ public abstract class Settings { | |||
* @return the value as {@code long}. If the property does not have value nor default value, then {@code 0L} is returned. | |||
* @throws NumberFormatException if value is not empty and is not a parsable {@code long} | |||
*/ | |||
@Override | |||
public long getLong(String key) { | |||
String value = getString(key); | |||
if (StringUtils.isNotEmpty(value)) { | |||
@@ -206,6 +201,7 @@ public abstract class Settings { | |||
* @throws RuntimeException if value is not empty and is not in accordance with {@link DateUtils#DATE_FORMAT}. | |||
*/ | |||
@CheckForNull | |||
@Override | |||
public Date getDate(String key) { | |||
String value = getString(key); | |||
if (StringUtils.isNotEmpty(value)) { | |||
@@ -221,6 +217,7 @@ public abstract class Settings { | |||
* @throws RuntimeException if value is not empty and is not in accordance with {@link DateUtils#DATETIME_FORMAT}. | |||
*/ | |||
@CheckForNull | |||
@Override | |||
public Date getDateTime(String key) { | |||
String value = getString(key); | |||
if (StringUtils.isNotEmpty(value)) { | |||
@@ -236,6 +233,7 @@ public abstract class Settings { | |||
* @throws NumberFormatException if value is not empty and is not a parsable number | |||
*/ | |||
@CheckForNull | |||
@Override | |||
public Float getFloat(String key) { | |||
String value = getString(key); | |||
if (StringUtils.isNotEmpty(value)) { | |||
@@ -255,6 +253,7 @@ public abstract class Settings { | |||
* @throws NumberFormatException if value is not empty and is not a parsable number | |||
*/ | |||
@CheckForNull | |||
@Override | |||
public Double getDouble(String key) { | |||
String value = getString(key); | |||
if (StringUtils.isNotEmpty(value)) { | |||
@@ -277,6 +276,7 @@ public abstract class Settings { | |||
* <li>"one, , three" -> ["one", "", "three"]</li> | |||
* </ul> | |||
*/ | |||
@Override | |||
public String[] getStringArray(String key) { | |||
String effectiveKey = definitions.validKey(key); | |||
Optional<PropertyDefinition> def = getDefinition(effectiveKey); | |||
@@ -300,6 +300,7 @@ public abstract class Settings { | |||
* @return non-null array of lines. The line termination characters are excluded. | |||
* @since 3.2 | |||
*/ | |||
@Override | |||
public String[] getStringLines(String key) { | |||
String value = getString(key); | |||
if (StringUtils.isEmpty(value)) { | |||
@@ -311,6 +312,7 @@ public abstract class Settings { | |||
/** | |||
* Value is split and trimmed. | |||
*/ | |||
@Override | |||
public String[] getStringArrayBySeparator(String key, String separator) { | |||
String value = getString(key); | |||
if (value != null) { | |||
@@ -451,6 +453,7 @@ public abstract class Settings { | |||
return this; | |||
} | |||
@Override | |||
public List<String> getKeysStartingWith(String prefix) { | |||
return getProperties().keySet().stream() | |||
.filter(key -> StringUtils.startsWith(key, prefix)) |
@@ -40,6 +40,7 @@ import org.sonar.api.batch.sensor.rule.AdHocRule; | |||
import org.sonar.api.batch.sensor.rule.NewAdHocRule; | |||
import org.sonar.api.batch.sensor.symbol.NewSymbolTable; | |||
import org.sonar.api.config.Configuration; | |||
import org.sonar.api.config.Settings; | |||
import org.sonar.api.scanner.fs.InputProject; | |||
import org.sonar.api.scanner.sensor.ProjectSensor; | |||
import org.sonar.api.utils.Version; | |||
@@ -51,6 +52,12 @@ import org.sonar.api.utils.Version; | |||
*/ | |||
public interface SensorContext { | |||
/** | |||
* @deprecated since 6.5 use {@link #config()} | |||
*/ | |||
@Deprecated | |||
Settings settings(); | |||
/** | |||
* Get settings of the project. | |||
* @since 6.5 |
@@ -0,0 +1,147 @@ | |||
/* | |||
* SonarQube | |||
* Copyright (C) 2009-2020 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.Date; | |||
import java.util.List; | |||
import javax.annotation.CheckForNull; | |||
import org.sonar.api.ce.ComputeEngineSide; | |||
import org.sonar.api.scanner.ScannerSide; | |||
import org.sonar.api.server.ServerSide; | |||
import org.sonar.api.utils.DateUtils; | |||
import org.sonarsource.api.sonarlint.SonarLintSide; | |||
/** | |||
* @deprecated since 6.5 use {@link Configuration}. Implementation moved out of the API in 8.3. Only remains minimal interface to make some outdated plugins happy. | |||
*/ | |||
@ServerSide | |||
@ComputeEngineSide | |||
@ScannerSide | |||
@SonarLintSide | |||
@Deprecated | |||
public abstract class Settings { | |||
/** | |||
* @return {@code true} if the property has a non-default value, else {@code false}. | |||
*/ | |||
public abstract boolean hasKey(String key); | |||
/** | |||
* The effective value of the specified property. Can return | |||
* {@code null} 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. | |||
*/ | |||
@CheckForNull | |||
public abstract String getString(String key); | |||
/** | |||
* Effective value as boolean. It is {@code false} if {@link #getString(String)} | |||
* does not return {@code "true"}, even if it's not a boolean representation. | |||
* | |||
* @return {@code true} if the effective value is {@code "true"}, else {@code false}. | |||
*/ | |||
public abstract boolean getBoolean(String key); | |||
/** | |||
* Effective value as {@code int}. | |||
* | |||
* @return the value as {@code int}. If the property does not have value nor default value, then {@code 0} is returned. | |||
* @throws NumberFormatException if value is not empty and is not a parsable integer | |||
*/ | |||
public abstract int getInt(String key); | |||
/** | |||
* Effective value as {@code long}. | |||
* | |||
* @return the value as {@code long}. If the property does not have value nor default value, then {@code 0L} is returned. | |||
* @throws NumberFormatException if value is not empty and is not a parsable {@code long} | |||
*/ | |||
public abstract long getLong(String key); | |||
/** | |||
* Effective value as {@link Date}, without time fields. Format is {@link DateUtils#DATE_FORMAT}. | |||
* | |||
* @return the value as a {@link Date}. If the property does not have value nor default value, then {@code null} is returned. | |||
* @throws RuntimeException if value is not empty and is not in accordance with {@link DateUtils#DATE_FORMAT}. | |||
*/ | |||
@CheckForNull | |||
public abstract Date getDate(String key); | |||
/** | |||
* Effective value as {@link Date}, with time fields. Format is {@link DateUtils#DATETIME_FORMAT}. | |||
* | |||
* @return the value as a {@link Date}. If the property does not have value nor default value, then {@code null} is returned. | |||
* @throws RuntimeException if value is not empty and is not in accordance with {@link DateUtils#DATETIME_FORMAT}. | |||
*/ | |||
@CheckForNull | |||
public abstract Date getDateTime(String key); | |||
/** | |||
* Effective value as {@code Float}. | |||
* | |||
* @return the value as {@code Float}. If the property does not have value nor default value, then {@code null} is returned. | |||
* @throws NumberFormatException if value is not empty and is not a parsable number | |||
*/ | |||
@CheckForNull | |||
public abstract Float getFloat(String key); | |||
/** | |||
* Effective value as {@code Double}. | |||
* | |||
* @return the value as {@code Double}. If the property does not have value nor default value, then {@code null} is returned. | |||
* @throws NumberFormatException if value is not empty and is not a parsable number | |||
*/ | |||
@CheckForNull | |||
public abstract Double getDouble(String key); | |||
/** | |||
* Value is split by comma and trimmed. Never returns null. | |||
* <br> | |||
* Examples : | |||
* <ul> | |||
* <li>"one,two,three " -> ["one", "two", "three"]</li> | |||
* <li>" one, two, three " -> ["one", "two", "three"]</li> | |||
* <li>"one, , three" -> ["one", "", "three"]</li> | |||
* </ul> | |||
*/ | |||
public abstract String[] getStringArray(String key); | |||
/** | |||
* Value is split by carriage returns. | |||
* | |||
* @return non-null array of lines. The line termination characters are excluded. | |||
* @since 3.2 | |||
*/ | |||
public abstract String[] getStringLines(String key); | |||
/** | |||
* Value is split and trimmed. | |||
*/ | |||
public abstract String[] getStringArrayBySeparator(String key, String separator); | |||
public abstract List<String> getKeysStartingWith(String prefix); | |||
} |
@@ -27,15 +27,16 @@ import org.sonar.api.batch.fs.internal.DefaultInputProject; | |||
import org.sonar.api.batch.rule.ActiveRules; | |||
import org.sonar.api.batch.sensor.internal.SensorStorage; | |||
import org.sonar.api.config.Configuration; | |||
import org.sonar.api.config.Settings; | |||
@ThreadSafe | |||
public class ModuleSensorContext extends ProjectSensorContext { | |||
private final InputModule module; | |||
public ModuleSensorContext(DefaultInputProject project, InputModule module, Configuration config, FileSystem fs, ActiveRules activeRules, | |||
public ModuleSensorContext(DefaultInputProject project, InputModule module, Configuration config, Settings mutableSettings, FileSystem fs, ActiveRules activeRules, | |||
SensorStorage sensorStorage, SonarRuntime sonarRuntime) { | |||
super(project, config, fs, activeRules, sensorStorage, sonarRuntime); | |||
super(project, config, mutableSettings, fs, activeRules, sensorStorage, sonarRuntime); | |||
this.module = module; | |||
} | |||
@@ -50,6 +50,7 @@ import org.sonar.api.batch.sensor.rule.internal.DefaultAdHocRule; | |||
import org.sonar.api.batch.sensor.symbol.NewSymbolTable; | |||
import org.sonar.api.batch.sensor.symbol.internal.DefaultSymbolTable; | |||
import org.sonar.api.config.Configuration; | |||
import org.sonar.api.config.Settings; | |||
import org.sonar.api.scanner.fs.InputProject; | |||
import org.sonar.api.utils.Version; | |||
import org.sonar.scanner.sensor.noop.NoOpNewAnalysisError; | |||
@@ -59,6 +60,7 @@ public class ProjectSensorContext implements SensorContext { | |||
static final NoOpNewAnalysisError NO_OP_NEW_ANALYSIS_ERROR = new NoOpNewAnalysisError(); | |||
private final Settings mutableSettings; | |||
private final FileSystem fs; | |||
private final ActiveRules activeRules; | |||
private final SensorStorage sensorStorage; | |||
@@ -66,16 +68,22 @@ public class ProjectSensorContext implements SensorContext { | |||
private final SonarRuntime sonarRuntime; | |||
private final Configuration config; | |||
public ProjectSensorContext(DefaultInputProject project, Configuration config, FileSystem fs, ActiveRules activeRules, | |||
public ProjectSensorContext(DefaultInputProject project, Configuration config, Settings mutableSettings, FileSystem fs, ActiveRules activeRules, | |||
SensorStorage sensorStorage, SonarRuntime sonarRuntime) { | |||
this.project = project; | |||
this.config = config; | |||
this.mutableSettings = mutableSettings; | |||
this.fs = fs; | |||
this.activeRules = activeRules; | |||
this.sensorStorage = sensorStorage; | |||
this.sonarRuntime = sonarRuntime; | |||
} | |||
@Override | |||
public Settings settings() { | |||
return mutableSettings; | |||
} | |||
@Override | |||
public Configuration config() { | |||
return config; |
@@ -68,7 +68,7 @@ public class ModuleSensorContextTest { | |||
settings = new MapSettings(); | |||
sensorStorage = mock(SensorStorage.class); | |||
runtime = SonarRuntimeImpl.forSonarQube(Version.parse("5.5"), SonarQubeSide.SCANNER, SonarEdition.COMMUNITY); | |||
adaptor = new ModuleSensorContext(mock(DefaultInputProject.class), mock(InputModule.class), settings.asConfig(), fs, activeRules, sensorStorage, runtime); | |||
adaptor = new ModuleSensorContext(mock(DefaultInputProject.class), mock(InputModule.class), settings.asConfig(), settings, fs, activeRules, sensorStorage, runtime); | |||
} | |||
@Test |