diff options
author | Duarte Meneses <duarte.meneses@sonarsource.com> | 2019-06-19 13:56:51 -0500 |
---|---|---|
committer | SonarTech <sonartech@sonarsource.com> | 2019-07-12 20:21:14 +0200 |
commit | 93dc9770902dc7e168869d88b5ad731bfc0bedd9 (patch) | |
tree | 97ba885661d5cd9a2115fe212df31bacec9f9947 /sonar-plugin-api/src/main | |
parent | 7c7d9b6b90244d2c974207862071caccdb2c9bb5 (diff) | |
download | sonarqube-93dc9770902dc7e168869d88b5ad731bfc0bedd9.tar.gz sonarqube-93dc9770902dc7e168869d88b5ad731bfc0bedd9.zip |
Extract implementation from plugin API and create new module sonar-plugin-api-impl
Diffstat (limited to 'sonar-plugin-api/src/main')
30 files changed, 402 insertions, 2066 deletions
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/Metadata.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/Metadata.java deleted file mode 100644 index 50c0d753bcd..00000000000 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/Metadata.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 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.batch.fs.internal; - -import java.util.Arrays; - -import javax.annotation.concurrent.Immutable; - -@Immutable -public class Metadata { - private final int lines; - private final int nonBlankLines; - private final String hash; - private final int[] originalLineStartOffsets; - private final int[] originalLineEndOffsets; - private final int lastValidOffset; - - public Metadata(int lines, int nonBlankLines, String hash, int[] originalLineStartOffsets, int[] originalLineEndOffsets, int lastValidOffset) { - this.lines = lines; - this.nonBlankLines = nonBlankLines; - this.hash = hash; - this.originalLineStartOffsets = Arrays.copyOf(originalLineStartOffsets, originalLineStartOffsets.length); - this.originalLineEndOffsets = Arrays.copyOf(originalLineEndOffsets, originalLineEndOffsets.length); - this.lastValidOffset = lastValidOffset; - } - - public int lines() { - return lines; - } - - public int nonBlankLines() { - return nonBlankLines; - } - - public String hash() { - return hash; - } - - public int[] originalLineStartOffsets() { - return originalLineStartOffsets; - } - - public int[] originalLineEndOffsets() { - return originalLineEndOffsets; - } - - public int lastValidOffset() { - return lastValidOffset; - } - - public boolean isEmpty() { - return lastValidOffset == 0; - } -} diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/PathPattern.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/PathPattern.java deleted file mode 100644 index 41287d42011..00000000000 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/PathPattern.java +++ /dev/null @@ -1,136 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 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.batch.fs.internal; - -import java.nio.file.Path; -import javax.annotation.concurrent.ThreadSafe; -import org.apache.commons.io.FilenameUtils; -import org.apache.commons.lang.StringUtils; -import org.sonar.api.utils.PathUtils; -import org.sonar.api.utils.WildcardPattern; -import org.sonar.api.utils.log.Logger; -import org.sonar.api.utils.log.Loggers; - -@ThreadSafe -public abstract class PathPattern { - - private static final Logger LOG = Loggers.get(PathPattern.class); - - /** - * @deprecated since 6.6 - */ - @Deprecated - private static final String ABSOLUTE_PATH_PATTERN_PREFIX = "file:"; - final WildcardPattern pattern; - - PathPattern(String pattern) { - this.pattern = WildcardPattern.create(pattern); - } - - public abstract boolean match(Path absolutePath, Path relativePath); - - public abstract boolean match(Path absolutePath, Path relativePath, boolean caseSensitiveFileExtension); - - public static PathPattern create(String s) { - String trimmed = StringUtils.trim(s); - if (StringUtils.startsWithIgnoreCase(trimmed, ABSOLUTE_PATH_PATTERN_PREFIX)) { - LOG.warn("Using absolute path pattern is deprecated. Please use relative path instead of '" + trimmed + "'"); - return new AbsolutePathPattern(StringUtils.substring(trimmed, ABSOLUTE_PATH_PATTERN_PREFIX.length())); - } - return new RelativePathPattern(trimmed); - } - - public static PathPattern[] create(String[] s) { - PathPattern[] result = new PathPattern[s.length]; - for (int i = 0; i < s.length; i++) { - result[i] = create(s[i]); - } - return result; - } - - /** - * @deprecated since 6.6 - */ - @Deprecated - private static class AbsolutePathPattern extends PathPattern { - private AbsolutePathPattern(String pattern) { - super(pattern); - } - - @Override - public boolean match(Path absolutePath, Path relativePath) { - return match(absolutePath, relativePath, true); - } - - @Override - public boolean match(Path absolutePath, Path relativePath, boolean caseSensitiveFileExtension) { - String path = PathUtils.sanitize(absolutePath.toString()); - if (!caseSensitiveFileExtension) { - String extension = sanitizeExtension(FilenameUtils.getExtension(path)); - if (StringUtils.isNotBlank(extension)) { - path = StringUtils.removeEndIgnoreCase(path, extension); - path = path + extension; - } - } - return pattern.match(path); - } - - @Override - public String toString() { - return ABSOLUTE_PATH_PATTERN_PREFIX + pattern.toString(); - } - } - - /** - * Path relative to module basedir - */ - private static class RelativePathPattern extends PathPattern { - private RelativePathPattern(String pattern) { - super(pattern); - } - - @Override - public boolean match(Path absolutePath, Path relativePath) { - return match(absolutePath, relativePath, true); - } - - @Override - public boolean match(Path absolutePath, Path relativePath, boolean caseSensitiveFileExtension) { - String path = PathUtils.sanitize(relativePath.toString()); - if (!caseSensitiveFileExtension) { - String extension = sanitizeExtension(FilenameUtils.getExtension(path)); - if (StringUtils.isNotBlank(extension)) { - path = StringUtils.removeEndIgnoreCase(path, extension); - path = path + extension; - } - } - return path != null && pattern.match(path); - } - - @Override - public String toString() { - return pattern.toString(); - } - } - - static String sanitizeExtension(String suffix) { - return StringUtils.lowerCase(StringUtils.removeStart(suffix, ".")); - } -} diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/SensorStrategy.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/SensorStrategy.java deleted file mode 100644 index adde73809f6..00000000000 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/SensorStrategy.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 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.batch.fs.internal; - -import org.sonar.api.batch.fs.InputFile; - -/** - * A shared, mutable object in the project container. - * It's used during the execution of sensors to decide whether - * sensors should be executed once for the entire project, or per-module. - * It is also injected into each InputFile to change the behavior of {@link InputFile#relativePath()} - */ -public class SensorStrategy { - - private boolean global = true; - - public boolean isGlobal() { - return global; - } - - public void setGlobal(boolean global) { - this.global = global; - } -} diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/package-info.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/package-info.java deleted file mode 100644 index 4af8d775684..00000000000 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/package-info.java +++ /dev/null @@ -1,24 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 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.batch.fs.internal; - -import javax.annotation.ParametersAreNonnullByDefault; - diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/rule/LoadedActiveRule.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/rule/LoadedActiveRule.java new file mode 100644 index 00000000000..fa22fb46f13 --- /dev/null +++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/rule/LoadedActiveRule.java @@ -0,0 +1,111 @@ +/* + * SonarQube + * Copyright (C) 2009-2019 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.batch.rule; + +import java.util.Map; +import javax.annotation.CheckForNull; +import javax.annotation.Nullable; +import org.sonar.api.rule.RuleKey; + +public class LoadedActiveRule { + private RuleKey ruleKey; + private String severity; + private String name; + private String language; + private Map<String, String> params; + private long createdAt; + private long updatedAt; + private String templateRuleKey; + private String internalKey; + + public RuleKey getRuleKey() { + return ruleKey; + } + + public void setRuleKey(RuleKey ruleKey) { + this.ruleKey = ruleKey; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getSeverity() { + return severity; + } + + public void setSeverity(String severity) { + this.severity = severity; + } + + public String getLanguage() { + return language; + } + + public void setLanguage(String language) { + this.language = language; + } + + public Map<String, String> getParams() { + return params; + } + + public void setParams(Map<String, String> params) { + this.params = params; + } + + public long getCreatedAt() { + return createdAt; + } + + public void setCreatedAt(long createdAt) { + this.createdAt = createdAt; + } + + public long getUpdatedAt() { + return updatedAt; + } + + public void setUpdatedAt(long updatedAt) { + this.updatedAt = updatedAt; + } + + @CheckForNull + public String getTemplateRuleKey() { + return templateRuleKey; + } + + public void setTemplateRuleKey(@Nullable String templateRuleKey) { + this.templateRuleKey = templateRuleKey; + } + + public String getInternalKey() { + return internalKey; + } + + public void setInternalKey(String internalKey) { + this.internalKey = internalKey; + } + +} diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/rule/NewActiveRule.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/rule/NewActiveRule.java new file mode 100644 index 00000000000..6f14a13a990 --- /dev/null +++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/rule/NewActiveRule.java @@ -0,0 +1,134 @@ +/* + * SonarQube + * Copyright (C) 2009-2019 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.batch.rule; + +import java.util.HashMap; +import java.util.Map; +import javax.annotation.Nullable; +import javax.annotation.concurrent.Immutable; +import org.apache.commons.lang.StringUtils; +import org.sonar.api.rule.RuleKey; +import org.sonar.api.rule.Severity; + +/** + * @since 4.2 + */ +@Immutable +public class NewActiveRule { + final RuleKey ruleKey; + final String name; + final String severity; + final Map<String, String> params; + final long createdAt; + final long updatedAt; + final String internalKey; + final String language; + final String templateRuleKey; + final String qProfileKey; + + NewActiveRule(Builder builder) { + this.ruleKey = builder.ruleKey; + this.name = builder.name; + this.severity = builder.severity; + this.params = builder.params; + this.createdAt = builder.createdAt; + this.updatedAt = builder.updatedAt; + this.internalKey = builder.internalKey; + this.language = builder.language; + this.templateRuleKey = builder.templateRuleKey; + this.qProfileKey = builder.qProfileKey; + } + + public RuleKey ruleKey() { + return this.ruleKey; + } + + public static class Builder { + private RuleKey ruleKey; + private String name; + private String severity = Severity.defaultSeverity(); + private Map<String, String> params = new HashMap<>(); + private long createdAt; + private long updatedAt; + private String internalKey; + private String language; + private String templateRuleKey; + private String qProfileKey; + + public Builder setRuleKey(RuleKey ruleKey) { + this.ruleKey = ruleKey; + return this; + } + + public Builder setName(String name) { + this.name = name; + return this; + } + + public Builder setSeverity(@Nullable String severity) { + this.severity = StringUtils.defaultIfBlank(severity, Severity.defaultSeverity()); + return this; + } + + public Builder setParam(String key, @Nullable String value) { + // possible improvement : check that the param key exists in rule definition + if (value == null) { + params.remove(key); + } else { + params.put(key, value); + } + return this; + } + + public Builder setCreatedAt(long createdAt) { + this.createdAt = createdAt; + return this; + } + + public Builder setUpdatedAt(long updatedAt) { + this.updatedAt = updatedAt; + return this; + } + + public Builder setInternalKey(@Nullable String internalKey) { + this.internalKey = internalKey; + return this; + } + + public Builder setLanguage(@Nullable String language) { + this.language = language; + return this; + } + + public Builder setTemplateRuleKey(@Nullable String templateRuleKey) { + this.templateRuleKey = templateRuleKey; + return this; + } + + public Builder setQProfileKey(String qProfileKey) { + this.qProfileKey = qProfileKey; + return this; + } + + public NewActiveRule build() { + return new NewActiveRule(this); + } + } +} diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/rule/NewRule.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/rule/NewRule.java new file mode 100644 index 00000000000..edcf70f8ce6 --- /dev/null +++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/rule/NewRule.java @@ -0,0 +1,92 @@ +/* + * SonarQube + * Copyright (C) 2009-2019 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.batch.rule; + +import java.util.HashMap; +import java.util.Map; +import javax.annotation.Nullable; +import org.apache.commons.lang.ObjectUtils; +import org.apache.commons.lang.StringUtils; +import org.sonar.api.rule.RuleKey; +import org.sonar.api.rule.RuleStatus; +import org.sonar.api.rule.Severity; + +public class NewRule { + + private static final String DEFAULT_SEVERITY = Severity.defaultSeverity(); + + final RuleKey key; + Integer id; + String name; + String description; + String severity = DEFAULT_SEVERITY; + String type; + String internalKey; + RuleStatus status = RuleStatus.defaultStatus(); + Map<String, NewRuleParam> params = new HashMap<>(); + + public NewRule(RuleKey key) { + this.key = key; + } + + public NewRule setId(@Nullable Integer id) { + this.id = id; + return this; + } + + public NewRule setDescription(@Nullable String description) { + this.description = description; + return this; + } + + public NewRule setName(@Nullable String s) { + this.name = s; + return this; + } + + public NewRule setSeverity(@Nullable String severity) { + this.severity = StringUtils.defaultIfBlank(severity, DEFAULT_SEVERITY); + return this; + } + + public NewRule setType(@Nullable String type) { + this.type = type; + return this; + } + + public NewRule setStatus(@Nullable RuleStatus s) { + this.status = (RuleStatus) ObjectUtils.defaultIfNull(s, RuleStatus.defaultStatus()); + return this; + } + + public NewRule setInternalKey(@Nullable String s) { + this.internalKey = s; + return this; + } + + public NewRuleParam addParam(String paramKey) { + if (params.containsKey(paramKey)) { + throw new IllegalStateException(String.format("Parameter '%s' already exists on rule '%s'", paramKey, key)); + } + NewRuleParam param = new NewRuleParam(paramKey); + params.put(paramKey, param); + return param; + } +} diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/utils/internal/package-info.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/rule/NewRuleParam.java index f3fea3220e9..f06830d9245 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/utils/internal/package-info.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/rule/NewRuleParam.java @@ -17,8 +17,20 @@ * 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.utils.internal; +package org.sonar.api.batch.rule; -import javax.annotation.ParametersAreNonnullByDefault; +import javax.annotation.Nullable; +public class NewRuleParam { + final String key; + String description; + + NewRuleParam(String key) { + this.key = key; + } + + public NewRuleParam setDescription(@Nullable String s) { + description = s; + return this; + } +} 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 index 2a1ee512bc0..3afb8c8608e 100644 --- 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 @@ -22,7 +22,6 @@ package org.sonar.api.config; import java.util.Optional; import org.sonar.api.scanner.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; @@ -65,7 +64,7 @@ import org.sonarsource.api.sonarlint.SonarLintSide; * </pre> * * <p> - * For testing, and only for testing, the in-memory implementation {@link MapSettings} can be used. + * For testing, and only for testing, the in-memory implementation MapSettings can be used. * <pre> * {@literal @}Test * public void my_test() { @@ -76,7 +75,6 @@ import org.sonarsource.api.sonarlint.SonarLintSide; * } * </pre> * - * @see MapSettings * @see PropertyDefinition * @since 6.5 */ 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 deleted file mode 100644 index 5455cf03191..00000000000 --- a/sonar-plugin-api/src/main/java/org/sonar/api/config/internal/ConfigurationBridge.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 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/internal/MapSettings.java b/sonar-plugin-api/src/main/java/org/sonar/api/config/internal/MapSettings.java deleted file mode 100644 index 5d07d607923..00000000000 --- a/sonar-plugin-api/src/main/java/org/sonar/api/config/internal/MapSettings.java +++ /dev/null @@ -1,112 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 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.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; -import static java.util.Objects.requireNonNull; - -/** - * In-memory map-based implementation of {@link Settings}. It must be used - * <b>only for unit tests</b>. This is not the implementation - * deployed at runtime, so non-test code must never cast - * {@link Settings} to {@link MapSettings}. - * - * @since 6.1 - */ -public class MapSettings extends Settings { - - private final Map<String, String> props = new HashMap<>(); - private final ConfigurationBridge configurationBridge; - - public MapSettings() { - this(new PropertyDefinitions()); - } - - public MapSettings(PropertyDefinitions definitions) { - super(definitions, new Encryption(null)); - configurationBridge = new ConfigurationBridge(this); - } - - @Override - protected Optional<String> get(String key) { - return Optional.ofNullable(props.get(key)); - } - - @Override - protected void set(String key, String value) { - props.put( - requireNonNull(key, "key can't be null"), - requireNonNull(value, "value can't be null").trim()); - } - - @Override - protected void remove(String key) { - props.remove(key); - } - - @Override - public Map<String, String> getProperties() { - return unmodifiableMap(props); - } - - /** - * Delete all properties - */ - public MapSettings clear() { - props.clear(); - return this; - } - - @Override - public MapSettings setProperty(String key, String value) { - return (MapSettings) super.setProperty(key, value); - } - - @Override - public MapSettings setProperty(String key, Integer value) { - return (MapSettings) super.setProperty(key, value); - } - - @Override - public MapSettings setProperty(String key, Boolean value) { - return (MapSettings) super.setProperty(key, value); - } - - @Override - public MapSettings setProperty(String key, Long value) { - return (MapSettings) super.setProperty(key, value); - } - - /** - * @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/MultivalueProperty.java b/sonar-plugin-api/src/main/java/org/sonar/api/config/internal/MultivalueProperty.java deleted file mode 100644 index dab98c55781..00000000000 --- a/sonar-plugin-api/src/main/java/org/sonar/api/config/internal/MultivalueProperty.java +++ /dev/null @@ -1,208 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 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.io.IOException; -import java.io.StringReader; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; -import java.util.function.Function; -import org.apache.commons.csv.CSVFormat; -import org.apache.commons.csv.CSVParser; -import org.apache.commons.csv.CSVRecord; -import org.apache.commons.lang.ArrayUtils; - -public class MultivalueProperty { - private MultivalueProperty() { - // prevents instantiation - } - - public static String[] parseAsCsv(String key, String value) { - return parseAsCsv(key, value, Function.identity()); - } - - public static String[] parseAsCsv(String key, String value, Function<String, String> valueProcessor) { - String cleanValue = MultivalueProperty.trimFieldsAndRemoveEmptyFields(value); - List<String> result = new ArrayList<>(); - try (CSVParser csvParser = CSVFormat.RFC4180 - .withHeader((String) null) - .withIgnoreEmptyLines() - .withIgnoreSurroundingSpaces() - .parse(new StringReader(cleanValue))) { - List<CSVRecord> records = csvParser.getRecords(); - if (records.isEmpty()) { - return ArrayUtils.EMPTY_STRING_ARRAY; - } - processRecords(result, records, valueProcessor); - return result.toArray(new String[result.size()]); - } catch (IOException e) { - throw new IllegalStateException("Property: '" + key + "' doesn't contain a valid CSV value: '" + value + "'", e); - } - } - - /** - * In most cases we expect a single record. <br>Having multiple records means the input value was splitted over multiple lines (this is common in Maven). - * For example: - * <pre> - * <sonar.exclusions> - * src/foo, - * src/bar, - * src/biz - * <sonar.exclusions> - * </pre> - * In this case records will be merged to form a single list of items. Last item of a record is appended to first item of next record. - * <p> - * This is a very curious case, but we try to preserve line break in the middle of an item: - * <pre> - * <sonar.exclusions> - * a - * b, - * c - * <sonar.exclusions> - * </pre> - * will produce ['a\nb', 'c'] - */ - private static void processRecords(List<String> result, List<CSVRecord> records, Function<String, String> valueProcessor) { - for (CSVRecord csvRecord : records) { - Iterator<String> it = csvRecord.iterator(); - if (!result.isEmpty()) { - String next = it.next(); - if (!next.isEmpty()) { - int lastItemIdx = result.size() - 1; - String previous = result.get(lastItemIdx); - if (previous.isEmpty()) { - result.set(lastItemIdx, valueProcessor.apply(next)); - } else { - result.set(lastItemIdx, valueProcessor.apply(previous + "\n" + next)); - } - } - } - it.forEachRemaining(s -> { - String apply = valueProcessor.apply(s); - result.add(apply); - }); - } - } - - /** - * Removes the empty fields from the value of a multi-value property from empty fields, including trimming each field. - * <p> - * Quotes can be used to prevent an empty field to be removed (as it is used to preserve empty spaces). - * <ul> - * <li>{@code "" => ""}</li> - * <li>{@code " " => ""}</li> - * <li>{@code "," => ""}</li> - * <li>{@code ",," => ""}</li> - * <li>{@code ",,," => ""}</li> - * <li>{@code ",a" => "a"}</li> - * <li>{@code "a," => "a"}</li> - * <li>{@code ",a," => "a"}</li> - * <li>{@code "a,,b" => "a,b"}</li> - * <li>{@code "a, ,b" => "a,b"}</li> - * <li>{@code "a,\"\",b" => "a,b"}</li> - * <li>{@code "\"a\",\"b\"" => "\"a\",\"b\""}</li> - * <li>{@code "\" a \",\"b \"" => "\" a \",\"b \""}</li> - * <li>{@code "\"a\",\"\",\"b\"" => "\"a\",\"\",\"b\""}</li> - * <li>{@code "\"a\",\" \",\"b\"" => "\"a\",\" \",\"b\""}</li> - * <li>{@code "\" a,,b,c \",\"d \"" => "\" a,,b,c \",\"d \""}</li> - * <li>{@code "a,\" \",b" => "ab"]}</li> - * </ul> - */ - static String trimFieldsAndRemoveEmptyFields(String str) { - char[] chars = str.toCharArray(); - char[] res = new char[chars.length]; - /* - * set when reading the first non trimmable char after a separator char (or the beginning of the string) - * unset when reading a separator - */ - boolean inField = false; - boolean inQuotes = false; - int i = 0; - int resI = 0; - for (; i < chars.length; i++) { - boolean isSeparator = chars[i] == ','; - if (!inQuotes && isSeparator) { - // exiting field (may already be unset) - inField = false; - if (resI > 0) { - resI = retroTrim(res, resI); - } - } else { - boolean isTrimmed = !inQuotes && istrimmable(chars[i]); - if (isTrimmed && !inField) { - // we haven't meet any non trimmable char since the last separator yet - continue; - } - - boolean isEscape = isEscapeChar(chars[i]); - if (isEscape) { - inQuotes = !inQuotes; - } - - // add separator as we already had one field - if (!inField && resI > 0) { - res[resI] = ','; - resI++; - } - - // register in field (may already be set) - inField = true; - // copy current char - res[resI] = chars[i]; - resI++; - } - } - // inQuotes can only be true at this point if quotes are unbalanced - if (!inQuotes) { - // trim end of str - resI = retroTrim(res, resI); - } - return new String(res, 0, resI); - } - - private static boolean isEscapeChar(char aChar) { - return aChar == '"'; - } - - private static boolean istrimmable(char aChar) { - return aChar <= ' '; - } - - /** - * Reads from index {@code resI} to the beginning into {@code res} looking up the location of the trimmable char with - * the lowest index before encountering a non-trimmable char. - * <p> - * This basically trims {@code res} from any trimmable char at its end. - * - * @return index of next location to put new char in res - */ - private static int retroTrim(char[] res, int resI) { - int i = resI; - while (i >= 1) { - if (!istrimmable(res[i - 1])) { - return i; - } - i--; - } - return i; - } - -} 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 deleted file mode 100644 index f6774798046..00000000000 --- a/sonar-plugin-api/src/main/java/org/sonar/api/config/internal/package-info.java +++ /dev/null @@ -1,23 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 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/internal/MetadataLoader.java b/sonar-plugin-api/src/main/java/org/sonar/api/internal/MetadataLoader.java deleted file mode 100644 index bb155753d55..00000000000 --- a/sonar-plugin-api/src/main/java/org/sonar/api/internal/MetadataLoader.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 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.internal; - -import java.io.IOException; -import java.net.URL; -import java.nio.charset.StandardCharsets; -import java.util.Scanner; -import org.sonar.api.SonarEdition; -import org.sonar.api.utils.System2; -import org.sonar.api.utils.Version; - -import static org.apache.commons.lang.StringUtils.trimToEmpty; - -/** - * For internal use - * - * @since 7.8 - */ -public class MetadataLoader { - - private static final String VERSION_FILE_PATH = "/sonar-api-version.txt"; - private static final String EDITION_FILE_PATH = "/sonar-edition.txt"; - - private MetadataLoader() { - // only static methods - } - - public static Version loadVersion(System2 system) { - try { - URL url = system.getResource(VERSION_FILE_PATH); - Scanner scanner = new Scanner(url.openStream(), StandardCharsets.UTF_8.name()); - String versionInFile = scanner.nextLine(); - return Version.parse(versionInFile); - } catch (IOException e) { - throw new IllegalStateException("Can not load " + VERSION_FILE_PATH + " from classpath ", e); - } - } - - public static SonarEdition loadEdition(System2 system) { - try { - URL url = system.getResource(EDITION_FILE_PATH); - if (url == null) { - return SonarEdition.COMMUNITY; - } - Scanner scanner = new Scanner(url.openStream(), StandardCharsets.UTF_8.name()); - String editionInFile = scanner.nextLine(); - return parseEdition(editionInFile); - } catch (IOException e) { - throw new IllegalStateException("Can not load " + EDITION_FILE_PATH + " from classpath", e); - } - } - - static SonarEdition parseEdition(String edition) { - String str = trimToEmpty(edition.toUpperCase()); - try { - return SonarEdition.valueOf(str); - } catch (IllegalArgumentException e) { - throw new IllegalStateException(String.format("Invalid edition found in '%s': '%s'", EDITION_FILE_PATH, str)); - } - } -} diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/internal/PluginContextImpl.java b/sonar-plugin-api/src/main/java/org/sonar/api/internal/PluginContextImpl.java deleted file mode 100644 index 3fccb4c59cc..00000000000 --- a/sonar-plugin-api/src/main/java/org/sonar/api/internal/PluginContextImpl.java +++ /dev/null @@ -1,89 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 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.internal; - -import org.sonar.api.Plugin; -import org.sonar.api.SonarRuntime; -import org.sonar.api.config.Configuration; -import org.sonar.api.config.internal.MapSettings; - -/** - * Implementation of {@link Plugin.Context} that plugins could use in their unit tests. - * - * Example: - * - * <pre> - * import org.sonar.api.internal.SonarRuntimeImpl; - * import org.sonar.api.config.internal.MapSettings; - * - * ... - * - * SonarRuntime runtime = SonarRuntimeImpl.forSonarQube(Version.create(7, 1), SonarQubeSide.SCANNER); - * MapSettings settings = new MapSettings().setProperty("foo", "bar"); - * Plugin.Context context = new PluginContextImpl.Builder() - * .setSonarRuntime(runtime) - * .setBootConfiguration(settings.asConfig()); - * .build(); - * </pre> - * - * @since 7.1 - */ -public class PluginContextImpl extends Plugin.Context { - - private final Configuration bootConfiguration; - - private PluginContextImpl(Builder builder) { - super(builder.sonarRuntime); - this.bootConfiguration = builder.bootConfiguration != null ? builder.bootConfiguration : new MapSettings().asConfig(); - } - - @Override - public Configuration getBootConfiguration() { - return bootConfiguration; - } - - public static class Builder { - private SonarRuntime sonarRuntime; - private Configuration bootConfiguration; - - /** - * Required. - * @see SonarRuntimeImpl - * @return this - */ - public Builder setSonarRuntime(SonarRuntime r) { - this.sonarRuntime = r; - return this; - } - - /** - * If not set, then an empty configuration is used. - * @return this - */ - public Builder setBootConfiguration(Configuration c) { - this.bootConfiguration = c; - return this; - } - - public Plugin.Context build() { - return new PluginContextImpl(this); - } - } -} diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/internal/SonarRuntimeImpl.java b/sonar-plugin-api/src/main/java/org/sonar/api/internal/SonarRuntimeImpl.java deleted file mode 100644 index 3f69f36bb4e..00000000000 --- a/sonar-plugin-api/src/main/java/org/sonar/api/internal/SonarRuntimeImpl.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 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.internal; - -import javax.annotation.Nullable; -import javax.annotation.concurrent.Immutable; -import org.sonar.api.SonarEdition; -import org.sonar.api.SonarProduct; -import org.sonar.api.SonarQubeSide; -import org.sonar.api.SonarRuntime; -import org.sonar.api.utils.Version; - -import static java.util.Objects.requireNonNull; -import static org.sonar.api.utils.Preconditions.checkArgument; - -/** - * @since 6.0 - */ -@Immutable -public class SonarRuntimeImpl implements SonarRuntime { - - private final Version version; - private final SonarProduct product; - private final SonarQubeSide sonarQubeSide; - private final SonarEdition edition; - - private SonarRuntimeImpl(Version version, SonarProduct product, @Nullable SonarQubeSide sonarQubeSide, @Nullable SonarEdition edition) { - this.edition = edition; - requireNonNull(product); - checkArgument((product == SonarProduct.SONARQUBE) == (sonarQubeSide != null), "sonarQubeSide should be provided only for SonarQube product"); - checkArgument((product == SonarProduct.SONARQUBE) == (edition != null), "edition should be provided only for SonarQube product"); - this.version = requireNonNull(version); - this.product = product; - this.sonarQubeSide = sonarQubeSide; - } - - @Override - public Version getApiVersion() { - return version; - } - - @Override - public SonarProduct getProduct() { - return product; - } - - @Override - public SonarQubeSide getSonarQubeSide() { - if (sonarQubeSide == null) { - throw new UnsupportedOperationException("Can only be called in SonarQube"); - } - return sonarQubeSide; - } - - @Override - public SonarEdition getEdition() { - if (sonarQubeSide == null) { - throw new UnsupportedOperationException("Can only be called in SonarQube"); - } - return edition; - } - - /** - * Create an instance for SonarQube runtime environment. - */ - public static SonarRuntime forSonarQube(Version version, SonarQubeSide side, SonarEdition edition) { - return new SonarRuntimeImpl(version, SonarProduct.SONARQUBE, side, edition); - } - - /** - * Create an instance for SonarLint runtime environment. - */ - public static SonarRuntime forSonarLint(Version version) { - return new SonarRuntimeImpl(version, SonarProduct.SONARLINT, null, null); - } - -} diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/internal/package-info.java b/sonar-plugin-api/src/main/java/org/sonar/api/internal/package-info.java deleted file mode 100644 index 17dc1220665..00000000000 --- a/sonar-plugin-api/src/main/java/org/sonar/api/internal/package-info.java +++ /dev/null @@ -1,24 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 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.internal; - -import javax.annotation.ParametersAreNonnullByDefault; - diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/rules/Rule.java b/sonar-plugin-api/src/main/java/org/sonar/api/rules/Rule.java index 2eb4d07f57d..6f8452a8bd4 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/rules/Rule.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/rules/Rule.java @@ -324,7 +324,7 @@ public class Rule { */ public Rule setStatus(String status) { if (!STATUS_LIST.contains(status)) { - throw new SonarException("The status of a rule can only contain : " + String.join(", ", STATUS_LIST)); + throw new IllegalStateException("The status of a rule can only contain : " + String.join(", ", STATUS_LIST)); } this.status = status; return this; diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/server/rule/RulesDefinition.java b/sonar-plugin-api/src/main/java/org/sonar/api/server/rule/RulesDefinition.java index 6ad36f5998e..d249ac0bda8 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/server/rule/RulesDefinition.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/server/rule/RulesDefinition.java @@ -347,7 +347,7 @@ public interface RulesDefinition { /** * Instantiated by core but not by plugins, except for their tests. */ - interface Context { + abstract class Context { /* * New builder for {@link org.sonar.api.server.rule.RulesDefinition.Repository}. * <br> @@ -355,7 +355,7 @@ public interface RulesDefinition { * the FbContrib plugin contributes to the Findbugs plugin rules. In this case no need * to execute {@link org.sonar.api.server.rule.RulesDefinition.NewRepository#setName(String)} */ - NewRepository createRepository(String key, String language); + public abstract NewRepository createRepository(String key, String language); /** * Creates a repository of rules from external rule engines. @@ -363,34 +363,34 @@ public interface RulesDefinition { * * @since 7.2 */ - NewRepository createExternalRepository(String engineId, String language); + public abstract NewRepository createExternalRepository(String engineId, String language); /** * @deprecated since 5.2. Simply use {@link #createRepository(String, String)} */ @Deprecated - NewRepository extendRepository(String key, String language); + public abstract NewRepository extendRepository(String key, String language); @CheckForNull - Repository repository(String key); + public abstract Repository repository(String key); - List<Repository> repositories(); + public abstract List<Repository> repositories(); /** * @deprecated returns empty list since 5.2. Concept of "extended repository" was misleading and not valuable. Simply declare * repositories and use {@link #repositories()}. See http://jira.sonarsource.com/browse/SONAR-6709 */ @Deprecated - List<ExtendedRepository> extendedRepositories(String repositoryKey); + public abstract List<ExtendedRepository> extendedRepositories(String repositoryKey); /** * @deprecated returns empty list since 5.2. Concept of "extended repository" was misleading and not valuable. Simply declare * repositories and use {@link #repositories()}. See http://jira.sonarsource.com/browse/SONAR-6709 */ @Deprecated - List<ExtendedRepository> extendedRepositories(); + public abstract List<ExtendedRepository> extendedRepositories(); - void setCurrentPluginKey(@Nullable String pluginKey); + public abstract void setCurrentPluginKey(@Nullable String pluginKey); } interface NewExtendedRepository { @@ -484,36 +484,36 @@ public interface RulesDefinition { DebtRemediationFunction create(DebtRemediationFunction.Type type, @Nullable String gapMultiplier, @Nullable String baseEffort); } - interface NewRule { + abstract class NewRule { - String key(); + public abstract String key(); /** * @since 7.1 */ @CheckForNull - RuleScope scope(); + public abstract RuleScope scope(); /** * @since 7.1 */ - NewRule setScope(RuleScope scope); + public abstract NewRule setScope(RuleScope scope); /** * Required rule name */ - NewRule setName(String s); + public abstract NewRule setName(String s); - NewRule setTemplate(boolean template); + public abstract NewRule setTemplate(boolean template); /** * Should this rule be enabled by default. For example in SonarLint standalone. * * @since 6.0 */ - NewRule setActivatedByDefault(boolean activatedByDefault); + public abstract NewRule setActivatedByDefault(boolean activatedByDefault); - NewRule setSeverity(String s); + public abstract NewRule setSeverity(String s); /** * The type as defined by the SonarQube Quality Model. @@ -531,36 +531,36 @@ public interface RulesDefinition { * * @since 5.5 */ - NewRule setType(RuleType t); + public abstract NewRule setType(RuleType t); /** * The optional description, in HTML format, has no max length. It's exclusive with markdown description * (see {@link #setMarkdownDescription(String)}) */ - NewRule setHtmlDescription(@Nullable String s); + public abstract NewRule setHtmlDescription(@Nullable String s); /** * Load description from a file available in classpath. Example : <code>setHtmlDescription(getClass().getResource("/myrepo/Rule1234.html")</code> */ - NewRule setHtmlDescription(@Nullable URL classpathUrl); + public abstract NewRule setHtmlDescription(@Nullable URL classpathUrl); /** * The optional description, in a restricted Markdown format, has no max length. It's exclusive with HTML description * (see {@link #setHtmlDescription(String)}) */ - NewRule setMarkdownDescription(@Nullable String s); + public abstract NewRule setMarkdownDescription(@Nullable String s); /** * Load description from a file available in classpath. Example : {@code setMarkdownDescription(getClass().getResource("/myrepo/Rule1234.md")} */ - NewRule setMarkdownDescription(@Nullable URL classpathUrl); + public abstract NewRule setMarkdownDescription(@Nullable URL classpathUrl); /** * Default value is {@link org.sonar.api.rule.RuleStatus#READY}. The value * {@link org.sonar.api.rule.RuleStatus#REMOVED} is not accepted and raises an * {@link java.lang.IllegalArgumentException}. */ - NewRule setStatus(RuleStatus status); + public abstract NewRule setStatus(RuleStatus status); /** * SQALE sub-characteristic. See http://www.sqale.org @@ -570,23 +570,24 @@ public interface RulesDefinition { * @deprecated in 5.5. SQALE Quality Model is replaced by SonarQube Quality Model. This method does nothing. * See https://jira.sonarsource.com/browse/MMF-184 */ - NewRule setDebtSubCharacteristic(@Nullable String s); + @Deprecated + public abstract NewRule setDebtSubCharacteristic(@Nullable String s); /** * Factory of {@link org.sonar.api.server.debt.DebtRemediationFunction} */ - DebtRemediationFunctions debtRemediationFunctions(); + public abstract DebtRemediationFunctions debtRemediationFunctions(); /** * @see #debtRemediationFunctions() */ - NewRule setDebtRemediationFunction(@Nullable DebtRemediationFunction fn); + public abstract NewRule setDebtRemediationFunction(@Nullable DebtRemediationFunction fn); /** * @deprecated since 5.5, replaced by {@link #setGapDescription(String)} */ @Deprecated - NewRule setEffortToFixDescription(@Nullable String s); + public abstract NewRule setEffortToFixDescription(@Nullable String s); /** * For rules that use LINEAR or LINEAR_OFFSET remediation functions, the meaning @@ -597,44 +598,44 @@ public interface RulesDefinition { * remediation function gap multiplier/base effort would be something like * "Effort to test one uncovered condition". */ - NewRule setGapDescription(@Nullable String s); + public abstract NewRule setGapDescription(@Nullable String s); /** * Create a parameter with given unique key. Max length of key is 128 characters. */ - NewParam createParam(String paramKey); + public abstract NewParam createParam(String paramKey); @CheckForNull - NewParam param(String paramKey); + public abstract NewParam param(String paramKey); - Collection<NewParam> params(); + public abstract Collection<NewParam> params(); /** * @see RuleTagFormat */ - NewRule addTags(String... list); + public abstract NewRule addTags(String... list); /** * @see RuleTagFormat */ - NewRule setTags(String... list); + public abstract NewRule setTags(String... list); /** * @since 7.3 */ - NewRule addOwaspTop10(OwaspTop10... standards); + public abstract NewRule addOwaspTop10(OwaspTop10... standards); /** * @since 7.3 */ - NewRule addCwe(int... nums); + public abstract NewRule addCwe(int... nums); /** * Optional key that can be used by the rule engine. Not displayed * in webapp. For example the Java Checkstyle plugin feeds this field * with the internal path ("Checker/TreeWalker/AnnotationUseStyle"). */ - NewRule setInternalKey(@Nullable String s); + public abstract NewRule setInternalKey(@Nullable String s); /** * Register a repository and key under which this rule used to be known @@ -646,10 +647,7 @@ public interface RulesDefinition { * @see Rule#deprecatedRuleKeys * @since 7.1 */ - NewRule addDeprecatedRuleKey(String repository, String key); - - @Override - String toString(); + public abstract NewRule addDeprecatedRuleKey(String repository, String key); } @Immutable @@ -796,22 +794,22 @@ public interface RulesDefinition { } - interface NewParam { - String key(); + abstract class NewParam { + public abstract String key(); - NewParam setName(@Nullable String s); + public abstract NewParam setName(@Nullable String s); - NewParam setType(RuleParamType t); + public abstract NewParam setType(RuleParamType t); /** * Plain-text description. Can be null. Max length is 4000 characters. */ - NewParam setDescription(@Nullable String s); + public abstract NewParam setDescription(@Nullable String s); /** * Empty default value will be converted to null. Max length is 4000 characters. */ - NewParam setDefaultValue(@Nullable String s); + public abstract NewParam setDefaultValue(@Nullable String s); } @Immutable diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/server/ws/internal/PartImpl.java b/sonar-plugin-api/src/main/java/org/sonar/api/server/ws/internal/PartImpl.java deleted file mode 100644 index 0aca8b452d5..00000000000 --- a/sonar-plugin-api/src/main/java/org/sonar/api/server/ws/internal/PartImpl.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 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.server.ws.internal; - -import java.io.InputStream; -import org.sonar.api.server.ws.Request; - -public class PartImpl implements Request.Part { - - private final InputStream inputStream; - private final String fileName; - - public PartImpl(InputStream inputStream, String fileName) { - this.inputStream = inputStream; - this.fileName = fileName; - } - - @Override - public InputStream getInputStream() { - return inputStream; - } - - @Override - public String getFileName() { - return fileName; - } -} diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/server/ws/internal/SimpleGetRequest.java b/sonar-plugin-api/src/main/java/org/sonar/api/server/ws/internal/SimpleGetRequest.java deleted file mode 100644 index 757f8ea932c..00000000000 --- a/sonar-plugin-api/src/main/java/org/sonar/api/server/ws/internal/SimpleGetRequest.java +++ /dev/null @@ -1,148 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 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.server.ws.internal; - -import java.io.InputStream; -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Optional; -import java.util.stream.Collectors; -import javax.annotation.CheckForNull; -import javax.annotation.Nullable; -import org.apache.commons.io.IOUtils; -import org.sonar.api.server.ws.LocalConnector; -import org.sonar.api.server.ws.Request; - -import static java.nio.charset.StandardCharsets.UTF_8; -import static java.util.Collections.emptyList; -import static java.util.Collections.singletonList; -import static java.util.Objects.requireNonNull; - -/** - * Fake implementation of {@link org.sonar.api.server.ws.Request} used - * for testing. Call the method {@link #setParam(String, String)} to - * emulate some parameter values. - */ -public class SimpleGetRequest extends Request { - - private final Map<String, String[]> params = new HashMap<>(); - private final Map<String, Part> parts = new HashMap<>(); - private final Map<String, String> headers = new HashMap<>(); - private String mediaType = "application/json"; - private String path; - - @Override - public String method() { - return "GET"; - } - - @Override - public String getMediaType() { - return mediaType; - } - - public SimpleGetRequest setMediaType(String mediaType) { - requireNonNull(mediaType); - this.mediaType = mediaType; - return this; - } - - @Override - public boolean hasParam(String key) { - return params.keySet().contains(key); - } - - @Override - public String param(String key) { - String[] strings = params.get(key); - return strings == null || strings.length == 0 ? null : strings[0]; - } - - @Override - public List<String> multiParam(String key) { - String value = param(key); - return value == null ? emptyList() : singletonList(value); - } - - @Override - @CheckForNull - public List<String> paramAsStrings(String key) { - String value = param(key); - if (value == null) { - return null; - } - - return Arrays.stream(value.split(",")).map(String::trim).filter(x -> !x.isEmpty()).collect(Collectors.toList()); - } - - @Override - public InputStream paramAsInputStream(String key) { - return IOUtils.toInputStream(param(key), UTF_8); - } - - public SimpleGetRequest setParam(String key, @Nullable String value) { - if (value != null) { - params.put(key, new String[] {value}); - } - return this; - } - - @Override - public Map<String, String[]> getParams() { - return params; - } - - @Override - public Part paramAsPart(String key) { - return parts.get(key); - } - - public SimpleGetRequest setPart(String key, InputStream input, String fileName) { - parts.put(key, new PartImpl(input, fileName)); - return this; - } - - @Override - public LocalConnector localConnector() { - throw new UnsupportedOperationException(); - } - - @Override - public String getPath() { - return path; - } - - public SimpleGetRequest setPath(String path) { - this.path = path; - return this; - } - - @Override - public Optional<String> header(String name) { - return Optional.ofNullable(headers.get(name)); - } - - public SimpleGetRequest setHeader(String name, String value) { - headers.put(name, value); - return this; - } -} diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/server/ws/internal/ValidatingRequest.java b/sonar-plugin-api/src/main/java/org/sonar/api/server/ws/internal/ValidatingRequest.java deleted file mode 100644 index 5a9ee977497..00000000000 --- a/sonar-plugin-api/src/main/java/org/sonar/api/server/ws/internal/ValidatingRequest.java +++ /dev/null @@ -1,242 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 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.server.ws.internal; - -import java.io.InputStream; -import java.util.Arrays; -import java.util.List; -import java.util.Set; -import java.util.stream.Collectors; -import javax.annotation.CheckForNull; -import javax.annotation.Nullable; -import org.sonar.api.server.ws.LocalConnector; -import org.sonar.api.server.ws.Request; -import org.sonar.api.server.ws.WebService; - -import static java.lang.String.format; -import static java.util.Collections.emptyList; -import static java.util.Collections.singletonList; -import static java.util.Objects.requireNonNull; -import static org.apache.commons.lang.StringUtils.defaultString; -import static org.sonar.api.utils.Preconditions.checkArgument; - -/** - * @since 4.2 - */ -public abstract class ValidatingRequest extends Request { - - private static final String COMMA_SPLITTER = ","; - private WebService.Action action; - private LocalConnector localConnector; - - public void setAction(WebService.Action action) { - this.action = action; - } - - public WebService.Action action() { - return action; - } - - @Override - public LocalConnector localConnector() { - requireNonNull(localConnector, "Local connector has not been set"); - return localConnector; - } - - public void setLocalConnector(LocalConnector lc) { - this.localConnector = lc; - } - - @Override - @CheckForNull - public String param(String key) { - WebService.Param definition = action.param(key); - String rawValue = readParam(key, definition); - String rawValueOrDefault = defaultString(rawValue, definition.defaultValue()); - String value = rawValueOrDefault == null ? null : trim(rawValueOrDefault); - validateRequiredValue(key, definition, rawValue); - if (value == null) { - return null; - } - validatePossibleValues(key, value, definition); - validateMaximumLength(key, definition, rawValueOrDefault); - validateMinimumLength(key, definition, rawValueOrDefault); - validateMaximumValue(key, definition, value); - return value; - } - - @Override - public List<String> multiParam(String key) { - WebService.Param definition = action.param(key); - List<String> values = readMultiParamOrDefaultValue(key, definition); - return validateValues(values, definition); - } - - private static String trim(String s) { - int begin; - for (begin = 0; begin < s.length(); begin++) { - if (!Character.isWhitespace(s.charAt(begin))) { - break; - } - } - - int end; - for (end = s.length(); end > begin; end--) { - if (!Character.isWhitespace(s.charAt(end - 1))) { - break; - } - } - return s.substring(begin, end); - } - - @Override - @CheckForNull - public InputStream paramAsInputStream(String key) { - return readInputStreamParam(key); - } - - @Override - @CheckForNull - public Part paramAsPart(String key) { - return readPart(key); - } - - @CheckForNull - @Override - public List<String> paramAsStrings(String key) { - WebService.Param definition = action.param(key); - String value = defaultString(readParam(key, definition), definition.defaultValue()); - if (value == null) { - return null; - } - List<String> values = Arrays.stream(value.split(COMMA_SPLITTER)) - .map(String::trim) - .filter(s -> !s.isEmpty()) - .collect(Collectors.toList()); - return validateValues(values, definition); - } - - @CheckForNull - @Override - public <E extends Enum<E>> List<E> paramAsEnums(String key, Class<E> enumClass) { - List<String> values = paramAsStrings(key); - if (values == null) { - return null; - } - return values.stream() - .filter(s -> !s.isEmpty()) - .map(value -> Enum.valueOf(enumClass, value)) - .collect(Collectors.toList()); - } - - @CheckForNull - private String readParam(String key, @Nullable WebService.Param definition) { - checkArgument(definition != null, "BUG - parameter '%s' is undefined for action '%s'", key, action.key()); - String deprecatedKey = definition.deprecatedKey(); - return deprecatedKey != null ? defaultString(readParam(deprecatedKey), readParam(key)) : readParam(key); - } - - private List<String> readMultiParamOrDefaultValue(String key, @Nullable WebService.Param definition) { - checkArgument(definition != null, "BUG - parameter '%s' is undefined for action '%s'", key, action.key()); - - List<String> keyValues = readMultiParam(key); - if (!keyValues.isEmpty()) { - return keyValues; - } - - String deprecatedKey = definition.deprecatedKey(); - List<String> deprecatedKeyValues = deprecatedKey == null ? emptyList() : readMultiParam(deprecatedKey); - if (!deprecatedKeyValues.isEmpty()) { - return deprecatedKeyValues; - } - - String defaultValue = definition.defaultValue(); - return defaultValue == null ? emptyList() : singletonList(defaultValue); - } - - @CheckForNull - protected abstract String readParam(String key); - - protected abstract List<String> readMultiParam(String key); - - @CheckForNull - protected abstract InputStream readInputStreamParam(String key); - - @CheckForNull - protected abstract Part readPart(String key); - - private static List<String> validateValues(List<String> values, WebService.Param definition) { - Integer maximumValues = definition.maxValuesAllowed(); - checkArgument(maximumValues == null || values.size() <= maximumValues, "'%s' can contains only %s values, got %s", definition.key(), maximumValues, values.size()); - values.forEach(value -> validatePossibleValues(definition.key(), value, definition)); - return values; - } - - private static void validatePossibleValues(String key, String value, WebService.Param definition) { - Set<String> possibleValues = definition.possibleValues(); - if (possibleValues == null) { - return; - } - checkArgument(possibleValues.contains(value), "Value of parameter '%s' (%s) must be one of: %s", key, value, possibleValues); - } - - private static void validateMaximumLength(String key, WebService.Param definition, String valueOrDefault) { - Integer maximumLength = definition.maximumLength(); - if (maximumLength == null) { - return; - } - int valueLength = valueOrDefault.length(); - checkArgument(valueLength <= maximumLength, "'%s' length (%s) is longer than the maximum authorized (%s)", key, valueLength, maximumLength); - } - - private static void validateMinimumLength(String key, WebService.Param definition, String valueOrDefault) { - Integer minimumLength = definition.minimumLength(); - if (minimumLength == null) { - return; - } - int valueLength = valueOrDefault.length(); - checkArgument(valueLength >= minimumLength, "'%s' length (%s) is shorter than the minimum authorized (%s)", key, valueLength, minimumLength); - } - - private static void validateMaximumValue(String key, WebService.Param definition, String value) { - Integer maximumValue = definition.maximumValue(); - if (maximumValue == null) { - return; - } - int valueAsInt = validateAsNumeric(key, value); - checkArgument(valueAsInt <= maximumValue, "'%s' value (%s) must be less than %s", key, valueAsInt, maximumValue); - } - - private static void validateRequiredValue(String key, WebService.Param definition, String value) { - boolean required = definition.isRequired(); - if (required) { - checkArgument(value != null, format(MSG_PARAMETER_MISSING, key)); - } - } - - private static int validateAsNumeric(String key, String value) { - try { - return Integer.parseInt(value); - } catch (NumberFormatException exception) { - throw new IllegalArgumentException(format("'%s' value '%s' cannot be parsed as an integer", key, value), exception); - } - } - -} diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/server/ws/internal/package-info.java b/sonar-plugin-api/src/main/java/org/sonar/api/server/ws/internal/package-info.java deleted file mode 100644 index 1dc6d3eda19..00000000000 --- a/sonar-plugin-api/src/main/java/org/sonar/api/server/ws/internal/package-info.java +++ /dev/null @@ -1,23 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 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.server.ws.internal; - -import javax.annotation.ParametersAreNonnullByDefault; diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/utils/Preconditions.java b/sonar-plugin-api/src/main/java/org/sonar/api/utils/Preconditions.java index 1a70241d869..a67dd38eb84 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/utils/Preconditions.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/utils/Preconditions.java @@ -20,6 +20,10 @@ package org.sonar.api.utils; public class Preconditions { + private Preconditions() { + // static only + } + public static void checkArgument(boolean condition, String message) { if (!condition) { throw new IllegalArgumentException(message); diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/utils/internal/AlwaysIncreasingSystem2.java b/sonar-plugin-api/src/main/java/org/sonar/api/utils/internal/AlwaysIncreasingSystem2.java deleted file mode 100644 index 35334080778..00000000000 --- a/sonar-plugin-api/src/main/java/org/sonar/api/utils/internal/AlwaysIncreasingSystem2.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 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.utils.internal; - -import java.util.Random; -import java.util.concurrent.atomic.AtomicLong; -import java.util.function.Supplier; -import org.sonar.api.utils.System2; - -import static org.sonar.api.utils.Preconditions.checkArgument; - -/** - * A subclass of {@link System2} which implementation of {@link System2#now()} always return a bigger value than the - * previous returned value. - * <p> - * This class is intended to be used in Unit tests. - * </p> - */ -public class AlwaysIncreasingSystem2 extends System2 { - private final AtomicLong now; - private final long increment; - - private AlwaysIncreasingSystem2(Supplier<Long> initialValueSupplier, long increment) { - checkArgument(increment > 0, "increment must be > 0"); - long initialValue = initialValueSupplier.get(); - checkArgument(initialValue >= 0, "Initial value must be >= 0"); - this.now = new AtomicLong(initialValue); - this.increment = increment; - } - - public AlwaysIncreasingSystem2(long increment) { - this(AlwaysIncreasingSystem2::randomInitialValue, increment); - } - - public AlwaysIncreasingSystem2(long initialValue, int increment) { - this(() -> initialValue, increment); - } - - /** - * Values returned by {@link #now()} will start with a random value and increment by 100. - */ - public AlwaysIncreasingSystem2() { - this(AlwaysIncreasingSystem2::randomInitialValue, 100); - } - - @Override - public long now() { - return now.getAndAdd(increment); - } - - private static long randomInitialValue() { - return (long) Math.abs(new Random().nextInt(2_000_000)); - } -} diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/utils/internal/DefaultTempFolder.java b/sonar-plugin-api/src/main/java/org/sonar/api/utils/internal/DefaultTempFolder.java deleted file mode 100644 index bedee39b7d0..00000000000 --- a/sonar-plugin-api/src/main/java/org/sonar/api/utils/internal/DefaultTempFolder.java +++ /dev/null @@ -1,126 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 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.utils.internal; - -import java.nio.file.FileVisitResult; -import java.nio.file.SimpleFileVisitor; -import java.nio.file.attribute.BasicFileAttributes; -import org.apache.commons.io.FileUtils; -import org.sonar.api.utils.TempFolder; - -import javax.annotation.Nullable; - -import java.io.File; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import org.sonar.api.utils.log.Logger; -import org.sonar.api.utils.log.Loggers; - -public class DefaultTempFolder implements TempFolder { - private static final Logger LOG = Loggers.get(DefaultTempFolder.class); - - private final File tempDir; - private final boolean deleteOnExit; - - public DefaultTempFolder(File tempDir) { - this(tempDir, false); - } - - public DefaultTempFolder(File tempDir, boolean deleteOnExit) { - this.tempDir = tempDir; - this.deleteOnExit = deleteOnExit; - } - - @Override - public File newDir() { - return createTempDir(tempDir.toPath()).toFile(); - } - - private static Path createTempDir(Path baseDir) { - try { - return Files.createTempDirectory(baseDir, null); - } catch (IOException e) { - throw new IllegalStateException("Failed to create temp directory", e); - } - } - - @Override - public File newDir(String name) { - File dir = new File(tempDir, name); - try { - FileUtils.forceMkdir(dir); - } catch (IOException e) { - throw new IllegalStateException("Failed to create temp directory - " + dir, e); - } - return dir; - } - - @Override - public File newFile() { - return newFile(null, null); - } - - @Override - public File newFile(@Nullable String prefix, @Nullable String suffix) { - return createTempFile(tempDir.toPath(), prefix, suffix).toFile(); - } - - private static Path createTempFile(Path baseDir, String prefix, String suffix) { - try { - return Files.createTempFile(baseDir, prefix, suffix); - } catch (IOException e) { - throw new IllegalStateException("Failed to create temp file", e); - } - } - - public void clean() { - try { - if (tempDir.exists()) { - Files.walkFileTree(tempDir.toPath(), DeleteRecursivelyFileVisitor.INSTANCE); - } - } catch (IOException e) { - LOG.error("Failed to delete temp folder", e); - } - } - - public void stop() { - if (deleteOnExit) { - clean(); - } - } - - private static final class DeleteRecursivelyFileVisitor extends SimpleFileVisitor<Path> { - public static final DeleteRecursivelyFileVisitor INSTANCE = new DeleteRecursivelyFileVisitor(); - - @Override - public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { - Files.deleteIfExists(file); - return FileVisitResult.CONTINUE; - } - - @Override - public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException { - Files.deleteIfExists(dir); - return FileVisitResult.CONTINUE; - } - } - -} diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/utils/internal/JUnitTempFolder.java b/sonar-plugin-api/src/main/java/org/sonar/api/utils/internal/JUnitTempFolder.java deleted file mode 100644 index 5c323f23f7d..00000000000 --- a/sonar-plugin-api/src/main/java/org/sonar/api/utils/internal/JUnitTempFolder.java +++ /dev/null @@ -1,108 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 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.utils.internal; - -import org.apache.commons.lang.StringUtils; -import org.junit.rules.ExternalResource; -import org.junit.rules.TemporaryFolder; -import org.junit.runner.Description; -import org.junit.runners.model.Statement; -import org.sonar.api.utils.TempFolder; - -import javax.annotation.Nullable; - -import java.io.File; -import java.io.IOException; - -/** - * Implementation of {@link org.sonar.api.utils.TempFolder} to be used - * only in JUnit tests. It wraps {@link org.junit.rules.TemporaryFolder}. - * <br> - * Example: - * <pre> - * public class MyTest { - * @@org.junit.Rule - * public JUnitTempFolder temp = new JUnitTempFolder(); - * - * @@org.junit.Test - * public void myTest() throws Exception { - * File dir = temp.newDir(); - * // ... - * } - * } - * </pre> - * - * @since 5.1 - */ -public class JUnitTempFolder extends ExternalResource implements TempFolder { - - private final TemporaryFolder junit = new TemporaryFolder(); - - @Override - public Statement apply(Statement base, Description description) { - return junit.apply(base, description); - } - - @Override - protected void before() throws Throwable { - junit.create(); - } - - @Override - protected void after() { - junit.delete(); - } - - @Override - public File newDir() { - try { - return junit.newFolder(); - } catch (IOException e) { - throw new IllegalStateException("Fail to create temp dir", e); - } - } - - @Override - public File newDir(String name) { - try { - return junit.newFolder(name); - } catch (IOException e) { - throw new IllegalStateException("Fail to create temp dir", e); - } - } - - @Override - public File newFile() { - try { - return junit.newFile(); - } catch (IOException e) { - throw new IllegalStateException("Fail to create temp file", e); - } - } - - @Override - public File newFile(@Nullable String prefix, @Nullable String suffix) { - try { - return junit.newFile(StringUtils.defaultString(prefix) + "-" + StringUtils.defaultString(suffix)); - } catch (IOException e) { - throw new IllegalStateException("Fail to create temp file", e); - } - } -} diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/utils/internal/TempFolderCleaner.java b/sonar-plugin-api/src/main/java/org/sonar/api/utils/internal/TempFolderCleaner.java deleted file mode 100644 index 3a7836cff4f..00000000000 --- a/sonar-plugin-api/src/main/java/org/sonar/api/utils/internal/TempFolderCleaner.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 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.utils.internal; - -import org.sonar.api.Startable; -import org.sonar.api.server.ServerSide; -import org.sonar.api.utils.TempFolder; - -@ServerSide -public class TempFolderCleaner implements Startable { - - private TempFolder defaultTempFolder; - - public TempFolderCleaner(TempFolder defaultTempFolder) { - this.defaultTempFolder = defaultTempFolder; - } - - /** - * This method should not be renamed. It follows the naming convention - * defined by IoC container. - */ - @Override - public void start() { - // Nothing to do - } - - /** - * This method should not be renamed. It follows the naming convention - * defined by IoC container. - */ - @Override - public void stop() { - ((DefaultTempFolder) defaultTempFolder).clean(); - } -} diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/utils/internal/TestSystem2.java b/sonar-plugin-api/src/main/java/org/sonar/api/utils/internal/TestSystem2.java deleted file mode 100644 index 37d2ed5d719..00000000000 --- a/sonar-plugin-api/src/main/java/org/sonar/api/utils/internal/TestSystem2.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 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.utils.internal; - -import java.util.TimeZone; -import org.sonar.api.utils.System2; - -public class TestSystem2 extends System2 { - - private long now = 0L; - private TimeZone defaultTimeZone = getDefaultTimeZone(); - - public TestSystem2 setNow(long l) { - this.now = l; - return this; - } - - @Override - public long now() { - if (now <= 0L) { - throw new IllegalStateException("Method setNow() was not called by test"); - } - return now; - } - - public TestSystem2 setDefaultTimeZone(TimeZone defaultTimeZone) { - this.defaultTimeZone = defaultTimeZone; - return this; - } - - @Override - public TimeZone getDefaultTimeZone() { - return defaultTimeZone; - } -} diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/utils/internal/WorkDuration.java b/sonar-plugin-api/src/main/java/org/sonar/api/utils/internal/WorkDuration.java deleted file mode 100644 index fc4de0037bc..00000000000 --- a/sonar-plugin-api/src/main/java/org/sonar/api/utils/internal/WorkDuration.java +++ /dev/null @@ -1,194 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 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.utils.internal; - -import java.io.Serializable; -import javax.annotation.Nullable; -import org.apache.commons.lang.builder.ToStringBuilder; -import org.apache.commons.lang.builder.ToStringStyle; - -/** - * @since 4.2 - */ -public class WorkDuration implements Serializable { - - static final int DAY_POSITION_IN_LONG = 10_000; - static final int HOUR_POSITION_IN_LONG = 100; - static final int MINUTE_POSITION_IN_LONG = 1; - - public enum UNIT { - DAYS, HOURS, MINUTES - } - - private int hoursInDay; - - private long durationInMinutes; - private int days; - private int hours; - private int minutes; - - private WorkDuration(long durationInMinutes, int days, int hours, int minutes, int hoursInDay) { - this.durationInMinutes = durationInMinutes; - this.days = days; - this.hours = hours; - this.minutes = minutes; - this.hoursInDay = hoursInDay; - } - - public static WorkDuration create(int days, int hours, int minutes, int hoursInDay) { - long durationInSeconds = 60L * days * hoursInDay; - durationInSeconds += 60L * hours; - durationInSeconds += minutes; - return new WorkDuration(durationInSeconds, days, hours, minutes, hoursInDay); - } - - public static WorkDuration createFromValueAndUnit(int value, UNIT unit, int hoursInDay) { - switch (unit) { - case DAYS: - return create(value, 0, 0, hoursInDay); - case HOURS: - return create(0, value, 0, hoursInDay); - case MINUTES: - return create(0, 0, value, hoursInDay); - default: - throw new IllegalStateException("Cannot create work duration"); - } - } - - static WorkDuration createFromLong(long duration, int hoursInDay) { - int days = 0; - int hours = 0; - int minutes = 0; - - long time = duration; - Long currentTime = time / WorkDuration.DAY_POSITION_IN_LONG; - if (currentTime > 0) { - days = currentTime.intValue(); - time = time - (currentTime * WorkDuration.DAY_POSITION_IN_LONG); - } - - currentTime = time / WorkDuration.HOUR_POSITION_IN_LONG; - if (currentTime > 0) { - hours = currentTime.intValue(); - time = time - (currentTime * WorkDuration.HOUR_POSITION_IN_LONG); - } - - currentTime = time / WorkDuration.MINUTE_POSITION_IN_LONG; - if (currentTime > 0) { - minutes = currentTime.intValue(); - } - return WorkDuration.create(days, hours, minutes, hoursInDay); - } - - static WorkDuration createFromMinutes(long duration, int hoursInDay) { - int days = (int)(duration / (double)hoursInDay / 60.0); - Long currentDurationInMinutes = duration - (60L * days * hoursInDay); - int hours = (int)(currentDurationInMinutes / 60.0); - currentDurationInMinutes = currentDurationInMinutes - (60L * hours); - return new WorkDuration(duration, days, hours, currentDurationInMinutes.intValue(), hoursInDay); - } - - /** - * Return the duration in number of working days. - * For instance, 3 days and 4 hours will return 3.5 days (if hoursIndDay is 8). - */ - public double toWorkingDays() { - return durationInMinutes / 60d / hoursInDay; - } - - /** - * Return the duration using the following format DDHHMM, where DD is the number of days, HH is the number of months, and MM the number of minutes. - * For instance, 3 days and 4 hours will return 030400 (if hoursIndDay is 8). - */ - public long toLong() { - int workingDays = days; - int workingHours = hours; - if (hours >= hoursInDay) { - int nbAdditionalDays = hours / hoursInDay; - workingDays += nbAdditionalDays; - workingHours = hours - (nbAdditionalDays * hoursInDay); - } - return 1L * workingDays * DAY_POSITION_IN_LONG + workingHours * HOUR_POSITION_IN_LONG + minutes * MINUTE_POSITION_IN_LONG; - } - - public long toMinutes() { - return durationInMinutes; - } - - public WorkDuration add(@Nullable WorkDuration with) { - if (with != null) { - return WorkDuration.createFromMinutes(this.toMinutes() + with.toMinutes(), this.hoursInDay); - } else { - return this; - } - } - - public WorkDuration subtract(@Nullable WorkDuration with) { - if (with != null) { - return WorkDuration.createFromMinutes(this.toMinutes() - with.toMinutes(), this.hoursInDay); - } else { - return this; - } - } - - public WorkDuration multiply(int factor) { - return WorkDuration.createFromMinutes(this.toMinutes() * factor, this.hoursInDay); - } - - public int days() { - return days; - } - - public int hours() { - return hours; - } - - public int minutes() { - return minutes; - } - - int hoursInDay() { - return hoursInDay; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - - WorkDuration that = (WorkDuration) o; - return durationInMinutes == that.durationInMinutes; - - } - - @Override - public int hashCode() { - return (int) (durationInMinutes ^ (durationInMinutes >>> 32)); - } - - @Override - public String toString() { - return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE); - } -} |