diff options
Diffstat (limited to 'sonar-core')
41 files changed, 4698 insertions, 1347 deletions
diff --git a/sonar-core/pom.xml b/sonar-core/pom.xml index c36e3da4723..a2679eec095 100644 --- a/sonar-core/pom.xml +++ b/sonar-core/pom.xml @@ -5,7 +5,7 @@ <parent> <groupId>org.sonarsource.sonarqube</groupId> <artifactId>sonarqube</artifactId> - <version>5.6.2-SNAPSHOT</version> + <version>6.1-SNAPSHOT</version> </parent> <artifactId>sonar-core</artifactId> @@ -14,7 +14,7 @@ <description>Library shared by analyzer and server</description> <properties> - <sonar.exclusions>target/generated-sources/**/*</sonar.exclusions> + <sonar.exclusions>target/generated-sources/**/*,target/generated-test-sources/**/*</sonar.exclusions> </properties> <dependencies> @@ -44,7 +44,7 @@ <artifactId>sonar-plugin-api</artifactId> </dependency> <dependency> - <groupId>org.codehaus.sonar</groupId> + <groupId>org.sonarsource.update-center</groupId> <artifactId>sonar-update-center-common</artifactId> </dependency> @@ -100,6 +100,22 @@ </dependencies> <build> + <pluginManagement> + <plugins> + <plugin> + <groupId>org.basepom.maven</groupId> + <artifactId>duplicate-finder-maven-plugin</artifactId> + <configuration> + <ignoredDependencies> + <dependency> + <groupId>${project.groupId}</groupId> + <artifactId>sonar-plugin-api-deps</artifactId> + </dependency> + </ignoredDependencies> + </configuration> + </plugin> + </plugins> + </pluginManagement> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> diff --git a/sonar-core/src/main/java/org/sonar/core/component/ComponentKeys.java b/sonar-core/src/main/java/org/sonar/core/component/ComponentKeys.java index defab7e80a0..c018516ffe3 100644 --- a/sonar-core/src/main/java/org/sonar/core/component/ComponentKeys.java +++ b/sonar-core/src/main/java/org/sonar/core/component/ComponentKeys.java @@ -26,6 +26,8 @@ import org.sonar.api.resources.Project; import org.sonar.api.resources.Resource; import org.sonar.api.resources.Scopes; +import static com.google.common.base.Preconditions.checkArgument; + public final class ComponentKeys { public static final int MAX_COMPONENT_KEY_LENGTH = 400; @@ -97,6 +99,15 @@ public final class ComponentKeys { } /** + * Checks if given parameter is valid for a project/module following {@link #isValidModuleKey(String)} contract. + * + * @throws IllegalArgumentException if the format is incorrect + */ + public static void checkModuleKey(String keyCandidate) { + checkArgument(isValidModuleKey(keyCandidate), "Malformed key for '%s'. Allowed characters are alphanumeric, '-', '_', '.' and ':', with at least one non-digit.", keyCandidate); + } + + /** * Same as {@link #isValidModuleKey(String)}, but allows additionally '/'. */ public static boolean isValidModuleKeyIssuesMode(String keyCandidate) { diff --git a/sonar-core/src/main/java/org/sonar/core/component/DefaultResourceTypes.java b/sonar-core/src/main/java/org/sonar/core/component/DefaultResourceTypes.java index 7539c40512a..03fe1f5d58f 100644 --- a/sonar-core/src/main/java/org/sonar/core/component/DefaultResourceTypes.java +++ b/sonar-core/src/main/java/org/sonar/core/component/DefaultResourceTypes.java @@ -19,14 +19,14 @@ */ package org.sonar.core.component; -import org.sonar.api.batch.BatchSide; +import org.sonar.api.batch.ScannerSide; +import org.sonar.api.ce.ComputeEngineSide; import org.sonar.api.resources.Qualifiers; import org.sonar.api.resources.ResourceType; import org.sonar.api.resources.ResourceTypeTree; -import org.sonar.api.ce.ComputeEngineSide; import org.sonar.api.server.ServerSide; -@BatchSide +@ScannerSide @ServerSide @ComputeEngineSide public final class DefaultResourceTypes { @@ -59,24 +59,18 @@ public final class DefaultResourceTypes { .addType(ResourceType.builder(Qualifiers.DIRECTORY) .setProperty(SUPPORTS_MEASURE_FILTERS, true) .build()) - .addType(ResourceType.builder(Qualifiers.PACKAGE) - .build()) .addType(ResourceType.builder(Qualifiers.FILE) .hasSourceCode() .setProperty(SUPPORTS_MEASURE_FILTERS, true) .build()) - .addType(ResourceType.builder(Qualifiers.CLASS) - .hasSourceCode() - .build()) .addType(ResourceType.builder(Qualifiers.UNIT_TEST_FILE) .hasSourceCode() .setProperty(SUPPORTS_MEASURE_FILTERS, true) .build()) .addRelations(Qualifiers.PROJECT, Qualifiers.MODULE) - .addRelations(Qualifiers.MODULE, Qualifiers.DIRECTORY, Qualifiers.PACKAGE) + .addRelations(Qualifiers.MODULE, Qualifiers.DIRECTORY) .addRelations(Qualifiers.DIRECTORY, Qualifiers.FILE, Qualifiers.UNIT_TEST_FILE) - .addRelations(Qualifiers.PACKAGE, Qualifiers.CLASS, Qualifiers.UNIT_TEST_FILE) .build(); } diff --git a/sonar-core/src/main/java/org/sonar/core/config/CorePropertyDefinitions.java b/sonar-core/src/main/java/org/sonar/core/config/CorePropertyDefinitions.java index 3369492cdc9..982466b9d5c 100644 --- a/sonar-core/src/main/java/org/sonar/core/config/CorePropertyDefinitions.java +++ b/sonar-core/src/main/java/org/sonar/core/config/CorePropertyDefinitions.java @@ -25,6 +25,7 @@ import java.util.Arrays; import java.util.List; import org.sonar.api.CoreProperties; import org.sonar.api.PropertyType; +import org.sonar.api.config.EmailSettings; import org.sonar.api.config.PropertyDefinition; import org.sonar.api.resources.Qualifiers; @@ -57,6 +58,7 @@ public class CorePropertyDefinitions { defs.addAll(SecurityProperties.all()); defs.addAll(DebtProperties.all()); defs.addAll(PurgeProperties.all()); + defs.addAll(EmailSettings.definitions()); defs.addAll(ImmutableList.of( PropertyDefinition.builder(PROP_PASSWORD) @@ -120,10 +122,6 @@ public class CorePropertyDefinitions { .name("Security Realm") .hidden() .build(), - PropertyDefinition.builder("sonar.security.savePassword") - .name("Save external password") - .hidden() - .build(), PropertyDefinition.builder("sonar.authenticator.downcase") .name("Downcase login") .description("Downcase login during user authentication, typically for Active Directory") @@ -150,14 +148,6 @@ public class CorePropertyDefinitions { .type(PropertyType.BOOLEAN) .defaultValue(String.valueOf(false)) .build(), - PropertyDefinition.builder(CoreProperties.CORE_AUTHENTICATOR_LOCAL_USERS) - .name("Local/technical users") - .description("Comma separated list of user logins that will always be authenticated using SonarQube database. " - + "When using the LDAP plugin, for these accounts, the user attributes (name, email, ...) are not re-synchronized") - .type(PropertyType.STRING) - .multiValues(true) - .defaultValue("admin") - .build(), PropertyDefinition.builder(CoreProperties.SCM_DISABLED_KEY) .name("Disable the SCM Sensor") .description("Disable the retrieval of blame information from Source Control Manager") @@ -216,13 +206,6 @@ public class CorePropertyDefinitions { // BATCH - PropertyDefinition.builder(CoreProperties.CORE_VIOLATION_LOCALE_PROPERTY) - .defaultValue("en") - .name("Locale used for issue messages") - .description("Deprecated property. Keep default value for backward compatibility.") - .hidden() - .build(), - PropertyDefinition.builder(TIMEMACHINE_PERIOD_PREFIX + 1) .name("Leak Period") .description("Period used to compare measures and track new issues. Values are : <ul class='bullet'><li>Number of days before " + diff --git a/sonar-core/src/main/java/org/sonar/core/config/Logback.java b/sonar-core/src/main/java/org/sonar/core/config/Logback.java index e8b70c0633d..08447fac1ad 100644 --- a/sonar-core/src/main/java/org/sonar/core/config/Logback.java +++ b/sonar-core/src/main/java/org/sonar/core/config/Logback.java @@ -31,14 +31,14 @@ import java.util.Map; import org.apache.commons.io.FileUtils; import org.apache.commons.io.IOUtils; import org.slf4j.LoggerFactory; -import org.sonar.api.batch.BatchSide; +import org.sonar.api.batch.ScannerSide; /** * Configure Logback * * @since 2.12 */ -@BatchSide +@ScannerSide public class Logback { private Logback() { diff --git a/sonar-core/src/main/java/org/sonar/core/i18n/DefaultI18n.java b/sonar-core/src/main/java/org/sonar/core/i18n/DefaultI18n.java index 72486d51c07..5c6bfb9818f 100644 --- a/sonar-core/src/main/java/org/sonar/core/i18n/DefaultI18n.java +++ b/sonar-core/src/main/java/org/sonar/core/i18n/DefaultI18n.java @@ -41,7 +41,7 @@ import javax.annotation.CheckForNull; import javax.annotation.Nullable; import org.apache.commons.io.IOUtils; import org.picocontainer.Startable; -import org.sonar.api.batch.BatchSide; +import org.sonar.api.batch.ScannerSide; import org.sonar.api.i18n.I18n; import org.sonar.api.ce.ComputeEngineSide; import org.sonar.api.server.ServerSide; @@ -52,7 +52,7 @@ import org.sonar.api.utils.log.Loggers; import org.sonar.core.platform.PluginInfo; import org.sonar.core.platform.PluginRepository; -@BatchSide +@ScannerSide @ServerSide @ComputeEngineSide public class DefaultI18n implements I18n, Startable { diff --git a/sonar-core/src/main/java/org/sonar/core/i18n/RuleI18nManager.java b/sonar-core/src/main/java/org/sonar/core/i18n/RuleI18nManager.java index a3270e12e3f..6ca91cd7e96 100644 --- a/sonar-core/src/main/java/org/sonar/core/i18n/RuleI18nManager.java +++ b/sonar-core/src/main/java/org/sonar/core/i18n/RuleI18nManager.java @@ -22,7 +22,7 @@ package org.sonar.core.i18n; import java.util.Locale; import javax.annotation.CheckForNull; import org.apache.commons.lang.StringUtils; -import org.sonar.api.batch.BatchSide; +import org.sonar.api.batch.ScannerSide; import org.sonar.api.i18n.RuleI18n; import org.sonar.api.rules.Rule; import org.sonar.api.ce.ComputeEngineSide; @@ -32,7 +32,7 @@ import org.sonar.api.server.ServerSide; * @deprecated in 4.1. Rules are not localized anymore. See http://jira.sonarsource.com/browse/SONAR-4885 */ @Deprecated -@BatchSide +@ScannerSide @ServerSide @ComputeEngineSide public class RuleI18nManager implements RuleI18n { diff --git a/sonar-core/src/main/java/org/sonar/core/issue/DefaultIssue.java b/sonar-core/src/main/java/org/sonar/core/issue/DefaultIssue.java index e8885be59ba..12b5f9ae573 100644 --- a/sonar-core/src/main/java/org/sonar/core/issue/DefaultIssue.java +++ b/sonar-core/src/main/java/org/sonar/core/issue/DefaultIssue.java @@ -19,7 +19,6 @@ */ package org.sonar.core.issue; -import com.google.common.base.Objects; import com.google.common.base.Preconditions; import com.google.common.base.Strings; import com.google.common.collect.ImmutableList; @@ -35,6 +34,7 @@ import java.util.Date; import java.util.LinkedHashSet; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.Set; import javax.annotation.CheckForNull; import javax.annotation.Nullable; @@ -509,7 +509,7 @@ public class DefaultIssue implements Issue, Trackable, org.sonar.api.ce.measure. } public DefaultIssue setFieldChange(IssueChangeContext context, String field, @Nullable Serializable oldValue, @Nullable Serializable newValue) { - if (!Objects.equal(oldValue, newValue)) { + if (!Objects.equals(oldValue, newValue)) { if (currentChange == null) { currentChange = new FieldDiffs(); currentChange.setUserLogin(context.login()); diff --git a/sonar-core/src/main/java/org/sonar/core/issue/DefaultIssueBuilder.java b/sonar-core/src/main/java/org/sonar/core/issue/DefaultIssueBuilder.java index 4f44a40bba1..b89ad385c3a 100644 --- a/sonar-core/src/main/java/org/sonar/core/issue/DefaultIssueBuilder.java +++ b/sonar-core/src/main/java/org/sonar/core/issue/DefaultIssueBuilder.java @@ -19,7 +19,7 @@ */ package org.sonar.core.issue; -import com.google.common.base.Objects; +import com.google.common.base.MoreObjects; import com.google.common.base.Preconditions; import com.google.common.collect.Maps; import java.util.Map; @@ -150,7 +150,7 @@ public class DefaultIssueBuilder implements Issuable.IssueBuilder { DefaultIssue issue = new DefaultIssue(); String key = Uuids.create(); issue.setKey(key); - issue.setType(Objects.firstNonNull(type, RuleType.CODE_SMELL)); + issue.setType(MoreObjects.firstNonNull(type, RuleType.CODE_SMELL)); issue.setComponentKey(componentKey); issue.setProjectKey(projectKey); issue.setRuleKey(ruleKey); diff --git a/sonar-core/src/main/java/org/sonar/core/issue/tracking/Tracker.java b/sonar-core/src/main/java/org/sonar/core/issue/tracking/Tracker.java index 9b57dd27efb..7fe871be272 100644 --- a/sonar-core/src/main/java/org/sonar/core/issue/tracking/Tracker.java +++ b/sonar-core/src/main/java/org/sonar/core/issue/tracking/Tracker.java @@ -25,12 +25,12 @@ import java.util.Collection; import java.util.Objects; import javax.annotation.Nonnull; import org.apache.commons.lang.StringUtils; -import org.sonar.api.batch.BatchSide; +import org.sonar.api.batch.ScannerSide; import org.sonar.api.batch.InstantiationStrategy; import org.sonar.api.rule.RuleKey; @InstantiationStrategy(InstantiationStrategy.PER_BATCH) -@BatchSide +@ScannerSide public class Tracker<RAW extends Trackable, BASE extends Trackable> { public Tracking<RAW, BASE> track(Input<RAW> rawInput, Input<BASE> baseInput) { diff --git a/sonar-core/src/main/java/org/sonar/core/issue/tracking/Tracking.java b/sonar-core/src/main/java/org/sonar/core/issue/tracking/Tracking.java index 2f7e326a5c6..ee93e3cd55a 100644 --- a/sonar-core/src/main/java/org/sonar/core/issue/tracking/Tracking.java +++ b/sonar-core/src/main/java/org/sonar/core/issue/tracking/Tracking.java @@ -19,14 +19,13 @@ */ package org.sonar.core.issue.tracking; -import com.google.common.base.Objects; +import com.google.common.base.MoreObjects; import com.google.common.base.Predicate; import com.google.common.collect.Iterables; import java.util.Collection; import java.util.IdentityHashMap; import java.util.Map; import javax.annotation.CheckForNull; -import javax.annotation.Nonnull; public class Tracking<RAW extends Trackable, BASE extends Trackable> { @@ -39,19 +38,9 @@ public class Tracking<RAW extends Trackable, BASE extends Trackable> { private final Collection<RAW> raws; private final Collection<BASE> bases; - private final Predicate<RAW> unmatchedRawPredicate = new Predicate<RAW>() { - @Override - public boolean apply(@Nonnull RAW raw) { - return !rawToBase.containsKey(raw); - } - }; + private final Predicate<RAW> unmatchedRawPredicate = raw -> !rawToBase.containsKey(raw); - private final Predicate<BASE> unmatchedBasePredicate = new Predicate<BASE>() { - @Override - public boolean apply(@Nonnull BASE raw) { - return !baseToRaw.containsKey(raw); - } - }; + private final Predicate<BASE> unmatchedBasePredicate = raw -> !baseToRaw.containsKey(raw); public Tracking(Input<RAW> rawInput, Input<BASE> baseInput) { this.raws = rawInput.getIssues(); @@ -100,7 +89,7 @@ public class Tracking<RAW extends Trackable, BASE extends Trackable> { @Override public String toString() { - return Objects.toStringHelper(this) + return MoreObjects.toStringHelper(this) .add("rawToBase", rawToBase) .add("baseToRaw", baseToRaw) .add("raws", raws) diff --git a/sonar-core/src/main/java/org/sonar/core/metric/ScannerMetrics.java b/sonar-core/src/main/java/org/sonar/core/metric/ScannerMetrics.java index 05bcb7a5ac1..e1b3dc647b8 100644 --- a/sonar-core/src/main/java/org/sonar/core/metric/ScannerMetrics.java +++ b/sonar-core/src/main/java/org/sonar/core/metric/ScannerMetrics.java @@ -25,16 +25,15 @@ import com.google.common.collect.Iterables; import java.util.List; import java.util.Set; import javax.annotation.Nullable; -import org.sonar.api.batch.BatchSide; +import org.sonar.api.batch.ScannerSide; +import org.sonar.api.ce.ComputeEngineSide; import org.sonar.api.measures.Metric; import org.sonar.api.measures.Metrics; -import org.sonar.api.ce.ComputeEngineSide; import static com.google.common.collect.FluentIterable.from; import static java.util.Arrays.asList; import static org.sonar.api.measures.CoreMetrics.ACCESSORS; import static org.sonar.api.measures.CoreMetrics.CLASSES; -import static org.sonar.api.measures.CoreMetrics.COMMENTED_OUT_CODE_LINES; import static org.sonar.api.measures.CoreMetrics.COMMENT_LINES; import static org.sonar.api.measures.CoreMetrics.COMMENT_LINES_DATA; import static org.sonar.api.measures.CoreMetrics.COMPLEXITY; @@ -87,7 +86,7 @@ import static org.sonar.api.measures.CoreMetrics.UNCOVERED_LINES; * Scanners should not send other metrics, and the Compute Engine should not allow other metrics. */ @ComputeEngineSide -@BatchSide +@ScannerSide public class ScannerMetrics { private static final Set<Metric> ALLOWED_CORE_METRICS = ImmutableSet.<Metric>of( @@ -99,7 +98,6 @@ public class ScannerMetrics { COMMENT_LINES, COMMENT_LINES_DATA, NCLOC_LANGUAGE_DISTRIBUTION, - COMMENTED_OUT_CODE_LINES, PUBLIC_API, PUBLIC_UNDOCUMENTED_API, diff --git a/sonar-core/src/main/java/org/sonar/core/platform/ComponentContainer.java b/sonar-core/src/main/java/org/sonar/core/platform/ComponentContainer.java index f94f2245278..c82d857b858 100644 --- a/sonar-core/src/main/java/org/sonar/core/platform/ComponentContainer.java +++ b/sonar-core/src/main/java/org/sonar/core/platform/ComponentContainer.java @@ -36,7 +36,7 @@ import org.picocontainer.PicoContainer; import org.picocontainer.behaviors.OptInCaching; import org.picocontainer.lifecycle.ReflectionLifecycleStrategy; import org.picocontainer.monitors.NullComponentMonitor; -import org.sonar.api.batch.BatchSide; +import org.sonar.api.batch.ScannerSide; import org.sonar.api.ce.ComputeEngineSide; import org.sonar.api.config.PropertyDefinitions; import org.sonar.api.server.ServerSide; @@ -46,7 +46,7 @@ import org.sonar.api.utils.log.Profiler; import static com.google.common.collect.ImmutableList.copyOf; import static java.util.Objects.requireNonNull; -@BatchSide +@ScannerSide @ServerSide @ComputeEngineSide public class ComponentContainer implements ContainerPopulator.Container { @@ -245,7 +245,7 @@ public class ComponentContainer implements ContainerPopulator.Container { try { pico.as(Characteristics.CACHE).addComponent(key, extension); } catch (Throwable t) { - throw new IllegalStateException("Unable to register extension " + getName(extension), t); + throw new IllegalStateException("Unable to register extension " + getName(extension) + (pluginInfo != null ? (" from plugin '" + pluginInfo.getKey() + "'") : ""), t); } declareExtension(pluginInfo, extension); return this; diff --git a/sonar-core/src/main/java/org/sonar/core/platform/ContainerPopulator.java b/sonar-core/src/main/java/org/sonar/core/platform/ContainerPopulator.java index b63adfaace2..029698a247e 100644 --- a/sonar-core/src/main/java/org/sonar/core/platform/ContainerPopulator.java +++ b/sonar-core/src/main/java/org/sonar/core/platform/ContainerPopulator.java @@ -21,6 +21,7 @@ package org.sonar.core.platform; import java.util.List; +@FunctionalInterface public interface ContainerPopulator<T extends ContainerPopulator.Container> { void populateContainer(T container); diff --git a/sonar-core/src/main/java/org/sonar/core/platform/PluginClassloaderFactory.java b/sonar-core/src/main/java/org/sonar/core/platform/PluginClassloaderFactory.java index 03a3c21f501..df9913f19a4 100644 --- a/sonar-core/src/main/java/org/sonar/core/platform/PluginClassloaderFactory.java +++ b/sonar-core/src/main/java/org/sonar/core/platform/PluginClassloaderFactory.java @@ -26,7 +26,7 @@ import java.util.Collection; import java.util.HashMap; import java.util.Map; import org.apache.commons.io.FileUtils; -import org.sonar.api.batch.BatchSide; +import org.sonar.api.batch.ScannerSide; import org.sonar.api.ce.ComputeEngineSide; import org.sonar.api.server.ServerSide; import org.sonar.api.utils.TempFolder; @@ -46,7 +46,7 @@ import static org.sonar.classloader.ClassloaderBuilder.LoadingOrder.SELF_FIRST; * <li>loading of the libraries embedded in plugin JAR files (directory META-INF/libs)</li> * </ul> */ -@BatchSide +@ScannerSide @ServerSide @ComputeEngineSide public class PluginClassloaderFactory { diff --git a/sonar-core/src/main/java/org/sonar/core/platform/PluginInfo.java b/sonar-core/src/main/java/org/sonar/core/platform/PluginInfo.java index ec0806d0f3d..a7b68c7558c 100644 --- a/sonar-core/src/main/java/org/sonar/core/platform/PluginInfo.java +++ b/sonar-core/src/main/java/org/sonar/core/platform/PluginInfo.java @@ -22,7 +22,7 @@ package org.sonar.core.platform; import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Function; import com.google.common.base.Joiner; -import com.google.common.base.Objects; +import com.google.common.base.MoreObjects; import com.google.common.base.Preconditions; import com.google.common.collect.ComparisonChain; import com.google.common.collect.Ordering; @@ -136,6 +136,9 @@ public class PluginInfo implements Comparable<PluginInfo> { @CheckForNull private String implementationBuild; + @CheckForNull + private boolean sonarLintSupported; + private final Set<RequiredPlugin> requiredPlugins = new HashSet<>(); public PluginInfo(String key) { @@ -217,6 +220,11 @@ public class PluginInfo implements Comparable<PluginInfo> { } @CheckForNull + public boolean isSonarLintSupported() { + return sonarLintSupported; + } + + @CheckForNull public String getBasePlugin() { return basePlugin; } @@ -231,7 +239,7 @@ public class PluginInfo implements Comparable<PluginInfo> { } public PluginInfo setName(@Nullable String name) { - this.name = Objects.firstNonNull(name, this.key); + this.name = MoreObjects.firstNonNull(name, this.key); return this; } @@ -288,6 +296,11 @@ public class PluginInfo implements Comparable<PluginInfo> { return this; } + public PluginInfo setSonarLintSupported(boolean sonarLintPlugin) { + this.sonarLintSupported = sonarLintPlugin; + return this; + } + public PluginInfo setBasePlugin(@Nullable String s) { if ("l10nen".equals(s)) { Loggers.get(PluginInfo.class).info("Plugin [{}] defines 'l10nen' as base plugin. " + @@ -395,6 +408,7 @@ public class PluginInfo implements Comparable<PluginInfo> { info.setHomepageUrl(manifest.getHomepage()); info.setIssueTrackerUrl(manifest.getIssueTrackerUrl()); info.setUseChildFirstClassLoader(manifest.isUseChildFirstClassLoader()); + info.setSonarLintSupported(manifest.isSonarLintSupported()); info.setBasePlugin(manifest.getBasePlugin()); info.setImplementationBuild(manifest.getImplementationBuild()); String[] requiredPlugins = manifest.getRequirePlugins(); diff --git a/sonar-core/src/main/java/org/sonar/core/platform/PluginRepository.java b/sonar-core/src/main/java/org/sonar/core/platform/PluginRepository.java index f90c2881f43..a5aff6b1583 100644 --- a/sonar-core/src/main/java/org/sonar/core/platform/PluginRepository.java +++ b/sonar-core/src/main/java/org/sonar/core/platform/PluginRepository.java @@ -21,14 +21,14 @@ package org.sonar.core.platform; import java.util.Collection; import org.sonar.api.Plugin; -import org.sonar.api.batch.BatchSide; +import org.sonar.api.batch.ScannerSide; import org.sonar.api.ce.ComputeEngineSide; import org.sonar.api.server.ServerSide; /** * Provides information about the plugins installed in the dependency injection container */ -@BatchSide +@ScannerSide @ServerSide @ComputeEngineSide public interface PluginRepository { diff --git a/sonar-core/src/main/java/org/sonar/core/platform/RemotePlugin.java b/sonar-core/src/main/java/org/sonar/core/platform/RemotePlugin.java index d7e24418de4..13f97be6abd 100644 --- a/sonar-core/src/main/java/org/sonar/core/platform/RemotePlugin.java +++ b/sonar-core/src/main/java/org/sonar/core/platform/RemotePlugin.java @@ -27,6 +27,7 @@ import org.apache.commons.lang.StringUtils; public class RemotePlugin { private String pluginKey; + private boolean sonarLintSupported; private RemotePluginFile file = null; public RemotePlugin(String pluginKey) { @@ -36,14 +37,16 @@ public class RemotePlugin { public static RemotePlugin create(PluginInfo pluginInfo) { RemotePlugin result = new RemotePlugin(pluginInfo.getKey()); result.setFile(pluginInfo.getNonNullJarFile()); + result.setSonarLintSupported(pluginInfo.isSonarLintSupported()); return result; } public static RemotePlugin unmarshal(String row) { String[] fields = StringUtils.split(row, ","); RemotePlugin result = new RemotePlugin(fields[0]); - if (fields.length >= 2) { - String[] nameAndHash = StringUtils.split(fields[1], "|"); + if (fields.length >= 3) { + result.setSonarLintSupported(StringUtils.equals("true", fields[1])); + String[] nameAndHash = StringUtils.split(fields[2], "|"); result.setFile(nameAndHash[0], nameAndHash[1]); } return result; @@ -51,8 +54,13 @@ public class RemotePlugin { public String marshal() { StringBuilder sb = new StringBuilder(); - sb.append(pluginKey); - sb.append(",").append(file.getFilename()).append("|").append(file.getHash()); + sb.append(pluginKey) + .append(",") + .append(sonarLintSupported) + .append(",") + .append(file.getFilename()) + .append("|") + .append(file.getHash()); return sb.toString(); } @@ -65,6 +73,11 @@ public class RemotePlugin { return this; } + public RemotePlugin setSonarLintSupported(boolean sonarLintPlugin) { + this.sonarLintSupported = sonarLintPlugin; + return this; + } + public RemotePlugin setFile(File f) { try (FileInputStream fis = new FileInputStream(f)) { return this.setFile(f.getName(), DigestUtils.md5Hex(fis)); @@ -77,6 +90,10 @@ public class RemotePlugin { return file; } + public boolean isSonarLintSupported() { + return sonarLintSupported; + } + @Override public boolean equals(Object o) { if (this == o) { diff --git a/sonar-core/src/main/java/org/sonar/core/timemachine/Periods.java b/sonar-core/src/main/java/org/sonar/core/timemachine/Periods.java new file mode 100644 index 00000000000..914278a9955 --- /dev/null +++ b/sonar-core/src/main/java/org/sonar/core/timemachine/Periods.java @@ -0,0 +1,203 @@ +/* + * SonarQube + * Copyright (C) 2009-2016 SonarSource SA + * mailto:contact 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.core.timemachine; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; +import javax.annotation.CheckForNull; +import javax.annotation.Nullable; +import org.sonar.api.config.Settings; +import org.sonar.api.i18n.I18n; + +import static com.google.common.base.Preconditions.checkArgument; +import static java.util.Locale.ENGLISH; +import static org.apache.commons.lang.StringUtils.isNotBlank; +import static org.sonar.core.config.CorePropertyDefinitions.TIMEMACHINE_MODE_DATE; +import static org.sonar.core.config.CorePropertyDefinitions.TIMEMACHINE_MODE_DAYS; +import static org.sonar.core.config.CorePropertyDefinitions.TIMEMACHINE_MODE_PREVIOUS_ANALYSIS; +import static org.sonar.core.config.CorePropertyDefinitions.TIMEMACHINE_MODE_PREVIOUS_VERSION; +import static org.sonar.core.config.CorePropertyDefinitions.TIMEMACHINE_MODE_VERSION; +import static org.sonar.core.config.CorePropertyDefinitions.TIMEMACHINE_PERIOD_PREFIX; + +public class Periods { + + private final Settings settings; + private final I18n i18n; + + public Periods(Settings settings, I18n i18n) { + this.settings = settings; + this.i18n = i18n; + } + + @CheckForNull + private static String convertDate(@Nullable Date date) { + if (date != null) { + SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy MMM dd"); + return dateFormat.format(date); + } + return null; + } + + @CheckForNull + public String label(int periodIndex) { + String periodProperty = settings.getString(TIMEMACHINE_PERIOD_PREFIX + periodIndex); + PeriodParameters periodParameters = new PeriodParameters(periodProperty); + return label(periodParameters.getMode(), periodParameters.getParam(), periodParameters.getDate()); + } + + @CheckForNull + public String abbreviation(int periodIndex) { + String periodProperty = settings.getString(TIMEMACHINE_PERIOD_PREFIX + periodIndex); + PeriodParameters periodParameters = new PeriodParameters(periodProperty); + return abbreviation(periodParameters.getMode(), periodParameters.getParam(), periodParameters.getDate()); + } + + @CheckForNull + public String label(String mode, @Nullable String param, @Nullable Date date) { + return label(mode, param, convertDate(date), false); + } + + @CheckForNull + public String label(String mode, @Nullable String param, @Nullable String date) { + return label(mode, param, date, false); + } + + @CheckForNull + public String abbreviation(String mode, @Nullable String param, @Nullable Date date) { + return label(mode, param, convertDate(date), true); + } + + @CheckForNull + private String label(String mode, @Nullable String param, @Nullable String date, boolean shortLabel) { + switch (mode) { + case TIMEMACHINE_MODE_DAYS: + return labelForDays(param, date, shortLabel); + case TIMEMACHINE_MODE_VERSION: + return labelForVersion(param, date, shortLabel); + case TIMEMACHINE_MODE_PREVIOUS_ANALYSIS: + return labelForPreviousAnalysis(date, shortLabel); + case TIMEMACHINE_MODE_PREVIOUS_VERSION: + return labelForPreviousVersion(param, date, shortLabel); + case TIMEMACHINE_MODE_DATE: + return label("since_x", shortLabel, date); + default: + throw new IllegalArgumentException("This mode is not supported : " + mode); + } + } + + private String labelForDays(@Nullable String param, @Nullable String date, boolean shortLabel) { + if (date == null) { + return label("over_x_days", shortLabel, param); + } + return label("over_x_days_detailed", shortLabel, param, date); + } + + private String labelForVersion(@Nullable String param, @Nullable String date, boolean shortLabel) { + if (date == null) { + return label("since_version", shortLabel, param); + } + return label("since_version_detailed", shortLabel, param, date); + } + + private String labelForPreviousAnalysis(@Nullable String date, boolean shortLabel) { + if (date == null) { + return label("since_previous_analysis", shortLabel); + } + return label("since_previous_analysis_detailed", shortLabel, date); + } + + private String labelForPreviousVersion(@Nullable String param, @Nullable String date, boolean shortLabel) { + if (param == null && date == null) { + return label("since_previous_version", shortLabel); + } + if (param == null) { + // Special case when no snapshot for previous version is found. The first analysis is then returned -> Display only the date. + return label("since_previous_version_with_only_date", shortLabel, date); + } + if (date == null) { + return label("since_previous_version_detailed", shortLabel, param); + } + return label("since_previous_version_detailed", shortLabel, param, date); + } + + private String label(String key, boolean shortLabel, Object... parameters) { + String msgKey = key; + if (shortLabel) { + msgKey += ".short"; + } + return i18n.message(ENGLISH, msgKey, null, parameters); + } + + private static class PeriodParameters { + + private String mode = null; + private String param = null; + private Date date = null; + + public PeriodParameters(String periodProperty) { + checkArgument(isNotBlank(periodProperty), "Period property should not be empty"); + Integer possibleDaysValue = findByDays(periodProperty); + Date possibleDatesValue = findByDate(periodProperty); + if (TIMEMACHINE_MODE_PREVIOUS_ANALYSIS.equals(periodProperty) || TIMEMACHINE_MODE_PREVIOUS_VERSION.equals(periodProperty)) { + mode = periodProperty; + } else if (possibleDaysValue != null) { + mode = TIMEMACHINE_MODE_DAYS; + param = Integer.toString(possibleDaysValue); + } else if (possibleDatesValue != null) { + mode = TIMEMACHINE_MODE_DATE; + date = possibleDatesValue; + } else { + mode = TIMEMACHINE_MODE_VERSION; + param = periodProperty; + } + } + + private static Integer findByDays(String property) { + try { + return Integer.parseInt(property); + } catch (NumberFormatException e) { + return null; + } + } + + private static Date findByDate(String property) { + SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd"); + try { + return format.parse(property); + } catch (ParseException e) { + return null; + } + } + + public String getMode() { + return mode; + } + + public String getParam() { + return param; + } + + public Date getDate() { + return date; + } + } + +} diff --git a/sonar-core/src/main/java/org/sonar/core/timemachine/package-info.java b/sonar-core/src/main/java/org/sonar/core/timemachine/package-info.java new file mode 100644 index 00000000000..7d65a931ce8 --- /dev/null +++ b/sonar-core/src/main/java/org/sonar/core/timemachine/package-info.java @@ -0,0 +1,24 @@ +/* + * SonarQube + * Copyright (C) 2009-2016 SonarSource SA + * mailto:contact 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.core.timemachine; + +import javax.annotation.ParametersAreNonnullByDefault; + diff --git a/sonar-core/src/main/java/org/sonar/core/util/ContextException.java b/sonar-core/src/main/java/org/sonar/core/util/ContextException.java index e469d6197ca..1b5de2f8f7d 100644 --- a/sonar-core/src/main/java/org/sonar/core/util/ContextException.java +++ b/sonar-core/src/main/java/org/sonar/core/util/ContextException.java @@ -69,7 +69,7 @@ public class ContextException extends RuntimeException { private static final Joiner COMMA_JOINER = Joiner.on(','); // LinkedListMultimap is used to keep order of keys and values - private final ListMultimap<String, Object> context = LinkedListMultimap.create(); + private final transient ListMultimap<String, Object> context = LinkedListMultimap.create(); private ContextException(Throwable t) { super(t); diff --git a/sonar-core/src/main/java/org/sonar/core/util/DefaultHttpDownloader.java b/sonar-core/src/main/java/org/sonar/core/util/DefaultHttpDownloader.java index d7b343787ad..ed174aff4c9 100644 --- a/sonar-core/src/main/java/org/sonar/core/util/DefaultHttpDownloader.java +++ b/sonar-core/src/main/java/org/sonar/core/util/DefaultHttpDownloader.java @@ -25,9 +25,6 @@ import com.google.common.base.Strings; import com.google.common.collect.ImmutableList; import com.google.common.collect.Lists; import com.google.common.io.ByteStreams; -import com.google.common.io.CharStreams; -import com.google.common.io.Files; -import com.google.common.io.InputSupplier; import java.io.File; import java.io.IOException; import java.io.InputStream; @@ -40,16 +37,19 @@ import java.net.URI; import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; import java.util.List; +import java.util.Optional; import java.util.zip.GZIPInputStream; import javax.annotation.Nullable; import org.apache.commons.codec.binary.Base64; import org.apache.commons.io.IOUtils; +import org.sonar.api.CoreProperties; import org.sonar.api.config.Settings; import org.sonar.api.platform.Server; import org.sonar.api.utils.HttpDownloader; import org.sonar.api.utils.SonarException; import org.sonar.api.utils.log.Loggers; +import static org.apache.commons.io.FileUtils.copyInputStreamToFile; import static org.apache.commons.lang.StringUtils.isNotEmpty; import static org.sonar.core.util.FileUtils.deleteQuietly; @@ -110,7 +110,7 @@ public class DefaultHttpDownloader extends HttpDownloader { @Override protected String readString(URI uri, Charset charset) { try { - return CharStreams.toString(CharStreams.newReaderSupplier(downloader.newInputSupplier(uri, this.connectTimeout, this.readTimeout), charset)); + return IOUtils.toString(downloader.newInputSupplier(uri, this.connectTimeout, this.readTimeout).getInput(), charset); } catch (IOException e) { throw failToDownload(uri, e); } @@ -124,7 +124,7 @@ public class DefaultHttpDownloader extends HttpDownloader { @Override public byte[] download(URI uri) { try { - return ByteStreams.toByteArray(downloader.newInputSupplier(uri, this.connectTimeout, this.readTimeout)); + return ByteStreams.toByteArray(downloader.newInputSupplier(uri, this.connectTimeout, this.readTimeout).getInput()); } catch (IOException e) { throw failToDownload(uri, e); } @@ -146,7 +146,7 @@ public class DefaultHttpDownloader extends HttpDownloader { @Override public void download(URI uri, File toFile) { try { - Files.copy(downloader.newInputSupplier(uri, this.connectTimeout, this.readTimeout), toFile); + copyInputStreamToFile(downloader.newInputSupplier(uri, this.connectTimeout, this.readTimeout).getInput(), toFile); } catch (IOException e) { deleteQuietly(toFile); throw failToDownload(uri, e); @@ -191,7 +191,7 @@ public class DefaultHttpDownloader extends HttpDownloader { BaseHttpDownloader(SystemFacade system, Settings settings, @Nullable String userAgent) { initProxy(system, settings); - initUserAgent(userAgent); + initUserAgent(userAgent, settings); } private void initProxy(SystemFacade system, Settings settings) { @@ -218,8 +218,9 @@ public class DefaultHttpDownloader extends HttpDownloader { } } - private void initUserAgent(@Nullable String sonarVersion) { - userAgent = sonarVersion == null ? "SonarQube" : String.format("SonarQube %s", sonarVersion); + private void initUserAgent(@Nullable String sonarVersion, Settings settings) { + String serverId = settings.getString(CoreProperties.SERVER_ID); + userAgent = sonarVersion == null ? "SonarQube" : String.format("SonarQube %s # %s", sonarVersion, Optional.ofNullable(serverId).orElse("")); System.setProperty("http.agent", userAgent); } @@ -244,65 +245,22 @@ public class DefaultHttpDownloader extends HttpDownloader { return Joiner.on(", ").join(descriptions); } - public InputSupplier<InputStream> newInputSupplier(URI uri) { - return newInputSupplier(uri, GET, null, null, null, null); - } - - public InputSupplier<InputStream> newInputSupplier(URI uri, @Nullable Integer readTimeoutMillis) { - return newInputSupplier(uri, GET, readTimeoutMillis); - } - - /** - * @since 5.2 - */ - public InputSupplier<InputStream> newInputSupplier(URI uri, @Nullable Integer connectTimeoutMillis, @Nullable Integer readTimeoutMillis) { + public HttpInputSupplier newInputSupplier(URI uri, @Nullable Integer connectTimeoutMillis, @Nullable Integer readTimeoutMillis) { return newInputSupplier(uri, GET, connectTimeoutMillis, readTimeoutMillis); } - /** - * @since 5.2 - */ - public InputSupplier<InputStream> newInputSupplier(URI uri, String requestMethod, @Nullable Integer connectTimeoutMillis, @Nullable Integer readTimeoutMillis) { + public HttpInputSupplier newInputSupplier(URI uri, String requestMethod, @Nullable Integer connectTimeoutMillis, @Nullable Integer readTimeoutMillis) { return newInputSupplier(uri, requestMethod, null, null, connectTimeoutMillis, readTimeoutMillis); } - public InputSupplier<InputStream> newInputSupplier(URI uri, String requestMethod, @Nullable Integer readTimeoutMillis) { - return newInputSupplier(uri, requestMethod, null, null, null, readTimeoutMillis); - } - - public InputSupplier<InputStream> newInputSupplier(URI uri, String login, String password) { - return newInputSupplier(uri, GET, login, password); - } - - /** - * @since 5.0 - */ - public InputSupplier<InputStream> newInputSupplier(URI uri, String requestMethod, String login, String password) { - return newInputSupplier(uri, requestMethod, login, password, null, null); - } - - public InputSupplier<InputStream> newInputSupplier(URI uri, String login, String password, @Nullable Integer readTimeoutMillis) { - return newInputSupplier(uri, GET, login, password, readTimeoutMillis); - } - - /** - * @since 5.0 - */ - public InputSupplier<InputStream> newInputSupplier(URI uri, String requestMethod, String login, String password, @Nullable Integer readTimeoutMillis) { - return newInputSupplier(uri, requestMethod, login, password, null, readTimeoutMillis); - } - - /** - * @since 5.2 - */ - public InputSupplier<InputStream> newInputSupplier(URI uri, String requestMethod, String login, String password, @Nullable Integer connectTimeoutMillis, + public HttpInputSupplier newInputSupplier(URI uri, String requestMethod, String login, String password, @Nullable Integer connectTimeoutMillis, @Nullable Integer readTimeoutMillis) { int read = readTimeoutMillis != null ? readTimeoutMillis : TIMEOUT_MILLISECONDS; int connect = connectTimeoutMillis != null ? connectTimeoutMillis : TIMEOUT_MILLISECONDS; return new HttpInputSupplier(uri, requestMethod, userAgent, login, password, connect, read); } - private static class HttpInputSupplier implements InputSupplier<InputStream> { + private static class HttpInputSupplier { private final String login; private final String password; private final URI uri; @@ -325,7 +283,6 @@ public class DefaultHttpDownloader extends HttpDownloader { * @throws IOException any I/O error, not limited to the network connection * @throws HttpException if HTTP response code > 400 */ - @Override public InputStream getInput() throws IOException { Loggers.get(getClass()).debug("Download: " + uri + " (" + getProxySynthesis(uri, ProxySelector.getDefault()) + ")"); HttpURLConnection connection = (HttpURLConnection) uri.toURL().openConnection(); diff --git a/sonar-core/src/main/java/org/sonar/core/util/ProgressLogger.java b/sonar-core/src/main/java/org/sonar/core/util/ProgressLogger.java index b6ac17345e2..e69b02e0981 100644 --- a/sonar-core/src/main/java/org/sonar/core/util/ProgressLogger.java +++ b/sonar-core/src/main/java/org/sonar/core/util/ProgressLogger.java @@ -30,7 +30,7 @@ import org.sonar.api.utils.log.Loggers; */ public class ProgressLogger { - public static final long DEFAULT_PERIOD_MS = 60000L; + public static final long DEFAULT_PERIOD_MS = 60_000L; private final Timer timer; private final LoggerTimerTask task; diff --git a/sonar-core/src/main/java/org/sonar/core/util/SequenceUuidFactory.java b/sonar-core/src/main/java/org/sonar/core/util/SequenceUuidFactory.java new file mode 100644 index 00000000000..c35f78c71dc --- /dev/null +++ b/sonar-core/src/main/java/org/sonar/core/util/SequenceUuidFactory.java @@ -0,0 +1,36 @@ +/* + * SonarQube + * Copyright (C) 2009-2016 SonarSource SA + * mailto:contact 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.core.util; + +import java.util.concurrent.atomic.AtomicInteger; + +/** + * Only for tests. This implementation of {@link UuidFactory} generates + * ids as a sequence of integers ("1", "2", ...). It starts with "1". + */ +public class SequenceUuidFactory implements UuidFactory { + + private final AtomicInteger id = new AtomicInteger(1); + + @Override + public String create() { + return String.valueOf(id.getAndIncrement()); + } +} diff --git a/sonar-core/src/main/java/org/sonar/core/util/Slug.java b/sonar-core/src/main/java/org/sonar/core/util/Slug.java index eb96a0b8da8..a25ecdfd452 100644 --- a/sonar-core/src/main/java/org/sonar/core/util/Slug.java +++ b/sonar-core/src/main/java/org/sonar/core/util/Slug.java @@ -21,19 +21,86 @@ package org.sonar.core.util; import java.text.Normalizer; import java.util.Locale; +import java.util.regex.Pattern; public class Slug { + private static final String DASH = "-"; + private static final Pattern NON_ASCII_CHARS = Pattern.compile("[^\\p{ASCII}]"); + private static final Pattern NON_WORD_CHARS = Pattern.compile("[^\\w+]"); + private static final Pattern WHITESPACES_CHARS = Pattern.compile("\\s+"); + private static final Pattern DASHES_IN_ROWS = Pattern.compile("[-]+"); - private Slug() { + private String in; + + private Slug(String in) { + this.in = in; } public static String slugify(String s) { - return Normalizer.normalize(s, Normalizer.Form.NFD) - .replaceAll("[^\\p{ASCII}]", "") - .replaceAll("[^\\w+]", "-") - .replaceAll("\\s+", "-") - .replaceAll("[-]+", "-") - .replaceAll("^-", "") - .replaceAll("-$", "").toLowerCase(Locale.ENGLISH); + Slug slug = new Slug(s); + return slug + .normalize() + .removeNonAsciiChars() + .dashifyNonWordChars() + .dashifyWhitespaceChars() + .collapseDashes() + .removeHeadingDash() + .removeTrailingDash() + .toLowerCase(); + } + + private Slug normalize() { + this.in = Normalizer.normalize(in, Normalizer.Form.NFD); + return this; + } + + private Slug removeNonAsciiChars() { + this.in = removeAll(NON_ASCII_CHARS, in); + return this; + } + + private Slug dashifyNonWordChars() { + this.in = dashify(NON_WORD_CHARS, in); + return this; + } + + private Slug dashifyWhitespaceChars() { + this.in = dashify(WHITESPACES_CHARS, in); + return this; + } + + private Slug collapseDashes() { + this.in = dashify(DASHES_IN_ROWS, in); + return this; + } + + private Slug removeHeadingDash() { + if (this.in.startsWith(DASH)) { + this.in = this.in.substring(1); + } + return this; + } + + private Slug removeTrailingDash() { + if (this.in.endsWith(DASH)) { + this.in = this.in.substring(0, this.in.length() - 1); + } + return this; + } + + private String toLowerCase() { + return in.toLowerCase(Locale.ENGLISH); + } + + private static String removeAll(Pattern pattern, String in) { + return replaceAll(pattern, in, ""); + } + + private static String dashify(Pattern pattern, String in) { + return replaceAll(pattern, in, DASH); + } + + private static String replaceAll(Pattern pattern, String str, String replacement) { + return pattern.matcher(str).replaceAll(replacement); } } diff --git a/sonar-core/src/main/java/org/sonar/core/util/UuidFactory.java b/sonar-core/src/main/java/org/sonar/core/util/UuidFactory.java index 81203880500..42980f37395 100644 --- a/sonar-core/src/main/java/org/sonar/core/util/UuidFactory.java +++ b/sonar-core/src/main/java/org/sonar/core/util/UuidFactory.java @@ -27,7 +27,7 @@ public interface UuidFactory { * <p/> * UUID is a base64 ASCII encoded string and is URL-safe. It does not contain - and + characters * but only letters, digits, dash (-) and underscore (_). Length can vary but does - * not exceed 40 characters (arbitrary value). + * not exceed {@link Uuids#MAX_LENGTH} characters (arbitrary value). */ String create(); diff --git a/sonar-core/src/main/java/org/sonar/core/util/Uuids.java b/sonar-core/src/main/java/org/sonar/core/util/Uuids.java index f7ff3d68421..13fb00a196c 100644 --- a/sonar-core/src/main/java/org/sonar/core/util/Uuids.java +++ b/sonar-core/src/main/java/org/sonar/core/util/Uuids.java @@ -21,6 +21,7 @@ package org.sonar.core.util; public class Uuids { + public static final int MAX_LENGTH = 40; public static final String UUID_EXAMPLE_01 = "AU-Tpxb--iU5OvuD2FLy"; public static final String UUID_EXAMPLE_02 = "AU-TpxcA-iU5OvuD2FLz"; public static final String UUID_EXAMPLE_03 = "AU-TpxcA-iU5OvuD2FL0"; diff --git a/sonar-core/src/main/java/org/sonar/core/util/stream/Collectors.java b/sonar-core/src/main/java/org/sonar/core/util/stream/Collectors.java new file mode 100644 index 00000000000..449261a6c4a --- /dev/null +++ b/sonar-core/src/main/java/org/sonar/core/util/stream/Collectors.java @@ -0,0 +1,348 @@ +/* + * SonarQube + * Copyright (C) 2009-2016 SonarSource SA + * mailto:contact 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.core.util.stream; + +import com.google.common.base.Joiner; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableListMultimap; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableSet; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.function.BiConsumer; +import java.util.function.BinaryOperator; +import java.util.function.Function; +import java.util.function.Supplier; +import java.util.stream.Collector; + +import static java.util.Objects.requireNonNull; + +public final class Collectors { + + private static final int DEFAULT_HASHMAP_CAPACITY = 0; + + private Collectors() { + // prevents instantiation + } + + /** + * A Collector into an {@link ImmutableList}. + */ + public static <T> Collector<T, List<T>, List<T>> toList() { + return Collector.of( + ArrayList::new, + List::add, + (left, right) -> { + left.addAll(right); + return left; + }, + ImmutableList::copyOf); + } + + /** + * A Collector into an {@link ImmutableList} of the specified expected size. + * + * <p>Note: using this method with a parallel stream will likely not have the expected memory usage benefit as all + * processing threads will use a List with a capacity large enough for the final size.</p> + */ + public static <T> Collector<T, List<T>, List<T>> toList(int expectedSize) { + // use ArrayList rather than ImmutableList.Builder because initial capacity of builder can not be specified + return Collector.of( + () -> new ArrayList<>(expectedSize), + List::add, + (left, right) -> { + left.addAll(right); + return left; + }, + ImmutableList::copyOf); + } + + /** + * A Collector into an {@link ImmutableSet}. + */ + public static <T> Collector<T, Set<T>, Set<T>> toSet() { + return Collector.of( + HashSet::new, + Set::add, + (left, right) -> { + left.addAll(right); + return left; + }, + ImmutableSet::copyOf); + } + + /** + * A Collector into an {@link ImmutableSet} of the specified expected size. + * + * <p>Note: using this method with a parallel stream will likely not have the expected memory usage benefit as all + * processing threads will use a Set with a capacity large enough for the final size.</p> + */ + public static <T> Collector<T, Set<T>, Set<T>> toSet(int expectedSize) { + // use HashSet rather than ImmutableSet.Builder because initial capacity of builder can not be specified + return Collector.of( + () -> new HashSet<>(expectedSize), + Set::add, + (left, right) -> { + left.addAll(right); + return left; + }, + ImmutableSet::copyOf); + } + + /** + * Delegates to {@link java.util.stream.Collectors#toCollection(Supplier)}. + */ + public static <T> Collector<T, ?, ArrayList<T>> toArrayList() { + return java.util.stream.Collectors.toCollection(ArrayList::new); + } + + /** + * Does {@code java.util.stream.Collectors.toCollection(() -> new ArrayList<>(size));} which is equivalent to + * {@link #toArrayList()} but avoiding array copies when the size of the resulting list is already known. + * + * <p>Note: using this method with a parallel stream will likely not have the expected memory usage benefit as all + * processing threads will use a ArrayList with a capacity large enough for the final size.</p> + * + * @see java.util.stream.Collectors#toList() + * @see java.util.stream.Collectors#toCollection(Supplier) + */ + public static <T> Collector<T, ?, ArrayList<T>> toArrayList(int size) { + return java.util.stream.Collectors.toCollection(() -> new ArrayList<>(size)); + } + + /** + * Delegates to {@link java.util.stream.Collectors#toCollection(Supplier)}. + */ + public static <T> Collector<T, ?, HashSet<T>> toHashSet() { + return java.util.stream.Collectors.toCollection(HashSet::new); + } + + /** + * Does {@code java.util.stream.Collectors.toCollection(() -> new HashSet<>(size));} which is equivalent to + * {@link #toHashSet()} but avoiding array copies when the size of the resulting set is already known. + * + * <p>Note: using this method with a parallel stream will likely not have the expected memory usage benefit as all + * processing threads will use a HashSet with a capacity large enough for the final size.</p> + * + * @see java.util.stream.Collectors#toSet() + * @see java.util.stream.Collectors#toCollection(Supplier) + */ + public static <T> Collector<T, ?, HashSet<T>> toHashSet(int size) { + return java.util.stream.Collectors.toCollection(() -> new HashSet<>(size)); + } + + /** + * Creates an {@link ImmutableMap} from the stream where the values are the values in the stream and the keys are the + * result of the provided {@link Function keyFunction} applied to each value in the stream. + * + * <p> + * The {@link Function keyFunction} must return a unique (according to the key's type {@link Object#equals(Object)} + * and/or {@link Comparable#compareTo(Object)} implementations) value for each of them, otherwise a + * {@link IllegalArgumentException} will be thrown. + * </p> + * + * <p> + * {@link Function keyFunction} can't return {@code null}, otherwise a {@link NullPointerException} will be thrown. + * </p> + * + * @throws NullPointerException if {@code keyFunction} is {@code null}. + * @throws NullPointerException if result of {@code keyFunction} is {@code null}. + * @throws IllegalArgumentException if {@code keyFunction} returns the same value for multiple entries in the stream. + */ + public static <K, E> Collector<E, Map<K, E>, ImmutableMap<K, E>> uniqueIndex(Function<? super E, K> keyFunction) { + return uniqueIndex(keyFunction, Function.<E>identity()); + } + + /** + * Same as {@link #uniqueIndex(Function)} but using an underlying {@link Map} initialized with a capacity for the + * specified expected size. + * + * <p>Note: using this method with a parallel stream will likely not have the expected memory usage benefit as all + * processing threads will use a Map with a capacity large enough for the final size.</p> + * + * <p> + * {@link Function keyFunction} can't return {@code null}, otherwise a {@link NullPointerException} will be thrown. + * </p> + * + * @throws NullPointerException if {@code keyFunction} is {@code null}. + * @throws NullPointerException if result of {@code keyFunction} is {@code null}. + * @throws IllegalArgumentException if {@code keyFunction} returns the same value for multiple entries in the stream. + * @see #uniqueIndex(Function) + */ + public static <K, E> Collector<E, Map<K, E>, ImmutableMap<K, E>> uniqueIndex(Function<? super E, K> keyFunction, int expectedSize) { + return uniqueIndex(keyFunction, Function.<E>identity(), expectedSize); + } + + /** + * Creates an {@link ImmutableMap} from the stream where the values are the result of {@link Function valueFunction} + * applied to the values in the stream and the keys are the result of the provided {@link Function keyFunction} + * applied to each value in the stream. + * + * <p> + * The {@link Function keyFunction} must return a unique (according to the key's type {@link Object#equals(Object)} + * and/or {@link Comparable#compareTo(Object)} implementations) value for each of them, otherwise a + * {@link IllegalArgumentException} will be thrown. + * </p> + * + * <p> + * Neither {@link Function keyFunction} nor {@link Function valueFunction} can return {@code null}, otherwise a + * {@link NullPointerException} will be thrown. + * </p> + * + * @throws NullPointerException if {@code keyFunction} or {@code valueFunction} is {@code null}. + * @throws NullPointerException if result of {@code keyFunction} or {@code valueFunction} is {@code null}. + * @throws IllegalArgumentException if {@code keyFunction} returns the same value for multiple entries in the stream. + */ + public static <K, E, V> Collector<E, Map<K, V>, ImmutableMap<K, V>> uniqueIndex(Function<? super E, K> keyFunction, + Function<? super E, V> valueFunction) { + return uniqueIndex(keyFunction, valueFunction, DEFAULT_HASHMAP_CAPACITY); + } + + /** + * Same as {@link #uniqueIndex(Function, Function)} but using an underlying {@link Map} initialized with a capacity + * for the specified expected size. + * + * <p>Note: using this method with a parallel stream will likely not have the expected memory usage benefit as all + * processing threads will use a Map with a capacity large enough for the final size.</p> + * + * <p> + * Neither {@link Function keyFunction} nor {@link Function valueFunction} can return {@code null}, otherwise a + * {@link NullPointerException} will be thrown. + * </p> + * + * @throws NullPointerException if {@code keyFunction} or {@code valueFunction} is {@code null}. + * @throws NullPointerException if result of {@code keyFunction} or {@code valueFunction} is {@code null}. + * @throws IllegalArgumentException if {@code keyFunction} returns the same value for multiple entries in the stream. + * @see #uniqueIndex(Function, Function) + */ + public static <K, E, V> Collector<E, Map<K, V>, ImmutableMap<K, V>> uniqueIndex(Function<? super E, K> keyFunction, + Function<? super E, V> valueFunction, int expectedSize) { + requireNonNull(keyFunction, "Key function can't be null"); + requireNonNull(valueFunction, "Value function can't be null"); + BiConsumer<Map<K, V>, E> accumulator = (map, element) -> { + K key = requireNonNull(keyFunction.apply(element), "Key function can't return null"); + V value = requireNonNull(valueFunction.apply(element), "Value function can't return null"); + + putAndFailOnDuplicateKey(map, key, value); + }; + BinaryOperator<Map<K, V>> merger = (m1, m2) -> { + for (Map.Entry<K, V> entry : m2.entrySet()) { + putAndFailOnDuplicateKey(m1, entry.getKey(), entry.getValue()); + } + return m1; + }; + return Collector.of( + newHashMapSupplier(expectedSize), + accumulator, + merger, + ImmutableMap::copyOf, + Collector.Characteristics.UNORDERED); + } + + private static <K, V> Supplier<Map<K, V>> newHashMapSupplier(int expectedSize) { + return () -> expectedSize == DEFAULT_HASHMAP_CAPACITY ? new HashMap<>() : new HashMap<>(expectedSize); + } + + private static <K, V> void putAndFailOnDuplicateKey(Map<K, V> map, K key, V value) { + V existingValue = map.put(key, value); + if (existingValue != null) { + throw new IllegalArgumentException(String.format("Duplicate key %s", key)); + } + } + + /** + * Creates an {@link com.google.common.collect.ImmutableListMultimap} from the stream where the values are the values + * in the stream and the keys are the result of the provided {@link Function keyFunction} applied to each value in the + * stream. + * + * <p> + * Neither {@link Function keyFunction} nor {@link Function valueFunction} can return {@code null}, otherwise a + * {@link NullPointerException} will be thrown. + * </p> + * + * @throws NullPointerException if {@code keyFunction} or {@code valueFunction} is {@code null}. + * @throws NullPointerException if result of {@code keyFunction} or {@code valueFunction} is {@code null}. + */ + public static <K, E> Collector<E, ImmutableListMultimap.Builder<K, E>, ImmutableListMultimap<K, E>> index(Function<? super E, K> keyFunction) { + return index(keyFunction, Function.<E>identity()); + } + + /** + * Creates an {@link com.google.common.collect.ImmutableListMultimap} from the stream where the values are the result + * of {@link Function valueFunction} applied to the values in the stream and the keys are the result of the provided + * {@link Function keyFunction} applied to each value in the stream. + * + * <p> + * Neither {@link Function keyFunction} nor {@link Function valueFunction} can return {@code null}, otherwise a + * {@link NullPointerException} will be thrown. + * </p> + * + * @throws NullPointerException if {@code keyFunction} or {@code valueFunction} is {@code null}. + * @throws NullPointerException if result of {@code keyFunction} or {@code valueFunction} is {@code null}. + */ + public static <K, E, V> Collector<E, ImmutableListMultimap.Builder<K, V>, ImmutableListMultimap<K, V>> index(Function<? super E, K> keyFunction, + Function<? super E, V> valueFunction) { + requireNonNull(keyFunction, "Key function can't be null"); + requireNonNull(valueFunction, "Value function can't be null"); + BiConsumer<ImmutableListMultimap.Builder<K, V>, E> accumulator = (map, element) -> { + K key = requireNonNull(keyFunction.apply(element), "Key function can't return null"); + V value = requireNonNull(valueFunction.apply(element), "Value function can't return null"); + + map.put(key, value); + }; + BinaryOperator<ImmutableListMultimap.Builder<K, V>> merger = (m1, m2) -> { + for (Map.Entry<K, V> entry : m2.build().entries()) { + m1.put(entry.getKey(), entry.getValue()); + } + return m1; + }; + return Collector.of( + ImmutableListMultimap::builder, + accumulator, + merger, + ImmutableListMultimap.Builder::build); + } + + /** + * Applies the specified {@link Joiner} to the current stream. + * + * @throws NullPointerException of {@code joiner} is {@code null} + * @throws IllegalStateException if a merge operation happens because parallel processing has been enabled on the current stream + */ + public static <E> Collector<E, List<E>, String> join(Joiner joiner) { + requireNonNull(joiner, "Joiner can't be null"); + + return Collector.of( + ArrayList::new, + List::add, + mergeNotSupportedMerger(), + joiner::join); + } + + private static <R> BinaryOperator<R> mergeNotSupportedMerger() { + return (m1, m2) -> { + throw new IllegalStateException("Parallel processing is not supported"); + }; + } +} diff --git a/sonar-core/src/main/java/org/sonar/core/util/stream/package-info.java b/sonar-core/src/main/java/org/sonar/core/util/stream/package-info.java new file mode 100644 index 00000000000..31da2808440 --- /dev/null +++ b/sonar-core/src/main/java/org/sonar/core/util/stream/package-info.java @@ -0,0 +1,24 @@ +/* + * SonarQube + * Copyright (C) 2009-2016 SonarSource SA + * mailto:contact 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.core.util.stream; + +import javax.annotation.ParametersAreNonnullByDefault; + diff --git a/sonar-core/src/main/resources/org/sonar/l10n/core.properties b/sonar-core/src/main/resources/org/sonar/l10n/core.properties index bfdc872a746..c6faa548cb4 100644 --- a/sonar-core/src/main/resources/org/sonar/l10n/core.properties +++ b/sonar-core/src/main/resources/org/sonar/l10n/core.properties @@ -1,85 +1,27 @@ +#------------------------------------------------------------------------------ +# +# GENERIC WORDS, sorted alphabetically +# +#------------------------------------------------------------------------------ + action=Action +actions=Actions activate_all=Activate all activation=Activation active=Active -added_over_x_days=Added over {0} days -added_since=Added since {0} -added_since_previous_analysis=Added since previous analysis -added_since_previous_analysis_detailed=Added since previous analysis ({0}) -added_since_previous_version=Added since previous version -added_since_previous_version_detailed=Added since previous version ({0}) -added_since_version=Added since version {0} -add_a_column=Add a column add_verb=Add age=Age -alerts.notes.description=<p>Only project measures are checked against thresholds. Modules, packages and classes are ignored.</p>Project health icons represent : -alerts.notes.error=at least one error threshold is reached. -alerts.notes.ok=at least one threshold is defined, no threshold is reached. -alerts.notes.warn=at least one warning threshold is reached, no error threshold is reached. -alerts.no_alerts=No alerts. -alerts.operator.!\==is not -alerts.operator.<=is less than -alerts.operator.>=is greater than -alerts.operator.\==equals -alerts.select_metric=Select a metric -all-projects.cols.name=Name -all-projects.results_not_display_due_to_security=Due to security settings, some results are not being displayed. +apply=Apply +assigned_to_me=Assigned to me +association=Association all=All -all_issues=All issues -all_rules.page=All Rules -all_violations=All violations -analysis_reports.current_activity=Current Activity -analysis_reports.page=Project Computation -analysis_reports.past_reports=Past Reports -analysis_reports.show_current_activity=Show Current Activity -analysis_reports.show_past_reports=Show Past Reports -analysis_reports.x_reports={0} reports and=And any=Any anytime=Anytime -api_documentation.deprecation_tooltip=If an API is deprecated in version X.Y, this API will be dropped in version (X+2).0. Example: an API deprecated in 4.1 is supported in 4.2, 4.3, 5.0, 5.1, 5.2, 5.3 and is dropped in version 6.0. -api_documentation.internal_tooltip=Use at your own risk; internal services are subject to change or removal without notice. -apply=Apply -Apr=Apr -April=April -are_you_sure=Are you sure? ascending=Ascending -assigned_to=Assigned to -assigned_to_me=Assigned to me assignee=Assignee -association=Association -Aug=Aug -August=August author=Author back=Back -background_task.status.ALL=All -background_task.status.ALL_EXCEPT_PENDING=All Except Pending -background_task.status.CANCELED=Canceled -background_task.status.FAILED=Failed -background_task.status.IN_PROGRESS=In Progress -background_task.status.PENDING=Pending -background_task.status.SUCCESS=Success -background_task.type.ALL=All -background_task.type.DEV_PURGE=Developer Cleaning -background_task.type.DEV_REFRESH=Developer Analysis -background_task.type.REPORT=Project Analysis -background_tasks.cancel_all_tasks=Cancel All Pending Tasks -background_tasks.cancel_task=Cancel Task -background_tasks.currents_filter.ALL=All -background_tasks.currents_filter.ONLY_CURRENTS=Only Latest Analysis -background_tasks.date_filter.ALL=Any Date -background_tasks.date_filter.CUSTOM=Custom -background_tasks.date_filter.TODAY=Today -background_tasks.failures=still failing -background_tasks.in_progress_duration=Duration of the current task in progress. -background_tasks.logs=Logs -background_tasks.page.description=This page allows monitoring of the queue of tasks running asynchronously on the server. It also gives access to the history of finished tasks, their status and logs. Analysis report processing is the most common kind of background task. -background_tasks.page=Background Tasks -background_tasks.pending=pending -background_tasks.table.duration=Duration -background_tasks.table.finished=Finished -background_tasks.table.started=Started -background_tasks.table.submitted=Submitted backup=Backup backup_verb=Back up blocker=Blocker @@ -88,34 +30,6 @@ branch=Branch browsed_recently=Browsed Recently build_date=Build date build_time=Build time -bulk_change=Bulk Change -bulk_deletion.clear_selection=Clear selection of all {0} components -bulk_deletion.delete_all_ghosts=Delete all ghosts -bulk_deletion.deletion_manager.currently_deleting_x_out_of_x=Currently deleting components... ({0} out of {1}) -bulk_deletion.deletion_manager.deleting_resources=Deleting components... -bulk_deletion.deletion_manager.deletion_completed=Component deletion completed. -bulk_deletion.deletion_manager.however_failures_occurred=However, some failures occurred. -bulk_deletion.deletion_manager.no_resource_to_delete=No results. -bulk_deletion.filter=Filter -bulk_deletion.following_deletions_failed=The following components could not be deleted. Please check the logs to know more about it. -bulk_deletion.following_ghosts_can_be_deleted=The following ghosts can be safely deleted: -bulk_deletion.ghosts.description=A ghost is the result of constantly failed attempts to analyse a project. In such a case, the project is not linked to any successful analysis, and therefore cannot be displayed in SonarQube. When the user authentication is forced, leaving a ghost can even prevent further analyses of the corresponding project. -bulk_deletion.ghosts=Ghosts -bulk_deletion.hide_message=Hide message -bulk_deletion.no_ghosts=There is currently no ghost. -bulk_deletion.page.description=Use this page to delete multiple projects at once. -bulk_deletion.page=Bulk Deletion -bulk_deletion.page_size=Page size -bulk_deletion.please_select_at_least_one_resource=Please select at least one component to delete. -bulk_deletion.resource.devs=Developers -bulk_deletion.resource.projects=Projects -bulk_deletion.resource.views=Views -bulk_deletion.resource_name_filter_by_name=Filter by name: -bulk_deletion.select_all=Select all -bulk_deletion.select_all_x_resources=Select all {0} components -bulk_deletion.started_since_x=Started {0} ago -bulk_deletion.sure_to_delete_the_resources=Are you sure you want to delete the selected components? -bulleted_point=Bulleted point calendar=Calendar cancel=Cancel category=Category @@ -123,688 +37,76 @@ changelog=Changelog change_verb=Change class=Class classes=Classes -click_to_add_to_favorites=Click to add to favorites -click_to_remove_from_favorites=Click to remove from favorites close=Close closed=Closed -cloud.quick_wins=Quick wins -cloud.top_risk=Top risk -clouds.page=Clouds -code.open_component_page=Open Component's Page -code.page=Code code=Code -code_viewer.no_info_displayed_due_to_security=Due to security settings, no information can be displayed. -code_viewer.no_source_code_displayed_due_to_security=Due to security settings, no source code can be displayed. -coding_rules.activate=Activate -coding_rules.activate_in=Activate In -coding_rules.activate_in_all_quality_profiles=Activate In All {0} Profiles -coding_rules.activate_in_quality_profile=Activate In Quality Profile -coding_rules.active_in_all_profiles=The rule is already activated on all available quality profiles. -coding_rules.add_note=Add Note -coding_rules.add_tags=Add Tags -coding_rules.available_since=Available Since -coding_rules.bulk_change.success={2} rule(s) changed in profile {0} - {1} -coding_rules.bulk_change.warning={2} rule(s) changed, {3} rule(s) ignored in profile {0} - {1} -coding_rules.bulk_change=Bulk Change -coding_rules.change_details=Change Details of Quality Profile -coding_rules.change_severity=Change Severity -coding_rules.change_severity_in=Change Severity In -coding_rules.create=Create -coding_rules.create_custom_rule=Create Custom Rule -coding_rules.custom_rule.activation_notice=Note: parameters of a custom rule are not customizable on rule activation, only during creation/edit. -coding_rules.custom_rule.title=This rule has been created through customization of a rule template -coding_rules.custom_rule=Custom Rule -coding_rules.custom_rules=Custom Rules -coding_rules.deactivate.confirm=Are you sure you want to deactivate this rule in the profile? -coding_rules.deactivate=Deactivate -coding_rules.deactivate_in=Deactivate In -coding_rules.deactivate_in_all_quality_profiles=Deactivate In All {0} Profiles -coding_rules.deactivate_in_quality_profile=Deactivate In Quality Profile -coding_rules.delete.custom.confirm=Are you sure you want to delete custom rule "{0}"? -coding_rules.delete_rule=Delete Rule -coding_rules.extend_description=Extend Description -coding_rules.facet.active_severities=Activation Severity -coding_rules.facet.available_since=Available Since -coding_rules.facet.debt_characteristics=Characteristic -coding_rules.facet.inheritance=Inheritance -coding_rules.facet.is_template=Template -coding_rules.facet.languages=Language -coding_rules.facet.qprofile=Quality Profile -coding_rules.facet.repositories=Repository -coding_rules.facet.rule_key=Rule -coding_rules.facet.severities=Default Severity -coding_rules.facet.statuses=Status -coding_rules.facet.tags=Tag -coding_rules.facet.types=Type -coding_rules.facets.languages=Languages -coding_rules.facets.repositories=Repositories -coding_rules.facets.tags=Tags -coding_rules.facets.top=Top {0} -coding_rules.filters.activation.active=Active -coding_rules.filters.activation.help=Activation criterion is available when a quality profile is selected -coding_rules.filters.activation.inactive=Inactive -coding_rules.filters.activation=Activation -coding_rules.filters.active_severity.inactive=Active severity criterion is available when a quality profile is selected -coding_rules.filters.active_severity=Active Severity -coding_rules.filters.availableSince=Available Since -coding_rules.filters.characteristic=Characteristic -coding_rules.filters.description=Description -coding_rules.filters.inheritance.inactive=Inheritance criterion is available when an inherited quality profile is selected -coding_rules.filters.inheritance.inherited=Inherited -coding_rules.filters.inheritance.none=Not Inherited -coding_rules.filters.inheritance.overrides=Overridden -coding_rules.filters.inheritance=Inheritance -coding_rules.filters.key=Key -coding_rules.filters.language=Language -coding_rules.filters.name=Name -coding_rules.filters.quality_profile=Quality Profile -coding_rules.filters.repository=Repository -coding_rules.filters.severity=Severity -coding_rules.filters.status=Status -coding_rules.filters.tag=Tag -coding_rules.filters.template.is_not_template=Hide Templates -coding_rules.filters.template.is_template=Show Templates Only -coding_rules.filters.template=Templates -coding_rules.filter_similar_rules=Filter Similar Rules -coding_rules.found=Found -coding_rules.inherits="{0}" inherits from "{1}" -coding_rules.issues=Issues -coding_rules.key=Key: -coding_rules.most_violated_projects=Most Violated Projects -coding_rules.new_search=New Search -coding_rules.noncharacterized=Uncharacterized -coding_rules.no_results=No Coding Rules -coding_rules.no_tags=No tags -coding_rules.order=Order -coding_rules.ordered_by=Ordered By -coding_rules.original=Original: -coding_rules.overrides="{0}" overrides "{1}" -coding_rules.overwrite=Overwrite -coding_rules.page=Rules -coding_rules.parameter.empty=(empty) -coding_rules.parameters.default_value=Default Value: -coding_rules.parameters=Parameters -coding_rules.permalink=Permalink -coding_rules.quality_profile=Quality Profile -coding_rules.quality_profiles.template_caption=This rule template was activated on the following profiles in previous versions of SonarQube. It is not possible anymore to do so. Instead, please create a custom rule. -coding_rules.quality_profiles=Quality Profiles -coding_rules.reactivate.help=A rule with the same key has been previously deleted. Please reactivate the existing rule or modify the key to create a new rule. -coding_rules.reactivate=Reactivate -coding_rules.remediation_function.coeff=Coeff -coding_rules.remediation_function.constant=Constant -coding_rules.remediation_function.CONSTANT_ISSUE=Constant/issue -coding_rules.remediation_function.LINEAR=Linear -coding_rules.remediation_function.LINEAR_OFFSET=Linear with offset -coding_rules.remediation_function.offset=Offset -coding_rules.remediation_function=Remediation function -coding_rules.remove_extended_description.confirm=Are you sure you want to remove the extended description? -coding_rules.repository=Repository: -coding_rules.return_to_list=Return to List -coding_rules.revert_to_parent_definition.confirm=This rule will be reverted to the parameters defined in profile {0}. Are you sure? -coding_rules.revert_to_parent_definition=Revert to Parent Definition -coding_rules.rule_template.title=This rule can be used as a template to create custom rules,\nit cannot be activated on a profile -coding_rules.rule_template=Rule Template -coding_rules.select_tag=Select Tag -coding_rules.show_template=Show Template -coding_rules.sort.creation_date=Creation Date -coding_rules.sort.name=Name -coding_rules.sort.relevance=Relevance -coding_rules.type.tooltip.BUG=Bug Detection Rule -coding_rules.type.tooltip.CODE_SMELL=Code Smell Detection Rule -coding_rules.type.tooltip.VULNERABILITY=Vulnerability Detection Rule -coding_rules.update_custom_rule=Update Custom Rule -coding_rules.validation.invalid_rule_key=The rule key "%s" is invalid, it should only contain: a-z, 0-9, "_" -coding_rules.validation.invalid_severity=Severity "{0}" is invalid -coding_rules.validation.missing_description=The description is missing -coding_rules.validation.missing_name=The name is missing -coding_rules.validation.missing_severity=The severity is missing -coding_rules.validation.missing_status=The status is missing -coding_rules._rules=rules -coding_rules=Rules color=Color compare=Compare -comparison.add_metric=Add metric -comparison.add_project=Add project -comparison.compare=Compare -comparison.move_down=Move down -comparison.move_left=Move left -comparison.move_right=Move right -comparison.move_up=Move up -comparison.page=Compare -comparison.select_version=Select a version -comparison.suppress_column=Suppress column -comparison.suppress_line=Suppress line -comparison.version.latest=LATEST -comparison_global.page=Compare Projects component=Component -components.explanation_launch_sonar_to_have_results=If Maven and SonarQube are installed with default parameters on the same box, just launch the command <code>mvn sonar:sonar</code> to analyse your first project. In any other case, please refer to the <a href="http://www.sonarsource.org/documentation">documentation</a>. -components.note_changes_impact_all_users=Note that these changes will impact all users and all projects. -components.no_projects_have_been_analysed=No projects have been analysed. -components.page=Components -component_measures.all_measures=All Measures -component_measures.back_to_list=Back to List -component_measures.domain_measures={0} Measures -component_measures.legend.color_x=Color: {0} -component_measures.legend.size_x=Size: {0} -component_measures.no_history=There is no historical data. -component_measures.tab.bubbles=Bubble Chart -component_measures.tab.history=History -component_measures.tab.list=List -component_measures.tab.tree=Tree -component_measures.tab.treemap=Treemap -component_measures.x_of_y={0} of {1} -component_navigation.status.failed.admin=The last analysis has failed.<br>More details available on the <a href="{0}">Background Tasks</a> page. -component_navigation.status.failed=The last analysis has failed. -component_navigation.status.in_progress.admin=The analysis is in progress.<br>More details available on the <a href="{0}">Background Tasks</a> page. -component_navigation.status.in_progress=The analysis is in progress. -component_navigation.status.pending.admin=There is a pending analysis.<br>More details available on the <a href="{0}">Background Tasks</a> page. -component_navigation.status.pending=There is a pending analysis. -component_viewer.added=Added -component_viewer.cannot_show=We're sorry, but something went wrong. Please try back in a few minutes and contact support if the problem persists. -component_viewer.covered_lines=Covered Lines -component_viewer.details=Details -component_viewer.extensions=Extensions -component_viewer.get_permalink=Get Permalink -component_viewer.header.debt=Debt -component_viewer.header.toggle_coverage=Toggle coverage -component_viewer.header.toggle_duplications=Toggle duplications -component_viewer.header.toggle_issues=Toggle issues -component_viewer.header.toggle_scm=Toggle SCM -component_viewer.issues.current_issue=Current Issue -component_viewer.issues.false_positive_issues=False Positive Issues -component_viewer.issues.fixed_issues=Fixed Issues -component_viewer.issues.open_issues=Open/Reopened Issues -component_viewer.issues.unresolved_issues=Unresolved Issues -component_viewer.issues_limit_reached=For usability reasons, only the {0} first issues will be fully displayed. Remaining issues will simply be underlined. -component_viewer.issues_limit_reached_tooltip={0}\n\nRefine your filter to be able to see the details of this issue. -component_viewer.line_actions=Line Actions -component_viewer.measure_section.complexity=Complexity -component_viewer.measure_section.documentation=Documentation -component_viewer.measure_section.filters=Filters -component_viewer.measure_section.integration_tests=Integration Tests -component_viewer.measure_section.issues=Issues -component_viewer.measure_section.overall=Overall -component_viewer.measure_section.rules=Rules -component_viewer.measure_section.severities=Severities -component_viewer.measure_section.size=Size -component_viewer.measure_section.sqale=SQALE -component_viewer.measure_section.structure=Structure -component_viewer.measure_section.tests=Tests -component_viewer.measure_section.test_cases=Test Cases -component_viewer.measure_section.unit_tests=Unit Tests -component_viewer.more_actions=More Actions -component_viewer.new_window=Open in New Window -component_viewer.no_component=The component has been removed or never existed. -component_viewer.no_coverage=No Coverage -component_viewer.no_issues=No Issues -component_viewer.open_in_workspace=Pin This File -component_viewer.scm.modified_lines=Modified Lines -component_viewer.show_all_measures=Show all measures -component_viewer.show_details=Show Measures -component_viewer.show_full_source=Show Full Source -component_viewer.show_raw_source=Show Raw Source -component_viewer.tests.duration=duration -component_viewer.tests.ordered_by=ordered by -component_viewer.tests.status=status -component_viewer.tests.test_name=name -component_viewer.time_changes=Time Changes -component_viewer.transition.coverage=Covered By -component_viewer.transition.covers=Covers -component_viewer.transition.duplication=Duplicated By -component_viewer.workspace.hide_workspace=Hide workspace -component_viewer.workspace.show_workspace=Show workspace -component_viewer.workspace.tooltip=Keeps track of history of navigation -component_viewer.workspace=Workspace -component_viewer.x_lines_are_covered={0} lines are covered configurable=Configurable configure=Configure confirm=Confirm -contact_admin=Please contact your administrator. copy=Copy -coverage.page=Coverage -coverage_viewer.by=by unit tests -coverage_viewer.integration_tests=Integration Tests -coverage_viewer.lines_covered_per_test=Covered lines -coverage_viewer.line_covered_by_x_tests=Line is covered by {0} tests -coverage_viewer.on_new_code=On new code -coverage_viewer.overall_tests=All Tests -coverage_viewer.per_test=Per test -coverage_viewer.select_test=Select a test -coverage_viewer.unit_tests=Unit Tests -coverage_viewer.x_covered_conditions={0} conditions are covered by tests create=Create created=Created -created_by=Created by critical=Critical customize=Customize -custom_measures.all_metrics_taken=There are already measures on all available custom metrics. -custom_measures.page.description=Update the values of custom metrics for this project. Changes will take effect at the project's next analysis. Custom metrics must be created at the global level. -custom_measures.page=Custom Measures -custom_measures.pending=Pending -custom_measures.pending_tooltip=The value will be integrated to project during next analysis. -dashboard.add_widget=Add widget -dashboard.available_dashboards=Available Dashboards -dashboard.back_to_dashboard=Back to dashboard -dashboard.cannot_render_widget_x=Can not render widget {0}: {1} -dashboard.configure_widgets=Configure widgets -dashboard.create_dashboard=Create dashboard -dashboard.create_global_dashboard=Create global dashboard -dashboard.create_project_dashboard=Create project dashboard -dashboard.default_dashboard=This dashboard is the default one and is displayed when clicking on "Overview". -dashboard.default_restored=Default dashboards are restored -dashboard.delete_confirm_title=Delete dashboard -dashboard.delete_dashboard=Delete dashboard -dashboard.do_you_want_to_delete_dashboard=Do you want to delete this dashboard? -dashboard.edit_dashboard=Edit dashboard -dashboard.error_create_existing_name=A dashboard already exists with the same name -dashboard.error_delete_default=This dashboard can't be deleted as long as it's defined as a default dashboard -dashboard.error_follow_existing_name=A dashboard already exists with the same name -dashboard.error_unshare_default=This dashboard can't be unshared as long as it's defined as a default dashboard -dashboard.global_dashboards.description=These dashboards are displayed to anonymous users or users who have not customized their dashboards. -dashboard.global_dashboards=Global Dashboards -dashboard.manage_dashboards=Manage Dashboards -dashboard.my_global_dashboards=My Global Dashboards -dashboard.my_project_dashboards=My Project Dashboards -dashboard.new_dashboard=New dashboard -dashboard.not_found=This dashboard was not found -dashboard.no_dashboard=No dashboard -dashboard.please_configure_the_widget_x=Please configure the widget <b>{0}</b>. -dashboard.project_dashboards.description=These dashboards are available to anonymous users or users who have not customized their dashboards. -dashboard.project_dashboards=Project Dashboards -dashboard.project_not_found=The requested project does not exist. Either it has never been analyzed successfully or it has been deleted. -dashboard.shared_dashboards.description=These dashboards can be added to default dashboards. -dashboard.shared_dashboards=Shared Dashboards -dashboard.update_dashboard=Update dashboard -dashboard.username.default=[SonarQube] date=Date days=Days -deactivate_all=Deactivate all -Dec=Dec -December=December default=Default -default_dashboards.page=Default Dashboards -default_error_message=The request cannot be processed. Try again later. -default_severity=Default severity -default_sort_on=Default sort on delete=Delete -deletion.page=Deletion -dependencies.not_used=Not used -dependencies.page=Dependencies -dependencies.search_help=Find out which projects depend on a given library.<br/>Search by group, artifact or name. E.g.: org.apache.struts, struts-core or Struts -dependencies.search_library=Search library -dependencies.select_library=Select library -dependencies.select_version=Select version -dependencies.used_by=Used by deprecated=Deprecated descending=Descending description=Description directories=Directories directory=Directory -disable_treemap=Disable treemap display=Display -Done=Done download_verb=Download -drilldown.drilldown_on=Drilldown on -drilldown.no_items_found=No items found -duplications.blocks=Blocks -duplications.block_was_duplicated_by_a_deleted_resource=This block was duplicated by a resource that has been deleted. -duplications.collapse=Collapse -duplications.details=Details -duplications.dups_found_on_deleted_resource=This file contains duplicated blocks with some deleted resources. This project should be reanalyzed to remove these obsolete duplicated blocks. -duplications.expand=Expand -duplications.file=File -duplications.from_line=From line -duplications.no_duplicated_block=No duplicated blocks. -duplications.number_of_lines=Nb Lines -duplications.old_format_should_reanalyze=This file contains duplications but a new analysis must be done in order to be able to display them. -duplications.page=Duplications duplications=Duplications -duration.day=a day -duration.days={0} days -duration.hour=about an hour -duration.hours={0} hours -duration.minute=about a minute -duration.minutes={0} minutes -duration.month=about a month -duration.months={0} months -duration.seconds=less than a minute -duration.year=about a year -duration.years={0} years edit=Edit -email_configuration.email_prefix.description=This prefix will be prepended to all outgoing email subjects. -email_configuration.email_prefix=Email prefix -email_configuration.from_address.description=Emails will come from this address. For example - "noreply@sonarsource.com". Note that server may ignore this setting (like does GMail). -email_configuration.from_address=From address -email_configuration.page=Email Settings -email_configuration.save_settings=Save Email Settings -email_configuration.saving_settings=Saving -email_configuration.settings_saved=Settings are saved. -email_configuration.smtp_host.description=For example "smtp.gmail.com". Leave blank to disable email sending. -email_configuration.smtp_host=SMTP host -email_configuration.smtp_password.description=Optional - as above, enter your password if you use authenticated SMTP. -email_configuration.smtp_password=SMTP password -email_configuration.smtp_port.description=Port number to connect with SMTP server. -email_configuration.smtp_port=SMTP port -email_configuration.smtp_secure_connection.description=Whether to use secure connection and its type. -email_configuration.smtp_secure_connection=Use secure connection -email_configuration.smtp_username.description=Optional - if you use authenticated SMTP, enter your username. -email_configuration.smtp_username=SMTP username -email_configuration.test.email_was_sent_to_x=Email was sent to {0} -email_configuration.test.message=Message -email_configuration.test.message_text=This is a test message from SonarQube at -email_configuration.test.send=Send Test Email -email_configuration.test.sending=Sending Test Email -email_configuration.test.subject=Subject -email_configuration.test.subject_text=Test Message from SonarQube -email_configuration.test.title=Test Configuration -email_configuration.test.to_address=To -email_configuration.test.to_address_required=You must provide address where to send test email -enable_treemap=Enable treemap -equals=Equals -errors.cant_be_empty={0} can't be empty -errors.is_already_used={0} has already been taken -errors.is_not_valid={0} is not valid -errors.is_too_long={0} is too long (maximum is {1} characters) -errors.is_too_short={0} is too short (minimum is {1} characters) -errors.type.notBoolean=Value '{0}' must be one of "true" or "false". -errors.type.notFloat=Value '{0}' must be an floating point number. -errors.type.notInOptions=Value '{0}' must be one of : {1}. -errors.type.notInteger=Value '{0}' must be an integer. -errors.type.notLong=Value '{0}' must be a long. -errors.type.notMetricLevel=Value '{0}' must be one of "OK", "WARN", "ERROR". -event.category.Alert=Quality Gate -event.category.All=All -event.category.Other=Other -event.category.Profile=Quality Profile -event.category.Version=Version -events.add_an_event=Add an event -events.name_required=Name (required) events=Events -event_categories.page=Event Categories false=False -false_positive=False positive -false_positives_only=False positives only favorite=Favorite -Feb=Feb -February=February file=File files=Files -filters.page=Filters filter_verb=Filter follow=Follow -Fr=Fr -Fri=Fri -Friday=Friday -full_source=Full source global=Global -global_permissions.admin.desc=Ability to perform all administration functions for the instance: global configuration and customization of default dashboards. -global_permissions.admin=Administer System -global_permissions.gateadmin.desc=Ability to perform any action on quality gates. -global_permissions.gateadmin=Administer Quality Gates -global_permissions.groups=Groups -global_permissions.page.description=Grant and revoke permissions to make changes at the global level. These permissions include editing quality profiles, sharing dashboards, and performing global system administration. -global_permissions.page=Global Permissions -global_permissions.permission=Permission -global_permissions.profileadmin.desc=Ability to perform any action on quality profiles. -global_permissions.profileadmin=Administer Quality Profiles -global_permissions.provisioning.desc=Ability to initialize a project so its settings can be configured before the first analysis. -global_permissions.provisioning=Create Projects -global_permissions.scan.desc=Ability to get all settings required to perform an analysis (including the secured settings like passwords) and to push analysis results to the SonarQube server. -global_permissions.scan=Execute Analysis -global_permissions.shareDashboard.desc=Ability to share dashboards, issue filters and measure filters. -global_permissions.shareDashboard=Share Dashboards And Filters -global_permissions.users=Users -greater_or_equals=Greater or equals -greater_than=Greater than help=Help -help_tips=Help tips hide=Hide identifier_abbreviated=Id inactive=Inactive including_abbreviated=incl. info=Info -inheritance=Inheritance -issue.add_tags=Add Tags -issue.assign.formlink=Assign -issue.assign.submit=Assign -issue.assign.to_me=to me -issue.authorLogin=Author: -issue.changelog.changed_to={0} changed to {1} -issue.changelog.field.actionPlan=Action Plan -issue.changelog.field.assignee=Assignee -issue.changelog.field.author=Author -issue.changelog.field.effort=Effort -issue.changelog.field.resolution=Resolution -issue.changelog.field.severity=Severity -issue.changelog.field.status=Status -issue.changelog.field.tags=Tags -issue.changelog.field.type=Type -issue.changelog.removed={0} removed -issue.changelog.was=was {0} -issue.comment.delete_confirm_button=Delete -issue.comment.delete_confirm_message=Do you want to delete this comment? -issue.comment.delete_confirm_title=Delete Comment -issue.comment.formlink=Comment -issue.comment.submit=Comment -issue.component_deleted=Removed -issue.creation_date=Created -issue.details=Details -issue.effort=Effort: -issue.filter_similar_issues=Filter Similar Issues -issue.manual.missing_rule=Missing rule -issue.no_tag=No tags -issue.remove_tags=Remove Tags -issue.reported_by=Reported by -issue.resolution.FALSE-POSITIVE.description=Issues that manual review determined were False Positives. Effort from these issues is ignored. -issue.resolution.FALSE-POSITIVE=False Positive -issue.resolution.FIXED.description=Issues that were corrected in code and reanalyzed. -issue.resolution.FIXED=Fixed -issue.resolution.REMOVED.description=Either the rule or the resource was changed (removed, relocated, parameters changed, etc.) so that analysis no longer finds these issues. -issue.resolution.REMOVED=Removed -issue.resolution.WONTFIX.description=Issues that are accepted in this context. They and their effort will be ignored. -issue.resolution.WONTFIX=Won't fix -issue.send_notifications=Send Notifications -issue.set_severity.submit=Change Severity -issue.set_severity=Change Severity -issue.set_type=Change Type -issue.status.CLOSED.description=Non-active and no longer requiring attention. -issue.status.CLOSED=Closed -issue.status.CONFIRMED.description=Manually examined and affirmed as an issue that needs attention. -issue.status.CONFIRMED=Confirmed -issue.status.OPEN.description=Untouched. This status is set automatically at issue creation. -issue.status.OPEN=Open -issue.status.REOPENED.description=Transitioned to and then back from some other status. -issue.status.REOPENED=Reopened -issue.status.RESOLVED.description=Manually marked as corrected. -issue.status.RESOLVED=Resolved -issue.transition.close.description= -issue.transition.close=Close -issue.transition.confirm.description=This issue has been reviewed and something should be done eventually to handle it. -issue.transition.confirm=Confirm -issue.transition.falsepositive.description=This issue can be ignored because it is due to a limitation of the analysis engine. Its effort won't be counted. -issue.transition.falsepositive=Resolve as false positive -issue.transition.reopen.description=This issue is not resolved, and should be reviewed again. -issue.transition.reopen=Reopen -issue.transition.resolve.description=This issue has been fixed in the code and is waiting for the next analysis to close it - or reopen it if it was not actually fixed. -issue.transition.resolve=Resolve as fixed -issue.transition.unconfirm.description=This issue should be reviewed again to decide what to do with it. -issue.transition.unconfirm=Unconfirm -issue.transition.wontfix.description=This issue can be ignored because the rule is irrelevant in this context. Its effort won't be counted. -issue.transition.wontfix=Resolve as won't fix -issue.transition=Transition -issue.type.BUG=Bug -issue.type.CODE_SMELL=Code Smell -issue.type.VULNERABILITY=Vulnerability -issue.unassign.submit=Unassign -issue.unresolved.description=Unresolved issues have not been addressed in any way. -issue.updated=Updated: -issue.x_effort={0} effort issue=Issue -issues.bulk_change=All Issues ({0}) -issues.bulk_change_selected=Selected Issues ({0}) -issues.facet.assignees=Assignee -issues.facet.authors=Author -issues.facet.createdAt.all=All -issues.facet.createdAt.last_month=Last month -issues.facet.createdAt.last_week=Last week -issues.facet.createdAt.last_year=Last year -issues.facet.createdAt.or=Or: -issues.facet.createdAt=New Issues -issues.facet.directories=Directory -issues.facet.fileUuids=File -issues.facet.issues=Issue Key -issues.facet.languages=Language -issues.facet.mode.effort=Effort -issues.facet.mode.issues=Issues -issues.facet.moduleUuids=Module -issues.facet.projectUuids=Project -issues.facet.resolutions=Resolution -issues.facet.rules=Rule -issues.facet.severities=Severity -issues.facet.statuses=Status -issues.facet.tags=Tag -issues.facet.types=Type -issues.found=Found -issues.home.authors=Authors -issues.home.my_filters=My Filters -issues.home.my_recent_issues=My Recent Issues -issues.home.new_search=New Search -issues.home.over_last_week=Over Last Week -issues.home.projects=Projects -issues.home.recent_issues=Recent Issues -issues.home.tags=Tags -issues.issues_limit_reached=For usability reasons, only the {0} issues are displayed. -issues.ordered_by=Ordered by -issues.page=Issues -issues.return_to_list=Return to List -issues.sort.assignee=Assignee -issues.sort.close_date=Close Date -issues.sort.creation_date=Creation Date -issues.sort.severity=Severity -issues.sort.status=Status -issues.sort.update_date=Update Date -issues.toggle_selection_tooltip=(De-)Select all currently visible issues issues=Issues -issues_drilldown.col.rule=Rule -issues_drilldown.col.severity=Severity -issues_drilldown.no_issue=No issue -issues_drilldown.page=Issues Drilldown -issues_viewer.issue_filter.false_positives=False positives -issues_viewer.issue_filter.unassigned=Not assigned -issue_bulk_change.comment.help=This comment will be applied only to issues that will effectively be modified -issue_bulk_change.error.empty_issues=Issues must not be empty -issue_bulk_change.error.need_one_action=At least one action must be provided -issue_bulk_change.form.title=Change {0} issues -issue_bulk_change.max_issues_reached=As too many issues have been selected, only the first {0} issues will be updated. -issue_bulk_change.x_issues={0} issues -issue_filter.are_you_sure_want_delete_filter_x=Are you sure that you want to delete the filter "{0}"? -issue_filter.copy_filter=Copy Filter -issue_filter.criteria.assignee=Assignee -issue_filter.criteria.created=Created -issue_filter.criteria.created_after=Created since -issue_filter.criteria.created_at=Created at -issue_filter.criteria.created_before=Created before -issue_filter.criteria.date_format=year-month-day (2013-01-31) -issue_filter.criteria.project=Project -issue_filter.criteria.resolution=Resolution -issue_filter.criteria.rule=Rule -issue_filter.criteria.severity=Severity -issue_filter.criteria.status=Status -issue_filter.delete_confirm_title=Delete Filter -issue_filter.edit_filter=Edit Filter -issue_filter.favourite_filters=Favourite Filters -issue_filter.filter_list=Issues Filters -issue_filter.form.description=Description -issue_filter.form.name=Name -issue_filter.form.owner=Owner -issue_filter.form.share=Shared with all users -issue_filter.header.assignee=Assignee -issue_filter.header.creation_date=Created -issue_filter.header.resolution=Resolution -issue_filter.header.update_date=Updated -issue_filter.manage.my_filters=My Issues Filters -issue_filter.manage.shared_filters=Shared Issues Filters -issue_filter.max_results_reached=Only the first {0} issues matching the search criteria have been retrieved. Add some additional criteria to get fewer results to be able to sort this list. -issue_filter.more_criteria=+ More Criteria -issue_filter.new_search=New Search -issue_filter.no_filters=No filters -issue_filter.no_issues=No Issues -issue_filter.no_result.help=Status of the related issues may have changed since the last analysis. -issue_filter.no_result=No matching issues found. -issue_filter.private=Private -issue_filter.save_filter=Save Filter -issue_filter.shared=Shared -issue_filter.shared_with_all_users=Shared with all users -issue_filter.sharing=Sharing -it_coverage_viewer.by=by integration tests -Jan=Jan -January=January -Jul=Jul -July=July -Jun=Jun -June=June +inheritance=Inheritance key=Key language=Language -layout.configuration=Project Configuration -layout.dashboards=Dashboards -layout.home=Home -layout.login=Log in -layout.logout=Log out -layout.measures=Measures -layout.permalink=Permalink -layout.print=Print -layout.projects=Projects -layout.recent_projects=Recent Projects -layout.settings=Administration -layout.sonar.slogan=Embrace Quality -layout.user_panel.my_profile=My profile -less_or_equals=Less or equals -less_than=Less than library=Library line_number=Line Number links=Links load_verb=Load login=Login major=Major -manage=Manage manual=Manual -manual_measures.add_measure=Add Manual Measure -manual_measures.col.author=Author -manual_measures.col.date=Date -manual_measures.col.description=Description -manual_measures.col.domain=Domain -manual_measures.col.last_change=Last change -manual_measures.col.last_change_label=By {0} at {1} -manual_measures.col.metric=Metric -manual_measures.col.operations=Operations -manual_measures.col.value=Value -manual_measures.create_measure=Create Manual Measure -manual_measures.delete_measure.desc=Are you sure that you want to delete manual measure "{0}"? -manual_measures.delete_measure=Delete Manual Measure -manual_measures.edit_measure=Edit Manual Measure: {0} -manual_measures.manage_metrics=Manage Metrics -manual_measures.no_more_available_metric=All available manual metrics have a measure. -manual_measures.page.description=Update the values of manual metrics for this project. Changes will take effect at the project's next analysis. Manual Metrics must be created at the global level. -manual_measures.page=Manual Measures -manual_measures.pending_message=Pending measures are marked with orange box. Their values will be integrated to project during next analysis. -manual_measures.save_and_add_button=Save & Add new -manual_measures.save_button=Save -manual_measures.to_define_new_manual_metric_il_require=You can define new manual metrics if required. -manual_metrics.add_manual_metric=Add New Manual Metric -manual_metrics.delete_manual_metric=Delete Manual Metric -manual_metrics.delete_manual_metric_message=Are you sure that you want to delete manual metric "{0}"? \n Warning: all the associated manual measures will be deleted. -manual_metrics.page.description=These metrics are available for all projects. Manual measures can be set at project level via the configuration interface. -manual_metrics.page=Manual Metrics -manual_rules.add_manual_rule=Add Manual Rule -manual_rules.should_provide_real_description=Rule created on the fly. A description should be provided. -Mar=Mar -March=March -markdown.helplink=Markdown Help max=Max max_items_reached=Only the first {0} components are displayed max_results_reached=Only the first {0} results are displayed -May=May me=Me +<<<<<<< HEAD +min=Min +minor=Minor +more=More +more_actions=More Actions +moreCriteria=+ More Criteria +name=Name +name_too_long_x=Name is too long (maximum is {0} characters) +navigation=Navigation +never=Never +none=None +unassigned=Not assigned +======= measures.select_components=Please select "Components", "Components of" or "Favorites only" filter to see results. measure_filter.abbr.date=Last Analysis measure_filter.abbr.description=Description @@ -1354,6 +656,7 @@ no_lines_match_your_filter_criteria=No lines match your filter criteria. no_results=No results Oct=Oct October=October +>>>>>>> branch-5.6 off=Off on=On open=Open @@ -1361,6 +664,11 @@ open_verb=Open operations=Operations optional=Optional order=Order +<<<<<<< HEAD +owner=Owner +package=Package +packages=Packages +======= overall_coverage_viewer.by=by all tests overview.complexity_tooltip.file={0} files have complexity around {1} overview.complexity_tooltip.function={0} functions have complexity around {1} @@ -1417,11 +725,18 @@ paging_first=First paging_last=Last paging_next=Next paging_previous=Previous +>>>>>>> branch-5.6 parameters=Parameters password=Password path=Path permalink=Permanent Link permalinks=Permalinks +<<<<<<< HEAD +plugin=Plugin +project=Project +projects=Projects +quality_profile=Quality Profile +======= permissions.page=Permissions permission_template.create_template=Create permission_template.default_for=Default for {0} @@ -1764,209 +1079,54 @@ quality_profiles.x_profiles={0} Profiles quality_profiles.x_projects={0} projects quality_profiles.x_rules_have_different_configuration={0} rules have a different configuration quality_profiles.x_rules_only_in={0} rules only in +>>>>>>> branch-5.6 raw=Raw recent_history=Recent History refresh=Refresh reload=Reload remove=Remove -remove_column=Remove this column rename=Rename reset_verb=Reset resolution=Resolution -resource_viewer.resource_deleted=This resource has been deleted. restore=Restore result=Result results=Results -results_not_display_due_to_security=Due to security settings, some results are not being displayed. +x_results={0} results review=Review reviews=Reviews review_verb=Review -roles.page.description2=Grant and revoke project-level permissions. Permissions can be granted to groups or individual users. -roles.page.description=Grant and revoke project-level permissions to Browse (view a project's metrics), See Source Code, and Administer individual projects. Permissions can be granted to groups or individual users. -roles.page=Project Permissions rule=Rule -rules.identification=Identification -rules.more_about_rule_on_profile_x=More about this rule on profile "{0}" -rules.not_found=The rule "{0}" does not exist -rules.parameters=Parameters -rules.status.beta=Beta -rules.status.deprecated=Deprecated -rules.status.ready=Ready rules=Rules -Sa=Sa -Sat=Sat -Saturday=Saturday save=Save -save_and_preview=Save & Preview save_as=Save As -search.duration=({0} seconds) -search.results=results -search.shortcut=Press S to quickly open search bar search_verb=Search see_all=See All -select2.noMatches=No matches -select2.searching=Searching... -select2.tooShort=Please enter at least {0} characters select_all=Select all -select_a_metric=Select a metric select_verb=Select -Sep=Sep -September=September -server_id_configuration.bad_key=The ID is not valid anymore. Please check the organisation and the IP address. -server_id_configuration.does_not_match_organisation_pattern=Organisation does not match the required pattern. -server_id_configuration.fields_cannot_be_blank=Organisation and IP address cannot be blank. -server_id_configuration.generate_button=Generate ID -server_id_configuration.generating_button=Generating ID... -server_id_configuration.generation_error=Organisation and/or IP address are not valid. -server_id_configuration.information=The Server ID is a unique identifier of this SonarQube instance. It is used for example to obtain a license key for the SonarSource's commercial plugins. Two fields have to be provided to generate the ID : organisation name and one of the IP addresses of the machine that hosts this server. There is no need to restart the server after generating a new server ID. -server_id_configuration.ip.desc=A server ID is linked to the IP address of the hosting machine that runs SonarQube. If the server IP address was to change, the server ID will have to be regenerated. The valid addresses are : -server_id_configuration.ip.title=Fixed IP Address -server_id_configuration.organisation.desc=Name of the organisation -server_id_configuration.organisation.pattern=Only letters, digits and whitespaces are allowed. -server_id_configuration.organisation.title=Organisation -session.flash_notice.authentication_failed=Authentication failed. -session.flash_notice.logged_out=You have been logged out. -sessions.confirm_password=Confirm password -sessions.log_in=Log in -sessions.new_account=Not a member? <a href="{0}" tabindex="-1">Sign up</a> for an account. -sessions.old_account=<a href="{0}" tabindex="-1">Log in</a> if you already have an account. -sessions.remember_me=Remember me on this computer -sessions.sign_up=Sign up -settings.add=Add value -settings.page.description=Edit global settings for this SonarQube instance. -settings.page=General Settings -settings.save_category=Save {0} Settings -set_as_default=Set as Default -severity.BLOCKER.description=Must be fixed immediately. -severity.BLOCKER=Blocker -severity.CRITICAL.description=Must be reviewed immediately and fixed soon. -severity.CRITICAL=Critical -severity.INFO.description=Neither a bug nor a quality flaw. Just a finding. -severity.INFO=Info -severity.MAJOR.description=High potential for significant to moderate impact. -severity.MAJOR=Major -severity.MINOR.description=Potential for moderate to minor impact. -severity.MINOR=Minor +set=Set severity=Severity severity_abbreviated=Se. shared=Shared -shared_by=Shared by -shortcuts.modal_title=Shortcuts -shortcuts.section.code.search=search components in the project scope -shortcuts.section.code=Code Page -shortcuts.section.global.search=quickly open search bar -shortcuts.section.global.shortcuts=open this window -shortcuts.section.global=Global -shortcuts.section.issue.assign=assign issue -shortcuts.section.issue.assign_to_me=assign issue to the current user -shortcuts.section.issue.change_severity=change severity of issue -shortcuts.section.issue.change_tags=change tags of issue -shortcuts.section.issue.comment=comment issue -shortcuts.section.issue.do_transition=do an issue transition -shortcuts.section.issue.select=select an issue -shortcuts.section.issue.submit_comment=submit comment -shortcuts.section.issues.navigate_between_issues=navigate between issues -shortcuts.section.issues.open_details=go from the list of issues to the source code -shortcuts.section.issues.return_to_list=return back to the list -shortcuts.section.issues=Issues Page -shortcuts.section.rules.activate=activate selected rule -shortcuts.section.rules.deactivate=deactivate selected rule -shortcuts.section.rules.navigate_between_rules=navigate between rules -shortcuts.section.rules.open_details=go from the list of rules to the rule details -shortcuts.section.rules.return_to_list=return back to the list -shortcuts.section.rules=Rules Page -show_less=Show Less -show_more=Show More show_verb=Show -sidebar.projects=Projects -sidebar.project_settings=Configuration -sidebar.security=Security -sidebar.system=System -sidebar.tools=Tools -since_previous_analysis.short=\u0394 last -since_previous_analysis=since previous analysis -since_previous_analysis_detailed.short=\u0394 last ({0}) -since_previous_analysis_detailed=since previous analysis ({0}) -since_previous_version.short=\u0394 version -since_previous_version=since previous version -since_previous_version_detailed.short=\u0394 version ({0}) -since_previous_version_detailed=since previous version ({0} - {1}) -since_previous_version_with_only_date=since previous version ({0}) -since_version.short={0} -since_version=since version {0} -since_version_detailed.short={0} ({1}) -since_version_detailed=since version {0} ({1}) -since_x.short={0} -since_x=since {0} +x_of_y_shown={0} of {1} shown size=Size -source.page=Source -source_viewer.conditions=conditions -source_viewer.it.covered=Covered by integration tests -source_viewer.it.not_covered=Not covered by integration tests -source_viewer.loading_more_code=Loading More Code... -source_viewer.load_more_code=Load More Code -source_viewer.tooltip.duplicated_block=Duplicated block. Click for details. -source_viewer.tooltip.duplicated_line=This line is duplicated. Click to see duplicated blocks. -source_viewer.tooltip.it.covered=Fully covered by integration tests. Click for details. -source_viewer.tooltip.it.partially-covered=Partially covered by integration tests. Click for details. -source_viewer.tooltip.it.uncovered=Not covered by integration tests. -source_viewer.tooltip.new_code=New {0}. -source_viewer.tooltip.ut.covered=Fully covered by unit tests. Click for details. -source_viewer.tooltip.ut.partially-covered=Partially covered by unit tests. Click for details. -source_viewer.tooltip.ut.uncovered=Not covered by unit tests. -source_viewer.ut.covered=Covered by unit tests -source_viewer.ut.not_covered=Not covered by unit tests status=Status status_abbreviated=St. -Su=Su sub_project=Sub-project sub_projects=Sub-projects sub_view=Sub-view sub_views=Sub-views -Sun=Sun -Sunday=Sunday -system.log_level.warning=Current level has performance impacts, please make sure to get back to INFO level once your investigation is done. Please note that when you restart the server, the level will automatically be reset to INFO. -system_info.page=System Info table=Table technical_debt=Technical Debt template=Template -test_viewer.collapse=collapse -test_viewer.covered_lines=Covered Lines -test_viewer.duration=Duration -test_viewer.errors=Errors -test_viewer.expand=expand -test_viewer.failures=Failures -test_viewer.files_covered_by=Files covered by <b>{0}</b> ({1}) -test_viewer.skipped=skipped -test_viewer.tests=Tests -test_viewer.tests_covering=Tests covering <b>{0}</b> on line <b>{1}</b> -test_viewer.unit_test_name=Unit test name -Th=Th the_end=The End -Thu=Thu -Thursday=Thursday -timemachine.page=Time Machine -time_changes=Time changes -time_machine.compare_on_chart=Compare on chart -time_machine.distributions=Distributions -time_machine.distribution_chart=Distribution chart -time_machine.set_as_default_for_all_users=Set as default (for all users) -time_machine.show_date=Show date -time_machine.show_event=Show event title=Title -to.downcase=to to=To -Today=Today +to.downcase=to total=Total -treemap.all_measures_undefined=The widget cannot be displayed, because all components don't have the size measure. -treemap.open_dashboard=Open Dashboard treemap=Treemap true=True -Tu=Tu -Tue=Tue -Tuesday=Tuesday type=Type -unassigned=Not assigned unfollow=Unfollow unit_test=Unit test unit_tests=Unit tests @@ -1974,104 +1134,993 @@ unknown=Unknown unresolved=Unresolved unselect_all=Unselect all unselect_verb=Unselect -unset_as_default=Unset as Default updated=Updated -update_center.page.description=Install, uninstall and delete plugins. You can also download SonarQube updates from the System Updates tab on this page. -update_center.page=Update Center -update_center.status.COMPATIBLE=Compatible -update_center.status.DEPS_REQUIRE_SYSTEM_UPGRADE=Some of dependencies requires system update -update_center.status.INCOMPATIBLE=Incompatible -update_center.status.REQUIRES_SYSTEM_UPGRADE=Requires system update -update_key.are_you_sure_to_rename_x=Are you sure you want to rename "{0}", as well as all its modules and resources? -update_key.bulk_change_description=The bulk update allows to replace a part of the current key(s) by another string on the current project and all its submodules - if applicable. -update_key.bulk_update=Bulk Update -update_key.bulk_update_confirmation_page=Do you really want to perform the bulk update on project keys? -update_key.bulk_update_impossible=Bulk update can not be performed -update_key.by=By -update_key.by_example=Ex.: "com.myNewCompany" -update_key.cant_update_because_duplicate_keys=The replacement of "{0}" by "{1}" is impossible as it would result in duplicate keys (in red below): -update_key.cant_update_x_because_resource_already_exist_with_key_x="{0}" can not be renamed because "{1}" is the key of an existing resource. The update has been canceled. -update_key.current_key_for_project_x_is_x=The key of the "{0}" project is currently "<b>{1}</b>". -update_key.duplicate_key=Duplicate key -update_key.error_occured_while_renaming_key_of_x=An error occurred while renaming the key "{0}": {1} -update_key.fieds_cant_be_blank_for_bulk_update=The two fields can not be blank for the bulk update. -update_key.fine_grained_key_update=Fine-grained Update -update_key.keys_will_be_updated_as_follows=The resources will be updated as follows (updated keys in bold): -update_key.key_updated=The key has successfully been updated for all required resources. -update_key.new_key=New key -update_key.new_key_cant_be_blank_for_x=The new key can not be blank for "{0}". -update_key.no_key_to_update=No key contains the string to replace ("{0}"). -update_key.old_key=Old key -update_key.page.description=Edit the keys of a project and/or its modules. Key changes must be made here BEFORE analyzing the project with the new keys, otherwise the analysis will simply create another project with the new key, rather than updating the existing project. -update_key.page=Update Key -update_key.rename=Rename -update_key.replace=Replace -update_key.replace_example=Ex.: "org.myCompany" -update_key.reset=Reset -update_key.same_key_for_x=The new key is the same as the original one ("{0}"), nothing has been updated. update_verb=Update updating=Updating -user.add_scm_account=Add SCM account -user.bad_login=Use only letters, numbers, and .-_@ please. -user.login_or_email_used_as_scm_account=Login and email are automatically considered as SCM accounts -user.password_cant_be_changed_on_external_auth=Password cannot be changed when external authentication is used -user.password_doesnt_match_confirmation=Password doesn't match confirmation. -user.reactivated=The user '{0}' has been reactivated. -user.scm_account_already_used=The scm account '{0}' is already used by user(s) : '{1}' user=User -users.page.description=Create and administer individual users. -users.page=Users -user_groups.anyone.description=Anybody (authenticated or not) who browses the application belongs to this group -user_groups.page.description=Create and administer groups of users. -user_groups.page=Groups value=Value variation=Variation version=Version view=View views=Views -view_projects.page=Projects violations=Violations -We=We -Wed=Wed +with=With + + + +#------------------------------------------------------------------------------ +# +# GENERIC EXPRESSIONS, sorted alphabetically +# +#------------------------------------------------------------------------------ + +activate_all=Activate all +add_a_column=Add a column +added_over_x_days=Added over {0} days +added_since=Added since {0} +added_since_previous_analysis=Added since previous analysis +added_since_previous_analysis_detailed=Added since previous analysis ({0}) +added_since_previous_version=Added since previous version +added_since_previous_version_detailed=Added since previous version ({0}) +added_since_version=Added since version {0} +all_violations=All violations +all_issues=All issues +apply_template +are_you_sure=Are you sure? +assigned_to=Assigned to +bulk_change=Bulk Change +bulleted_point=Bulleted point +check_project=Check project +coding_rules=Rules +click_to_add_to_favorites=Click to add to favorites +click_to_remove_from_favorites=Click to remove from favorites +contact_admin=Please contact your administrator. +created_by=Created by +deactivate_all=Deactivate all +default_error_message=The request cannot be processed. Try again later. +default_severity=Default severity +default_sort_on=Default sort on +disable_treemap=Disable treemap +edit_permissions=Edit Permissions +enable_treemap=Enable treemap +equals=Equals +false_positive=False positive +false_positives_only=False positives only +full_source=Full source +greater_or_equals=Greater or equals +greater_than=Greater than +help_tips=Help tips +less_or_equals=Less or equals +less_than=Less than +manage=Manage +move_left=Move left +move_right=Move right +new_issues=New issues +new_violations=New violations +new_window=New window +no_data=No data +no_lines_match_your_filter_criteria=No lines match your filter criteria. +no_results=No results +no_results_search=No results. Try to modify the search query to get some results. +not_authorized=You are not authorized. +not_authorized_to_access_project=You are not authorized to access to this '{0}' project +over_x_days=over {0} days +over_x_days.short={0} days +over_x_days_detailed=over {0} days ({1}) +over_x_days_detailed.short={0} days ({1}) +page_size=Page size +paging_first=First +paging_last=Last +paging_next=Next +paging_previous=Previous +project_name=Project name +remove_column=Remove this column +results_not_display_due_to_security=Due to security settings, some results are not being displayed. +save_and_preview=Save & Preview +select_a_metric=Select a metric +set_as_default=Set as Default +unset_as_default=Unset as Default +shared_by=Shared by +show_less=Show Less +show_more=Show More +since_x=since {0} +since_x.short={0} +since_previous_analysis=since previous analysis +since_previous_analysis_detailed=since previous analysis ({0}) +since_previous_analysis.short=\u0394 last +since_previous_analysis_detailed.short=\u0394 last ({0}) +since_version=since version {0} +since_version.short={0} +since_version_detailed=since version {0} ({1}) +since_version_detailed.short={0} ({1}) +since_previous_version=since previous version +since_previous_version.short=\u0394 version +since_previous_version_detailed=since previous version ({0} - {1}) +since_previous_version_with_only_date=since previous version ({0}) +since_previous_version_detailed.short=\u0394 version ({0}) +time_changes=Time changes +work_duration.x_days={0}d +work_duration.x_hours={0}h +work_duration.x_minutes={0}min +work_duration.about=~ {0} + + +#------------------------------------------------------------------------------ +# +# CALENDAR +# +#------------------------------------------------------------------------------ + +Done=Done +Prev=Prev +Next=Next +Today=Today +January=January +February=February +March=March +April=April +May=May +June=June +July=July +August=August +September=September +October=October +November=November +December=December +Jan=Jan +Feb=Feb +Mar=Mar +Apr=Apr +Jun=Jun +Jul=Jul +Aug=Aug +Sep=Sep +Oct=Oct +Nov=Nov +Dec=Dec +Sunday=Sunday +Monday=Monday +Tuesday=Tuesday Wednesday=Wednesday -widget.alerts.description=Displays the project's quality gate status. -widget.alerts.errors=The project failed the quality gate on the following conditions:\u00a0 -widget.alerts.missing_metric=Some information regarding the status of the quality gate is missing. A fresh analysis of the project is needed to reload this information. +Thursday=Thursday +Friday=Friday +Saturday=Saturday +Sun=Sun +Mon=Mon +Tue=Tue +Wed=Wed +Thu=Thu +Fri=Fri +Sat=Sat +Su=Su +Mo=Mo +Tu=Tu +We=We +Th=Th +Fr=Fr +Sa=Sa + + + +#------------------------------------------------------------------------------ +# +# RESOURCE QUALIFIERS +# +#------------------------------------------------------------------------------ + +qualifier.TRK=Project +qualifier.BRC=Sub-project +qualifier.DIR=Directory +qualifier.PAC=Package +qualifier.VW=View +qualifier.SVW=Sub-view +qualifier.FIL=File +qualifier.CLA=File +qualifier.UTS=Unit Test File +qualifier.DEV=Developer + +qualifier.configuration.TRK=Project Configuration +qualifier.configuration.BRC=Sub-project Configuration +qualifier.configuration.DIR=Directory Configuration +qualifier.configuration.PAC=Package Configuration +qualifier.configuration.VW=View Configuration +qualifier.configuration.SVW=Sub-view Configuration +qualifier.configuration.FIL=File Configuration +qualifier.configuration.CLA=File Configuration +qualifier.configuration.UTS=Unit Test File Configuration +qualifier.configuration.DEV=Developer Configuration + +qualifiers.TRK=Projects +qualifiers.BRC=Sub-projects +qualifiers.DIR=Directories +qualifiers.PAC=Packages +qualifiers.VW=Views +qualifiers.SVW=Sub-views +qualifiers.FIL=Files +qualifiers.CLA=Files +qualifiers.UTS=Unit Test Files +qualifiers.DEV=Developers + +qualifiers.all.TRK=All Projects +qualifiers.all.VW=All Views +qualifiers.all.DEV=All Developers + +qualifiers.new.TRK=New Project +qualifiers.new.VW=New View +qualifiers.new.DEV=New Developer + +qualifiers.delete.TRK=Delete Project +qualifiers.delete.VW=Delete View +qualifiers.delete.DEV=Delete Developer + +qualifiers.delete_confirm.TRK=Do you want to delete this project? +qualifiers.delete_confirm.VW=Do you want to delete this view? +qualifiers.delete_confirm.DEV=Do you want to delete this developer? + +qualifiers.create.TRK=Create Project +qualifiers.create.VW=Create View +qualifiers.create.DEV=Create Developer + +qualifiers.update.VW=Update View +qualifiers.update.DEV=Update Developer + +#------------------------------------------------------------------------------ +# +# PROJECT LINKS +# +#------------------------------------------------------------------------------ + +project_links.homepage=Home +project_links.ci=Continuous integration +project_links.issue=Bug Tracker +project_links.scm=Sources +project_links.scm_ro=Read-only connection +project_links.scm_dev=Developer connection + +project_links.create_new_project_link=Create New Project Link +project_links.delete_project_link=Delete Project Link +project_links.are_you_sure_to_delete_x_link=Are you sure you want to delete the "{0}" link? +project_links.name=Name +project_links.url=URL + + +#------------------------------------------------------------------------------ +# +# EVENT CATEGORIES +# +#------------------------------------------------------------------------------ + +event.category.All=All +event.category.Version=Version +event.category.Alert=Quality Gate +event.category.Profile=Quality Profile +event.category.Other=Other + + +#------------------------------------------------------------------------------ +# +# LAYOUT +# +#------------------------------------------------------------------------------ + +layout.home=Home +layout.login=Log in +layout.logout=Log out +layout.measures=Measures +layout.settings=Administration +layout.print=Print +layout.permalink=Permalink +layout.sonar.slogan=Embrace Quality +layout.dashboards=Dashboards +layout.configuration=Project Configuration +layout.projects=Projects +layout.recent_projects=Recent Projects +layout.user_panel.my_profile=My profile + +sidebar.projects=Projects +sidebar.project_settings=Configuration +sidebar.security=Security +sidebar.system=System +sidebar.tools=Tools + + +#------------------------------------------------------------------------------ +# +# ADMIN PAGE TITLES and descriptions +# +#------------------------------------------------------------------------------ + +all_rules.page=All Rules +analysis_reports.page=Project Computation +coding_rules.page=Rules +global_permissions.page=Global Permissions +global_permissions.page.description=Grant and revoke permissions to make changes at the global level. These permissions include editing quality profiles, sharing dashboards, and performing global system administration. +manual_metrics.page=Manual Metrics +manual_metrics.page.description=These metrics are available for all projects. Manual measures can be set at project level via the configuration interface. +manual_metrics.add_manual_metric=Add New Manual Metric +manual_metrics.delete_manual_metric=Delete Manual Metric +manual_metrics.delete_manual_metric_message=Are you sure that you want to delete manual metric "{0}"? \n Warning: all the associated manual measures will be deleted. +manual_measures.page=Manual Measures +manual_measures.page.description=Update the values of manual metrics for this project. Changes will take effect at the project's next analysis. Manual Metrics must be created at the global level. +custom_measures.page=Custom Measures +custom_measures.page.description=Update the values of custom metrics for this project. Changes will take effect at the project's next analysis. Custom metrics must be created at the global level. +roles.page=Project Permissions +roles.page.description2=Grant and revoke project-level permissions. Permissions can be granted to groups or individual users. +project_settings.page=General Settings +project_settings.page.description=Edit project settings. +project_links.page=Links +project_links.page.description=Edit some links associated with this project. +project_history.page=History +project_history.page.description=Edit snapshot metadata, or delete snapshots from the project history. +project_roles.page=Project Permissions +project_roles.page.description=Grant and revoke permissions to this project to Browse (view a project's metrics), See Source Code, and Administer. Permissions can be granted to groups or individual users. +project_roles.page.description2=Grant and revoke project-level permissions. Permissions can be granted to groups or individual users. +settings.page=General Settings +settings.page.description=Edit global settings for this SonarQube instance. +system_info.page=System Info +users.page=Users +users.page.description=Create and administer individual users. +user_groups.page=Groups +user_groups.page.description=Create and administer groups of users. +user_groups.anyone.description=Anybody (authenticated or not) who browses the application belongs to this group +update_center.page=Update Center +update_center.page.description=Install, uninstall and delete plugins. You can also download SonarQube updates from the System Updates tab on this page. +project_quality_profiles.page=Quality Profiles +project_quality_profiles.page.description=Choose which profile is associated with this project on a language-by-language basis. (Note that you will only need to select profiles for multiple languages for multi-language projects.) +project_quality_gate.page=Quality Gate +project_quality_gate.page.description=Choose which quality gate is associated with this project. +bulk_deletion.page=Bulk Deletion +bulk_deletion.page.description=Use this page to delete multiple projects at once. +update_key.page=Update Key +update_key.page.description=Edit the keys of a project and/or its modules. Key changes must be made here BEFORE analyzing the project with the new keys, otherwise the analysis will simply create another project with the new key, rather than updating the existing project. +deletion.page=Deletion +project_deletion.page.description=Delete this project from SonarQube. The operation cannot be undone. +provisioning.page=Provisioning +provisioning.page.description=Use this page to initialize projects if you would like to configure them before the first analysis. Once a project is provisioned, you have access to perform all project configurations on it. + +#------------------------------------------------------------------------------ +# +# OTHER PAGE TITLES +# +#------------------------------------------------------------------------------ + +clouds.page=Clouds +overview.page=Overview +code.page=Code +components.page=Components +coverage.page=Coverage +default_dashboards.page=Default Dashboards +dependencies.page=Dependencies +duplications.page=Duplications +email_configuration.page=Email Settings +event_categories.page=Event Categories +filters.page=Filters +my_profile.page=My Profile +permissions.page=Permissions +quality_profiles.page=Quality Profiles +quality_gates.page=Quality Gates +issues.page=Issues +issues_drilldown.page=Issues Drilldown +source.page=Source +timemachine.page=Time Machine +comparison.page=Compare +view_projects.page=Projects + + +#------------------------------------------------------------------------------ +# +# ASYNC PROCESS +# +#------------------------------------------------------------------------------ + +process.still_working=Still Working... +process.fail=Failed + + +#------------------------------------------------------------------------------ +# +# SESSION +# +#------------------------------------------------------------------------------ + +sessions.log_in=Log in +sessions.new_account=Not a member? <a href="{0}" tabindex="-1">Sign up</a> for an account. +sessions.confirm_password=Confirm password +sessions.sign_up=Sign up +sessions.old_account=<a href="{0}" tabindex="-1">Log in</a> if you already have an account. +session.flash_notice.authentication_failed=Authentication failed. +session.flash_notice.logged_out=You have been logged out. + +#------------------------------------------------------------------------------ +# +# MEASURES & MEASURE FILTERS +# +#------------------------------------------------------------------------------ +measures.select_components=Please select "Components", "Components of" or "Favorites only" filter to see results. +measure_filter.delete_column=Delete column +measure_filter.no_filters=No filters +measure_filter.display_as=Display as +measure_filter.shared_with_all_users=Shared with all users +measure_filter.private=Private +measure_filter.manage.shared_filters=Shared Measures Filters +measure_filter.manage.my_filters=My Measures Filters +measure_filter.criteria.what=What? Projects, files... +measure_filter.criteria.components=Components +measure_filter.criteria.age=Age +measure_filter.criteria.date=Date +measure_filter.criteria.only_favorites=Favorites only +measure_filter.criteria.key=Key +measure_filter.criteria.name=Name +measure_filter.criteria.key_contains=Key contains +measure_filter.criteria.name_contains=Name contains +measure_filter.criteria.language=Language +measure_filter.criteria.last_analysis=Last analysis +measure_filter.criteria.metric=Metric +measure_filter.criteria.metric.not_set=Not set +measure_filter.criteria.project=Project +measure_filter.criteria.alert=Quality Gate +measure_filter.criteria.alert.error=Error +measure_filter.criteria.alert.warn=Warning +measure_filter.criteria.alert.ok=Ok +measure_filter.criteria.from_date=Inspected since +measure_filter.criteria.to_date=Inspected before +measure_filter.criteria.date_format=year-month-day (2013-01-31) +measure_filter.criteria.age.more_than=Inspected more than +measure_filter.criteria.age.within_last=Inspected within the last +measure_filter.criteria.age.days_ago=days ago +measure_filter.criteria.age.days=days +measure_filter.criteria.components_of=Components of +measure_filter.criteria.components_of_project=Components of project +measure_filter.new_search=New Search +measure_filter.favourite_filters=Favourite Filters +measure_filter.more_criteria=+ More Criteria +measure_filter.languages=Languages +measure_filter.filter_list=Measures Filters +measure_filter.col.date=Last Analysis +measure_filter.col.description=Description +measure_filter.col.key=Key +measure_filter.col.links=Links +measure_filter.col.name=Name +measure_filter.col.short_name=Short Name +measure_filter.col.version=Version +measure_filter.col.project_creation_date=First Analysis +measure_filter.abbr.date=Last Analysis +measure_filter.abbr.description=Description +measure_filter.abbr.key=Key +measure_filter.abbr.links=Links +measure_filter.abbr.name=Name +measure_filter.abbr.short_name=Name +measure_filter.abbr.version=Version +measure_filter.abbr.project_creation_date=First Analysis +measure_filter.missing_name=Name is missing +measure_filter.name_too_long=Name is too long +measure_filter.sharing=Sharing +measure_filter.delete_confirm_title=Delete Filter +measure_filter.are_you_sure_want_delete_filter_x=Are you sure that you want to delete the filter "{0}"? +measure_filter.title_shared_filters=Shared Filters +measure_filter.key_contains=Key contains +measure_filter.name_contains=Name contains +measure_filter.manage_filters=Manage Filters +measure_filter.display.list=List +measure_filter.display.treemap=Treemap +measure_filter.list.change=Change Columns +measure_filter.treemap.change=Change Treemap +measure_filter.add_column_button=Add Column +measure_filter.widget.unknown_filter_warning=This widget is configured to display a measure filter that does not exist anymore. +measure_filter.error.UNKNOWN=Unexpected error. Please contact the administrator. +measure_filter.error.TOO_MANY_RESULTS=Too many results. Please refine your search. +measure_filter.error.VALUE_SHOULD_BE_A_NUMBER=Value used for metric should be a number. + + +#------------------------------------------------------------------------------ +# +# ISSUES +# +#------------------------------------------------------------------------------ + +issue.add_tags=Add Tags +issue.remove_tags=Remove Tags +issue.no_tag=No tags +issue.assign.formlink=Assign +issue.assign.submit=Assign +issue.unassign.submit=Unassign +issue.assign.to_me=to me +issue.comment.formlink=Comment +issue.comment.submit=Comment +issue.comment.delete_confirm_title=Delete Comment +issue.comment.delete_confirm_message=Do you want to delete this comment? +issue.comment.delete_confirm_button=Delete +issue.details=Details +issue.send_notifications=Send Notifications +issue.transition=Transition +issue.transition.confirm=Confirm +issue.transition.confirm.description=This issue has been reviewed and something should be done eventually to handle it. +issue.transition.unconfirm=Unconfirm +issue.transition.unconfirm.description=This issue should be reviewed again to decide what to do with it. +issue.transition.resolve=Resolve as fixed +issue.transition.resolve.description=This issue has been fixed in the code and is waiting for the next analysis to close it - or reopen it if it was not actually fixed. +issue.transition.falsepositive=Resolve as false positive +issue.transition.falsepositive.description=This issue can be ignored because it is due to a limitation of the analysis engine. Its effort won't be counted. +issue.transition.reopen=Reopen +issue.transition.reopen.description=This issue is not resolved, and should be reviewed again. +issue.transition.close=Close +issue.transition.close.description= +issue.transition.wontfix=Resolve as won't fix +issue.transition.wontfix.description=This issue can be ignored because the rule is irrelevant in this context. Its effort won't be counted. +issue.set_severity=Change Severity +issue.set_severity.submit=Change Severity +issue.set_type=Change Type + +issue.type.CODE_SMELL=Code Smell +issue.type.BUG=Bug +issue.type.VULNERABILITY=Vulnerability +issue.type.CODE_SMELL.plural=Code Smells +issue.type.BUG.plural=Bugs +issue.type.VULNERABILITY.plural=Vulnerabilities + + +issue.status.REOPENED=Reopened +issue.status.REOPENED.description=Transitioned to and then back from some other status. +issue.status.RESOLVED=Resolved +issue.status.RESOLVED.description=Manually marked as corrected. +issue.status.OPEN=Open +issue.status.OPEN.description=Untouched. This status is set automatically at issue creation. +issue.status.CONFIRMED=Confirmed +issue.status.CONFIRMED.description=Manually examined and affirmed as an issue that needs attention. +issue.status.CLOSED=Closed +issue.status.CLOSED.description=Non-active and no longer requiring attention. + +issue.resolution.FALSE-POSITIVE=False Positive +issue.resolution.FALSE-POSITIVE.description=Issues that manual review determined were False Positives. Effort from these issues is ignored. +issue.resolution.FIXED=Fixed +issue.resolution.FIXED.description=Issues that were corrected in code and reanalyzed. +issue.resolution.WONTFIX=Won't fix +issue.resolution.WONTFIX.description=Issues that are accepted in this context. They and their effort will be ignored. +issue.resolution.REMOVED=Removed +issue.resolution.REMOVED.description=Either the rule or the resource was changed (removed, relocated, parameters changed, etc.) so that analysis no longer finds these issues. +issue.unresolved.description=Unresolved issues have not been addressed in any way. + +issue.updated=Updated: +issue.manual.missing_rule=Missing rule +issue.reported_by=Reported by +issue.authorLogin=Author: +issue.component_deleted=Removed +issue.effort=Effort: +issue.x_effort={0} effort +issue.creation_date=Created +issue.filter_similar_issues=Filter Similar Issues +issues.return_to_list=Return to List +issues.issues_limit_reached=For usability reasons, only the {0} issues are displayed. +issues.bulk_change=All Issues ({0}) +issues.bulk_change_selected=Selected Issues ({0}) +issues.home.recent_issues=Recent Issues +issues.home.my_recent_issues=My Recent Issues +issues.home.over_last_week=Over Last Week +issues.home.my_filters=My Filters +issues.home.projects=Projects +issues.home.authors=Authors +issues.home.tags=Tags +issues.home.new_search=New Search +issues.toggle_selection_tooltip=(De-)Select all currently visible issues + + +#------------------------------------------------------------------------------ +# +# ISSUE CHANGELOG +# +#------------------------------------------------------------------------------ +issue.changelog.changed_to={0} changed to {1} +issue.changelog.was=was {0} +issue.change.issue_was_moved=The issue was moved +issue.changelog.removed={0} removed +issue.changelog.field.severity=Severity +issue.changelog.field.actionPlan=Action Plan +issue.changelog.field.assignee=Assignee +issue.changelog.field.author=Author +issue.changelog.field.resolution=Resolution +issue.changelog.field.effort=Effort +issue.changelog.field.status=Status +issue.changelog.field.tags=Tags +issue.changelog.field.type=Type +issue.changelog.field.file=File + + +#------------------------------------------------------------------------------ +# +# ISSUE FILTERS +# +#------------------------------------------------------------------------------ +issue_filter.new_search=New Search +issue_filter.header.assignee=Assignee +issue_filter.header.creation_date=Created +issue_filter.header.resolution=Resolution +issue_filter.header.update_date=Updated +issue_filter.criteria.assignee=Assignee +issue_filter.criteria.created=Created +issue_filter.criteria.created_at=Created at +issue_filter.criteria.created_after=Created since +issue_filter.criteria.created_before=Created before +issue_filter.criteria.date_format=year-month-day (2013-01-31) +issue_filter.criteria.project=Project +issue_filter.criteria.resolution=Resolution +issue_filter.criteria.rule=Rule +issue_filter.criteria.severity=Severity +issue_filter.criteria.status=Status +issue_filter.filter_list=Issues Filters +issue_filter.max_results_reached=Only the first {0} issues matching the search criteria have been retrieved. Add some additional criteria to get fewer results to be able to sort this list. +issue_filter.no_result=No matching issues found. +issue_filter.no_result.help=Status of the related issues may have changed since the last analysis. +issue_filter.save_filter=Save Filter +issue_filter.edit_filter=Edit Filter +issue_filter.copy_filter=Copy Filter +issue_filter.form.name=Name +issue_filter.form.description=Description +issue_filter.form.share=Shared with all users +issue_filter.form.owner=Owner +issue_filter.more_criteria=+ More Criteria +issue_filter.favourite_filters=Favourite Filters +issue_filter.manage.my_filters=My Issues Filters +issue_filter.manage.shared_filters=Shared Issues Filters +issue_filter.no_filters=No filters +issue_filter.delete_confirm_title=Delete Filter +issue_filter.are_you_sure_want_delete_filter_x=Are you sure that you want to delete the filter "{0}"? +issue_filter.private=Private +issue_filter.shared=Shared +issue_filter.shared_with_all_users=Shared with all users +issue_filter.sharing=Sharing +issue_filter.no_issues=No Issues + + +#------------------------------------------------------------------------------ +# +# ISSUE FILTERS +# +#------------------------------------------------------------------------------ +issues.sort.creation_date=Creation Date +issues.sort.update_date=Update Date +issues.sort.close_date=Close Date +issues.sort.assignee=Assignee +issues.sort.severity=Severity +issues.sort.status=Status +issues.ordered_by=Ordered by +issues.found=Found + + +#------------------------------------------------------------------------------ +# +# ISSUES FACETS +# +#------------------------------------------------------------------------------ +issues.facet.types=Type +issues.facet.severities=Severity +issues.facet.projectUuids=Project +issues.facet.statuses=Status +issues.facet.assignees=Assignee +issues.facet.fileUuids=File +issues.facet.moduleUuids=Module +issues.facet.directories=Directory +issues.facet.tags=Tag +issues.facet.rules=Rule +issues.facet.resolutions=Resolution +issues.facet.languages=Language +issues.facet.createdAt=New Issues +issues.facet.createdAt.or=Or: +issues.facet.createdAt.all=All +issues.facet.createdAt.last_week=Last week +issues.facet.createdAt.last_month=Last month +issues.facet.createdAt.last_year=Last year +issues.facet.authors=Author +issues.facet.issues=Issue Key +issues.facet.mode.issues=Issues +issues.facet.mode.effort=Effort + + +#------------------------------------------------------------------------------ +# +# ISSUE BULK CHANGE +# +#------------------------------------------------------------------------------ + +issue_bulk_change.form.title=Change {0} issues +issue_bulk_change.comment.help=This comment will be applied only to issues that will effectively be modified +issue_bulk_change.max_issues_reached=As too many issues have been selected, only the first {0} issues will be updated. +issue_bulk_change.x_issues={0} issues +issue_bulk_change.error.empty_issues=Issues must not be empty +issue_bulk_change.error.need_one_action=At least one action must be provided + + + +#------------------------------------------------------------------------------ +# +# ALL PROJECTS PAGE +# +#------------------------------------------------------------------------------ + +all-projects.cols.name=Name +all-projects.results_not_display_due_to_security=Due to security settings, some results are not being displayed. + + +#------------------------------------------------------------------------------ +# +# COMPARISON +# +#------------------------------------------------------------------------------ + +comparison.compare=Compare +comparison.add_metric=Add metric +comparison.add_project=Add project +comparison.select_version=Select a version +comparison.suppress_column=Suppress column +comparison.suppress_line=Suppress line +comparison.move_left=Move left +comparison.move_right=Move right +comparison.move_down=Move down +comparison.move_up=Move up +comparison.version.latest=LATEST + + +#------------------------------------------------------------------------------ +# +# DEPENDENCIES +# +#------------------------------------------------------------------------------ + +dependencies.search_library=Search library +dependencies.search_help=Find out which projects depend on a given library.<br/>Search by group, artifact or name. E.g.: org.apache.struts, struts-core or Struts +dependencies.select_library=Select library +dependencies.select_version=Select version +dependencies.used_by=Used by +dependencies.not_used=Not used + + +#------------------------------------------------------------------------------ +# +# DASHBOARD / DASHBOARDS +# +#------------------------------------------------------------------------------ + +dashboard.cannot_render_widget_x=Can not render widget {0}: {1} +dashboard.back_to_dashboard=Back to dashboard +dashboard.configure_widgets=Configure widgets +dashboard.manage_dashboards=Manage Dashboards +dashboard.add_widget=Add widget +dashboard.please_configure_the_widget_x=Please configure the widget <b>{0}</b>. +dashboard.global_dashboards=Global Dashboards +dashboard.project_dashboards=Project Dashboards +dashboard.my_global_dashboards=My Global Dashboards +dashboard.my_project_dashboards=My Project Dashboards +dashboard.no_dashboard=No dashboard +dashboard.do_you_want_to_delete_dashboard=Do you want to delete this dashboard? +dashboard.available_dashboards=Available Dashboards +dashboard.shared_dashboards=Shared Dashboards +dashboard.new_dashboard=New dashboard +dashboard.create_dashboard=Create dashboard +dashboard.create_project_dashboard=Create project dashboard +dashboard.create_global_dashboard=Create global dashboard +dashboard.edit_dashboard=Edit dashboard +dashboard.update_dashboard=Update dashboard +dashboard.not_found=This dashboard was not found +dashboard.error_create_existing_name=A dashboard already exists with the same name +dashboard.error_follow_existing_name=A dashboard already exists with the same name +dashboard.default_restored=Default dashboards are restored +dashboard.error_delete_default=This dashboard can't be deleted as long as it's defined as a default dashboard +dashboard.error_unshare_default=This dashboard can't be unshared as long as it's defined as a default dashboard +dashboard.global_dashboards.description=These dashboards are displayed to anonymous users or users who have not customized their dashboards. +dashboard.project_dashboards.description=These dashboards are available to anonymous users or users who have not customized their dashboards. +dashboard.shared_dashboards.description=These dashboards can be added to default dashboards. +dashboard.username.default=[SonarQube] +dashboard.delete_confirm_title=Delete dashboard +dashboard.delete_dashboard=Delete dashboard +dashboard.project_not_found=The requested project does not exist. Either it has never been analyzed successfully or it has been deleted. +dashboard.default_dashboard=This dashboard is the default one and is displayed when clicking on "Overview". + + +#------------------------------------------------------------------------------ +# +# SETTINGS +# +#------------------------------------------------------------------------------ +settings.add=Add value +settings.save_category=Save {0} Settings +settings.key_x=Key: {0} +settings.default_x=Default: {0} +settings.not_set=(not set) +settings.state.saving=Saving... +settings.state.saved=Saved! +settings.state.validation_failed=Validation failed. {0} +settings.state.value_cant_be_empty=Value can't be empty. Use "Reset" to set value to the default one. +settings._default=(default) +settings.boolean.true=True +settings.boolean.false=False +settings.default.no_value=<no value> +settings.default.complex_value=<complex value> +settings.default.password=<password> + +property.category.general=General +property.category.general.email=Email +property.category.general.duplications=Duplications +property.category.general.differentialViews=Differential Views +property.category.general.localization=Localization +property.category.general.databaseCleaner=Database Cleaner +property.category.general.looknfeel=Look & Feel +property.category.general.issues=Issues +property.category.security=Security +property.category.security.encryption=Encryption +property.category.java=Java +property.category.differentialViews=Differential Views +property.category.codeCoverage=Code Coverage +property.category.duplications=Duplications +property.category.localization=Localization +property.category.server_id=Server ID +property.category.exclusions=Analysis Scope +property.sonar.inclusions.name=Source File Inclusions +property.sonar.inclusions.description=Patterns used to include some source files and only these ones in analysis. +property.sonar.test.inclusions.name=Test File Inclusions +property.sonar.test.inclusions.description=Patterns used to include some test files and only these ones in analysis. +property.sonar.exclusions.name=Source File Exclusions +property.sonar.exclusions.description=Patterns used to exclude some source files from analysis. +property.sonar.test.exclusions.name=Test File Exclusions +property.sonar.test.exclusions.description=Patterns used to exclude some test files from analysis. +property.sonar.global.exclusions.name=Global Source File Exclusions +property.sonar.global.exclusions.description=Patterns used to exclude some source files from analysis. They apply to every project and cannot be overridden. +property.sonar.global.test.exclusions.name=Global Test File Exclusions +property.sonar.global.test.exclusions.description=Patterns used to exclude some test files from analysis. They apply to every project and cannot be overridden. +property.category.exclusions.files=Files +property.category.exclusions.files.description=Configure the files that should be completely ignored by the analysis. +property.sonar.skippedModules.name=Module Exclusions +property.sonar.skippedModules.description=This property is deprecated since version 4.3 and should not be used anymore. +property.sonar.includedModules.name=Module Inclusions +property.sonar.includedModules.description=This property is deprecated since version 4.3 and should not be used anymore. +property.category.exclusions.issues=Issues +property.category.exclusions.issues.description=Configure the conditions under which issues should not be reported. +property.category.exclusions.duplications=Duplications +property.category.exclusions.duplications.description=Configure the files that should be ignored by duplication detection. +property.category.exclusions.coverage=Code Coverage +property.category.exclusions.coverage.description=Configure the files that should be ignored by code coverage calculations. +property.sonar.coverage.exclusions.name=Coverage Exclusions +property.sonar.coverage.exclusions.description=Patterns used to exclude some files from coverage report. +property.category.technicalDebt=Technical Debt +property.error.notBoolean=Valid options are "true" and "false" +property.error.notInteger=Only digits are allowed +property.error.notFloat=Not a floating point number +property.error.notRegexp=Not a valid Java regular expression +property.error.notInOptions=Not a valid option +property.category.scm=SCM + +#------------------------------------------------------------------------------ +# +# SEARCH ENGINE FOR RESOURCES +# +#------------------------------------------------------------------------------ +search.results=results +search.duration=({0} seconds) +search.shortcut=Press S to quickly open search bar + + +#------------------------------------------------------------------------------ +# +# SHORTCUTS +# +#------------------------------------------------------------------------------ +shortcuts.modal_title=Shortcuts + +shortcuts.section.global=Global +shortcuts.section.global.search=quickly open search bar +shortcuts.section.global.shortcuts=open this window + +shortcuts.section.issues=Issues Page +shortcuts.section.issues.navigate_between_issues=navigate between issues +shortcuts.section.issues.open_details=go from the list of issues to the source code +shortcuts.section.issues.return_to_list=return back to the list + +shortcuts.section.issue.select=select an issue +shortcuts.section.issue.do_transition=do an issue transition +shortcuts.section.issue.assign=assign issue +shortcuts.section.issue.assign_to_me=assign issue to the current user +shortcuts.section.issue.change_severity=change severity of issue +shortcuts.section.issue.comment=comment issue +shortcuts.section.issue.submit_comment=submit comment +shortcuts.section.issue.change_tags=change tags of issue + +shortcuts.section.rules=Rules Page +shortcuts.section.rules.navigate_between_rules=navigate between rules +shortcuts.section.rules.open_details=go from the list of rules to the rule details +shortcuts.section.rules.return_to_list=return back to the list +shortcuts.section.rules.activate=activate selected rule +shortcuts.section.rules.deactivate=deactivate selected rule + +shortcuts.section.code=Code Page +shortcuts.section.code.search=search components in the project scope + + +#------------------------------------------------------------------------------ +# +# SELECT2.js +# +#------------------------------------------------------------------------------ +select2.noMatches=No matches +select2.searching=Searching... +select2.tooShort=Please enter at least {0} characters + + +#------------------------------------------------------------------------------ +# +# WIDGETS +# +#------------------------------------------------------------------------------ + +widgets.more=More +widget.error_occurred_please_read_logs=An error occurred while trying to display the widget "{0}". Please contact the administrator. +widget.unsupported_browser_warning=Your browser is out of date and does not support this widget. +widget.as_calculated_on_x=As calculated on {0} +widget.select_project=Please select a project + widget.alerts.name=Quality Gate +widget.alerts.description=Displays the project's quality gate status. widget.alerts.no_alert=The project has passed the quality gate -widget.alerts.property.show_ok.name=Show passed conditions widget.alerts.warnings=The project has warnings on the following quality gate conditions:\u00a0 -widget.as_calculated_on_x=As calculated on {0} -widget.bubble_chart.description=Display a component's source files in a Bubble chart. Both axes and bubble size are configurable. -widget.bubble_chart.name=Project File Bubble Chart -widget.bubble_chart.property.chartHeight.name=Chart Height -widget.bubble_chart.property.chartTitle.name=Chart Title -widget.bubble_chart.property.sizeMetric.name=Size Metric -widget.bubble_chart.property.xLogarithmic.name=X Logarithmic Scale -widget.bubble_chart.property.xMetric.name=X Metric -widget.bubble_chart.property.yLogarithmic.name=Y Logarithmic Scale -widget.bubble_chart.property.yMetric.name=Y Metric -widget.code_coverage.condition_coverage.suffix=\ condition coverage +widget.alerts.errors=The project failed the quality gate on the following conditions:\u00a0 +widget.alerts.property.show_ok.name=Show passed conditions +widget.alerts.missing_metric=Some information regarding the status of the quality gate is missing. A fresh analysis of the project is needed to reload this information. + +widget.code_coverage.name=Unit Tests Coverage widget.code_coverage.description=Reports on units tests and code coverage by unit tests. -widget.code_coverage.errors.suffix=\ errors -widget.code_coverage.execution_time=Execution Time -widget.code_coverage.failures.suffix=\ failures widget.code_coverage.line_coverage.suffix=\ line coverage -widget.code_coverage.name=Unit Tests Coverage -widget.code_coverage.no_new_lines_to_cover=No new lines to cover +widget.code_coverage.condition_coverage.suffix=\ condition coverage widget.code_coverage.on_new_code=On new code -widget.code_coverage.skipped.suffix=\ skipped -widget.code_coverage.tests.suffix=\ tests +widget.code_coverage.no_new_lines_to_cover=No new lines to cover widget.code_coverage.test_success=Unit test success -widget.complexity.description=Reports on complexity, average complexity and complexity distribution. +widget.code_coverage.failures.suffix=\ failures +widget.code_coverage.errors.suffix=\ errors +widget.code_coverage.tests.suffix=\ tests +widget.code_coverage.skipped.suffix=\ skipped +widget.code_coverage.execution_time=Execution Time + +# id of this widget does not use underscore in order to be backward-compatible with previous version of JaCoCo plugin +widget.it-coverage.name=Integration Tests Coverage +widget.it-coverage.description=Reports on code coverage by integration tests. When both the code coverage by unit tests and by integration tests are available, an overall code coverage is also computed and displayed in this widget. +widget.it-coverage.line_coverage.suffix=\ line coverage +widget.it-coverage.condition_coverage.suffix=\ condition coverage +widget.it-coverage.lines_to_cover.suffix=\ lines to cover +widget.it-coverage.on_new_code=On new code +widget.it-coverage.no_new_lines_to_cover=No new lines to cover + +# id of this widget does not use underscore in order to be backward-compatible with previous version of JaCoCo plugin +widget.overall-coverage.name=Overall Coverage +widget.overall-coverage.description=Reports on code coverage by all tests. +widget.overall-coverage.line_coverage.suffix=\ line coverage +widget.overall-coverage.condition_coverage.suffix=\ condition coverage +widget.overall-coverage.lines_to_cover.suffix=\ lines to cover +widget.overall-coverage.on_new_code=On new code +widget.overall-coverage.no_new_lines_to_cover=No new lines to cover + +widget.documentation_comments.name=Documentation & Comments +widget.documentation_comments.description=Reports on comments and documentation +widget.documentation_comments.comments=Comments +widget.documentation_comments.documentation=Documentation +widget.documentation_comments.lines.suffix=\ lines +widget.documentation_comments.docu_api.suffix=\ docu. API +widget.documentation_comments.undocu_api.suffix=\ undocu. API +widget.documentation_comments.public_api.suffix=\ public API +widget.documentation_comments.blank.suffix=\ blank + +widget.duplications.name=Duplications +widget.duplications.description= Reports on copy/paste and code duplications +widget.duplications.duplications=Duplications +widget.duplications.useless-duplications-title=Duplicated lines that can be reduced +widget.duplications.lines.suffix=\ lines +widget.duplications.blocks.suffix=\ blocks +widget.duplications.files.suffix=\ files + widget.complexity.name=Complexity +widget.complexity.description=Reports on complexity, average complexity and complexity distribution. +widget.complexity.per_method.suffix=\ /function widget.complexity.per_class.suffix=\ /class widget.complexity.per_file.suffix=\ /file -widget.complexity.per_method.suffix=\ /function -widget.custom_measures.description=Displays a list of selected measures. + widget.custom_measures.name=Custom Measures +widget.custom_measures.description=Displays a list of selected measures. widget.custom_measures.property.metric1.name=Metric 1 -widget.custom_measures.property.metric10.name=Metric 10 widget.custom_measures.property.metric2.name=Metric 2 widget.custom_measures.property.metric3.name=Metric 3 widget.custom_measures.property.metric4.name=Metric 4 @@ -2080,213 +2129,125 @@ widget.custom_measures.property.metric6.name=Metric 6 widget.custom_measures.property.metric7.name=Metric 7 widget.custom_measures.property.metric8.name=Metric 8 widget.custom_measures.property.metric9.name=Metric 9 -widget.debt_overview.description=Display the maintainability rating and the technical debt ratio. -widget.debt_overview.name=Technical Debt Synopsis -widget.debt_overview.on_new_code=On New Code -widget.description.alerts=Displays a summary of the project's quality gate status. +widget.custom_measures.property.metric10.name=Metric 10 + +widget.description.name=Description widget.description.description=Displays general project information. widget.description.key=Key widget.description.language=Language -widget.description.links=Links -widget.description.name=Description widget.description.profile=Profile widget.description.profiles=Profiles widget.description.qualitygate=Quality Gate -widget.documentation_comments.blank.suffix=\ blank -widget.documentation_comments.comments=Comments -widget.documentation_comments.description=Reports on comments and documentation -widget.documentation_comments.documentation=Documentation -widget.documentation_comments.docu_api.suffix=\ docu. API -widget.documentation_comments.lines.suffix=\ lines -widget.documentation_comments.name=Documentation & Comments -widget.documentation_comments.public_api.suffix=\ public API -widget.documentation_comments.undocu_api.suffix=\ undocu. API -widget.duplications.blocks.suffix=\ blocks -widget.duplications.description= Reports on copy/paste and code duplications -widget.duplications.duplications=Duplications -widget.duplications.files.suffix=\ files -widget.duplications.lines.suffix=\ lines -widget.duplications.name=Duplications -widget.duplications.useless-duplications-title=Duplicated lines that can be reduced -widget.error_occurred_please_read_logs=An error occurred while trying to display the widget "{0}". Please contact the administrator. -widget.events.all=All -widget.events.description=Reports events on the project life cycle such as versions and quality gate status updates. +widget.description.alerts=Displays a summary of the project's quality gate status. +widget.description.links=Links + widget.events.name=Events +widget.events.description=Reports events on the project life cycle such as versions and quality gate status updates. +widget.events.title=Events +widget.events.all=All widget.events.no_event=No event widget.events.show_all=Show All -widget.events.title=Events -widget.filter.description=Shows a pre-configured filter -widget.filter.edit=Edit my filters -widget.filter.name=Filter -widget.hotspot_metric.description=Shows the files that have the worst result for a specific metric. -widget.hotspot_metric.hotspots_by_x=Hotspots by {0} -widget.hotspot_metric.more=More -widget.hotspot_metric.name=Metric Hotspot -widget.hotspot_metric.property.metric.name=Metric -widget.hotspot_metric.property.numberOfLines.name=Number of lines -widget.hotspot_metric.property.title.name=Title -widget.image.description=Shows an image with a link -widget.image.name=Image -widget.issue_filter.description=Displays the result of a pre-configured issue filter. -widget.issue_filter.insufficient_privileges_warning=Widget cannot be displayed: insufficient privileges. -widget.issue_filter.name=Issue Filter -widget.issue_filter.property.displayFilterDescription.name=Display Filter Description -widget.issue_filter.property.displayMode.name=Display Mode -widget.issue_filter.property.displayMode.option.count.name=Issues -widget.issue_filter.property.displayMode.option.debt.name=Effort -widget.issue_filter.property.distributionAxis.name=Distribution Axis -widget.issue_filter.property.distributionAxis.option.assignees.name=By Assignee -widget.issue_filter.property.distributionAxis.option.authors.name=By Author -widget.issue_filter.property.distributionAxis.option.createdAt.name=By Creation Date -widget.issue_filter.property.distributionAxis.option.languages.name=By Language -widget.issue_filter.property.distributionAxis.option.projectUuids.name=By Project -widget.issue_filter.property.distributionAxis.option.resolutions.name=By Resolution -widget.issue_filter.property.distributionAxis.option.rules.name=By Rule -widget.issue_filter.property.distributionAxis.option.severities.name=By Severity -widget.issue_filter.property.distributionAxis.option.statuses.name=By Status -widget.issue_filter.property.distributionAxis.option.tags.name=By Tag -widget.issue_filter.property.distributionAxis.option.types.name=By Type -widget.issue_filter.property.filter.name=Filter -widget.issue_filter.unknown_filter_warning=This widget is configured to display an issue filter that doesn't exist anymore. -widget.issue_tag_cloud.description=Displays the cloud of tags associated to unresolved issues. -widget.issue_tag_cloud.name=Project Issue Tag Cloud -widget.issue_tag_cloud.property.maxItems.desc=Maximum number of tags to show -widget.issue_tag_cloud.property.maxItems.name=Max Tags -widget.issue_tag_cloud.title=Issue Tag Cloud -widget.it-coverage.condition_coverage.suffix=\ condition coverage -widget.it-coverage.description=Reports on code coverage by integration tests. When both the code coverage by unit tests and by integration tests are available, an overall code coverage is also computed and displayed in this widget. -widget.it-coverage.lines_to_cover.suffix=\ lines to cover -widget.it-coverage.line_coverage.suffix=\ line coverage -widget.it-coverage.name=Integration Tests Coverage -widget.it-coverage.no_new_lines_to_cover=No new lines to cover -widget.it-coverage.on_new_code=On new code + +widget.rules.name=Issues and Effort +widget.rules.description=Reports issues and effort. +widget.rules.issues=Issues +widget.rules.added=Added: +widget.rules.removed=Removed: + +widget.size.name=Size Metrics +widget.size.description=Reports general metrics on the size of the project. + +widget.timeline.name=Timeline +widget.timeline.description=Displays up to 3 metrics on a history chart. +widget.timeline.timeline_not_displayed=No history +widget.timeline.property.chartTitle.name=Chart title +widget.timeline.property.metric1.name=Metric 1 +widget.timeline.property.metric2.name=Metric 2 +widget.timeline.property.metric3.name=Metric 3 +widget.timeline.property.hideEvents.name=Hide events +widget.timeline.property.chartHeight.name=Chart Height +widget.timeline.limited_histortical_data=Current timeline is reduced to a shorter period because of limited historical data for one or more of the metrics. +widget.timeline.property.undefinedToZero.name=Default missing data +widget.timeline.property.undefinedToZero.desc=Graph undefined values as zero. When set to false, the graph is only drawn for the period for which all values are defined. + +widget.bubble_chart.name=Project File Bubble Chart +widget.bubble_chart.description=Display a component's source files in a Bubble chart. Both axes and bubble size are configurable. +widget.bubble_chart.property.chartTitle.name=Chart Title +widget.bubble_chart.property.chartHeight.name=Chart Height +widget.bubble_chart.property.xMetric.name=X Metric +widget.bubble_chart.property.yMetric.name=Y Metric +widget.bubble_chart.property.sizeMetric.name=Size Metric +widget.bubble_chart.property.xLogarithmic.name=X Logarithmic Scale +widget.bubble_chart.property.yLogarithmic.name=Y Logarithmic Scale + widget.measure_filter.no_main_metric=The widget can not be rendered because some components have no measure for the selected metric(s). -widget.measure_filter_bubble_chart.description=Displays the result of a pre-configured measure filter as a bubble chart. -widget.measure_filter_bubble_chart.name=Measure Filter as Bubble Chart -widget.measure_filter_bubble_chart.property.chartHeight.name=Chart Height -widget.measure_filter_bubble_chart.property.chartTitle.name=Chart Title -widget.measure_filter_bubble_chart.property.filter.name=Filter -widget.measure_filter_bubble_chart.property.maxItems.desc=Maximum number of components to display -widget.measure_filter_bubble_chart.property.maxItems.name=Max Components -widget.measure_filter_bubble_chart.property.sizeMetric.name=Size Metric -widget.measure_filter_bubble_chart.property.xLogarithmic.name=X Logarithmic Scale -widget.measure_filter_bubble_chart.property.xMetric.name=X Metric -widget.measure_filter_bubble_chart.property.yLogarithmic.name=Y Logarithmic Scale -widget.measure_filter_bubble_chart.property.yMetric.name=Y Metric -widget.measure_filter_cloud.description=Displays the result of a pre-configured measure filter as a word cloud. + +widget.measure_filter_pie_chart.name=Measure Filter as Donut Chart +widget.measure_filter_pie_chart.description=Displays the result of a pre-configured measure filter as a donut chart. +widget.measure_filter_pie_chart.property.chartTitle.name=Chart Title +widget.measure_filter_pie_chart.property.chartHeight.name=Chart Height +widget.measure_filter_pie_chart.property.filter.name=Filter +widget.measure_filter_pie_chart.property.mainMetric.name=Main Metric +widget.measure_filter_pie_chart.property.mainMetric.desc=This metric will be used to size the donut wedges, and will be shown when you mouse over a wedge. +widget.measure_filter_pie_chart.property.extraMetric1.name=Extra Metric 1 +widget.measure_filter_pie_chart.property.extraMetric1.desc=This metric will be shown when you mouse over a wedge. +widget.measure_filter_pie_chart.property.extraMetric2.name=Extra Metric 2 +widget.measure_filter_pie_chart.property.extraMetric2.desc=This metric will be shown when you mouse over a wedge. +widget.measure_filter_pie_chart.property.maxItems.name=Max Components +widget.measure_filter_pie_chart.property.maxItems.desc=Maximum number of components to display + widget.measure_filter_cloud.name=Measure Filter as Word Cloud +widget.measure_filter_cloud.description=Displays the result of a pre-configured measure filter as a word cloud. widget.measure_filter_cloud.property.chartTitle.name=Chart Title -widget.measure_filter_cloud.property.colorMetric.name=Color Metric widget.measure_filter_cloud.property.filter.name=Filter -widget.measure_filter_cloud.property.maxItems.desc=Maximum number of components to show +widget.measure_filter_cloud.property.colorMetric.name=Color Metric +widget.measure_filter_cloud.property.sizeMetric.name=Size Metric widget.measure_filter_cloud.property.maxItems.name=Max Components +widget.measure_filter_cloud.property.maxItems.desc=Maximum number of components to show widget.measure_filter_cloud.property.reverseColor.name=Reverse Order on Color -widget.measure_filter_cloud.property.sizeMetric.name=Size Metric -widget.measure_filter_histogram.description=Displays the result of a pre-configured measure filter as a histogram. -widget.measure_filter_histogram.max_items_reached=Only the first {0} components are displayed + widget.measure_filter_histogram.name=Measure Filter as Histogram -widget.measure_filter_histogram.property.chartHeight.name=Chart Height +widget.measure_filter_histogram.description=Displays the result of a pre-configured measure filter as a histogram. widget.measure_filter_histogram.property.chartTitle.name=Chart Title +widget.measure_filter_histogram.property.chartHeight.name=Chart Height widget.measure_filter_histogram.property.filter.name=Filter -widget.measure_filter_histogram.property.maxItems.desc=Maximum number of components to display -widget.measure_filter_histogram.property.maxItems.name=Max Components widget.measure_filter_histogram.property.metric.name=Metric -widget.measure_filter_histogram.property.relativeScale.desc=An "Absolute" scale uses the metric's full range of values on the y-axis. For instance, for code coverage, it spans from 0% to 100%. A "Relative" scale limits the y-axis to only those values represented among your projects. Like grading on a curve, the effect is to give your worst project a height of 0 on the y-axis and your best project the full height of the graph. This is useful when you want to compare your projects only to each other. Note that changes in either the best or worst projects will affect the graph scale. -widget.measure_filter_histogram.property.relativeScale.name=Relative Scale -widget.measure_filter_histogram.property.reverseOrder.desc=Reverse sort order of filter +widget.measure_filter_histogram.property.maxItems.name=Max Components +widget.measure_filter_histogram.property.maxItems.desc=Maximum number of components to display widget.measure_filter_histogram.property.reverseOrder.name=Descending -widget.measure_filter_list.description=Displays the result of a pre-configured measure filter as a list. -widget.measure_filter_list.name=Measure Filter as List -widget.measure_filter_list.property.displayFilterDescription.name=Display Filter Description -widget.measure_filter_list.property.filter.name=Filter -widget.measure_filter_list.property.pageSize.desc=Size limit is 250. -widget.measure_filter_list.property.pageSize.name=Page Size -widget.measure_filter_pie_chart.description=Displays the result of a pre-configured measure filter as a donut chart. -widget.measure_filter_pie_chart.name=Measure Filter as Donut Chart -widget.measure_filter_pie_chart.property.chartHeight.name=Chart Height -widget.measure_filter_pie_chart.property.chartTitle.name=Chart Title -widget.measure_filter_pie_chart.property.extraMetric1.desc=This metric will be shown when you mouse over a wedge. -widget.measure_filter_pie_chart.property.extraMetric1.name=Extra Metric 1 -widget.measure_filter_pie_chart.property.extraMetric2.desc=This metric will be shown when you mouse over a wedge. -widget.measure_filter_pie_chart.property.extraMetric2.name=Extra Metric 2 -widget.measure_filter_pie_chart.property.filter.name=Filter -widget.measure_filter_pie_chart.property.mainMetric.desc=This metric will be used to size the donut wedges, and will be shown when you mouse over a wedge. -widget.measure_filter_pie_chart.property.mainMetric.name=Main Metric -widget.measure_filter_pie_chart.property.maxItems.desc=Maximum number of components to display -widget.measure_filter_pie_chart.property.maxItems.name=Max Components -widget.measure_filter_treemap.description=Displays the result of pre-configured measure filter as a Treemap. -widget.measure_filter_treemap.name=Measure Filter as Treemap -widget.measure_filter_treemap.property.chartTitle.name=Chart Title -widget.measure_filter_treemap.property.colorMetric.desc=Metric used for square color -widget.measure_filter_treemap.property.colorMetric.name=Color Metric -widget.measure_filter_treemap.property.filter.name=Filter -widget.measure_filter_treemap.property.heightInPercents.desc=Height in percents of width -widget.measure_filter_treemap.property.heightInPercents.name=Height -widget.measure_filter_treemap.property.maxItems.desc=Maximum number of components to show -widget.measure_filter_treemap.property.maxItems.name=Max Components -widget.measure_filter_treemap.property.sizeMetric.desc=Metric used for square size -widget.measure_filter_treemap.property.sizeMetric.name=Size Metric -widget.overall-coverage.condition_coverage.suffix=\ condition coverage -widget.overall-coverage.description=Reports on code coverage by all tests. -widget.overall-coverage.lines_to_cover.suffix=\ lines to cover -widget.overall-coverage.line_coverage.suffix=\ line coverage -widget.overall-coverage.name=Overall Coverage -widget.overall-coverage.no_new_lines_to_cover=No new lines to cover -widget.overall-coverage.on_new_code=On new code -widget.project_file_cloud.description=Display a component's source files in a word cloud. Both axes are configurable. +widget.measure_filter_histogram.property.reverseOrder.desc=Reverse sort order of filter +widget.measure_filter_histogram.property.relativeScale.name=Relative Scale +widget.measure_filter_histogram.property.relativeScale.desc=An "Absolute" scale uses the metric's full range of values on the y-axis. For instance, for code coverage, it spans from 0% to 100%. A "Relative" scale limits the y-axis to only those values represented among your projects. Like grading on a curve, the effect is to give your worst project a height of 0 on the y-axis and your best project the full height of the graph. This is useful when you want to compare your projects only to each other. Note that changes in either the best or worst projects will affect the graph scale. +widget.measure_filter_histogram.max_items_reached=Only the first {0} components are displayed + +widget.measure_filter_bubble_chart.name=Measure Filter as Bubble Chart +widget.measure_filter_bubble_chart.description=Displays the result of a pre-configured measure filter as a bubble chart. +widget.measure_filter_bubble_chart.property.filter.name=Filter +widget.measure_filter_bubble_chart.property.chartTitle.name=Chart Title +widget.measure_filter_bubble_chart.property.chartHeight.name=Chart Height +widget.measure_filter_bubble_chart.property.xMetric.name=X Metric +widget.measure_filter_bubble_chart.property.yMetric.name=Y Metric +widget.measure_filter_bubble_chart.property.sizeMetric.name=Size Metric +widget.measure_filter_bubble_chart.property.xLogarithmic.name=X Logarithmic Scale +widget.measure_filter_bubble_chart.property.yLogarithmic.name=Y Logarithmic Scale +widget.measure_filter_bubble_chart.property.maxItems.name=Max Components +widget.measure_filter_bubble_chart.property.maxItems.desc=Maximum number of components to display + widget.project_file_cloud.name=Project File Word Cloud +widget.project_file_cloud.description=Display a component's source files in a word cloud. Both axes are configurable. widget.project_file_cloud.property.chartTitle.name=Chart Title -widget.project_file_cloud.property.colorMetric.name=Color Metric widget.project_file_cloud.property.filter.name=Filter -widget.project_file_cloud.property.maxItems.desc=Maximum number of components to show -widget.project_file_cloud.property.maxItems.name=Max Components +widget.project_file_cloud.property.colorMetric.name=Color Metric widget.project_file_cloud.property.sizeMetric.name=Size Metric -widget.project_issue_filter.description=Displays the result of a pre-configured issue filter applied to the project. -widget.project_issue_filter.insufficient_privileges_warning=Widget cannot be displayed: insufficient privileges. -widget.project_issue_filter.name=Project Issue Filter -widget.project_issue_filter.property.displayFilterDescription.name=Display Filter Description -widget.project_issue_filter.property.displayMode.name=Display Mode -widget.project_issue_filter.property.displayMode.option.count.name=Issues -widget.project_issue_filter.property.displayMode.option.debt.name=Technical Debt -widget.project_issue_filter.property.distributionAxis.name=Distribution Axis -widget.project_issue_filter.property.distributionAxis.option.assignees.name=By Assignee -widget.project_issue_filter.property.distributionAxis.option.authors.name=By Author -widget.project_issue_filter.property.distributionAxis.option.createdAt.name=By Creation Date -widget.project_issue_filter.property.distributionAxis.option.languages.name=By Language -widget.project_issue_filter.property.distributionAxis.option.resolutions.name=By Resolution -widget.project_issue_filter.property.distributionAxis.option.rules.name=By Rule -widget.project_issue_filter.property.distributionAxis.option.severities.name=By Severity -widget.project_issue_filter.property.distributionAxis.option.statuses.name=By Status -widget.project_issue_filter.property.distributionAxis.option.tags.name=By Tag -widget.project_issue_filter.property.distributionAxis.option.types.name=By Type -widget.project_issue_filter.property.filter.name=Filter -widget.project_issue_filter.unknown_filter_warning=This widget is configured to display an issue filter that doesn't exist anymore. -widget.resource_id=Project -widget.rules.added=Added: -widget.rules.description=Reports issues and effort. -widget.rules.issues=Issues -widget.rules.name=Issues and Effort -widget.rules.removed=Removed: -widget.select_project=Please select a project -widget.size.description=Reports general metrics on the size of the project. -widget.size.name=Size Metrics -widget.timeline.description=Displays up to 3 metrics on a history chart. -widget.timeline.limited_histortical_data=Current timeline is reduced to a shorter period because of limited historical data for one or more of the metrics. -widget.timeline.name=Timeline -widget.timeline.property.chartHeight.name=Chart Height -widget.timeline.property.chartTitle.name=Chart title -widget.timeline.property.hideEvents.name=Hide events -widget.timeline.property.metric1.name=Metric 1 -widget.timeline.property.metric2.name=Metric 2 -widget.timeline.property.metric3.name=Metric 3 -widget.timeline.property.undefinedToZero.desc=Graph undefined values as zero. When set to false, the graph is only drawn for the period for which all values are defined. -widget.timeline.property.undefinedToZero.name=Default missing data -widget.timeline.timeline_not_displayed=No history -widget.time_machine.description=Displays up to 10 metrics in a table, showing their value for a specified number of past snapshots. +widget.project_file_cloud.property.maxItems.name=Max Components +widget.project_file_cloud.property.maxItems.desc=Maximum number of components to show + widget.time_machine.name=History Table +widget.time_machine.description=Displays up to 10 metrics in a table, showing their value for a specified number of past snapshots. +widget.time_machine.property.title.name=Title +widget.time_machine.property.numberOfColumns.name=Number of columns widget.time_machine.property.displaySparkLine.name=Display spark line widget.time_machine.property.metric1.name=Metric 1 -widget.time_machine.property.metric10.name=Metric 10 widget.time_machine.property.metric2.name=Metric 2 widget.time_machine.property.metric3.name=Metric 3 widget.time_machine.property.metric4.name=Metric 4 @@ -2295,33 +2256,1816 @@ widget.time_machine.property.metric6.name=Metric 6 widget.time_machine.property.metric7.name=Metric 7 widget.time_machine.property.metric8.name=Metric 8 widget.time_machine.property.metric9.name=Metric 9 -widget.time_machine.property.numberOfColumns.name=Number of columns -widget.time_machine.property.title.name=Title -widget.treemap-widget.description=Displays a treemap of all direct components of the selected resource. +widget.time_machine.property.metric10.name=Metric 10 + +widget.hotspot_metric.name=Metric Hotspot +widget.hotspot_metric.description=Shows the files that have the worst result for a specific metric. +widget.hotspot_metric.more=More +widget.hotspot_metric.hotspots_by_x=Hotspots by {0} +widget.hotspot_metric.property.title.name=Title +widget.hotspot_metric.property.metric.name=Metric +widget.hotspot_metric.property.numberOfLines.name=Number of lines + +widget.issue_filter.name=Issue Filter +widget.issue_filter.description=Displays the result of a pre-configured issue filter. +widget.issue_filter.property.filter.name=Filter +widget.issue_filter.property.distributionAxis.name=Distribution Axis +widget.issue_filter.property.displayFilterDescription.name=Display Filter Description +widget.issue_filter.property.displayMode.name=Display Mode +widget.issue_filter.unknown_filter_warning=This widget is configured to display an issue filter that doesn't exist anymore. +widget.issue_filter.insufficient_privileges_warning=Widget cannot be displayed: insufficient privileges. +widget.issue_filter.property.distributionAxis.option.types.name=By Type +widget.issue_filter.property.distributionAxis.option.severities.name=By Severity +widget.issue_filter.property.distributionAxis.option.projectUuids.name=By Project +widget.issue_filter.property.distributionAxis.option.statuses.name=By Status +widget.issue_filter.property.distributionAxis.option.createdAt.name=By Creation Date +widget.issue_filter.property.distributionAxis.option.assignees.name=By Assignee +widget.issue_filter.property.distributionAxis.option.tags.name=By Tag +widget.issue_filter.property.distributionAxis.option.rules.name=By Rule +widget.issue_filter.property.distributionAxis.option.resolutions.name=By Resolution +widget.issue_filter.property.distributionAxis.option.languages.name=By Language +widget.issue_filter.property.distributionAxis.option.authors.name=By Author +widget.issue_filter.property.displayMode.option.count.name=Issues +widget.issue_filter.property.displayMode.option.debt.name=Effort + +widget.project_issue_filter.name=Project Issue Filter +widget.project_issue_filter.description=Displays the result of a pre-configured issue filter applied to the project. +widget.project_issue_filter.property.filter.name=Filter +widget.project_issue_filter.property.distributionAxis.name=Distribution Axis +widget.project_issue_filter.property.displayFilterDescription.name=Display Filter Description +widget.project_issue_filter.property.displayMode.name=Display Mode +widget.project_issue_filter.unknown_filter_warning=This widget is configured to display an issue filter that doesn't exist anymore. +widget.project_issue_filter.insufficient_privileges_warning=Widget cannot be displayed: insufficient privileges. +widget.project_issue_filter.property.distributionAxis.option.types.name=By Type +widget.project_issue_filter.property.distributionAxis.option.severities.name=By Severity +widget.project_issue_filter.property.distributionAxis.option.statuses.name=By Status +widget.project_issue_filter.property.distributionAxis.option.createdAt.name=By Creation Date +widget.project_issue_filter.property.distributionAxis.option.assignees.name=By Assignee +widget.project_issue_filter.property.distributionAxis.option.tags.name=By Tag +widget.project_issue_filter.property.distributionAxis.option.rules.name=By Rule +widget.project_issue_filter.property.distributionAxis.option.resolutions.name=By Resolution +widget.project_issue_filter.property.distributionAxis.option.languages.name=By Language +widget.project_issue_filter.property.distributionAxis.option.authors.name=By Author +widget.project_issue_filter.property.displayMode.option.count.name=Issues +widget.project_issue_filter.property.displayMode.option.debt.name=Technical Debt + +widget.issue_tag_cloud.name=Project Issue Tag Cloud +widget.issue_tag_cloud.title=Issue Tag Cloud +widget.issue_tag_cloud.description=Displays the cloud of tags associated to unresolved issues. +widget.issue_tag_cloud.property.maxItems.name=Max Tags +widget.issue_tag_cloud.property.maxItems.desc=Maximum number of tags to show + widget.treemap-widget.name=Treemap of Components -widget.treemap-widget.property.chartTitle.name=Chart Title -widget.treemap-widget.property.colorMetric.desc=Metric used for square color +widget.treemap-widget.description=Displays a treemap of all direct components of the selected resource. +widget.treemap-widget.property.sizeMetric.name=Size Metric +widget.treemap-widget.property.sizeMetric.desc=Metric used for square size widget.treemap-widget.property.colorMetric.name=Color Metric -widget.treemap-widget.property.heightInPercents.desc=Height in percents of width +widget.treemap-widget.property.colorMetric.desc=Metric used for square color widget.treemap-widget.property.heightInPercents.name=Height -widget.treemap-widget.property.maxItems.desc=Maximum number of components to show +widget.treemap-widget.property.heightInPercents.desc=Height in percents of width +widget.treemap-widget.property.chartTitle.name=Chart Title widget.treemap-widget.property.maxItems.name=Max Components -widget.treemap-widget.property.sizeMetric.desc=Metric used for square size -widget.treemap-widget.property.sizeMetric.name=Size Metric -widget.unsupported_browser_warning=Your browser is out of date and does not support this widget. -widget.welcome.description=Welcome message used to provide links to the most valuable resources like documentation and support -widget.welcome.html=<h3 class="marginbottom5">Welcome to SonarQube Dashboard</h3><p class="marginbottom5">Since you are able to read this, it means that you have successfully started your SonarQube server. Well done!</p><p class="marginbottom5">If you have not removed this text, it also means that you have not yet played much with SonarQube. So here are a few pointers for your next step:</p> <ul class="bullet"><li>Do you now want to <a href="http://redirect.sonarsource.com/1">run analysis</a> on a project?</li> <li>Maybe start <a href="http://redirect.sonarsource.com/2">customizing dashboards</a>?</li><li>Or simply browse the <a href="http://redirect.sonarsource.com/3">complete documentation</a>?</li><li>If you have a question or an issue, please visit the <a href="http://www.sonarsource.org/get-support/">Get Support</a> page.</li></ul> +widget.treemap-widget.property.maxItems.desc=Maximum number of components to show + widget.welcome.name=Welcome -widgets.more=More -with=With -workspace.close=Remove from the list of pinned files -workspace.full_window=Expand to full window +widget.welcome.description=Welcome message used to provide links to the most valuable resources like documentation and support +widget.welcome.html=<h3 class="marginbottom5">Welcome to SonarQube</h3>\ + <p class="marginbottom5">Since you are able to read this, it means that you have successfully started your SonarQube server. Well done!</p>\ + <p class="marginbottom5">If you have not removed this text, it also means that you have not yet played much with SonarQube. So here are a few pointers for your next step:</p>\ + <ul class="bullet">\ + <li>Do you now want to <a href="http://redirect.sonarsource.com/1">run analysis</a> on a project ?</li>\ + <li>Maybe get familiar with <a href="http://redirect.sonarsource.com/doc/fix-the-leak.html">the Leak Concept</a> ?</li>\ + <li>Or simply browse the <a href="http://redirect.sonarsource.com/3">complete documentation</a> ?</li>\ + <li>If you have a question or an issue, please visit the <a href="http://www.sonarsource.org/get-support/">Get Support</a> page.</li>\ + </ul> + +widget.measure_filter_list.name=Measure Filter as List +widget.measure_filter_list.description=Displays the result of a pre-configured measure filter as a list. +widget.measure_filter_list.property.filter.name=Filter +widget.measure_filter_list.property.pageSize.name=Page Size +widget.measure_filter_list.property.pageSize.desc=Size limit is 250. +widget.measure_filter_list.property.displayFilterDescription.name=Display Filter Description + +widget.measure_filter_treemap.name=Measure Filter as Treemap +widget.measure_filter_treemap.description=Displays the result of pre-configured measure filter as a Treemap. +widget.measure_filter_treemap.property.filter.name=Filter +widget.measure_filter_treemap.property.sizeMetric.name=Size Metric +widget.measure_filter_treemap.property.sizeMetric.desc=Metric used for square size +widget.measure_filter_treemap.property.colorMetric.name=Color Metric +widget.measure_filter_treemap.property.colorMetric.desc=Metric used for square color +widget.measure_filter_treemap.property.heightInPercents.name=Height +widget.measure_filter_treemap.property.heightInPercents.desc=Height in percents of width +widget.measure_filter_treemap.property.chartTitle.name=Chart Title +widget.measure_filter_treemap.property.maxItems.name=Max Components +widget.measure_filter_treemap.property.maxItems.desc=Maximum number of components to show + +widget.debt_overview.name=Technical Debt Synopsis +widget.debt_overview.description=Display the maintainability rating and the technical debt ratio. +widget.debt_overview.on_new_code=On New Code + +# Below are labels used in widget edition pages +widget.image.name=Image +widget.image.description=Shows an image with a link +widget.filter.name=Filter +widget.filter.description=Shows a pre-configured filter +widget.filter.edit=Edit my filters +widget.resource_id=Project + + +#------------------------------------------------------------------------------ +# +# COMPONENTS +# +#------------------------------------------------------------------------------ + +components.no_projects_have_been_analysed=No projects have been analysed. +components.explanation_launch_sonar_to_have_results=If Maven and SonarQube are installed with default parameters on the same box, just launch the command <code>mvn sonar:sonar</code> to analyse your first project. In any other case, please refer to the <a href="http://www.sonarsource.org/documentation">documentation</a>. +components.note_changes_impact_all_users=Note that these changes will impact all users and all projects. + + +#------------------------------------------------------------------------------ +# +# DRILLDOWN +# +#------------------------------------------------------------------------------ + +drilldown.drilldown_on=Drilldown on +issues_drilldown.col.severity=Severity +issues_drilldown.col.rule=Rule +issues_drilldown.no_issue=No issue +drilldown.no_items_found=No items found + + +#------------------------------------------------------------------------------ +# +# RESOURCE VIEWER +# +#------------------------------------------------------------------------------ + +resource_viewer.resource_deleted=This resource has been deleted. + + +#------------------------------------------------------------------------------ +# +# ISSUES VIEWER +# +#------------------------------------------------------------------------------ + +issues_viewer.issue_filter.false_positives=False positives +issues_viewer.issue_filter.unassigned=Not assigned + + +#------------------------------------------------------------------------------ +# +# DUPLICATION VIEWER +# +#------------------------------------------------------------------------------ + +duplications.no_duplicated_block=No duplicated blocks. +duplications.dups_found_on_deleted_resource=This file contains duplicated blocks with some deleted resources. This project should be reanalyzed to remove these obsolete duplicated blocks. +duplications.block_was_duplicated_by_a_deleted_resource=This block was duplicated by a resource that has been deleted. +duplications.old_format_should_reanalyze=This file contains duplications but a new analysis must be done in order to be able to display them. +duplications.blocks=Blocks +duplications.number_of_lines=Nb Lines +duplications.from_line=From line +duplications.file=File +duplications.details=Details +duplications.expand=Expand +duplications.collapse=Collapse + + +#------------------------------------------------------------------------------ +# +# COVERAGE VIEWER +# +#------------------------------------------------------------------------------ +coverage_viewer.on_new_code=On new code +coverage_viewer.by=by unit tests +it_coverage_viewer.by=by integration tests +overall_coverage_viewer.by=by all tests +coverage_viewer.unit_tests=Unit Tests +coverage_viewer.integration_tests=Integration Tests +coverage_viewer.overall_tests=All Tests +coverage_viewer.per_test=Per test +coverage_viewer.lines_covered_per_test=Covered lines +coverage_viewer.select_test=Select a test +coverage_viewer.line_covered_by_x_tests=Line is covered by {0} tests +coverage_viewer.x_covered_conditions={0} conditions are covered by tests + +#------------------------------------------------------------------------------ +# +# GENERIC CODE VIEWER +# +#------------------------------------------------------------------------------ +code_viewer.no_info_displayed_due_to_security=Due to security settings, no information can be displayed. +code_viewer.no_source_code_displayed_due_to_security=Due to security settings, no source code can be displayed. + + +#------------------------------------------------------------------------------ +# +# TESTS VIEWER +# +#------------------------------------------------------------------------------ +test_viewer.tests=Tests +test_viewer.failures=Failures +test_viewer.errors=Errors +test_viewer.duration=Duration +test_viewer.unit_test_name=Unit test name +test_viewer.skipped=skipped +test_viewer.expand=expand +test_viewer.collapse=collapse +test_viewer.covered_lines=Covered Lines +test_viewer.tests_covering=Tests covering <b>{0}</b> on line <b>{1}</b> +test_viewer.files_covered_by=Files covered by <b>{0}</b> ({1}) + + +#------------------------------------------------------------------------------ +# +# MANUAL MEASURES +# +#------------------------------------------------------------------------------ + +manual_measures.add_measure=Add Manual Measure +manual_measures.manage_metrics=Manage Metrics +manual_measures.col.domain=Domain +manual_measures.col.metric=Metric +manual_measures.col.value=Value +manual_measures.col.description=Description +manual_measures.col.author=Author +manual_measures.col.date=Date +manual_measures.col.operations=Operations +manual_measures.col.last_change=Last change +manual_measures.col.last_change_label=By {0} at {1} +manual_measures.create_measure=Create Manual Measure +manual_measures.delete_measure=Delete Manual Measure +manual_measures.delete_measure.desc=Are you sure that you want to delete manual measure "{0}"? +manual_measures.edit_measure=Edit Manual Measure: {0} +manual_measures.save_button=Save +manual_measures.save_and_add_button=Save & Add new +manual_measures.pending_message=Pending measures are marked with orange box. Their values will be integrated to project during next analysis. +manual_measures.no_more_available_metric=All available manual metrics have a measure. +manual_measures.to_define_new_manual_metric_il_require=You can define new manual metrics if required. + + +#------------------------------------------------------------------------------ +# +# CUSTOM MEASURES +# +#------------------------------------------------------------------------------ + +custom_measures.pending=Pending +custom_measures.pending_tooltip=The value will be integrated to project during next analysis. +custom_measures.all_metrics_taken=There are already measures on all available custom metrics. + + + +#------------------------------------------------------------------------------ +# +# MANUAL MEASURES +# +#------------------------------------------------------------------------------ + +manual_rules.should_provide_real_description=Rule created on the fly. A description should be provided. +manual_rules.add_manual_rule=Add Manual Rule + + +#------------------------------------------------------------------------------ +# +# PROJECT HISTORY SERVICE +# +#------------------------------------------------------------------------------ + +project_history.col.year=Year +project_history.col.month=Month +project_history.col.day=Day +project_history.col.time=Time +project_history.col.events=Events +project_history.col.action=Action +project_history.col.version=Version +project_history.col.alert=Quality Gate Status +project_history.col.profile=Profile +project_history.delete=Delete +project_history.last_snapshot=Last Analysis +project_history.delete_snapshot=Delete +project_history.snapshot_deleted=The snapshot is deleted. +project_history.are_you_sure_delete_snapshot_x=Are you sure you want to delete the snapshot created on "{0}"? +project_history.rename_version=Rename +project_history.create_version=Create +project_history.remove_version=Remove +project_history.do_you_want_to_remove_version=Are you sure you want to remove "{0}" from this snapshot? +project_history.version_updated=Version was updated to "{0}" for current project. +project_history.version_created=Version "{0}" was created for current project. +project_history.version_removed=Version "{0}" was removed from current project. +project_history.version_already_exists=Version "{0}" already exists. +project_history.rename_event=Rename +project_history.create_event=Create +project_history.remove_event=Remove +project_history.event_updated=Event was successfully updated. +project_history.event_deleted=Event "{0}" was deleted. +project_history.event_created=Event "{0}" was created. +project_history.event_already_exists=Event "{0}" already exists. + + +#------------------------------------------------------------------------------ +# +# PROJECT / MODULE "UPDATE KEY" PAGE +# +#------------------------------------------------------------------------------ +update_key.bulk_update=Bulk Update +update_key.fine_grained_key_update=Fine-grained Update +update_key.old_key=Old Key +update_key.new_key=New Key +update_key.key_updated=The key has successfully been updated for all required resources. +update_key.key_updated.reload=The key has successfully been updated for all required resources. This page will be reloaded shortly. +update_key.bulk_change_description=The bulk update allows to replace a part of the current key(s) by another string on the current project and all its submodules - if applicable. +update_key.current_key_for_project_x_is_x=The key of the "{0}" project is currently "{1}". +update_key.replace=Replace +update_key.by=By +update_key.replace_example=org.myCompany +update_key.by_example=com.myNewCompany +update_key.cant_update_because_duplicate_keys=The replacement of "{0}" by "{1}" is impossible as it would result in duplicate keys (in red below): +update_key.keys_will_be_updated_as_follows=The resources will be updated as follows: +update_key.duplicate_key=Duplicate Key +update_key.no_key_to_update=No key contains the string to replace ("{0}"). +update_key.are_you_sure_to_change_key=Are you sure you want to change key of "{0}", as well as all its modules and resources? +update_key.see_results=See Results + + +#------------------------------------------------------------------------------ +# +# PROJECT QUALITY PROFILE PAGE +# +#------------------------------------------------------------------------------ +project_quality_profile.default_profile=Default +project_quality_profile.successfully_updated={0} quality profile has been successfully updated. + +#------------------------------------------------------------------------------ +# +# PROJECT QUALITY GATE PAGE +# +#------------------------------------------------------------------------------ +project_quality_gate.default_qgate=Default +project_quality_gate.successfully_updated=Quality gate has been successfully updated. + +#------------------------------------------------------------------------------ +# +# PROJECT (RESOURCE) DELETION PAGE +# +#------------------------------------------------------------------------------ + +project_deletion.delete_resource_confirmation=Are you sure you want to delete "{0}"? + + +#------------------------------------------------------------------------------ +# +# TIME MACHINE +# +#------------------------------------------------------------------------------ + +time_machine.show_date=Show date +time_machine.show_event=Show event +time_machine.distributions=Distributions +time_machine.distribution_chart=Distribution chart +time_machine.compare_on_chart=Compare on chart +time_machine.set_as_default_for_all_users=Set as default (for all users) + + +#------------------------------------------------------------------------------ +# +# CLOUDS +# +#------------------------------------------------------------------------------ + +cloud.quick_wins=Quick wins +cloud.top_risk=Top risk + + +#------------------------------------------------------------------------------ +# +# QUALITY PROFILES +# +#------------------------------------------------------------------------------ + +quality_profiles.quality_profiles=Quality Profiles +quality_profiles.new_profile=New Profile +quality_profiles.compare_profiles=Compare Profiles +quality_profiles.compare_with=Compare with +quality_profiles.restore_profile=Restore Profile +quality_profiles.restore_submit=Restore +quality_profiles.restore_profile.success={1} rule(s) restored in profile "{0}" +quality_profiles.restore_profile.warning={1} rule(s) restored, {2} rule(s) ignored in profile "{0}" +quality_profiles.x_language_profiles={0} Profiles +quality_profiles.optional_configuration_file=Optional configuration file +quality_profiles.create_x_language_profile=Create {0} Profile +quality_profiles.are_you_sure_want_x_profile_as_default=Are you sure that you want to set the profile "{0}" as default? +quality_profiles.profile_x_created=Profile "{0}" created. Set it as default or link it to a project to use it for next measures. +quality_profiles.already_exists=This profile already exists. +quality_profiles.profile_x_already_exists=Profile "{0}" already exists. +quality_profiles.please_type_profile_name=Please type a profile name. +quality_profiles.profile_x_deleted=Profile "{0}" is deleted. +quality_profiles.default_profile_is_x=Default profile is "{0}". +quality_profiles.profile_x_not_activated=Profile "{0}" is created but not activated. +quality_profiles.please_upload_backup_file=Please upload a backup file. +quality_profiles.profile_x_associated_to_x_projects=Profile "{0}" associated to {1} projects. +quality_profiles.profile_name_cant_be_blank=Profile name can not be blank. +quality_profiles.new_name=New name +quality_profiles.name_for_new_profile=Name for the new profile +quality_profiles.delete_confirm_title=Delete Profile +quality_profiles.are_you_sure_want_delete_profile_x=Are you sure that you want to delete the profile "{0}"? +quality_profiles.are_you_sure_want_delete_profile_x_and_descendants=Are you sure that you want to delete the profile "{0}" and all its descendants? +quality_profiles.this_profile_has_descendants=This profile has descendants. +quality_profiles.editing_profile=Editing profile +quality_profiles.profile_inheritance=Inheritance +quality_profiles.available_projects=Available projects +quality_profiles.associated_projects=Associated projects +quality_profiles.no_projects_associated_to_profile=No projects are explicitly associated to the profile. +quality_profiles.projects_warning=List of projects explicitly associated to this Quality profile : +quality_profiles.including_x_overriding.suffix=, incl. {0} overriding +quality_profiles.set_parent=Set parent +quality_profiles.inherit_rules_from_profile=Inherit rules configuration from the profile +quality_profiles.no_version=no version +quality_profiles.last_version_x_with_date=last version {0} ({1}) +quality_profiles.version_x_with_date=version {0} ({1}) +quality_profiles.version_x=version {0} +quality_profiles.parameter_set_to=Parameter {0} set to {1} +quality_profiles.only_in_profile_x=Only in {0} +quality_profiles.with_different_configuration=With different configuration +quality_profiles.with_same_configuration=With same configuration +quality_profiles.x_rules_only_in={0} rules only in +quality_profiles.x_rules_have_different_configuration={0} rules have a different configuration +quality_profiles.remove_project_action=Remove +quality_profiles.remove_projects_action=Remove All +quality_profiles.add_project_action=Add Project +quality_profiles.remove_project_confirm_title=Remove Project from Profile +quality_profiles.remove_project_confirm_message=Are you sure that you want to dissociate the project "{0}" from this profile? The default profile will be used during next analysis of this project. +quality_profiles.remove_project_confirm_button=Remove +quality_profiles.remove_projects_confirm_title=Remove All Projects from Profile +quality_profiles.remove_projects_confirm_message=Are you sure that you want to dissociate all the projects from this profile? The default profile will be used during next analysis of these projects. +quality_profiles.remove_projects_confirm_button=Remove All +quality_profiles.copy_x_title=Copy Profile {0} - {1} +quality_profiles.copy_new_name=New name +quality_profiles.copy_overwrite_x=You are about to copy this quality profile into the existing "{0}" profile, which will fully overwrite it. Please confirm the name if you want to overwrite, or choose another name. +quality_profiles.copy_x_overwritten=Profile '{0}' has been overwritten. +quality_profiles.rename_x_title=Rename Profile {0} - {1} +quality_profiles.restore_built_in_profiles=Restore Built-in Profiles +quality_profiles.restore_built_in_profiles_confirmation=Are you sure you want to restore {0} built-in profiles? +quality_profiles.restore_built_in_profiles_success_message={0} built-in profiles have been restored. +quality_profiles.including=including +quality_profiles.deprecated=deprecated +quality_profiles.manage_rules_tooltip=Manage rules of this profile +quality_profiles.manage_rules_tooltip_x_profile=Manage rules of profile '{0}' +quality_profiles.see_rules_tooltip=See rules of this profile +quality_profiles.see_rules_tooltip_x_profile=See rules of profile '{0}' +quality_profiles.severity_set_to=Severity set to +quality_profiles.changelog_from=Changelog from +quality_profiles.changelog.empty=No changes have been done. +quality_profiles.changelog.ACTIVATED=Activated +quality_profiles.changelog.DEACTIVATED=Deactivated +quality_profiles.changelog.UPDATED=Updated +quality_profiles.changelog.parameter_reset_to_default_value=Parameter {0} reset to default value +quality_profiles.deleted_profile=The profile {0} doesn't exist anymore +quality_profiles.projects_for_default=Every project not specifically associated with a quality profile will be associated to this one by default. +quality_profiles.projects_for_default.edit=You must not select specific projects for the default quality profile. +quality_profiles.inherits=Inherits "{0}" +quality_profile.x_rules={0} rule(s) +quality_profile.x_active_rules={0} active rules +quality_profiles.x_overridden_rules={0} overridden rules +quality_profiles.change_parent=Change Parent +quality_profiles.all_profiles=All Profiles +quality_profiles.x_profiles={0} profile(s) +quality_profiles.x_Profiles={0} Profiles +quality_profiles.x_projects={0} projects +quality_profiles.no_results=No profiles found. Try installing a language plugin. +quality_profiles.projects.select_hint=Click to associate this project with the quality profile +quality_profiles.projects.deselect_hint=Click to remove association between this project and the quality profile +quality_profiles.no_profiles_for_comparison=There are no profiles for comparison +quality_profile.empty_comparison=The quality profiles are equal. +quality_profiles.activate_more=Activate More +quality_profiles.activate_more_rules=Activate More Rules +quality_profiles.intro1=Quality Profiles are collections of rules to apply during an analysis. +quality_profiles.intro2=For each language there is a default profile. All projects not explicitly assigned to some other profile will be analyzed with the default. +quality_profiles.list.profile=Profile +quality_profiles.list.inheritance=Inheritance +quality_profiles.list.projects=Projects +quality_profiles.list.rules=Rules +quality_profiles.list.updated=Updated +quality_profiles.list.used=Used +quality_profiles.x_activated_out_of_y={0} rules activated out of {1} available +quality_profiles.change_projects=Change Projects +quality_profiles.not_found=The requested quality profile was not found. +quality_profiles.latest_new_rules=Latest New Rules +quality_profiles.latest_new_rules.activated={0}, activated on {1} profile(s) +quality_profiles.latest_new_rules.not_activated={0}, not yet activated +quality_profiles.deprecated_rules=Deprecated Rules +quality_profiles.deprecated_rules_are_still_activated=Deprecated rules are still activated on {0} quality profile(s): +quality_profiles.stagnant_profiles=Stagnant Profiles +quality_profiles.not_updated_more_than_year=The following profiles haven't been updated for more than 1 year: +quality_profiles.exporters=Exporters +quality_profiles.updated_=Updated: +quality_profiles.used_=Used: + + + + +#------------------------------------------------------------------------------ +# +# QUALITY GATES +# +#------------------------------------------------------------------------------ + +quality_gates.noQualityGates=No Quality Gates +quality_gates.create=Create Quality Gate +quality_gates.rename=Rename Quality Gate +quality_gates.delete=Delete Quality Gate +quality_gates.copy=Copy Quality Gate +quality_gates.conditions=Conditions +quality_gates.projects=Projects +quality_gates.add_condition=Add Condition +quality_gates.no_conditions=No Conditions +quality_gates.introduction=Only project measures are checked against thresholds. Sub-projects, directories and files are ignored. +quality_gates.health_icons=Project health icons represent: +quality_gates.metric=Metric +quality_gates.threshold=Threshold +quality_gates.projects_for_default=Every project not specifically associated to a quality gate will be associated to this one by default. +quality_gates.projects_for_default.edit=You must not select specific projects for the default quality gate. +quality_gates.projects.with=With +quality_gates.projects.without=Without +quality_gates.projects.all=All +quality_gates.projects.noResults=No Projects +quality_gates.projects.select_hint=Click to associate this project with the quality gate +quality_gates.projects.deselect_hint=Click to remove association between this project and the quality gate +quality_gates.operator.LT=is less than +quality_gates.operator.GT=is greater than +quality_gates.operator.EQ=equals +quality_gates.operator.NE=is not +quality_gates.operator.LT.short=< +quality_gates.operator.GT.short=> +quality_gates.operator.EQ.short== +quality_gates.operator.NE.short=\u2260 +quality_gates.delete.confirm.message=Are you sure you want to delete the "{0}" quality gate? +quality_gates.delete.confirm.default=Are you sure you want to delete the "{0}" quality gate, which is the default quality gate? +quality_gates.delete_condition=Delete Condition +quality_gates.delete_condition.confirm.message=Are you sure you want to delete the "{0}" condition? +quality_gates.project_period=over period {0} - defined at project level +quality_gates.warning_tooltip=Warning Threshold +quality_gates.error_tooltip=Error Threshold +quality_gates.condition.leak.yes=Yes +quality_gates.condition.leak.no=No +quality_gates.condition.leak.unconditional=Always +quality_gates.conditions.metric=Metric +quality_gates.conditions.leak=Over Leak Period +quality_gates.conditions.operator=Operator +quality_gates.conditions.warning=Warning +quality_gates.conditions.error=Error +quality_gates.duplicated_conditions=This quality gate has duplicated conditions: +quality_gates.intro.1=Quality Gates are collections of simple boolean thresholds set on project measures. A project must pass each of the thresholds in order to pass the Quality Gate as a whole. +quality_gates.intro.2=It is possible to set a default Quality Gate, which will be applied to all projects not explicitly assigned to some other gate. + +#------------------------------------------------------------------------------ +# +# RULES DOCUMENTATION PAGE +# +#------------------------------------------------------------------------------ +rules.more_about_rule_on_profile_x=More about this rule on profile "{0}" +rules.identification=Identification +rules.parameters=Parameters +rules.not_found=The rule "{0}" does not exist +rules.status.beta=Beta +rules.status.BETA=Beta +rules.status.deprecated=Deprecated +rules.status.DEPRECATED=Deprecated +rules.status.ready=Ready +rules.status.READY=Ready + + +#------------------------------------------------------------------------------ +# +# CODING RULES +# +#------------------------------------------------------------------------------ +coding_rules.active_in_all_profiles=The rule is already activated on all available quality profiles. +coding_rules.activate=Activate +coding_rules.activate_in=Activate In +coding_rules.activate_in_quality_profile=Activate In Quality Profile +coding_rules.activate_in_all_quality_profiles=Activate In All {0} Profiles +coding_rules.add_note=Add Note +coding_rules.add_tags=Add Tags +coding_rules.available_since=Available Since +coding_rules.bulk_change=Bulk Change +coding_rules.bulk_change.success={2} rule(s) changed in profile {0} - {1} +coding_rules.bulk_change.warning={2} rule(s) changed, {3} rule(s) ignored in profile {0} - {1} +coding_rules.change_severity=Change Severity +coding_rules.change_severity_in=Change Severity In +coding_rules.change_details=Change Details of Quality Profile +coding_rules.create=Create +coding_rules.create_custom_rule=Create Custom Rule +coding_rules.custom_rule=Custom Rule +coding_rules.custom_rule.title=This rule has been created through customization of a rule template +coding_rules.custom_rule.activation_notice=Note: parameters of a custom rule are not customizable on rule activation, only during creation/edit. +coding_rules.custom_rules=Custom Rules +coding_rules.delete_rule=Delete Rule +coding_rules.delete.custom.confirm=Are you sure you want to delete custom rule "{0}"? +coding_rules.extend_description=Extend Description +coding_rules.deactivate_in=Deactivate In +coding_rules.deactivate=Deactivate +coding_rules.deactivate.confirm=Are you sure you want to deactivate this rule in the profile? +coding_rules.deactivate_in_quality_profile=Deactivate In Quality Profile +coding_rules.deactivate_in_all_quality_profiles=Deactivate In All {0} Profiles +coding_rules.found=Found +coding_rules.inherits="{0}" inherits from "{1}" +coding_rules.issues=Issues +coding_rules.key=Key: +coding_rules.most_violated_projects=Most Violated Projects +coding_rules.new_search=New Search +coding_rules.no_results=No Coding Rules +coding_rules.no_tags=No tags +coding_rules.order=Order +coding_rules.ordered_by=Ordered By +coding_rules.original=Original: +coding_rules.overrides="{0}" overrides "{1}" +coding_rules.overwrite=Overwrite +coding_rules.parameter.empty=(empty) +coding_rules.parameters=Parameters +coding_rules.parameters.default_value=Default Value: +coding_rules.permalink=Permalink +coding_rules.quality_profiles=Quality Profiles +coding_rules.quality_profiles.template_caption=This rule template was activated on the following profiles in previous versions of SonarQube. It is not possible anymore to do so. Instead, please create a custom rule. +coding_rules.quality_profile=Quality Profile +coding_rules.reactivate=Reactivate +coding_rules.reactivate.help=A rule with the same key has been previously deleted. Please reactivate the existing rule or modify the key to create a new rule. +coding_rules.return_to_list=Return to List +coding_rules.remove_extended_description.confirm=Are you sure you want to remove the extended description? +coding_rules.repository=Repository: +coding_rules.revert_to_parent_definition=Revert to Parent Definition +coding_rules.revert_to_parent_definition.confirm=This rule will be reverted to the parameters defined in profile {0}. Are you sure? +coding_rules.rule_template=Rule Template +coding_rules.rule_template.title=This rule can be used as a template to create custom rules,\nit cannot be activated on a profile +coding_rules._rules=rules +coding_rules.select_tag=Select Tag +coding_rules.show_template=Show Template +coding_rules.type.tooltip.CODE_SMELL=Code Smell Detection Rule +coding_rules.type.tooltip.BUG=Bug Detection Rule +coding_rules.type.tooltip.VULNERABILITY=Vulnerability Detection Rule +coding_rules.noncharacterized=Uncharacterized +coding_rules.update_custom_rule=Update Custom Rule +coding_rules.filter_similar_rules=Filter Similar Rules + +coding_rules.validation.invalid_rule_key=The rule key "%s" is invalid, it should only contain: a-z, 0-9, "_" +coding_rules.validation.missing_name=The name is missing +coding_rules.validation.missing_description=The description is missing +coding_rules.validation.missing_severity=The severity is missing +coding_rules.validation.invalid_severity=Severity "{0}" is invalid +coding_rules.validation.missing_status=The status is missing + +coding_rules.filters.activation=Activation +coding_rules.filters.activation.active=Active +coding_rules.filters.activation.inactive=Inactive +coding_rules.filters.activation.help=Activation criterion is available when a quality profile is selected +coding_rules.filters.active_severity=Active Severity +coding_rules.filters.active_severity.inactive=Active severity criterion is available when a quality profile is selected +coding_rules.filters.availableSince=Available Since +coding_rules.filters.characteristic=Characteristic +coding_rules.filters.description=Description +coding_rules.filters.quality_profile=Quality Profile +coding_rules.filters.inheritance=Inheritance +coding_rules.filters.inheritance.inactive=Inheritance criterion is available when an inherited quality profile is selected +coding_rules.filters.inheritance.none=Not Inherited +coding_rules.filters.inheritance.inherited=Inherited +coding_rules.filters.inheritance.overrides=Overridden +coding_rules.filters.key=Key +coding_rules.filters.language=Language +coding_rules.filters.name=Name +coding_rules.filters.repository=Repository +coding_rules.filters.severity=Severity +coding_rules.filters.status=Status +coding_rules.filters.tag=Tag +coding_rules.filters.template=Templates +coding_rules.filters.template.is_template=Show Templates Only +coding_rules.filters.template.is_not_template=Hide Templates + +coding_rules.facet.languages=Language +coding_rules.facet.repositories=Repository +coding_rules.facet.tags=Tag +coding_rules.facet.qprofile=Quality Profile +coding_rules.facet.debt_characteristics=Characteristic +coding_rules.facet.severities=Default Severity +coding_rules.facet.statuses=Status +coding_rules.facet.available_since=Available Since +coding_rules.facet.inheritance=Inheritance +coding_rules.facet.active_severities=Activation Severity +coding_rules.facet.is_template=Template +coding_rules.facet.rule_key=Rule +coding_rules.facet.types=Type + +coding_rules.facets.languages=Languages +coding_rules.facets.tags=Tags +coding_rules.facets.repositories=Repositories +coding_rules.facets.top=Top {0} + +coding_rules.sort.creation_date=Creation Date +coding_rules.sort.name=Name +coding_rules.sort.relevance=Relevance + +coding_rules.remediation_function=Remediation function +coding_rules.remediation_function.LINEAR=Linear +coding_rules.remediation_function.LINEAR_OFFSET=Linear with offset +coding_rules.remediation_function.CONSTANT_ISSUE=Constant/issue +coding_rules.remediation_function.coeff=Coeff +coding_rules.remediation_function.offset=Offset +coding_rules.remediation_function.constant=Constant + +#------------------------------------------------------------------------------ +# +# EMAIL CONFIGURATION +# +#------------------------------------------------------------------------------ +email_configuration.smtp_host=SMTP host +email_configuration.smtp_host.description=For example "smtp.gmail.com". Leave blank to disable email sending. +email_configuration.smtp_port=SMTP port +email_configuration.smtp_port.description=Port number to connect with SMTP server. +email_configuration.smtp_secure_connection=Use secure connection +email_configuration.smtp_secure_connection.description=Whether to use secure connection and its type. +email_configuration.smtp_username=SMTP username +email_configuration.smtp_username.description=Optional - if you use authenticated SMTP, enter your username. +email_configuration.smtp_password=SMTP password +email_configuration.smtp_password.description=Optional - as above, enter your password if you use authenticated SMTP. +email_configuration.from_address=From address +email_configuration.from_address.description=Emails will come from this address. For example - "noreply@sonarsource.com". Note that server may ignore this setting (like does GMail). +email_configuration.email_prefix=Email prefix +email_configuration.email_prefix.description=This prefix will be prepended to all outgoing email subjects. +email_configuration.save_settings=Save Email Settings +email_configuration.saving_settings=Saving +email_configuration.settings_saved=Settings are saved. + +email_configuration.test.title=Test Configuration +email_configuration.test.to_address=To +email_configuration.test.to_address_required=You must provide address where to send test email +email_configuration.test.subject=Subject +email_configuration.test.subject_text=Test Message from SonarQube +email_configuration.test.message=Message +email_configuration.test.message_text=This is a test message from SonarQube. +email_configuration.test.send=Send Test Email +email_configuration.test.sending=Sending Test Email +email_configuration.test.email_was_sent_to_x=Email was sent to {0} + + +#------------------------------------------------------------------------------ +# +# LICENSES & SERVER KEY CONFIGURATION +# +#------------------------------------------------------------------------------ +property.category.licenses=Licenses +property.category.licenses.description=In case of any issue or question about licenses, please send an email to <a href="mailto:contact@sonarsource.com?subject=Question about license">contact@sonarsource.com</a>. +property.category.licenses.server_id=Server ID +server_id_configuration.generate_button=Generate ID +server_id_configuration.generating_button=Generating ID... +server_id_configuration.bad_key=The ID is not valid anymore. Please check the organisation and the IP address. +server_id_configuration.information=The Server ID is a unique identifier of this SonarQube instance. It is used for example to obtain a license key for the SonarSource's commercial plugins. Two fields have to be provided to generate the ID : organisation name and one of the IP addresses of the machine that hosts this server. There is no need to restart the server after generating a new server ID. +server_id_configuration.organisation.title=Organisation +server_id_configuration.organisation.desc=Name of the organisation +server_id_configuration.organisation.pattern=Only letters, digits and whitespaces are allowed. +server_id_configuration.ip.title=Fixed IP Address +server_id_configuration.ip.desc=A server ID is linked to the IP address of the hosting machine that runs SonarQube. If the server IP address was to change, the server ID will have to be regenerated. The valid addresses are : +server_id_configuration.generation_error=Organisation and/or IP address are not valid. +server_id_configuration.fields_cannot_be_blank=Organisation and IP address cannot be blank. +server_id_configuration.does_not_match_organisation_pattern=Organisation does not match the required pattern. +licenses.list.product=Product +licenses.list.organization=Organization +licenses.list.expiration=Expiration +licenses.list.type=Type +licenses.list.server=Server +licenses.update_license_for_x=Update License for {0} +licenses.license_input_label=Insert the license text below: +licenses.license_input_note=Keep empty if you want to unset this license. +licenses.success_message=The license has been updated. +licenses.error_message=The license you have just set is invalid. +licenses.there_are_invalid=Some of the licenses are not valid. Please check the details below. + + +#------------------------------------------------------------------------------ +# +# NOTIFICATIONS +# +#------------------------------------------------------------------------------ +notification.channel.EmailNotificationChannel=Email +notification.dispatcher.information=Receive notifications when specific types of events occur. A notification is never sent to the author of the event. +notification.dispatcher.ChangesOnMyIssue=Changes in issues assigned to me +notification.dispatcher.NewIssues=New issues +notification.dispatcher.NewAlerts=New quality gate status +notification.dispatcher.NewFalsePositiveIssue=Issues resolved as false positive or won't fix +notification.dispatcher.SQ-MyNewIssues=My new issues + + +#------------------------------------------------------------------------------ +# +# ALERTS +# +#------------------------------------------------------------------------------ + +alerts.no_alerts=No alerts. +alerts.notes.description=<p>Only project measures are checked against thresholds. Modules, packages and classes are ignored.</p>Project health icons represent : +alerts.notes.ok=at least one threshold is defined, no threshold is reached. +alerts.notes.warn=at least one warning threshold is reached, no error threshold is reached. +alerts.notes.error=at least one error threshold is reached. +alerts.select_metric=Select a metric +alerts.operator.<=is less than +alerts.operator.>=is greater than +alerts.operator.\==equals +alerts.operator.!\==is not + +#------------------------------------------------------------------------------ +# +# EVENTS +# +#------------------------------------------------------------------------------ + +events.add_an_event=Add an event +events.name_required=Name (required) + +#------------------------------------------------------------------------------ +# +# USER +# +#------------------------------------------------------------------------------ +user.bad_login=Use only letters, numbers, and .-_@ please. +user.password_doesnt_match_confirmation=Password doesn't match confirmation. +user.reactivated=The user '{0}' has been reactivated. +user.add_scm_account=Add SCM account +user.scm_account_already_used=The scm account '{0}' is already used by user(s) : '{1}' +user.login_or_email_used_as_scm_account=Login and email are automatically considered as SCM accounts +user.password_cant_be_changed_on_external_auth=Password cannot be changed when external authentication is used + + +#------------------------------------------------------------------------------ +# +# MY PROFILE & MY ACCOUNT +# +#------------------------------------------------------------------------------ +my_profile.login=Login +my_profile.name=Name +my_profile.email=Email +my_profile.groups=Groups +my_profile.scm_accounts=SCM Accounts +my_profile.password.title=Change password +my_profile.password.old=Old Password +my_profile.password.new=New Password +my_profile.password.confirm=Confirm Password +my_profile.password.submit=Change password +my_profile.password.changed=The password has been changed! +my_profile.password.empty=Password can not be empty +my_profile.password.wrong_old=Wrong old password +my_profile.notifications.submit=Save changes +my_profile.overall_notifications.title=Overall notifications +my_profile.per_project_notifications.title=Notifications per project +my_profile.add_project=Add project +my_profile.remove_this_line=Remove this line +my_profile.favorites.title=Favorites + +my_account.page=My Account +my_account.favorite_components=Favorite Components +my_account.no_favorite_components=You do not have favorite components yet. +my_account.favorite_issue_filters=Favorite Issue Filters +my_account.no_favorite_issue_filters=You do not have favorite issue filters yet. +my_account.favorite_measure_filters=Favorite Measure Filters +my_account.no_favorite_measure_filters=You do not have favorite measure filters yet. +my_account.notifications=Notifications +my_account.no_project_notifications=You have not set project notifications yet. +my_account.security=Security +my_account.tokens_description=If you want to enforce security by not providing credentials of a real SonarQube user to run your code scan or to invoke web services, you can provide a User Token as a replacement of the user login. This will increase the security of your installation by not letting your analysis user's password going through your network. +my_account.my_issues=My Issues +my_account.issue_widget.leak_last_week=Leak Last Week +my_account.issue_widget.by_project=My Issues by Project +my_account.issue_widget.by_severity=My Issues by Severity +my_account.to_fix=To Fix +my_account.to_review=To Review +my_account.projects=Projects +my_account.projects.description=Those projects are the ones you are administering. +my_account.projects.no_results=You are not administering any project yet. +my_account.projects.analyzed_x=Analyzed {0} +my_account.projects.never_analyzed=Never analyzed +my_account.projects.x_characters_min=({0} characters min) + + + +#------------------------------------------------------------------------------ +# +# BULK RESOURCE DELETION +# +#------------------------------------------------------------------------------ +bulk_deletion.resource.projects=Projects +bulk_deletion.resource.views=Views +bulk_deletion.resource.devs=Developers +bulk_deletion.resource_name_filter_by_name=Filter by name: +bulk_deletion.filter=Filter +bulk_deletion.page_size=Page size +bulk_deletion.select_all=Select all +bulk_deletion.select_all_x_resources=Select all {0} components +bulk_deletion.clear_selection=Clear selection of all {0} components +bulk_deletion.following_deletions_failed=The following components could not be deleted. Please check the logs to know more about it. +bulk_deletion.hide_message=Hide message +bulk_deletion.sure_to_delete_the_resources=Are you sure you want to delete the selected components? +bulk_deletion.please_select_at_least_one_resource=Please select at least one component to delete. +bulk_deletion.deletion_manager.deleting_resources=Deleting components... +bulk_deletion.deletion_manager.no_resource_to_delete=No results. +bulk_deletion.deletion_manager.currently_deleting_x_out_of_x=Currently deleting components... ({0} out of {1}) +bulk_deletion.deletion_manager.deletion_completed=Component deletion completed. +bulk_deletion.deletion_manager.however_failures_occurred=However, some failures occurred. +bulk_deletion.started_since_x=Started {0} ago +bulk_deletion.ghosts=Ghosts +bulk_deletion.ghosts.description=A ghost is the result of constantly failed attempts to analyse a project. In such a case, the project is not linked to any successful analysis, and therefore cannot be displayed in SonarQube. When the user authentication is forced, leaving a ghost can even prevent further analyses of the corresponding project. +bulk_deletion.no_ghosts=There is currently no ghost. +bulk_deletion.following_ghosts_can_be_deleted=The following ghosts can be safely deleted: +bulk_deletion.delete_all_ghosts=Delete all ghosts + + +#------------------------------------------------------------------------------ +# +# PROJECT PROVISIONING +# +#------------------------------------------------------------------------------ +provisioning.no_results=There is currently no provisioned project. +provisioning.missing.key=Key is missing +provisioning.missing.name=Name is missing +provisioning.no_analysis=No analysis has been performed since creation. The only available section is the configuration. + + +#------------------------------------------------------------------------------ +# +# TREEMAP +# +#------------------------------------------------------------------------------ +treemap.open_dashboard=Open Dashboard +treemap.all_measures_undefined=The widget cannot be displayed, because all components don't have the size measure. + + +#------------------------------------------------------------------------------ +# +# RULE SEVERITIES +# +#------------------------------------------------------------------------------ + +severity.BLOCKER=Blocker +severity.BLOCKER.description=Must be fixed immediately. +severity.CRITICAL=Critical +severity.CRITICAL.description=Must be reviewed immediately and fixed soon. +severity.MAJOR=Major +severity.MAJOR.description=High potential for significant to moderate impact. +severity.MINOR=Minor +severity.MINOR.description=Potential for moderate to minor impact. +severity.INFO=Info +severity.INFO.description=Neither a bug nor a quality flaw. Just a finding. + +#------------------------------------------------------------------------------ +# +# METRIC DOMAINS +# +#------------------------------------------------------------------------------ + +metric_domain.Size=Size +metric_domain.Tests=Tests +metric_domain.Integration Tests=Integration Tests +metric_domain.Complexity=Complexity +metric_domain.Documentation=Documentation +metric_domain.Rules=Rules +metric_domain.General=General +metric_domain.Duplication=Duplication +metric_domain.Design=Design +metric_domain.SCM=SCM +metric_domain.Maintainability=Maintainability +metric_domain.Reliability=Reliability +metric_domain.Security=Security +metric_domain.Issues=Issues +metric_domain.Duplications=Duplications +metric_domain.Coverage=Coverage + +#-------------------------------------------------------------------------------------------------------------------- +# +# METRIC TYPES +# +#-------------------------------------------------------------------------------------------------------------------- + +metric.type.INT=Integer +metric.type.FLOAT=Float +metric.type.PERCENT=Percent +metric.type.BOOL=Boolean +metric.type.STRING=String +metric.type.MILLISEC=Milliseconds +metric.type.DATA=Data +metric.type.LEVEL=Level +metric.type.DISTRIB=Distribution +metric.type.RATING=Rating +metric.type.WORK_DUR=Work Duration + +metric.level.ERROR=Failed +metric.level.WARN=Warning +metric.level.OK=Passed + +#------------------------------------------------------------------------------ +# +# METRICS +# +#------------------------------------------------------------------------------ + +metric.abstractness.description=Abstractness +metric.abstractness.name=Abstractness +metric.accessors.description=Accessors +metric.accessors.name=Accessors +metric.alert_status.abbreviation=QG +metric.alert_status.description=The project status with regard to its quality gate. +metric.alert_status.name=Quality Gate Status +metric.authors_by_line.description=Authors by line +metric.authors_by_line.name=Authors by Line +metric.blocker_violations.description=Blocker issues +metric.blocker_violations.name=Blocker Issues +metric.branch_coverage.description=Condition coverage +metric.branch_coverage.name=Condition Coverage +metric.bugs.description=Bugs +metric.bugs.name=Bugs +metric.ca.description=Afferent couplings +metric.ca.name=Afferent Couplings +metric.ce.description=Efferent couplings +metric.ce.name=Efferent Couplings +metric.classes.description=Classes +metric.classes.name=Classes +metric.class_complexity.abbreviation=Cmpx/class +metric.class_complexity.description=Complexity average by class +metric.class_complexity.name=Complexity / Class +metric.class_complexity_distribution.description=Classes distribution /complexity +metric.class_complexity_distribution.name=Class Distribution / Complexity +metric.code_smells.description=Code Smells +metric.code_smells.name=Code Smells +metric.commented_out_code_lines.description=Commented lines of code +metric.commented_out_code_lines.name=Commented-Out LOC +metric.comment_blank_lines.description=Comments that do not contain comments +metric.comment_blank_lines.name=Blank Comments +metric.comment_lines.description=Number of comment lines +metric.comment_lines.name=Comment Lines +metric.comment_lines_density.description=Comments balanced by ncloc + comment lines +metric.comment_lines_density.name=Comments (%) +metric.complexity.abbreviation=Cmpx +metric.complexity.description=Cyclomatic complexity +metric.complexity.name=Complexity +metric.complexity_in_classes.description=Cyclomatic complexity in classes +metric.complexity_in_classes.name=Complexity in Classes +metric.complexity_in_functions.description=Cyclomatic complexity in functions +metric.complexity_in_functions.name=Complexity in Functions +metric.conditions_by_line.description=Conditions by line +metric.conditions_by_line.name=Conditions by Line +metric.conditions_to_cover.description=Conditions to cover +metric.conditions_to_cover.name=Conditions to Cover +metric.confirmed_issues.description=Confirmed issues +metric.confirmed_issues.name=Confirmed Issues +metric.coverage.description=Coverage by unit tests +metric.coverage.name=Coverage +metric.coverage_line_hits_data.description=Coverage hits by line +metric.coverage_line_hits_data.name=Coverage Hits by Line +metric.covered_conditions.description=Covered conditions +metric.covered_conditions.name=Covered Conditions +metric.covered_conditions_by_line.description=Covered conditions by line +metric.covered_conditions_by_line.name=Covered Conditions by Line +metric.covered_lines.description=Covered lines +metric.covered_lines.name=Covered Lines +metric.critical_violations.description=Critical issues +metric.critical_violations.name=Critical Issues +metric.development_cost.name=SQALE Development Cost +metric.directories.abbreviation=Dirs +metric.directories.description=Directories +metric.directories.name=Directories +metric.distance.description=Distance +metric.distance.name=Distance +metric.dit.description=Depth in Inheritance Tree +metric.dit.name=Depth in Tree +metric.dsm.description=Dependency Matrix +metric.dsm.name=Dependency Matrix +metric.duplicated_blocks.abbreviation=Dup. blocks +metric.duplicated_blocks.description=Duplicated blocks +metric.duplicated_blocks.name=Duplicated Blocks +metric.duplicated_files.abbreviation=Dup. files +metric.duplicated_files.description=Duplicated files +metric.duplicated_files.name=Duplicated Files +metric.duplicated_lines.abbreviation=Dup. lines +metric.duplicated_lines.description=Duplicated lines +metric.duplicated_lines.name=Duplicated Lines +metric.duplicated_lines_density.abbreviation=Dup. lines(%) +metric.duplicated_lines_density.description=Duplicated lines balanced by statements +metric.duplicated_lines_density.name=Duplicated Lines (%) +metric.duplicated_lines_density.short_name=Duplications +metric.duplications_data.description=Duplications details +metric.duplications_data.name=Duplication Details +metric.efficiency.description=Efficiency +metric.efficiency.name=Efficiency +metric.effort_to_reach_maintainability_rating_a.description=Effort to reach maintainability rating A +metric.effort_to_reach_maintainability_rating_a.name=Effort to Reach Maintainability Rating A +metric.false_positive_issues.description=False positive issues +metric.false_positive_issues.name=False Positive Issues +metric.files.description=Number of files +metric.files.name=Files +metric.file_complexity.abbreviation=Cmpx/file +metric.file_complexity.description=Complexity average by file +metric.file_complexity.name=Complexity / File +metric.file_complexity_distribution.description=Files distribution /complexity +metric.file_complexity_distribution.name=File Distribution / Complexity +metric.file_cycles.description=File cycles +metric.file_cycles.name=File Cycles +metric.file_edges_weight.description=File edges weight +metric.file_edges_weight.name=File Edges Weight +metric.file_feedback_edges.description=Suspect file dependencies +metric.file_feedback_edges.name=Suspect File Dependencies +metric.file_tangles.description=Files tangles +metric.file_tangles.name=File Tangles +metric.file_tangle_index.description=File tangle index +metric.file_tangle_index.name=File Tangle Index +metric.functions.description=Functions +metric.functions.name=Functions +metric.function_complexity.abbreviation=Cmpx/function +metric.function_complexity.description=Complexity average by function +metric.function_complexity.name=Complexity / Function +metric.function_complexity_distribution.description=Functions distribution /complexity +metric.function_complexity_distribution.name=Function Distribution / Complexity +metric.generated_lines.abbreviation=Gen. Lines +metric.generated_lines.description=Number of generated lines +metric.generated_lines.name.suffix=generated lines +metric.generated_lines.name=Generated Lines +metric.generated_ncloc.abbreviation=Gen. LOC +metric.generated_ncloc.description=Generated non Commenting Lines of Code +metric.generated_ncloc.name.suffix=generated lines of code +metric.generated_ncloc.name=Generated Lines of Code +metric.info_violations.description=Info issues +metric.info_violations.name=Info Issues +metric.instability.description=Instability +metric.instability.name=Instability +metric.it_branch_coverage.description=Condition coverage by integration tests +metric.it_branch_coverage.name=IT Condition Coverage +metric.it_conditions_by_line.description=IT conditions by line +metric.it_conditions_by_line.name=IT Conditions by Line +metric.it_conditions_to_cover.description=Conditions to cover by integration tests +metric.it_conditions_to_cover.name=IT Conditions to Cover +metric.it_coverage.description=Integration tests coverage +metric.it_coverage.name=IT Coverage +metric.it_coverage_line_hits_data.description=Coverage hits by line by integration tests +metric.it_coverage_line_hits_data.name=IT Coverage Hits by Line +metric.it_covered_conditions_by_line.description=IT covered conditions by line +metric.it_covered_conditions_by_line.name=IT Covered Conditions by Line +metric.it_lines_to_cover.description=Lines to cover by integration tests +metric.it_lines_to_cover.name=IT Lines to Cover +metric.it_line_coverage.description=Line coverage by integration tests +metric.it_line_coverage.name=IT Line Coverage +metric.it_uncovered_conditions.description=Uncovered conditions by integration tests +metric.it_uncovered_conditions.name=IT Uncovered Conditions +metric.it_uncovered_lines.description=Uncovered lines by integration tests +metric.it_uncovered_lines.name=IT Uncovered Lines +metric.last_commit_date.name=Date of Last Commit +metric.last_commit_datetimes_by_line.description=Last commit dates by line +metric.last_commit_datetimes_by_line.name=Last Commit Dates by Line +metric.lcom4.description=Lack of Cohesion of Functions +metric.lcom4.name=LCOM4 +metric.lcom4_blocks.description=LCOM4 blocks +metric.lcom4_blocks.name=LCOM4 Blocks +metric.lcom4_distribution.description=Class distribution /LCOM4 +metric.lcom4_distribution.name=Class Distribution / LCOM4 +metric.lines.description=Lines +metric.lines.name=Lines +metric.lines_to_cover.description=Lines to cover +metric.lines_to_cover.name=Lines to Cover +metric.line_coverage.description=Line coverage +metric.line_coverage.name=Line Coverage +metric.maintainability.description=Maintainability +metric.maintainability.name=Maintainability +metric.major_violations.description=Major issues +metric.major_violations.name=Major Issues +metric.minor_violations.description=Minor issues +metric.minor_violations.name=Minor Issues +metric.ncloc.abbreviation=LOC +metric.ncloc.description=Non commenting lines of code +metric.ncloc.name=Lines of Code +metric.ncloc_language_distribution.description=Non Commenting Lines of Code Distributed By Language +metric.ncloc_language_distribution.name=Lines of Code Per Language +metric.new_blocker_violations.description=New Blocker issues +metric.new_blocker_violations.name=New Blocker Issues +metric.new_branch_coverage.description=Condition coverage of new/changed code +metric.new_branch_coverage.name=Condition Coverage on New Code +metric.new_bugs.description=New Bugs +metric.new_bugs.name=New Bugs +metric.new_code_smells.description=New Code Smells +metric.new_code_smells.name=New Code Smells +metric.new_conditions_to_cover.description=Conditions to cover on new code +metric.new_conditions_to_cover.name=Conditions to Cover on New Code +metric.new_coverage.description=Coverage of new/changed code +metric.new_coverage.name=Coverage on New Code +metric.new_critical_violations.description=New Critical issues +metric.new_critical_violations.name=New Critical Issues +metric.new_duplicated_blocks.name=Duplicated Blocks on New Code +metric.new_duplicated_blocks.description=Duplicated blocks on new code +metric.new_duplicated_lines.name=Duplicated Lines on New Code +metric.new_duplicated_lines.description=Duplicated Lines on New Code +metric.new_duplicated_lines_density.description=Duplicated lines on new code balanced by statements +metric.new_duplicated_lines_density.name=Duplicated Lines on New Code (%) +metric.new_info_violations.description=New Info issues +metric.new_info_violations.name=New Info Issues +metric.new_it_branch_coverage.description=Integration tests condition coverage of new/changed code +metric.new_it_branch_coverage.name=Condition Coverage by IT on New Code +metric.new_it_conditions_to_cover.description=New conditions to cover by integration tests +metric.new_it_conditions_to_cover.name=Conditions to Cover by IT on New Code +metric.new_it_coverage.description=Integration tests coverage of new/changed code +metric.new_it_coverage.name=Coverage by IT on New Code +metric.new_it_lines_to_cover.description=Lines to cover on new code by integration tests +metric.new_it_lines_to_cover.name=Lines to Cover by IT on New Code +metric.new_it_line_coverage.description=Integration tests line coverage of added/changed code +metric.new_it_line_coverage.name=Line Coverage by IT on New Code +metric.new_it_uncovered_conditions.description=New conditions that are not covered by integration tests +metric.new_it_uncovered_conditions.name=Uncovered Conditions by IT on New Code +metric.new_it_uncovered_lines.description=New lines that are not covered by integration tests +metric.new_it_uncovered_lines.name=Uncovered Lines by IT on New Code +metric.new_lines_to_cover.description=Lines to cover on new code +metric.new_lines_to_cover.name=Lines to Cover on New Code +metric.new_line_coverage.description=Line coverage of added/changed code +metric.new_line_coverage.name=Line Coverage on New Code +metric.new_major_violations.description=New Major issues +metric.new_major_violations.name=New Major Issues +metric.new_minor_violations.description=New Minor issues +metric.new_minor_violations.name=New Minor Issues +metric.new_lines.name=Lines on New Code +metric.new_lines.description=Non commenting lines on new code +metric.new_overall_branch_coverage.description=Condition coverage of new/changed code by all tests +metric.new_overall_branch_coverage.name=Overall Condition Coverage on New Code +metric.new_overall_conditions_to_cover.description=New conditions to cover by all tests +metric.new_overall_conditions_to_cover.name=Overall Conditions to Cover on New Code +metric.new_overall_coverage.description=Overall coverage of new/changed code +metric.new_overall_coverage.name=Overall Coverage on New Code +metric.new_overall_lines_to_cover.description=New lines to cover by all tests +metric.new_overall_lines_to_cover.name=Overall Lines to Cover on New Code +metric.new_overall_line_coverage.description=Line coverage of added/changed code by all tests +metric.new_overall_line_coverage.name=Overall Line Coverage on New Code +metric.new_overall_uncovered_conditions.description=New conditions that are not covered by any test +metric.new_overall_uncovered_conditions.name=Overall Uncovered Conditions on New Code +metric.new_overall_uncovered_lines.description=New lines that are not covered by any tests +metric.new_overall_uncovered_lines.name=Overall Uncovered Lines on New Code +metric.new_reliability_remediation_effort.description=Reliability remediation effort on new code +metric.new_reliability_remediation_effort.name=Reliability Remediation Effort on New Code +metric.new_security_remediation_effort.description=Security remediation effort on new code +metric.new_security_remediation_effort.name=Security Remediation Effort on New Code +metric.new_sqale_debt_ratio.description=Technical Debt Ratio of new/changed code. +metric.new_sqale_debt_ratio.name=Technical Debt Ratio on New Code +metric.new_sqale_debt_ratio.short_name=Debt Ratio on new code +metric.new_technical_debt.description=Added technical debt +metric.new_technical_debt.name=Added Technical Debt +metric.new_technical_debt.short_name=Added Debt +metric.new_uncovered_conditions.description=Uncovered conditions on new code +metric.new_uncovered_conditions.name=Uncovered Conditions on New Code +metric.new_uncovered_lines.description=Uncovered lines on new code +metric.new_uncovered_lines.name=Uncovered Lines on New Code +metric.new_violations.description=New issues +metric.new_violations.name=New Issues +metric.new_vulnerabilities.description=New Vulnerabilities +metric.new_vulnerabilities.name=New Vulnerabilities +metric.noc.description=Number of Children +metric.noc.name=Number of Children +metric.open_issues.description=Open issues +metric.open_issues.name=Open Issues +metric.overall_branch_coverage.description=Condition coverage by all tests +metric.overall_branch_coverage.name=Overall Condition Coverage +metric.overall_conditions_by_line.description=Overall conditions by all tests and by line +metric.overall_conditions_by_line.name=Overall Conditions by Line +metric.overall_conditions_to_cover.description=Conditions to cover by all tests +metric.overall_conditions_to_cover.name=Overall Conditions to Cover +metric.overall_coverage.description=Overall test coverage +metric.overall_coverage.name=Overall Coverage +metric.overall_coverage_line_hits_data.description=Coverage hits by all tests and by line +metric.overall_coverage_line_hits_data.name=Overall Coverage Hits by Line +metric.overall_covered_conditions_by_line.description=Overall covered conditions by all tests and by line +metric.overall_covered_conditions_by_line.name=Overall Covered Conditions by Line +metric.overall_lines_to_cover.description=Lines to cover by all tests +metric.overall_lines_to_cover.name=Overall Lines to Cover +metric.overall_line_coverage.description=Line coverage by all tests +metric.overall_line_coverage.name=Overall Line Coverage +metric.overall_uncovered_conditions.description=Uncovered conditions by all tests +metric.overall_uncovered_conditions.name=Overall Uncovered Conditions +metric.overall_uncovered_lines.description=Uncovered lines by all tests +metric.overall_uncovered_lines.name=Overall Uncovered Lines +metric.packages.abbreviation=Pkgs +metric.packages.description=Packages +metric.packages.name=Packages +metric.package_cycles.abbreviation=Pkgs cycles +metric.package_cycles.description=Package cycles +metric.package_cycles.name=Package Cycles +metric.package_edges_weight.description=Package edges weight +metric.package_edges_weight.name=Package Edges Weight +metric.package_feedback_edges.abbreviation=Pkgs dpds to cut +metric.package_feedback_edges.description=Package dependencies to cut +metric.package_feedback_edges.name=Package Dependencies to Cut +metric.package_tangles.abbreviation=File dpds to cut +metric.package_tangles.description=File dependencies to cut +metric.package_tangles.name=File Dependencies to Cut +metric.package_tangle_index.abbreviation=Pkgs tangle +metric.package_tangle_index.description=Package tangle index +metric.package_tangle_index.name=Package Tangle Index +metric.portability.description=Portability +metric.portability.name=Portability +metric.profile.description=Selected quality profile +metric.profile.name=Profile +metric.profile_version.description=Selected quality profile version +metric.profile_version.name=Profile Version +metric.projects.description=Number of projects +metric.projects.name=Projects +metric.public_api.description=Public API +metric.public_api.name=Public API +metric.public_documented_api_density.abbreviation=Pub. doc. API(%) +metric.public_documented_api_density.description=Public documented classes and functions balanced by ncloc +metric.public_documented_api_density.name=Public Documented API (%) +metric.public_undocumented_api.abbreviation=Pub. undoc. API +metric.public_undocumented_api.description=Public undocumented classes, functions and variables +metric.public_undocumented_api.name=Public Undocumented API +metric.quality_gate_details.description=The project detailed status with regard to its quality gate +metric.quality_gate_details.name=Quality Gate Details +metric.quality_profiles.description=Details of quality profiles used during analysis +metric.quality_profiles.name=Profiles +metric.reliability.description=Reliability +metric.reliability.name=Reliability +metric.reliability_rating.description=Reliability rating +metric.reliability_rating.name=Reliability Rating +metric.reliability_rating.tooltip.A=Reliability rating is A, because there are no bugs. +metric.reliability_rating.tooltip.B=Reliability rating is B, because there is at least one minor bug. +metric.reliability_rating.tooltip.C=Reliability rating is C, because there is at least one major bug. +metric.reliability_rating.tooltip.D=Reliability rating is D, because there is at least one critical bug. +metric.reliability_rating.tooltip.E=Reliability rating is E, because there is at least one blocker bug. +metric.reliability_remediation_effort.description=Reliability Remediation Effort +metric.reliability_remediation_effort.name=Reliability Remediation Effort +metric.reopened_issues.description=Reopened issues +metric.reopened_issues.name=Reopened Issues +metric.revisions_by_line.description=Revisions by line +metric.revisions_by_line.name=Revisions by Line +metric.rfc.description=Response for Class +metric.rfc.name=Response for Class +metric.rfc_distribution.description=Class distribution /RFC +metric.rfc_distribution.name=Class Distribution / RFC +metric.security_rating.description=Security rating +metric.security_rating.name=Security Rating +metric.security_rating.tooltip.A=Security rating is A, because there are no vulnerabilities. +metric.security_rating.tooltip.B=Security rating is B, because there is at least one minor vulnerability. +metric.security_rating.tooltip.C=Security rating is C, because there is at least one major vulnerability. +metric.security_rating.tooltip.D=Security rating is D, because there is at least one critical vulnerability. +metric.security_rating.tooltip.E=Security rating is E, because there is at least one blocker vulnerability. +metric.security_remediation_effort.description=Security remediation effort +metric.security_remediation_effort.name=Security Remediation Effort +metric.skipped_tests.abbreviation=Skipped UTs +metric.skipped_tests.description=Number of skipped unit tests +metric.skipped_tests.name=Skipped Unit Tests +metric.skipped_tests.short_name=Skipped +metric.sqale_debt_ratio.description=Ratio of the actual technical debt compared to the estimated cost to develop the whole source code from scratch +metric.sqale_debt_ratio.name=Technical Debt Ratio +metric.sqale_debt_ratio.short_name=Debt Ratio +metric.sqale_index.description=Total effort (in days) to fix all the issues on the component and therefore to comply to all the requirements. +metric.sqale_index.name=Technical Debt +metric.sqale_index.short_name=Effort +metric.sqale_rating.description=A-to-E rating based on the technical debt ratio +metric.sqale_rating.name=Maintainability Rating +metric.sqale_rating.tooltip=Maintainability rating is {0}, because the technical debt ratio is greater than {1} +metric.sqale_rating.tooltip.A=Maintainability rating is A, because the technical debt ratio is less than {0} +metric.statements.abbreviation=Stmts +metric.statements.description=Number of statements +metric.statements.name=Statements +metric.suspect_lcom4_density.description=Density of classes having LCOM4>1 +metric.suspect_lcom4_density.name=Suspect LCOM4 Density +metric.tests.abbreviation=UTs +metric.tests.description=Number of unit tests +metric.tests.name=Unit Tests +metric.test_data.description=Unit tests details +metric.test_data.name=Unit Test Details +metric.test_errors.abbreviation=UTs errors +metric.test_errors.description=Number of unit test errors +metric.test_errors.name=Unit Test Errors +metric.test_errors.short_name=Errors +metric.test_execution_time.abbreviation=UTs dur. +metric.test_execution_time.description=Execution duration of unit tests +metric.test_execution_time.name=Unit Test Duration +metric.test_execution_time.short_name=Duration +metric.test_failures.abbreviation=UTs failures +metric.test_failures.description=Number of unit test failures +metric.test_failures.name=Unit Test Failures +metric.test_failures.short_name=Failures +metric.test_success_density.abbreviation=UTs success +metric.test_success_density.description=Density of successful unit tests +metric.test_success_density.name=Unit Test Success (%) +metric.test_success_density.short_name=Success +metric.uncovered_conditions.description=Uncovered conditions +metric.uncovered_conditions.name=Uncovered Conditions +metric.uncovered_lines.description=Uncovered lines +metric.uncovered_lines.name=Uncovered Lines +metric.usability.description=Usability +metric.usability.name=Usability +metric.violations.description=Issues +metric.violations.name=Issues +metric.vulnerabilities.description=Vulnerabilities +metric.vulnerabilities.name=Vulnerabilities +metric.wont_fix_issues.description=Won't fix issues +metric.wont_fix_issues.name=Won't Fix Issues + +#------------------------------------------------------------------------------ +# +# GLOBAL PERMISSIONS +# +#------------------------------------------------------------------------------ +global_permissions.permission=Permission +global_permissions.users=Users +global_permissions.groups=Groups +global_permissions.admin=Administer System +global_permissions.admin.desc=Ability to perform all administration functions for the instance: global configuration and customization of default dashboards. +global_permissions.profileadmin=Administer Quality Profiles +global_permissions.profileadmin.desc=Ability to perform any action on quality profiles. +global_permissions.gateadmin=Administer Quality Gates +global_permissions.gateadmin.desc=Ability to perform any action on quality gates. +global_permissions.shareDashboard=Share Dashboards And Filters +global_permissions.shareDashboard.desc=Ability to share dashboards, issue filters and measure filters. +global_permissions.scan=Execute Analysis +global_permissions.scan.desc=Ability to get all settings required to perform an analysis (including the secured settings like passwords) and to push analysis results to the SonarQube server. +global_permissions.provisioning=Create Projects +global_permissions.provisioning.desc=Ability to initialize a project so its settings can be configured before the first analysis. + +#------------------------------------------------------------------------------ +# +# PROJECTS PERMISSIONS +# +#------------------------------------------------------------------------------ +projects_role.criteria.name=Name contains +projects_role.criteria.key=Key contains +projects_role.role=Role Membership For New +projects_role.groups=Groups +projects_role.admin=Administer +projects_role.admin.desc=Access project settings and perform administration tasks. (Users will also need "Browse" permission) +projects_role.issueadmin=Administer Issues +projects_role.issueadmin.desc=Perform advanced editing on issues: marking an issue False Positive / Won't Fix, and changing an Issue's severity. (Users will also need "Browse" permission) +projects_role.user=Browse +projects_role.user.desc=Access a project, browse its measures, and create/edit issues for it. +projects_role.codeviewer=See Source Code +projects_role.codeviewer.desc=View the project's source code. (Users will also need "Browse" permission) +projects_role.scan=Execute Analysis +projects_role.scan.desc=Ability to get all settings required to perform an analysis (including the secured settings like passwords) and to push analysis results to the SonarQube server. +projects_role.bulk_change=Bulk Change +projects_role.apply_template=Apply Permission Template +projects_role.apply_template_to_xxx=Apply Permission Template To "{0}" +projects_role.apply_template.success=Permission template was successfully applied. +projects_role.no_projects=There are currently no results to apply the permission template to. + + + +#------------------------------------------------------------------------------ +# +# PERMISSION TEMPLATES +# +#------------------------------------------------------------------------------ +permission_templates=Permission Templates +permission_templates.page=Permission Templates +permission_templates.page.description=Manage templates of project permission sets. The default template will be applied to all new projects. +permission_templates.set_default=Set Default +permission_templates.set_default_for=Set Default For +permission_template.new_template=Create Permission Template +permission_template.create_template=Create +permission_template.delete_confirm_title=Delete Permission Template +permission_template.do_you_want_to_delete_template_xxx=Are you sure that you want to delete permission template "{0}"? +permission_template.delete_template=Delete +permission_template.edit_template=Edit Permission Template +permission_template.update_template=Update +permission_template.edit_permissions=Edit Permissions: {0} +permission_template.update_permissions=Save +permission_template.no_results=No template to display +permission_template.set_default_templates=Set Default Templates +permission_template.key_pattern=Project key pattern +permission_template.default_for=Default for {0} +permission_templates.project_creators=Project Creators +permission_templates.project_creators.explanation=When a new project is created, the user who creates the project will receive this permission on the project. +permission_templates.grant_permission_to_project_creators=Grant the "{0}" permission to project creators + + +#------------------------------------------------------------------------------ +# +# ERRORS HANDLING +# +#------------------------------------------------------------------------------ +errors.is_too_short={0} is too short (minimum is {1} characters) +errors.is_too_long={0} is too long (maximum is {1} characters) +errors.is_already_used={0} has already been taken +errors.cant_be_empty={0} can't be empty +errors.is_not_valid={0} is not valid + +errors.type.notBoolean=Value '{0}' must be one of "true" or "false". +errors.type.notInteger=Value '{0}' must be an integer. +errors.type.notLong=Value '{0}' must be a long. +errors.type.notFloat=Value '{0}' must be an floating point number. +errors.type.notInOptions=Value '{0}' must be one of : {1}. +errors.type.notMetricLevel=Value '{0}' must be one of "OK", "WARN", "ERROR". + +#------------------------------------------------------------------------------ +# +# HELP +# +#------------------------------------------------------------------------------ +markdown.helplink=Markdown Help + +#------------------------------------------------------------------------------ +# +# DURATION +# +#------------------------------------------------------------------------------ +duration.seconds=less than a minute +duration.minute=about a minute +duration.minutes={0} minutes +duration.hour=about an hour +duration.hours={0} hours +duration.day=a day +duration.days={0} days +duration.month=about a month +duration.months={0} months +duration.year=about a year +duration.years={0} years + + +#------------------------------------------------------------------------------ +# +# COMPONENT VIEWER +# +#------------------------------------------------------------------------------ +component_viewer.measure_section.size=Size +component_viewer.measure_section.complexity=Complexity +component_viewer.measure_section.structure=Structure +component_viewer.measure_section.documentation=Documentation +component_viewer.measure_section.filters=Filters +component_viewer.measure_section.severities=Severities +component_viewer.measure_section.rules=Rules +component_viewer.measure_section.issues=Issues +component_viewer.measure_section.sqale=SQALE +component_viewer.measure_section.unit_tests=Unit Tests +component_viewer.measure_section.tests=Tests +component_viewer.measure_section.test_cases=Test Cases +component_viewer.measure_section.integration_tests=Integration Tests +component_viewer.measure_section.overall=Overall + +component_viewer.issues.current_issue=Current Issue +component_viewer.issues.unresolved_issues=Unresolved Issues +component_viewer.issues.fixed_issues=Fixed Issues +component_viewer.issues.false_positive_issues=False Positive Issues +component_viewer.issues.open_issues=Open/Reopened Issues + +component_viewer.header.debt=Debt +component_viewer.header.toggle_issues=Toggle issues +component_viewer.header.toggle_coverage=Toggle coverage +component_viewer.header.toggle_duplications=Toggle duplications +component_viewer.header.toggle_scm=Toggle SCM + +component_viewer.scm.modified_lines=Modified Lines + +component_viewer.transition.coverage=Covered By +component_viewer.transition.covers=Covers +component_viewer.transition.duplication=Duplicated By + +component_viewer.tests.ordered_by=ordered by +component_viewer.tests.duration=duration +component_viewer.tests.test_name=name +component_viewer.tests.status=status + +component_viewer.x_lines_are_covered={0} lines are covered +component_viewer.details=Details +component_viewer.line_actions=Line Actions +component_viewer.no_issues=No Issues +component_viewer.no_coverage=No Coverage +component_viewer.time_changes=Time Changes +component_viewer.added=Added +component_viewer.extensions=Extensions +component_viewer.show_full_source=Show Full Source +component_viewer.show_raw_source=Show Raw Source +component_viewer.more_actions=More Actions +component_viewer.new_window=Open in New Window +component_viewer.open_in_workspace=Pin This File +component_viewer.get_permalink=Get Permalink +component_viewer.covered_lines=Covered Lines +component_viewer.issues_limit_reached=For usability reasons, only the {0} first issues will be fully displayed. Remaining issues will simply be underlined. +component_viewer.issues_limit_reached_tooltip={0}\n\nRefine your filter to be able to see the details of this issue. +component_viewer.cannot_show=We're sorry, but something went wrong. Please try back in a few minutes and contact support if the problem persists. +component_viewer.show_details=Show Measures +component_viewer.show_all_measures=Show all measures +component_viewer.no_component=The component has been removed or never existed. + +component_viewer.workspace=Workspace +component_viewer.workspace.tooltip=Keeps track of history of navigation +component_viewer.workspace.show_workspace=Show workspace +component_viewer.workspace.hide_workspace=Hide workspace + +source_viewer.ut.covered=Covered by unit tests +source_viewer.ut.not_covered=Not covered by unit tests +source_viewer.it.covered=Covered by integration tests +source_viewer.it.not_covered=Not covered by integration tests +source_viewer.conditions=conditions + +source_viewer.tooltip.duplicated_line=This line is duplicated. Click to see duplicated blocks. +source_viewer.tooltip.duplicated_block=Duplicated block. Click for details. +source_viewer.tooltip.ut.covered=Fully covered by unit tests. Click for details. +source_viewer.tooltip.ut.partially-covered=Partially covered by unit tests. Click for details. +source_viewer.tooltip.ut.uncovered=Not covered by unit tests. +source_viewer.tooltip.it.covered=Fully covered by integration tests. Click for details. +source_viewer.tooltip.it.partially-covered=Partially covered by integration tests. Click for details. +source_viewer.tooltip.it.uncovered=Not covered by integration tests. +source_viewer.tooltip.new_code=New {0}. + +source_viewer.load_more_code=Load More Code +source_viewer.loading_more_code=Loading More Code... + + + +#------------------------------------------------------------------------------ +# +# Analysis Reports +# +#------------------------------------------------------------------------------ +analysis_reports.past_reports=Past Reports +analysis_reports.show_past_reports=Show Past Reports +analysis_reports.current_activity=Current Activity +analysis_reports.show_current_activity=Show Current Activity +analysis_reports.x_reports={0} reports + + + + +#------------------------------------------------------------------------------ +# +# WORKSPACE +# +#------------------------------------------------------------------------------ workspace.minimize=Minimize +workspace.full_window=Expand to full window workspace.normal_size=Collapse to normal size +workspace.close=Remove from the list of pinned files workspace.no_rule=The rule has been removed or never existed. -work_duration.about=~ {0} -work_duration.x_days={0}d -work_duration.x_hours={0}h -work_duration.x_minutes={0}min -x_of_y_shown={0} of {1} shown -x_results={0} results + + + +#------------------------------------------------------------------------------ +# +# UPDATE CENTER +# +#------------------------------------------------------------------------------ +update_center.status.COMPATIBLE=Compatible +update_center.status.INCOMPATIBLE=Incompatible +update_center.status.REQUIRES_SYSTEM_UPGRADE=Requires system update +update_center.status.DEPS_REQUIRE_SYSTEM_UPGRADE=Some of dependencies requires system update + + + +#------------------------------------------------------------------------------ +# +# BACKGROUND TASKS +# +#------------------------------------------------------------------------------ +component_navigation.status.failed=The last analysis has failed. +component_navigation.status.failed.admin=The last analysis has failed.<br>More details available on the <a href="{0}">Background Tasks</a> page. +component_navigation.status.pending=There is a pending analysis. +component_navigation.status.pending.admin=There is a pending analysis.<br>More details available on the <a href="{0}">Background Tasks</a> page. +component_navigation.status.in_progress=The analysis is in progress. +component_navigation.status.in_progress.admin=The analysis is in progress.<br>More details available on the <a href="{0}">Background Tasks</a> page. + +background_task.status.ALL=All +background_task.status.PENDING=Pending +background_task.status.IN_PROGRESS=In Progress +background_task.status.SUCCESS=Success +background_task.status.FAILED=Failed +background_task.status.CANCELED=Canceled +background_task.status.ALL_EXCEPT_PENDING=All Except Pending + +background_task.type.ALL=All +background_task.type.REPORT=Project Analysis +background_task.type.DEV_REFRESH=Developer Analysis +background_task.type.DEV_PURGE=Developer Cleaning + +background_tasks.page=Background Tasks +background_tasks.page.description=This page allows monitoring of the queue of tasks running asynchronously on the server. It also gives access to the history of finished tasks, their status and logs. Analysis report processing is the most common kind of background task. + +background_tasks.currents_filter.ALL=All +background_tasks.currents_filter.ONLY_CURRENTS=Only Latest Analysis + +background_tasks.date_filter.ALL=Any Date +background_tasks.date_filter.TODAY=Today +background_tasks.date_filter.CUSTOM=Custom + +background_tasks.table.status=Status +background_tasks.table.task=Task +background_tasks.table.id=ID +background_tasks.table.submitted=Submitted +background_tasks.table.started=Started +background_tasks.table.finished=Finished +background_tasks.table.duration=Duration + +background_tasks.logs=Logs +background_tasks.filter_by_component_x=Filter by Component "{0}" +background_tasks.cancel_task=Cancel Task +background_tasks.cancel_all_tasks=Cancel All Pending Tasks +background_tasks.scanner_context=Scanner Context +background_tasks.show_scanner_context=Show Scanner Context +background_tasks.show_stacktrace=Show Error Stacktrace +background_tasks.error_message=Error Message +background_tasks.error_stacktrace=Error Stacktrace +background_tasks.pending=pending +background_tasks.failures=still failing +background_tasks.in_progress_duration=Duration of the current task in progress. + + + +#------------------------------------------------------------------------------ +# +# SYSTEM +# +#------------------------------------------------------------------------------ +system.log_level.warning=Current level has performance impacts, please make sure to get back to INFO level once your investigation is done. Please note that when you restart the server, the level will automatically be reset to INFO. + + + +#------------------------------------------------------------------------------ +# +# OVERVIEW +# +#------------------------------------------------------------------------------ +overview.quality_gate=Quality Gate +overview.you_should_define_quality_gate=You should define a quality gate on this project. +overview.quality_profiles=Quality Profiles +overview.leak_period_x=Leak Period: {0} +overview.started_x=started {0} +overview.started_on_x=Started on {0} +overview.on_new_code=On New Code + +overview.metric.code_smells=Code Smells +overview.metric.new_code_smells=New Code Smells +overview.metric.bugs=Bugs +overview.metric.new_bugs=New Bugs +overview.metric.vulnerabilities=Vulnerabilities +overview.metric.new_vulnerabilities=New Vulnerabilities +overview.metric.issues=Issues +overview.metric.effort=Debt +overview.metric.new_issues=New Issues +overview.metric.new_effort=New Debt +overview.metric.coverage=Coverage +overview.metric.tests=Tests +overview.metric.new_coverage=Coverage on New Code +overview.metric.duplications=Duplications +overview.metric.duplicated_blocks=Duplicated Blocks +overview.metric.new_duplications=Duplications on New Code +overview.metric.ncloc=Lines of Code +overview.metric.new_lines=New Lines +overview.metric.new_lines_to_cover=New Lines to Cover +overview.metric.files=Files +overview.coverage_on=Coverage on +overview.duplications_on=Duplications on + +overview.period.previous_version=since {0} +overview.period.previous_version_only_date=since previous version +overview.period.previous_analysis=since previous analysis +overview.period.days=last {0} days +overview.period.version=since {0} +overview.period.date=since {0} + +overview.gate.ERROR=Failed +overview.gate.WARN=Warning +overview.gate.OK=Passed +overview.gate.view.no_alert=The view has passed the quality gate. +overview.gate.view.warnings=The view has warnings on the following quality gate conditions: {0}. +overview.gate.view.errors=The view failed the quality gate on the following conditions: {0}. + +overview.domain.duplications=Duplications +overview.domain.size=Size + +overview.complexity_tooltip.function={0} functions have complexity around {1} +overview.complexity_tooltip.file={0} files have complexity around {1} + +overview.deprecated_profile=This quality profile uses {0} deprecated rules and should be updated. + + +#------------------------------------------------------------------------------ +# +# WS API +# +#------------------------------------------------------------------------------ +api_documentation.deprecation_tooltip=If an API is deprecated in version X.Y, this API will be dropped in version (X+2).0. Example: an API deprecated in 4.1 is supported in 4.2, 4.3, 5.0, 5.1, 5.2, 5.3 and is dropped in version 6.0. +api_documentation.internal_tooltip=Use at your own risk; internal services are subject to change or removal without notice. + + +#------------------------------------------------------------------------------ +# +# CODE +# +#------------------------------------------------------------------------------ +code.open_component_page=Open Component's Page + + +#------------------------------------------------------------------------------ +# +# COMPONENT MEASURES +# +#------------------------------------------------------------------------------ +component_measures.all_measures=All Measures +component_measures.domain_measures={0} Measures +component_measures.back_to_list=Back to List +component_measures.tab.tree=Tree +component_measures.tab.list=List +component_measures.tab.bubbles=Bubble Chart +component_measures.tab.treemap=Treemap +component_measures.tab.history=History +component_measures.legend.color_x=Color: {0} +component_measures.legend.size_x=Size: {0} +component_measures.x_of_y={0} of {1} +component_measures.no_history=There is no historical data. diff --git a/sonar-core/src/test/java/org/sonar/core/component/ComponentKeysTest.java b/sonar-core/src/test/java/org/sonar/core/component/ComponentKeysTest.java index 56048b1c97e..e9818a55d37 100644 --- a/sonar-core/src/test/java/org/sonar/core/component/ComponentKeysTest.java +++ b/sonar-core/src/test/java/org/sonar/core/component/ComponentKeysTest.java @@ -19,7 +19,9 @@ */ package org.sonar.core.component; +import org.junit.Rule; import org.junit.Test; +import org.junit.rules.ExpectedException; import org.sonar.api.batch.fs.InputFile; import org.sonar.api.batch.fs.internal.DefaultInputFile; import org.sonar.api.resources.Directory; @@ -28,6 +30,8 @@ import org.sonar.api.resources.Project; import static org.assertj.core.api.Assertions.assertThat; public class ComponentKeysTest { + @Rule + public ExpectedException expectedException = ExpectedException.none(); @Test public void create_effective_key() { @@ -57,7 +61,7 @@ public class ComponentKeysTest { assertThat(ComponentKeys.isValidModuleKey("ab_12")).isTrue(); assertThat(ComponentKeys.isValidModuleKey("ab/12")).isFalse(); } - + @Test public void isValidModuleKeyIssuesMode() { assertThat(ComponentKeys.isValidModuleKeyIssuesMode("")).isFalse(); @@ -80,4 +84,38 @@ public class ComponentKeysTest { assertThat(ComponentKeys.isValidBranch("ab\n")).isFalse(); } + @Test + public void checkModuleKey_with_correct_keys() { + ComponentKeys.checkModuleKey("abc"); + ComponentKeys.checkModuleKey("a-b_1.:2"); + } + + @Test + public void checkModuleKey_fail_if_only_digit() { + expectedException.expect(IllegalArgumentException.class); + expectedException.expectMessage("Malformed key for '0123'. Allowed characters are alphanumeric, '-', '_', '.' and ':', with at least one non-digit."); + + ComponentKeys.checkModuleKey("0123"); + } + + @Test + public void checkModuleKey_fail_if_key_is_empty() { + expectedException.expect(IllegalArgumentException.class); + + ComponentKeys.checkModuleKey(""); + } + + @Test + public void checkModuleKey_fail_if_space() { + expectedException.expect(IllegalArgumentException.class); + + ComponentKeys.checkModuleKey("ab 12"); + } + + @Test + public void checkModuleKey_fail_if_special_characters_not_allowed() { + expectedException.expect(IllegalArgumentException.class); + + ComponentKeys.checkModuleKey("ab/12"); + } } diff --git a/sonar-core/src/test/java/org/sonar/core/component/DefaultResourceTypesTest.java b/sonar-core/src/test/java/org/sonar/core/component/DefaultResourceTypesTest.java index 801c84da141..8d1557b43fe 100644 --- a/sonar-core/src/test/java/org/sonar/core/component/DefaultResourceTypesTest.java +++ b/sonar-core/src/test/java/org/sonar/core/component/DefaultResourceTypesTest.java @@ -31,7 +31,7 @@ public class DefaultResourceTypesTest { public void provide_types() { ResourceTypeTree tree = DefaultResourceTypes.get(); - assertThat(tree.getTypes()).hasSize(7); + assertThat(tree.getTypes()).hasSize(5); assertThat(tree.getChildren(Qualifiers.PROJECT)).containsExactly(Qualifiers.MODULE); } diff --git a/sonar-core/src/test/java/org/sonar/core/metric/ScannerMetricsTest.java b/sonar-core/src/test/java/org/sonar/core/metric/ScannerMetricsTest.java index 5196fb7178d..346da60709a 100644 --- a/sonar-core/src/test/java/org/sonar/core/metric/ScannerMetricsTest.java +++ b/sonar-core/src/test/java/org/sonar/core/metric/ScannerMetricsTest.java @@ -36,7 +36,7 @@ public class ScannerMetricsTest { @Test public void check_number_of_allowed_core_metrics() throws Exception { - assertThat(SENSOR_METRICS_WITHOUT_METRIC_PLUGIN.getMetrics()).hasSize(48); + assertThat(SENSOR_METRICS_WITHOUT_METRIC_PLUGIN.getMetrics()).hasSize(47); } @Test diff --git a/sonar-core/src/test/java/org/sonar/core/platform/PluginInfoTest.java b/sonar-core/src/test/java/org/sonar/core/platform/PluginInfoTest.java index 35eec26eb91..a433bb905cb 100644 --- a/sonar-core/src/test/java/org/sonar/core/platform/PluginInfoTest.java +++ b/sonar-core/src/test/java/org/sonar/core/platform/PluginInfoTest.java @@ -157,6 +157,7 @@ public class PluginInfoTest { assertThat(pluginInfo.getOrganizationUrl()).isNull(); assertThat(pluginInfo.getMinimalSqVersion()).isNull(); assertThat(pluginInfo.getRequiredPlugins()).isEmpty(); + assertThat(pluginInfo.isSonarLintSupported()).isFalse(); } @Test @@ -176,6 +177,7 @@ public class PluginInfoTest { manifest.setOrganizationUrl("http://sonarsource.com"); manifest.setIssueTrackerUrl("http://jira.com"); manifest.setRequirePlugins(new String[] {"java:2.0", "pmd:1.3"}); + manifest.setSonarLintSupported(true); File jarFile = temp.newFile(); PluginInfo pluginInfo = PluginInfo.create(jarFile, manifest); @@ -190,6 +192,7 @@ public class PluginInfoTest { assertThat(pluginInfo.getOrganizationUrl()).isEqualTo("http://sonarsource.com"); assertThat(pluginInfo.getMinimalSqVersion().getName()).isEqualTo("4.5.1"); assertThat(pluginInfo.getRequiredPlugins()).extracting("key").containsOnly("java", "pmd"); + assertThat(pluginInfo.isSonarLintSupported()).isTrue(); } @Test diff --git a/sonar-core/src/test/java/org/sonar/core/platform/RemotePluginTest.java b/sonar-core/src/test/java/org/sonar/core/platform/RemotePluginTest.java index fbe8f21f5e4..b1e609bdb68 100644 --- a/sonar-core/src/test/java/org/sonar/core/platform/RemotePluginTest.java +++ b/sonar-core/src/test/java/org/sonar/core/platform/RemotePluginTest.java @@ -21,8 +21,7 @@ package org.sonar.core.platform; import org.junit.Test; -import static org.hamcrest.core.Is.is; -import static org.junit.Assert.assertThat; +import static org.assertj.core.api.Assertions.assertThat; public class RemotePluginTest { @Test @@ -30,23 +29,31 @@ public class RemotePluginTest { RemotePlugin clirr1 = new RemotePlugin("clirr"); RemotePlugin clirr2 = new RemotePlugin("clirr"); RemotePlugin checkstyle = new RemotePlugin("checkstyle"); - assertThat(clirr1.equals(clirr2), is(true)); - assertThat(clirr1.equals(clirr1), is(true)); - assertThat(clirr1.equals(checkstyle), is(false)); + assertThat(clirr1).isEqualTo(clirr2); + assertThat(clirr1).isEqualTo(clirr1); + assertThat(clirr1).isNotEqualTo(checkstyle); } @Test - public void shouldMarshal() { + public void shouldMarshalNotSonarLintByDefault() { RemotePlugin clirr = new RemotePlugin("clirr").setFile("clirr-1.1.jar", "fakemd5"); String text = clirr.marshal(); - assertThat(text, is("clirr,clirr-1.1.jar|fakemd5")); + assertThat(text).isEqualTo("clirr,false,clirr-1.1.jar|fakemd5"); + } + + @Test + public void shouldMarshalSonarLint() { + RemotePlugin clirr = new RemotePlugin("clirr").setFile("clirr-1.1.jar", "fakemd5").setSonarLintSupported(true); + String text = clirr.marshal(); + assertThat(text).isEqualTo("clirr,true,clirr-1.1.jar|fakemd5"); } @Test public void shouldUnmarshal() { - RemotePlugin clirr = RemotePlugin.unmarshal("clirr,clirr-1.1.jar|fakemd5"); - assertThat(clirr.getKey(), is("clirr")); - assertThat(clirr.file().getFilename(), is("clirr-1.1.jar")); - assertThat(clirr.file().getHash(), is("fakemd5")); + RemotePlugin clirr = RemotePlugin.unmarshal("clirr,true,clirr-1.1.jar|fakemd5"); + assertThat(clirr.getKey()).isEqualTo("clirr"); + assertThat(clirr.isSonarLintSupported()).isTrue(); + assertThat(clirr.file().getFilename()).isEqualTo("clirr-1.1.jar"); + assertThat(clirr.file().getHash()).isEqualTo("fakemd5"); } } diff --git a/sonar-core/src/test/java/org/sonar/core/timemachine/PeriodsTest.java b/sonar-core/src/test/java/org/sonar/core/timemachine/PeriodsTest.java new file mode 100644 index 00000000000..e4abf894bf7 --- /dev/null +++ b/sonar-core/src/test/java/org/sonar/core/timemachine/PeriodsTest.java @@ -0,0 +1,287 @@ +/* + * SonarQube + * Copyright (C) 2009-2016 SonarSource SA + * mailto:contact 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.core.timemachine; + +import java.util.Date; +import java.util.Locale; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.sonar.api.config.Settings; +import org.sonar.api.config.MapSettings; +import org.sonar.api.i18n.I18n; + +import static org.mockito.Matchers.anyString; +import static org.mockito.Mockito.any; +import static org.mockito.Mockito.eq; +import static org.mockito.Mockito.isNull; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.sonar.api.utils.DateUtils.parseDate; +import static org.sonar.core.config.CorePropertyDefinitions.TIMEMACHINE_MODE_DATE; +import static org.sonar.core.config.CorePropertyDefinitions.TIMEMACHINE_MODE_DAYS; +import static org.sonar.core.config.CorePropertyDefinitions.TIMEMACHINE_MODE_PREVIOUS_ANALYSIS; +import static org.sonar.core.config.CorePropertyDefinitions.TIMEMACHINE_MODE_PREVIOUS_VERSION; +import static org.sonar.core.config.CorePropertyDefinitions.TIMEMACHINE_MODE_VERSION; +import static org.sonar.core.config.CorePropertyDefinitions.TIMEMACHINE_PERIOD_PREFIX; + +public class PeriodsTest { + + static String NUMBER_OF_DAYS = "5"; + static String STRING_DATE = "2015-01-01"; + static Date DATE = parseDate(STRING_DATE); + static String VERSION = "1.1"; + static int PERIOD_INDEX = 1; + @Rule + public ExpectedException thrown = ExpectedException.none(); + Settings settings = new MapSettings(); + I18n i18n = mock(I18n.class); + Periods periods = new Periods(settings, i18n); + + @Test + public void return_over_x_days_label_when_no_date() { + periods.label(TIMEMACHINE_MODE_DAYS, NUMBER_OF_DAYS, (String) null); + + verify(i18n).message(any(Locale.class), eq("over_x_days"), isNull(String.class), eq(NUMBER_OF_DAYS)); + } + + @Test + public void return_over_x_days_abbreviation_when_no_date() { + periods.abbreviation(TIMEMACHINE_MODE_DAYS, NUMBER_OF_DAYS, null); + + verify(i18n).message(any(Locale.class), eq("over_x_days.short"), isNull(String.class), eq(NUMBER_OF_DAYS)); + } + + @Test + public void return_over_x_days_detailed_label_when_date_is_set() { + periods.label(TIMEMACHINE_MODE_DAYS, NUMBER_OF_DAYS, STRING_DATE); + + verify(i18n).message(any(Locale.class), eq("over_x_days_detailed"), isNull(String.class), eq(NUMBER_OF_DAYS), eq(STRING_DATE)); + } + + @Test + public void return_over_x_days_detailed_abbreviation_when_date_is_set() { + periods.abbreviation(TIMEMACHINE_MODE_DAYS, NUMBER_OF_DAYS, DATE); + + verify(i18n).message(any(Locale.class), eq("over_x_days_detailed.short"), isNull(String.class), eq(NUMBER_OF_DAYS), anyString()); + } + + @Test + public void return_over_x_days_label_using_settings() { + settings.setProperty(TIMEMACHINE_PERIOD_PREFIX + PERIOD_INDEX, NUMBER_OF_DAYS); + + periods.label(PERIOD_INDEX); + + verify(i18n).message(any(Locale.class), eq("over_x_days"), isNull(String.class), eq(NUMBER_OF_DAYS)); + } + + @Test + public void return_since_version_label_when_no_date() { + periods.label(TIMEMACHINE_MODE_VERSION, VERSION, (String) null); + + verify(i18n).message(any(Locale.class), eq("since_version"), isNull(String.class), eq(VERSION)); + } + + @Test + public void return_since_version_abbreviation_when_no_date() { + periods.abbreviation(TIMEMACHINE_MODE_VERSION, VERSION, null); + + verify(i18n).message(any(Locale.class), eq("since_version.short"), isNull(String.class), eq(VERSION)); + } + + @Test + public void return_since_version_detailed_label_when_date_is_set() { + periods.label(TIMEMACHINE_MODE_VERSION, VERSION, STRING_DATE); + + verify(i18n).message(any(Locale.class), eq("since_version_detailed"), isNull(String.class), eq(VERSION), eq(STRING_DATE)); + } + + @Test + public void return_since_version_detailed_abbreviation_when_date_is_set() { + periods.abbreviation(TIMEMACHINE_MODE_VERSION, VERSION, DATE); + + verify(i18n).message(any(Locale.class), eq("since_version_detailed.short"), isNull(String.class), eq(VERSION), anyString()); + } + + @Test + public void return_since_version_label_using_settings() { + settings.setProperty(TIMEMACHINE_PERIOD_PREFIX + PERIOD_INDEX, VERSION); + + periods.label(PERIOD_INDEX); + + verify(i18n).message(any(Locale.class), eq("since_version"), isNull(String.class), eq(VERSION)); + } + + @Test + public void return_since_previous_analysis_label_when_no_date() { + periods.label(TIMEMACHINE_MODE_PREVIOUS_ANALYSIS, null, (String) null); + + verify(i18n).message(any(Locale.class), eq("since_previous_analysis"), isNull(String.class)); + } + + @Test + public void return_since_previous_analysis_abbreviation_when_no_date() { + periods.abbreviation(TIMEMACHINE_MODE_PREVIOUS_ANALYSIS, null, null); + + verify(i18n).message(any(Locale.class), eq("since_previous_analysis.short"), isNull(String.class)); + } + + @Test + public void return_since_previous_analysis_detailed_label_when_date_is_set() { + periods.label(TIMEMACHINE_MODE_PREVIOUS_ANALYSIS, null, STRING_DATE); + + verify(i18n).message(any(Locale.class), eq("since_previous_analysis_detailed"), isNull(String.class), eq(STRING_DATE)); + } + + @Test + public void return_since_previous_analysis_detailed_abbreviation_when_date_is_set() { + periods.abbreviation(TIMEMACHINE_MODE_PREVIOUS_ANALYSIS, null, DATE); + + verify(i18n).message(any(Locale.class), eq("since_previous_analysis_detailed.short"), isNull(String.class), anyString()); + } + + @Test + public void return_since_previous_analysis_label_using_settings() { + settings.setProperty(TIMEMACHINE_PERIOD_PREFIX + PERIOD_INDEX, TIMEMACHINE_MODE_PREVIOUS_ANALYSIS); + + periods.label(PERIOD_INDEX); + + verify(i18n).message(any(Locale.class), eq("since_previous_analysis"), isNull(String.class)); + } + + @Test + public void return_since_previous_version_label_when_no_param() { + periods.label(TIMEMACHINE_MODE_PREVIOUS_VERSION, null, (String) null); + + verify(i18n).message(any(Locale.class), eq("since_previous_version"), isNull(String.class)); + } + + @Test + public void return_since_previous_version_abbreviation_when_no_param() { + periods.abbreviation(TIMEMACHINE_MODE_PREVIOUS_VERSION, null, null); + + verify(i18n).message(any(Locale.class), eq("since_previous_version.short"), isNull(String.class)); + } + + @Test + public void return_since_previous_version_detailed_label_when_param_is_set_and_no_date() { + periods.label(TIMEMACHINE_MODE_PREVIOUS_VERSION, VERSION, (String) null); + + verify(i18n).message(any(Locale.class), eq("since_previous_version_detailed"), isNull(String.class), eq(VERSION)); + } + + @Test + public void return_since_previous_version_detailed_abbreviation_when_param_is_set_and_no_date() { + periods.abbreviation(TIMEMACHINE_MODE_PREVIOUS_VERSION, VERSION, null); + + verify(i18n).message(any(Locale.class), eq("since_previous_version_detailed.short"), isNull(String.class), eq(VERSION)); + } + + @Test + public void return_since_previous_version_detailed_label_when_param_and_date_are_set() { + periods.label(TIMEMACHINE_MODE_PREVIOUS_VERSION, VERSION, STRING_DATE); + + verify(i18n).message(any(Locale.class), eq("since_previous_version_detailed"), isNull(String.class), eq(VERSION), eq(STRING_DATE)); + } + + @Test + public void return_since_previous_version_with_only_date_label_when_no_param_and_date_is_set() { + periods.label(TIMEMACHINE_MODE_PREVIOUS_VERSION, null, STRING_DATE); + + verify(i18n).message(any(Locale.class), eq("since_previous_version_with_only_date"), isNull(String.class), eq(STRING_DATE)); + } + + @Test + public void return_since_previous_version_detailed_abbreviation_when_param_and_date_are_set() { + periods.abbreviation(TIMEMACHINE_MODE_PREVIOUS_VERSION, VERSION, DATE); + + verify(i18n).message(any(Locale.class), eq("since_previous_version_detailed.short"), isNull(String.class), eq(VERSION), anyString()); + } + + @Test + public void return_since_previous_version_label_using_settings() { + settings.setProperty(TIMEMACHINE_PERIOD_PREFIX + PERIOD_INDEX, TIMEMACHINE_MODE_PREVIOUS_VERSION); + + periods.label(PERIOD_INDEX); + + verify(i18n).message(any(Locale.class), eq("since_previous_version"), isNull(String.class)); + } + + @Test + public void return_since_x_label() { + periods.label(TIMEMACHINE_MODE_DATE, null, STRING_DATE); + + verify(i18n).message(any(Locale.class), eq("since_x"), isNull(String.class), eq(STRING_DATE)); + } + + @Test + public void return_since_x_label_using_settings() { + settings.setProperty(TIMEMACHINE_PERIOD_PREFIX + PERIOD_INDEX, STRING_DATE); + + periods.label(PERIOD_INDEX); + + verify(i18n).message(any(Locale.class), eq("since_x"), isNull(String.class), anyString()); + } + + @Test + public void return_since_x_abbreviation() { + periods.abbreviation(TIMEMACHINE_MODE_DATE, null, DATE); + + verify(i18n).message(any(Locale.class), eq("since_x.short"), isNull(String.class), anyString()); + } + + @Test + public void throw_IAE_when_mode_is_unknown() { + thrown.expect(IllegalArgumentException.class); + thrown.expectMessage("This mode is not supported : unknown"); + + periods.label("unknown", null, (String) null); + } + + @Test + public void return_abbreviation_using_settings() { + settings.setProperty(TIMEMACHINE_PERIOD_PREFIX + PERIOD_INDEX, NUMBER_OF_DAYS); + + periods.abbreviation(PERIOD_INDEX); + + verify(i18n).message(any(Locale.class), eq("over_x_days.short"), isNull(String.class), eq(NUMBER_OF_DAYS)); + } + + @Test + public void throw_IAE_when_period_property_is_empty() { + settings.setProperty(TIMEMACHINE_PERIOD_PREFIX + PERIOD_INDEX, ""); + + thrown.expect(IllegalArgumentException.class); + thrown.expectMessage("Period property should not be empty"); + + periods.label(PERIOD_INDEX); + } + + @Test + public void throw_IAE_when_period_property_is_null() { + settings.setProperty(TIMEMACHINE_PERIOD_PREFIX + PERIOD_INDEX, (String) null); + + thrown.expect(IllegalArgumentException.class); + thrown.expectMessage("Period property should not be empty"); + + periods.label(PERIOD_INDEX); + } + +} diff --git a/sonar-core/src/test/java/org/sonar/core/util/DefaultHttpDownloaderTest.java b/sonar-core/src/test/java/org/sonar/core/util/DefaultHttpDownloaderTest.java index f9296bcd139..3dbd4c88800 100644 --- a/sonar-core/src/test/java/org/sonar/core/util/DefaultHttpDownloaderTest.java +++ b/sonar-core/src/test/java/org/sonar/core/util/DefaultHttpDownloaderTest.java @@ -51,7 +51,9 @@ import org.simpleframework.http.Request; import org.simpleframework.http.Response; import org.simpleframework.http.core.Container; import org.simpleframework.transport.connect.SocketConnection; +import org.sonar.api.CoreProperties; import org.sonar.api.config.Settings; +import org.sonar.api.config.MapSettings; import org.sonar.api.platform.Server; import org.sonar.api.utils.SonarException; @@ -146,31 +148,31 @@ public class DefaultHttpDownloaderTest { public void describeTo(Description arg0) { } }); - DefaultHttpDownloader downloader = new DefaultHttpDownloader(new Settings(), 10, 50000); + DefaultHttpDownloader downloader = new DefaultHttpDownloader(new MapSettings(), 10, 50000); downloader.openStream(new URI(url)); } @Test public void downloadBytes() throws URISyntaxException { - byte[] bytes = new DefaultHttpDownloader(new Settings()).readBytes(new URI(baseUrl)); + byte[] bytes = new DefaultHttpDownloader(new MapSettings()).readBytes(new URI(baseUrl)); assertThat(bytes.length).isGreaterThan(10); } @Test public void readString() throws URISyntaxException { - String text = new DefaultHttpDownloader(new Settings()).readString(new URI(baseUrl), StandardCharsets.UTF_8); + String text = new DefaultHttpDownloader(new MapSettings()).readString(new URI(baseUrl), StandardCharsets.UTF_8); assertThat(text.length()).isGreaterThan(10); } @Test public void readGzipString() throws URISyntaxException { - String text = new DefaultHttpDownloader(new Settings()).readString(new URI(baseUrl + "/gzip/"), StandardCharsets.UTF_8); + String text = new DefaultHttpDownloader(new MapSettings()).readString(new URI(baseUrl + "/gzip/"), StandardCharsets.UTF_8); assertThat(text).isEqualTo("GZIP response"); } @Test public void readStringWithDefaultTimeout() throws URISyntaxException { - String text = new DefaultHttpDownloader(new Settings()).readString(new URI(baseUrl + "/timeout/"), StandardCharsets.UTF_8); + String text = new DefaultHttpDownloader(new MapSettings()).readString(new URI(baseUrl + "/timeout/"), StandardCharsets.UTF_8); assertThat(text.length()).isGreaterThan(10); } @@ -186,7 +188,7 @@ public class DefaultHttpDownloaderTest { public void describeTo(Description arg0) { } }); - new DefaultHttpDownloader(new Settings(), 50).readString(new URI(baseUrl + "/timeout/"), StandardCharsets.UTF_8); + new DefaultHttpDownloader(new MapSettings(), 50).readString(new URI(baseUrl + "/timeout/"), StandardCharsets.UTF_8); } @Test @@ -194,7 +196,7 @@ public class DefaultHttpDownloaderTest { File toDir = temporaryFolder.newFolder(); File toFile = new File(toDir, "downloadToFile.txt"); - new DefaultHttpDownloader(new Settings()).download(new URI(baseUrl), toFile); + new DefaultHttpDownloader(new MapSettings()).download(new URI(baseUrl), toFile); assertThat(toFile).exists(); assertThat(toFile.length()).isGreaterThan(10l); } @@ -206,28 +208,53 @@ public class DefaultHttpDownloaderTest { try { int port = new InetSocketAddress("localhost", 0).getPort(); - new DefaultHttpDownloader(new Settings()).download(new URI("http://localhost:" + port), toFile); + new DefaultHttpDownloader(new MapSettings()).download(new URI("http://localhost:" + port), toFile); } catch (SonarException e) { assertThat(toFile).doesNotExist(); } } @Test - public void userAgentIsSonarVersion() throws URISyntaxException, IOException { + public void userAgent_includes_version_and_SERVER_ID_when_server_is_provided() throws URISyntaxException, IOException { Server server = mock(Server.class); when(server.getVersion()).thenReturn("2.2"); + MapSettings settings = new MapSettings(); + settings.setProperty(CoreProperties.SERVER_ID, "blablabla"); - InputStream stream = new DefaultHttpDownloader(server, new Settings()).openStream(new URI(baseUrl)); + InputStream stream = new DefaultHttpDownloader(server, settings).openStream(new URI(baseUrl)); Properties props = new Properties(); props.load(stream); stream.close(); - assertThat(props.getProperty("agent")).isEqualTo("SonarQube 2.2"); + assertThat(props.getProperty("agent")).isEqualTo("SonarQube 2.2 # blablabla"); + } + + @Test + public void userAgent_includes_only_version_when_there_is_no_SERVER_ID_and_server_is_provided() throws URISyntaxException, IOException { + Server server = mock(Server.class); + when(server.getVersion()).thenReturn("2.2"); + + InputStream stream = new DefaultHttpDownloader(server, new MapSettings()).openStream(new URI(baseUrl)); + Properties props = new Properties(); + props.load(stream); + stream.close(); + + assertThat(props.getProperty("agent")).isEqualTo("SonarQube 2.2 #"); + } + + @Test + public void userAgent_is_static_value_when_server_is_not_provided() throws URISyntaxException, IOException { + InputStream stream = new DefaultHttpDownloader(new MapSettings()).openStream(new URI(baseUrl)); + Properties props = new Properties(); + props.load(stream); + stream.close(); + + assertThat(props.getProperty("agent")).isEqualTo("SonarQube"); } @Test public void followRedirect() throws URISyntaxException { - String content = new DefaultHttpDownloader(new Settings()).readString(new URI(baseUrl + "/redirect/"), StandardCharsets.UTF_8); + String content = new DefaultHttpDownloader(new MapSettings()).readString(new URI(baseUrl + "/redirect/"), StandardCharsets.UTF_8); assertThat(content).contains("agent"); } @@ -247,19 +274,19 @@ public class DefaultHttpDownloaderTest { @Test public void supported_schemes() { - assertThat(new DefaultHttpDownloader(new Settings()).getSupportedSchemes()).contains("http"); + assertThat(new DefaultHttpDownloader(new MapSettings()).getSupportedSchemes()).contains("http"); } @Test public void uri_description() throws URISyntaxException { - String description = new DefaultHttpDownloader(new Settings()).description(new URI("http://sonarsource.org")); + String description = new DefaultHttpDownloader(new MapSettings()).description(new URI("http://sonarsource.org")); assertThat(description).matches("http://sonarsource.org \\(.*\\)"); } @Test public void configure_http_and_https_proxies() { DefaultHttpDownloader.SystemFacade system = mock(DefaultHttpDownloader.SystemFacade.class); - Settings settings = new Settings(); + Settings settings = new MapSettings(); settings.setProperty("http.proxyHost", "1.2.3.4"); settings.setProperty("http.proxyPort", "80"); settings.setProperty("https.proxyHost", "5.6.7.8"); @@ -277,7 +304,7 @@ public class DefaultHttpDownloaderTest { @Test public void https_defaults_are_http_properties() { DefaultHttpDownloader.SystemFacade system = mock(DefaultHttpDownloader.SystemFacade.class); - Settings settings = new Settings(); + Settings settings = new MapSettings(); settings.setProperty("http.proxyHost", "1.2.3.4"); settings.setProperty("http.proxyPort", "80"); @@ -292,7 +319,7 @@ public class DefaultHttpDownloaderTest { @Test public void configure_http_proxy_credentials() { DefaultHttpDownloader.SystemFacade system = mock(DefaultHttpDownloader.SystemFacade.class); - Settings settings = new Settings(); + Settings settings = new MapSettings(); settings.setProperty("https.proxyHost", "1.2.3.4"); settings.setProperty("http.proxyUser", "the_login"); settings.setProperty("http.proxyPassword", "the_passwd"); @@ -317,7 +344,7 @@ public class DefaultHttpDownloaderTest { @Test public void no_http_proxy_settings_by_default() { DefaultHttpDownloader.SystemFacade system = mock(DefaultHttpDownloader.SystemFacade.class); - Settings settings = new Settings(); + Settings settings = new MapSettings(); new DefaultHttpDownloader.BaseHttpDownloader(system, settings, null); verify(system, never()).setProperty(eq("http.proxyHost"), anyString()); diff --git a/sonar-core/src/test/java/org/sonar/core/util/FileUtilsTest.java b/sonar-core/src/test/java/org/sonar/core/util/FileUtilsTest.java index 28411c2c110..3e51afe40c9 100644 --- a/sonar-core/src/test/java/org/sonar/core/util/FileUtilsTest.java +++ b/sonar-core/src/test/java/org/sonar/core/util/FileUtilsTest.java @@ -25,12 +25,14 @@ import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.attribute.BasicFileAttributes; import javax.annotation.CheckForNull; +import org.apache.commons.lang.SystemUtils; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; import org.junit.rules.TemporaryFolder; import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.Assume.assumeTrue; public class FileUtilsTest { @Rule @@ -89,6 +91,7 @@ public class FileUtilsTest { @Test public void cleanDirectory_follows_symlink_to_target_directory() throws IOException { + assumeTrue(SystemUtils.IS_OS_UNIX); Path target = temporaryFolder.newFolder().toPath(); Path symToDir = Files.createSymbolicLink(temporaryFolder.newFolder().toPath().resolve("sym_to_dir"), target); Path childFile1 = Files.createFile(target.resolve("file1.txt")); @@ -157,6 +160,7 @@ public class FileUtilsTest { @Test public void deleteQuietly_deletes_symbolicLink() throws IOException { + assumeTrue(SystemUtils.IS_OS_UNIX); Path folder = temporaryFolder.newFolder().toPath(); Path file1 = Files.createFile(folder.resolve("file1.txt")); Path symLink = Files.createSymbolicLink(folder.resolve("link1"), file1); @@ -196,6 +200,7 @@ public class FileUtilsTest { @Test public void deleteDirectory_throws_IOE_if_file_is_symbolicLink() throws IOException { + assumeTrue(SystemUtils.IS_OS_UNIX); Path folder = temporaryFolder.newFolder().toPath(); Path file1 = Files.createFile(folder.resolve("file1.txt")); Path symLink = Files.createSymbolicLink(folder.resolve("link1"), file1); diff --git a/sonar-core/src/test/java/org/sonar/core/util/ProgressLoggerTest.java b/sonar-core/src/test/java/org/sonar/core/util/ProgressLoggerTest.java index d7e93c41c98..57bb0de02d5 100644 --- a/sonar-core/src/test/java/org/sonar/core/util/ProgressLoggerTest.java +++ b/sonar-core/src/test/java/org/sonar/core/util/ProgressLoggerTest.java @@ -19,33 +19,37 @@ */ package org.sonar.core.util; +import com.google.common.util.concurrent.Uninterruptibles; +import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicLong; +import org.junit.Rule; import org.junit.Test; -import org.sonar.api.utils.log.Logger; +import org.sonar.api.utils.log.LogTester; +import org.sonar.api.utils.log.LoggerLevel; +import org.sonar.api.utils.log.Loggers; import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.atLeast; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.startsWith; -import static org.mockito.Mockito.verify; public class ProgressLoggerTest { - @Test(timeout = 1000L) + @Rule + public LogTester logTester = new LogTester(); + + @Test(timeout = 5_000L) public void log_at_fixed_intervals() throws Exception { - Logger logger = mock(Logger.class); AtomicLong counter = new AtomicLong(42L); - ProgressLogger progress = new ProgressLogger("ProgressLoggerTest", counter, logger); + ProgressLogger progress = new ProgressLogger("ProgressLoggerTest", counter, Loggers.get(getClass())); progress.setPeriodMs(1L); progress.start(); - Thread.sleep(80L); + while (!hasInfoLog("42 rows processed")) { + Uninterruptibles.sleepUninterruptibly(1, TimeUnit.MILLISECONDS); + } progress.stop(); - verify(logger, atLeast(1)).info(startsWith("42 rows processed")); // ability to manual log, generally final status counter.incrementAndGet(); progress.log(); - verify(logger).info(startsWith("43 rows processed")); + assertThat(hasInfoLog("43 rows processed")).isTrue(); } @Test @@ -61,6 +65,9 @@ public class ProgressLoggerTest { progress.setPluralLabel("issues"); assertThat(progress.getPeriodMs()).isEqualTo(10L); assertThat(progress.getPluralLabel()).isEqualTo("issues"); + } + private boolean hasInfoLog(String expectedLog) { + return logTester.logs(LoggerLevel.INFO).stream().filter(s -> s.startsWith(expectedLog)).findFirst().isPresent(); } } diff --git a/sonar-core/src/test/java/org/sonar/core/util/SequenceUuidFactoryTest.java b/sonar-core/src/test/java/org/sonar/core/util/SequenceUuidFactoryTest.java new file mode 100644 index 00000000000..2ca09ce5907 --- /dev/null +++ b/sonar-core/src/test/java/org/sonar/core/util/SequenceUuidFactoryTest.java @@ -0,0 +1,37 @@ +/* + * SonarQube + * Copyright (C) 2009-2016 SonarSource SA + * mailto:contact 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.core.util; + +import org.junit.Test; + +import static org.assertj.core.api.Assertions.assertThat; + + +public class SequenceUuidFactoryTest { + + private SequenceUuidFactory underTest = new SequenceUuidFactory(); + + @Test + public void generate_sequence_of_integer_ids() { + for (int i = 1; i < 10; i++) { + assertThat(underTest.create()).isEqualTo(String.valueOf(i)); + } + } +} diff --git a/sonar-core/src/test/java/org/sonar/core/util/stream/CollectorsTest.java b/sonar-core/src/test/java/org/sonar/core/util/stream/CollectorsTest.java new file mode 100644 index 00000000000..694846f7600 --- /dev/null +++ b/sonar-core/src/test/java/org/sonar/core/util/stream/CollectorsTest.java @@ -0,0 +1,513 @@ +/* + * SonarQube + * Copyright (C) 2009-2016 SonarSource SA + * mailto:contact 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.core.util.stream; + +import com.google.common.base.Joiner; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Multimap; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.stream.IntStream; +import java.util.stream.Stream; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; + +import static java.util.function.Function.identity; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.entry; +import static org.assertj.guava.api.Assertions.assertThat; +import static org.sonar.core.util.stream.Collectors.index; +import static org.sonar.core.util.stream.Collectors.join; +import static org.sonar.core.util.stream.Collectors.toArrayList; +import static org.sonar.core.util.stream.Collectors.toHashSet; +import static org.sonar.core.util.stream.Collectors.toList; +import static org.sonar.core.util.stream.Collectors.toSet; +import static org.sonar.core.util.stream.Collectors.uniqueIndex; + +public class CollectorsTest { + + private static final List<String> HUGE_LIST = IntStream.range(0, 2_000).mapToObj(String::valueOf).collect(java.util.stream.Collectors.toList()); + private static final Set<String> HUGE_SET = new HashSet<>(HUGE_LIST); + private static final MyObj MY_OBJ_1_A = new MyObj(1, "A"); + private static final MyObj MY_OBJ_1_C = new MyObj(1, "C"); + private static final MyObj MY_OBJ_2_B = new MyObj(2, "B"); + private static final MyObj MY_OBJ_3_C = new MyObj(3, "C"); + private static final List<MyObj> SINGLE_ELEMENT_LIST = Arrays.asList(MY_OBJ_1_A); + private static final List<MyObj> LIST_WITH_DUPLICATE_ID = Arrays.asList(MY_OBJ_1_A, MY_OBJ_2_B, MY_OBJ_1_C); + private static final List<MyObj> LIST = Arrays.asList(MY_OBJ_1_A, MY_OBJ_2_B, MY_OBJ_3_C); + + @Rule + public ExpectedException expectedException = ExpectedException.none(); + + @Test + public void toList_builds_an_ImmutableList() { + List<Integer> res = Arrays.asList(1, 2, 3, 4, 5).stream().collect(toList()); + assertThat(res).isInstanceOf(ImmutableList.class) + .containsExactly(1, 2, 3, 4, 5); + } + + @Test + public void toList_parallel_stream() { + assertThat(HUGE_LIST.parallelStream().collect(toList())).isEqualTo(HUGE_LIST); + } + + @Test + public void toList_with_size_builds_an_ImmutableList() { + List<Integer> res = Arrays.asList(1, 2, 3, 4, 5).stream().collect(toList(30)); + assertThat(res).isInstanceOf(ImmutableList.class) + .containsExactly(1, 2, 3, 4, 5); + } + + @Test + public void toList_with_size_parallel_stream() { + assertThat(HUGE_LIST.parallelStream().collect(toList(HUGE_LIST.size()))).isEqualTo(HUGE_LIST); + } + + @Test + public void toSet_builds_an_ImmutableSet() { + Set<Integer> res = Arrays.asList(1, 2, 3, 4, 5).stream().collect(toSet()); + assertThat(res).isInstanceOf(ImmutableSet.class) + .containsExactly(1, 2, 3, 4, 5); + } + + @Test + public void toSet_parallel_stream() { + assertThat(HUGE_SET.parallelStream().collect(toSet())).isEqualTo(HUGE_SET); + } + + @Test + public void toSet_with_size_builds_an_ImmutableSet() { + Set<Integer> res = Arrays.asList(1, 2, 3, 4, 5).stream().collect(toSet(30)); + assertThat(res).isInstanceOf(ImmutableSet.class) + .containsExactly(1, 2, 3, 4, 5); + } + + @Test + public void toSet_with_size_parallel_stream() { + assertThat(HUGE_SET.parallelStream().collect(toSet(HUGE_SET.size()))).isEqualTo(HUGE_SET); + } + + @Test + public void toArrayList_builds_an_ArrayList() { + List<Integer> res = Arrays.asList(1, 2, 3, 4, 5).stream().collect(toArrayList()); + assertThat(res).isInstanceOf(ArrayList.class) + .containsExactly(1, 2, 3, 4, 5); + } + + @Test + public void toArrayList_parallel_stream() { + assertThat(HUGE_LIST.parallelStream().collect(toArrayList())).isEqualTo(HUGE_LIST); + } + + @Test + public void toArrayList_with_size_builds_an_ArrayList() { + List<Integer> res = Arrays.asList(1, 2, 3, 4, 5).stream().collect(toArrayList(30)); + assertThat(res).isInstanceOf(ArrayList.class) + .containsExactly(1, 2, 3, 4, 5); + } + + @Test + public void toArrayList_with_size_parallel_stream() { + assertThat(HUGE_LIST.parallelStream().collect(toArrayList(HUGE_LIST.size()))).isEqualTo(HUGE_LIST); + } + + @Test + public void toHashSet_builds_an_HashSet() { + Set<Integer> res = Arrays.asList(1, 2, 3, 4, 5).stream().collect(toHashSet()); + assertThat(res).isInstanceOf(HashSet.class) + .containsExactly(1, 2, 3, 4, 5); + } + + @Test + public void toHashSet_parallel_stream() { + assertThat(HUGE_SET.parallelStream().collect(toHashSet())).isEqualTo(HUGE_SET); + } + + @Test + public void toHashSet_with_size_builds_an_ArrayList() { + Set<Integer> res = Arrays.asList(1, 2, 3, 4, 5).stream().collect(toHashSet(30)); + assertThat(res).isInstanceOf(HashSet.class) + .containsExactly(1, 2, 3, 4, 5); + } + + @Test + public void toHashSet_with_size_parallel_stream() { + assertThat(HUGE_SET.parallelStream().collect(toHashSet(HUGE_SET.size()))).isEqualTo(HUGE_SET); + } + + @Test + public void uniqueIndex_empty_stream_returns_empty_map() { + assertThat(Collections.<MyObj>emptyList().stream().collect(uniqueIndex(MyObj::getId))).isEmpty(); + assertThat(Collections.<MyObj>emptyList().stream().collect(uniqueIndex(MyObj::getId, 6))).isEmpty(); + assertThat(Collections.<MyObj>emptyList().stream().collect(uniqueIndex(MyObj::getId, MyObj::getText))).isEmpty(); + assertThat(Collections.<MyObj>emptyList().stream().collect(uniqueIndex(MyObj::getId, MyObj::getText, 10))).isEmpty(); + } + + @Test + public void uniqueIndex_fails_when_there_is_duplicate_keys() { + Stream<MyObj> stream = LIST_WITH_DUPLICATE_ID.stream(); + + expectedDuplicateKey1IAE(); + + stream.collect(uniqueIndex(MyObj::getId)); + } + + @Test + public void uniqueIndex_with_expected_size_fails_when_there_is_duplicate_keys() { + Stream<MyObj> stream = LIST_WITH_DUPLICATE_ID.stream(); + + expectedDuplicateKey1IAE(); + + stream.collect(uniqueIndex(MyObj::getId, 1)); + } + + @Test + public void uniqueIndex_with_valueFunction_fails_when_there_is_duplicate_keys() { + Stream<MyObj> stream = LIST_WITH_DUPLICATE_ID.stream(); + + expectedDuplicateKey1IAE(); + + stream.collect(uniqueIndex(MyObj::getId, MyObj::getText)); + } + + @Test + public void uniqueIndex_with_valueFunction_and_expected_size_fails_when_there_is_duplicate_keys() { + Stream<MyObj> stream = LIST_WITH_DUPLICATE_ID.stream(); + + expectedDuplicateKey1IAE(); + + stream.collect(uniqueIndex(MyObj::getId, MyObj::getText, 10)); + } + + @Test + public void uniqueIndex_fails_if_key_function_is_null() { + expectedException.expect(NullPointerException.class); + expectedException.expectMessage("Key function can't be null"); + + uniqueIndex(null); + } + + @Test + public void uniqueIndex_with_expected_size_fails_if_key_function_is_null() { + expectedException.expect(NullPointerException.class); + expectedException.expectMessage("Key function can't be null"); + + uniqueIndex(null, 2); + } + + @Test + public void uniqueIndex_with_valueFunction_fails_if_key_function_is_null() { + expectedException.expect(NullPointerException.class); + expectedException.expectMessage("Key function can't be null"); + + uniqueIndex(null, MyObj::getText); + } + + @Test + public void uniqueIndex_with_valueFunction_and_expected_size_fails_if_key_function_is_null() { + expectedException.expect(NullPointerException.class); + expectedException.expectMessage("Key function can't be null"); + + uniqueIndex(null, MyObj::getText, 9); + } + + @Test + public void uniqueIndex_with_valueFunction_fails_if_value_function_is_null() { + expectedException.expect(NullPointerException.class); + expectedException.expectMessage("Value function can't be null"); + + uniqueIndex(MyObj::getId, null); + } + + @Test + public void uniqueIndex_with_valueFunction_and_expected_size_fails_if_value_function_is_null() { + expectedException.expect(NullPointerException.class); + expectedException.expectMessage("Value function can't be null"); + + uniqueIndex(MyObj::getId, null, 9); + } + + @Test + public void uniqueIndex_fails_if_key_function_returns_null() { + expectKeyFunctionCantReturnNullNPE(); + + SINGLE_ELEMENT_LIST.stream().collect(uniqueIndex(s -> null)); + } + + @Test + public void uniqueIndex_with_expected_size_fails_if_key_function_returns_null() { + expectKeyFunctionCantReturnNullNPE(); + + SINGLE_ELEMENT_LIST.stream().collect(uniqueIndex(s -> null, 90)); + } + + @Test + public void uniqueIndex_with_valueFunction_fails_if_key_function_returns_null() { + expectKeyFunctionCantReturnNullNPE(); + + SINGLE_ELEMENT_LIST.stream().collect(uniqueIndex(s -> null, MyObj::getText)); + } + + @Test + public void uniqueIndex_with_valueFunction_and_expected_size_fails_if_key_function_returns_null() { + expectKeyFunctionCantReturnNullNPE(); + + SINGLE_ELEMENT_LIST.stream().collect(uniqueIndex(s -> null, MyObj::getText, 9)); + } + + @Test + public void uniqueIndex_with_valueFunction_fails_if_value_function_returns_null() { + expectValueFunctionCantReturnNullNPE(); + + SINGLE_ELEMENT_LIST.stream().collect(uniqueIndex(MyObj::getId, s -> null)); + } + + @Test + public void uniqueIndex_with_valueFunction_and_expected_size_fails_if_value_function_returns_null() { + expectValueFunctionCantReturnNullNPE(); + + SINGLE_ELEMENT_LIST.stream().collect(uniqueIndex(MyObj::getId, s -> null, 9)); + } + + @Test + public void uniqueIndex_returns_map() { + assertThat(LIST.stream().collect(uniqueIndex(MyObj::getId))).containsOnly(entry(1, MY_OBJ_1_A), entry(2, MY_OBJ_2_B), entry(3, MY_OBJ_3_C)); + } + + @Test + public void uniqueIndex_with_expected_size_returns_map() { + assertThat(LIST.stream().collect(uniqueIndex(MyObj::getId, 3))).containsOnly(entry(1, MY_OBJ_1_A), entry(2, MY_OBJ_2_B), entry(3, MY_OBJ_3_C)); + } + + @Test + public void uniqueIndex_with_valueFunction_returns_map() { + assertThat(LIST.stream().collect(uniqueIndex(MyObj::getId, MyObj::getText))).containsOnly(entry(1, "A"), entry(2, "B"), entry(3, "C")); + } + + @Test + public void uniqueIndex_with_valueFunction_and_expected_size_returns_map() { + assertThat(LIST.stream().collect(uniqueIndex(MyObj::getId, MyObj::getText, 9))).containsOnly(entry(1, "A"), entry(2, "B"), entry(3, "C")); + } + + @Test + public void uniqueIndex_parallel_stream() { + Map<String, String> map = HUGE_LIST.parallelStream().collect(uniqueIndex(identity())); + assertThat(map.keySet()).isEqualTo(HUGE_SET); + assertThat(map.values()).containsExactlyElementsOf(HUGE_SET); + } + + @Test + public void uniqueIndex_with_expected_size_parallel_stream() { + Map<String, String> map = HUGE_LIST.parallelStream().collect(uniqueIndex(identity(), HUGE_LIST.size())); + assertThat(map.keySet()).isEqualTo(HUGE_SET); + assertThat(map.values()).containsExactlyElementsOf(HUGE_SET); + } + + @Test + public void uniqueIndex_with_valueFunction_parallel_stream() { + Map<String, String> map = HUGE_LIST.parallelStream().collect(uniqueIndex(identity(), identity())); + assertThat(map.keySet()).isEqualTo(HUGE_SET); + assertThat(map.values()).containsExactlyElementsOf(HUGE_SET); + } + + @Test + public void uniqueIndex_with_valueFunction_and_expected_size_parallel_stream() { + Map<String, String> map = HUGE_LIST.parallelStream().collect(uniqueIndex(identity(), identity(), HUGE_LIST.size())); + assertThat(map.keySet()).isEqualTo(HUGE_SET); + assertThat(map.values()).containsExactlyElementsOf(HUGE_SET); + } + + @Test + public void index_empty_stream_returns_empty_map() { + assertThat(Collections.<MyObj>emptyList().stream().collect(index(MyObj::getId))).isEmpty(); + assertThat(Collections.<MyObj>emptyList().stream().collect(index(MyObj::getId, MyObj::getText))).isEmpty(); + } + + @Test + public void index_fails_if_key_function_is_null() { + expectedException.expect(NullPointerException.class); + expectedException.expectMessage("Key function can't be null"); + + index(null); + } + + @Test + public void index_with_valueFunction_fails_if_key_function_is_null() { + expectedException.expect(NullPointerException.class); + expectedException.expectMessage("Key function can't be null"); + + index(null, MyObj::getText); + } + + @Test + public void index_with_valueFunction_fails_if_value_function_is_null() { + expectedException.expect(NullPointerException.class); + expectedException.expectMessage("Value function can't be null"); + + index(MyObj::getId, null); + } + + @Test + public void index_fails_if_key_function_returns_null() { + expectKeyFunctionCantReturnNullNPE(); + + SINGLE_ELEMENT_LIST.stream().collect(index(s -> null)); + } + + @Test + public void index_with_valueFunction_fails_if_key_function_returns_null() { + expectKeyFunctionCantReturnNullNPE(); + + SINGLE_ELEMENT_LIST.stream().collect(index(s -> null, MyObj::getText)); + } + + @Test + public void index_with_valueFunction_fails_if_value_function_returns_null() { + expectValueFunctionCantReturnNullNPE(); + + SINGLE_ELEMENT_LIST.stream().collect(index(MyObj::getId, s -> null)); + } + + @Test + public void index_supports_duplicate_keys() { + Multimap<Integer, MyObj> multimap = LIST_WITH_DUPLICATE_ID.stream().collect(index(MyObj::getId)); + + assertThat(multimap.keySet()).containsOnly(1, 2); + assertThat(multimap.get(1)).containsOnly(MY_OBJ_1_A, MY_OBJ_1_C); + assertThat(multimap.get(2)).containsOnly(MY_OBJ_2_B); + } + + @Test + public void uniqueIndex_supports_duplicate_keys() { + Multimap<Integer, String> multimap = LIST_WITH_DUPLICATE_ID.stream().collect(index(MyObj::getId, MyObj::getText)); + + assertThat(multimap.keySet()).containsOnly(1, 2); + assertThat(multimap.get(1)).containsOnly("A", "C"); + assertThat(multimap.get(2)).containsOnly("B"); + } + + @Test + public void index_returns_multimap() { + Multimap<Integer, MyObj> multimap = LIST.stream().collect(index(MyObj::getId)); + + assertThat(multimap).hasSize(3); + assertThat(multimap).contains(entry(1, MY_OBJ_1_A), entry(2, MY_OBJ_2_B), entry(3, MY_OBJ_3_C)); + } + + @Test + public void index_with_valueFunction_returns_multimap() { + Multimap<Integer, String> multimap = LIST.stream().collect(index(MyObj::getId, MyObj::getText)); + + assertThat(multimap).hasSize(3); + assertThat(multimap).contains(entry(1, "A"), entry(2, "B"), entry(3, "C")); + } + + @Test + public void index_parallel_stream() { + Multimap<String, String> multimap = HUGE_LIST.parallelStream().collect(index(identity())); + + assertThat(multimap.keySet()).isEqualTo(HUGE_SET); + } + + @Test + public void index_with_valueFunction_parallel_stream() { + Multimap<String, String> multimap = HUGE_LIST.parallelStream().collect(index(identity(), identity())); + + assertThat(multimap.keySet()).isEqualTo(HUGE_SET); + } + + @Test + public void join_on_empty_stream_returns_empty_string() { + assertThat(Collections.emptyList().stream().collect(join(Joiner.on(",")))).isEmpty(); + } + + @Test + public void join_fails_with_NPE_if_joiner_is_null() { + expectedException.expect(NullPointerException.class); + expectedException.expectMessage("Joiner can't be null"); + + join(null); + } + + @Test + public void join_applies_joiner_to_stream() { + assertThat(Arrays.asList("1", "2", "3", "4").stream().collect(join(Joiner.on(",")))) + .isEqualTo("1,2,3,4"); + } + + @Test + public void join_does_not_support_parallel_stream_and_fails_with_ISE() { + Stream<String> hugeStream = HUGE_LIST.parallelStream(); + + expectedException.expect(IllegalStateException.class); + expectedException.expectMessage("Parallel processing is not supported"); + + hugeStream.collect(join(Joiner.on(" "))); + } + + @Test + public void join_supports_null_if_joiner_does() { + Stream<String> stream = Arrays.asList("1", null).stream(); + + expectedException.expect(NullPointerException.class); + + stream.collect(join(Joiner.on(","))); + } + + private void expectedDuplicateKey1IAE() { + expectedException.expect(IllegalArgumentException.class); + expectedException.expectMessage("Duplicate key 1"); + } + + private void expectKeyFunctionCantReturnNullNPE() { + expectedException.expect(NullPointerException.class); + expectedException.expectMessage("Key function can't return null"); + } + + private void expectValueFunctionCantReturnNullNPE() { + expectedException.expect(NullPointerException.class); + expectedException.expectMessage("Value function can't return null"); + } + + private static final class MyObj { + private final int id; + private final String text; + + public MyObj(int id, String text) { + this.id = id; + this.text = text; + } + + public int getId() { + return id; + } + + public String getText() { + return text; + } + } +} |