return new SensorContextTester(moduleBaseDir); | return new SensorContextTester(moduleBaseDir); | ||||
} | } | ||||
@Override | |||||
public MapSettings settings() { | public MapSettings settings() { | ||||
return settings; | return settings; | ||||
} | } |
import javax.annotation.Nullable; | import javax.annotation.Nullable; | ||||
import org.apache.commons.lang.ArrayUtils; | import org.apache.commons.lang.ArrayUtils; | ||||
import org.apache.commons.lang.StringUtils; | 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.PropertyDefinition; | ||||
import org.sonar.api.config.PropertyDefinitions; | 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.sonar.api.utils.DateUtils; | ||||
import org.sonarsource.api.sonarlint.SonarLintSide; | |||||
import static java.util.Objects.requireNonNull; | import static java.util.Objects.requireNonNull; | ||||
import static org.apache.commons.lang.StringUtils.trim; | 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 PropertyDefinitions definitions; | ||||
private final Encryption encryption; | private final Encryption encryption; | ||||
/** | /** | ||||
* @return {@code true} if the property has a non-default value, else {@code false}. | * @return {@code true} if the property has a non-default value, else {@code false}. | ||||
*/ | */ | ||||
@Override | |||||
public boolean hasKey(String key) { | public boolean hasKey(String key) { | ||||
return getRawString(key).isPresent(); | return getRawString(key).isPresent(); | ||||
} | } | ||||
* @throws IllegalStateException if value is encrypted but fails to be decrypted. | * @throws IllegalStateException if value is encrypted but fails to be decrypted. | ||||
*/ | */ | ||||
@CheckForNull | @CheckForNull | ||||
@Override | |||||
public String getString(String key) { | public String getString(String key) { | ||||
String effectiveKey = definitions.validKey(key); | String effectiveKey = definitions.validKey(key); | ||||
Optional<String> value = getRawString(effectiveKey); | Optional<String> value = getRawString(effectiveKey); | ||||
* | * | ||||
* @return {@code true} if the effective value is {@code "true"}, else {@code false}. | * @return {@code true} if the effective value is {@code "true"}, else {@code false}. | ||||
*/ | */ | ||||
@Override | |||||
public boolean getBoolean(String key) { | public boolean getBoolean(String key) { | ||||
String value = getString(key); | String value = getString(key); | ||||
return StringUtils.isNotEmpty(value) && Boolean.parseBoolean(value); | return StringUtils.isNotEmpty(value) && Boolean.parseBoolean(value); | ||||
* @return the value as {@code int}. If the property does not have value nor default value, then {@code 0} is returned. | * @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 | * @throws NumberFormatException if value is not empty and is not a parsable integer | ||||
*/ | */ | ||||
@Override | |||||
public int getInt(String key) { | public int getInt(String key) { | ||||
String value = getString(key); | String value = getString(key); | ||||
if (StringUtils.isNotEmpty(value)) { | if (StringUtils.isNotEmpty(value)) { | ||||
* @return the value as {@code long}. If the property does not have value nor default value, then {@code 0L} is returned. | * @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} | * @throws NumberFormatException if value is not empty and is not a parsable {@code long} | ||||
*/ | */ | ||||
@Override | |||||
public long getLong(String key) { | public long getLong(String key) { | ||||
String value = getString(key); | String value = getString(key); | ||||
if (StringUtils.isNotEmpty(value)) { | if (StringUtils.isNotEmpty(value)) { | ||||
* @throws RuntimeException if value is not empty and is not in accordance with {@link DateUtils#DATE_FORMAT}. | * @throws RuntimeException if value is not empty and is not in accordance with {@link DateUtils#DATE_FORMAT}. | ||||
*/ | */ | ||||
@CheckForNull | @CheckForNull | ||||
@Override | |||||
public Date getDate(String key) { | public Date getDate(String key) { | ||||
String value = getString(key); | String value = getString(key); | ||||
if (StringUtils.isNotEmpty(value)) { | if (StringUtils.isNotEmpty(value)) { | ||||
* @throws RuntimeException if value is not empty and is not in accordance with {@link DateUtils#DATETIME_FORMAT}. | * @throws RuntimeException if value is not empty and is not in accordance with {@link DateUtils#DATETIME_FORMAT}. | ||||
*/ | */ | ||||
@CheckForNull | @CheckForNull | ||||
@Override | |||||
public Date getDateTime(String key) { | public Date getDateTime(String key) { | ||||
String value = getString(key); | String value = getString(key); | ||||
if (StringUtils.isNotEmpty(value)) { | if (StringUtils.isNotEmpty(value)) { | ||||
* @throws NumberFormatException if value is not empty and is not a parsable number | * @throws NumberFormatException if value is not empty and is not a parsable number | ||||
*/ | */ | ||||
@CheckForNull | @CheckForNull | ||||
@Override | |||||
public Float getFloat(String key) { | public Float getFloat(String key) { | ||||
String value = getString(key); | String value = getString(key); | ||||
if (StringUtils.isNotEmpty(value)) { | if (StringUtils.isNotEmpty(value)) { | ||||
* @throws NumberFormatException if value is not empty and is not a parsable number | * @throws NumberFormatException if value is not empty and is not a parsable number | ||||
*/ | */ | ||||
@CheckForNull | @CheckForNull | ||||
@Override | |||||
public Double getDouble(String key) { | public Double getDouble(String key) { | ||||
String value = getString(key); | String value = getString(key); | ||||
if (StringUtils.isNotEmpty(value)) { | if (StringUtils.isNotEmpty(value)) { | ||||
* <li>"one, , three" -> ["one", "", "three"]</li> | * <li>"one, , three" -> ["one", "", "three"]</li> | ||||
* </ul> | * </ul> | ||||
*/ | */ | ||||
@Override | |||||
public String[] getStringArray(String key) { | public String[] getStringArray(String key) { | ||||
String effectiveKey = definitions.validKey(key); | String effectiveKey = definitions.validKey(key); | ||||
Optional<PropertyDefinition> def = getDefinition(effectiveKey); | Optional<PropertyDefinition> def = getDefinition(effectiveKey); | ||||
* @return non-null array of lines. The line termination characters are excluded. | * @return non-null array of lines. The line termination characters are excluded. | ||||
* @since 3.2 | * @since 3.2 | ||||
*/ | */ | ||||
@Override | |||||
public String[] getStringLines(String key) { | public String[] getStringLines(String key) { | ||||
String value = getString(key); | String value = getString(key); | ||||
if (StringUtils.isEmpty(value)) { | if (StringUtils.isEmpty(value)) { | ||||
/** | /** | ||||
* Value is split and trimmed. | * Value is split and trimmed. | ||||
*/ | */ | ||||
@Override | |||||
public String[] getStringArrayBySeparator(String key, String separator) { | public String[] getStringArrayBySeparator(String key, String separator) { | ||||
String value = getString(key); | String value = getString(key); | ||||
if (value != null) { | if (value != null) { | ||||
return this; | return this; | ||||
} | } | ||||
@Override | |||||
public List<String> getKeysStartingWith(String prefix) { | public List<String> getKeysStartingWith(String prefix) { | ||||
return getProperties().keySet().stream() | return getProperties().keySet().stream() | ||||
.filter(key -> StringUtils.startsWith(key, prefix)) | .filter(key -> StringUtils.startsWith(key, prefix)) |
import org.sonar.api.batch.sensor.rule.NewAdHocRule; | import org.sonar.api.batch.sensor.rule.NewAdHocRule; | ||||
import org.sonar.api.batch.sensor.symbol.NewSymbolTable; | import org.sonar.api.batch.sensor.symbol.NewSymbolTable; | ||||
import org.sonar.api.config.Configuration; | import org.sonar.api.config.Configuration; | ||||
import org.sonar.api.config.Settings; | |||||
import org.sonar.api.scanner.fs.InputProject; | import org.sonar.api.scanner.fs.InputProject; | ||||
import org.sonar.api.scanner.sensor.ProjectSensor; | import org.sonar.api.scanner.sensor.ProjectSensor; | ||||
import org.sonar.api.utils.Version; | import org.sonar.api.utils.Version; | ||||
*/ | */ | ||||
public interface SensorContext { | public interface SensorContext { | ||||
/** | |||||
* @deprecated since 6.5 use {@link #config()} | |||||
*/ | |||||
@Deprecated | |||||
Settings settings(); | |||||
/** | /** | ||||
* Get settings of the project. | * Get settings of the project. | ||||
* @since 6.5 | * @since 6.5 |
/* | |||||
* 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); | |||||
} |
import org.sonar.api.batch.rule.ActiveRules; | import org.sonar.api.batch.rule.ActiveRules; | ||||
import org.sonar.api.batch.sensor.internal.SensorStorage; | import org.sonar.api.batch.sensor.internal.SensorStorage; | ||||
import org.sonar.api.config.Configuration; | import org.sonar.api.config.Configuration; | ||||
import org.sonar.api.config.Settings; | |||||
@ThreadSafe | @ThreadSafe | ||||
public class ModuleSensorContext extends ProjectSensorContext { | public class ModuleSensorContext extends ProjectSensorContext { | ||||
private final InputModule module; | 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) { | SensorStorage sensorStorage, SonarRuntime sonarRuntime) { | ||||
super(project, config, fs, activeRules, sensorStorage, sonarRuntime); | |||||
super(project, config, mutableSettings, fs, activeRules, sensorStorage, sonarRuntime); | |||||
this.module = module; | this.module = module; | ||||
} | } | ||||
import org.sonar.api.batch.sensor.symbol.NewSymbolTable; | import org.sonar.api.batch.sensor.symbol.NewSymbolTable; | ||||
import org.sonar.api.batch.sensor.symbol.internal.DefaultSymbolTable; | import org.sonar.api.batch.sensor.symbol.internal.DefaultSymbolTable; | ||||
import org.sonar.api.config.Configuration; | import org.sonar.api.config.Configuration; | ||||
import org.sonar.api.config.Settings; | |||||
import org.sonar.api.scanner.fs.InputProject; | import org.sonar.api.scanner.fs.InputProject; | ||||
import org.sonar.api.utils.Version; | import org.sonar.api.utils.Version; | ||||
import org.sonar.scanner.sensor.noop.NoOpNewAnalysisError; | import org.sonar.scanner.sensor.noop.NoOpNewAnalysisError; | ||||
static final NoOpNewAnalysisError NO_OP_NEW_ANALYSIS_ERROR = new NoOpNewAnalysisError(); | static final NoOpNewAnalysisError NO_OP_NEW_ANALYSIS_ERROR = new NoOpNewAnalysisError(); | ||||
private final Settings mutableSettings; | |||||
private final FileSystem fs; | private final FileSystem fs; | ||||
private final ActiveRules activeRules; | private final ActiveRules activeRules; | ||||
private final SensorStorage sensorStorage; | private final SensorStorage sensorStorage; | ||||
private final SonarRuntime sonarRuntime; | private final SonarRuntime sonarRuntime; | ||||
private final Configuration config; | 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) { | SensorStorage sensorStorage, SonarRuntime sonarRuntime) { | ||||
this.project = project; | this.project = project; | ||||
this.config = config; | this.config = config; | ||||
this.mutableSettings = mutableSettings; | |||||
this.fs = fs; | this.fs = fs; | ||||
this.activeRules = activeRules; | this.activeRules = activeRules; | ||||
this.sensorStorage = sensorStorage; | this.sensorStorage = sensorStorage; | ||||
this.sonarRuntime = sonarRuntime; | this.sonarRuntime = sonarRuntime; | ||||
} | } | ||||
@Override | |||||
public Settings settings() { | |||||
return mutableSettings; | |||||
} | |||||
@Override | @Override | ||||
public Configuration config() { | public Configuration config() { | ||||
return config; | return config; |
settings = new MapSettings(); | settings = new MapSettings(); | ||||
sensorStorage = mock(SensorStorage.class); | sensorStorage = mock(SensorStorage.class); | ||||
runtime = SonarRuntimeImpl.forSonarQube(Version.parse("5.5"), SonarQubeSide.SCANNER, SonarEdition.COMMUNITY); | 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 | @Test |