diff options
author | Julien HENRY <julien.henry@sonarsource.com> | 2014-06-12 09:38:46 +0200 |
---|---|---|
committer | Julien HENRY <julien.henry@sonarsource.com> | 2014-06-16 09:42:46 +0200 |
commit | d35dc73824f38e3585b44d8b7ee9df867bccec5b (patch) | |
tree | 1248c5da0843b6218c677f1a375a82e3bb67b383 /sonar-batch | |
parent | 74e76cbd9f07045561a219efe49f220253508ddb (diff) | |
download | sonarqube-d35dc73824f38e3585b44d8b7ee9df867bccec5b.tar.gz sonarqube-d35dc73824f38e3585b44d8b7ee9df867bccec5b.zip |
SONAR-5389 New Analyzer API
Diffstat (limited to 'sonar-batch')
85 files changed, 1384 insertions, 752 deletions
diff --git a/sonar-batch/pom.xml b/sonar-batch/pom.xml index db45a80e535..1db1f35f0e9 100644 --- a/sonar-batch/pom.xml +++ b/sonar-batch/pom.xml @@ -42,6 +42,10 @@ </dependency> <dependency> <groupId>org.codehaus.sonar</groupId> + <artifactId>sonar-batch-plugin-api</artifactId> + </dependency> + <dependency> + <groupId>org.codehaus.sonar</groupId> <artifactId>sonar-plugin-api</artifactId> <exclusions> <exclusion> diff --git a/sonar-batch/src/main/java/org/sonar/batch/DefaultSensorContext.java b/sonar-batch/src/main/java/org/sonar/batch/DefaultSensorContext.java index 4d71b95e470..089b2a3c58f 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/DefaultSensorContext.java +++ b/sonar-batch/src/main/java/org/sonar/batch/DefaultSensorContext.java @@ -30,11 +30,16 @@ import org.sonar.api.design.Dependency; import org.sonar.api.measures.Measure; import org.sonar.api.measures.MeasuresFilter; import org.sonar.api.measures.Metric; -import org.sonar.api.resources.*; +import org.sonar.api.resources.File; +import org.sonar.api.resources.Project; +import org.sonar.api.resources.ProjectLink; +import org.sonar.api.resources.Qualifiers; +import org.sonar.api.resources.Resource; import org.sonar.api.rules.Violation; import org.sonar.api.utils.SonarException; import org.sonar.core.measure.MeasurementFilters; +import java.io.Serializable; import java.util.Collection; import java.util.Date; import java.util.List; @@ -110,7 +115,7 @@ public class DefaultSensorContext implements SensorContext { } @Override - public Measure getMeasure(Metric metric) { + public <G extends Serializable> Measure<G> getMeasure(Metric<G> metric) { return index.getMeasure(project, metric); } @@ -130,7 +135,7 @@ public class DefaultSensorContext implements SensorContext { } @Override - public Measure getMeasure(Resource resource, Metric metric) { + public <G extends Serializable> Measure<G> getMeasure(Resource resource, Metric<G> metric) { return index.getMeasure(resource, metric); } diff --git a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/AnalysisMode.java b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/AnalysisMode.java index 4415122c3f6..89640219562 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/AnalysisMode.java +++ b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/AnalysisMode.java @@ -38,6 +38,7 @@ public class AnalysisMode implements BatchComponent { private boolean preview; private boolean incremental; private int previewReadTimeoutSec; + private boolean sensorMode; public AnalysisMode(BootstrapProperties bootstrapProps) { init(bootstrapProps); @@ -51,20 +52,28 @@ public class AnalysisMode implements BatchComponent { return incremental; } + public boolean isSensorMode() { + return sensorMode; + } + private void init(BootstrapProperties bootstrapProps) { if (bootstrapProps.properties().containsKey(CoreProperties.DRY_RUN)) { LOG.warn(MessageFormat.format("Property {0} is deprecated. Please use {1} instead.", CoreProperties.DRY_RUN, CoreProperties.ANALYSIS_MODE)); preview = "true".equals(bootstrapProps.property(CoreProperties.DRY_RUN)); incremental = false; + sensorMode = false; } else { String mode = bootstrapProps.property(CoreProperties.ANALYSIS_MODE); preview = CoreProperties.ANALYSIS_MODE_PREVIEW.equals(mode); incremental = CoreProperties.ANALYSIS_MODE_INCREMENTAL.equals(mode); + sensorMode = CoreProperties.ANALYSIS_MODE_SENSOR.equals(mode); } if (incremental) { LOG.info("Incremental mode"); } else if (preview) { LOG.info("Preview mode"); + } else if (sensorMode) { + LOG.info("Sensor mode"); } // To stay compatible with plugins that use the old property to check mode if (incremental || preview) { diff --git a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BatchComponents.java b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BatchComponents.java index 02c98554fa6..0391110d3a5 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BatchComponents.java +++ b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BatchComponents.java @@ -20,9 +20,6 @@ package org.sonar.batch.bootstrap; import com.google.common.collect.Lists; -import org.sonar.batch.debt.DebtDecorator; -import org.sonar.batch.debt.IssueChangelogDebtCalculator; -import org.sonar.batch.debt.NewDebtDecorator; import org.sonar.batch.maven.DefaultMavenPluginExecutor; import org.sonar.batch.maven.MavenProjectBootstrapper; import org.sonar.batch.maven.MavenProjectBuilder; @@ -36,11 +33,8 @@ public class BatchComponents { public static Collection all() { List components = Lists.newArrayList( // Maven - MavenProjectBootstrapper.class, DefaultMavenPluginExecutor.class, MavenProjectConverter.class, MavenProjectBuilder.class, - - // Debt - IssueChangelogDebtCalculator.class, DebtDecorator.class, NewDebtDecorator.class - ); + MavenProjectBootstrapper.class, DefaultMavenPluginExecutor.class, MavenProjectConverter.class, MavenProjectBuilder.class + ); components.addAll(CorePropertyDefinitions.all()); return components; } diff --git a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BatchExtensionDictionnary.java b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BatchExtensionDictionnary.java index 7cbf67570b1..538e3091e42 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BatchExtensionDictionnary.java +++ b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BatchExtensionDictionnary.java @@ -21,10 +21,14 @@ package org.sonar.batch.bootstrap; import com.google.common.collect.Lists; import org.apache.commons.lang.ClassUtils; -import org.sonar.api.BatchExtension; import org.sonar.api.batch.CheckProject; +import org.sonar.api.batch.Sensor; +import org.sonar.api.batch.fs.FileSystem; import org.sonar.api.platform.ComponentContainer; import org.sonar.api.resources.Project; +import org.sonar.batch.api.analyzer.Analyzer; +import org.sonar.batch.api.analyzer.AnalyzerContext; +import org.sonar.batch.scan.SensorWrapper; import java.util.Collection; import java.util.List; @@ -34,8 +38,13 @@ import java.util.List; */ public class BatchExtensionDictionnary extends org.sonar.api.batch.BatchExtensionDictionnary { - public BatchExtensionDictionnary(ComponentContainer componentContainer) { + private FileSystem fs; + private AnalyzerContext context; + + public BatchExtensionDictionnary(ComponentContainer componentContainer, FileSystem fs, AnalyzerContext context) { super(componentContainer); + this.fs = fs; + this.context = context; } public <T> Collection<T> select(Class<T> type, Project project, boolean sort, ExtensionMatcher matcher) { @@ -48,7 +57,10 @@ public class BatchExtensionDictionnary extends org.sonar.api.batch.BatchExtensio private <T> List<T> getFilteredExtensions(Class<T> type, Project project, ExtensionMatcher matcher) { List<T> result = Lists.newArrayList(); - for (BatchExtension extension : getExtensions()) { + for (Object extension : getExtensions()) { + if (type == Sensor.class && extension instanceof Analyzer) { + extension = new SensorWrapper((Analyzer) extension, context, fs); + } if (shouldKeep(type, extension, project, matcher)) { result.add((T) extension); } @@ -57,7 +69,9 @@ public class BatchExtensionDictionnary extends org.sonar.api.batch.BatchExtensio } private boolean shouldKeep(Class type, Object extension, Project project, ExtensionMatcher matcher) { - boolean keep = ClassUtils.isAssignable(extension.getClass(), type) && (matcher == null || matcher.accept(extension)); + boolean keep = (ClassUtils.isAssignable(extension.getClass(), type) + || (type == Sensor.class && ClassUtils.isAssignable(extension.getClass(), Analyzer.class))) + && (matcher == null || matcher.accept(extension)); if (keep && project != null && ClassUtils.isAssignable(extension.getClass(), CheckProject.class)) { keep = ((CheckProject) extension).shouldExecuteOnProject(project); } diff --git a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BootstrapContainer.java b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BootstrapContainer.java index 693be2183a2..5d7e836786b 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BootstrapContainer.java +++ b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BootstrapContainer.java @@ -39,6 +39,10 @@ import org.sonar.batch.components.PastSnapshotFinderByDays; import org.sonar.batch.components.PastSnapshotFinderByPreviousAnalysis; import org.sonar.batch.components.PastSnapshotFinderByPreviousVersion; import org.sonar.batch.components.PastSnapshotFinderByVersion; +import org.sonar.batch.debt.DebtModelProvider; +import org.sonar.batch.rule.RulesProvider; +import org.sonar.batch.rules.DefaultQProfileReferential; +import org.sonar.batch.rules.QProfilesReferential; import org.sonar.batch.settings.DefaultSettingsReferential; import org.sonar.batch.settings.SettingsReferential; import org.sonar.core.cluster.NullQueue; @@ -83,8 +87,8 @@ public class BootstrapContainer extends ComponentContainer { addBootstrapComponents(); if (!sensorMode) { addDatabaseComponents(); + addCoreComponents(); } - addCoreComponents(); } private void addBootstrapComponents() { @@ -118,6 +122,9 @@ public class BootstrapContainer extends ComponentContainer { if (getComponentByType(MetricFinder.class) == null) { add(CacheMetricFinder.class); } + if (getComponentByType(QProfilesReferential.class) == null) { + add(DefaultQProfileReferential.class); + } } private void addDatabaseComponents() { @@ -156,7 +163,9 @@ public class BootstrapContainer extends ComponentContainer { PastSnapshotFinderByPreviousVersion.class, PastMeasuresLoader.class, PastSnapshotFinder.class, - Durations.class); + Durations.class, + new DebtModelProvider(), + new RulesProvider()); } @Override @@ -172,8 +181,8 @@ public class BootstrapContainer extends ComponentContainer { } } - public void executeTask(Map<String, String> taskProperties) { - new TaskContainer(this, taskProperties).execute(); + public void executeTask(Map<String, String> taskProperties, Object... components) { + new TaskContainer(this, taskProperties, components).execute(); } } diff --git a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/ExtensionInstaller.java b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/ExtensionInstaller.java index bb2b2e431f2..b7088cf4c01 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/ExtensionInstaller.java +++ b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/ExtensionInstaller.java @@ -43,11 +43,10 @@ public class ExtensionInstaller { } public ExtensionInstaller install(ComponentContainer container, ExtensionMatcher matcher) { - boolean preview = analysisMode.isPreview(); // core components for (Object o : BatchComponents.all()) { - doInstall(container, matcher, null, preview, o); + doInstall(container, matcher, null, o); } // plugin extensions @@ -55,7 +54,7 @@ public class ExtensionInstaller { PluginMetadata metadata = entry.getKey(); Plugin plugin = entry.getValue(); for (Object extension : plugin.getExtensions()) { - doInstall(container, matcher, metadata, preview, extension); + doInstall(container, matcher, metadata, extension); } } List<ExtensionProvider> providers = container.getComponentsByType(ExtensionProvider.class); @@ -63,18 +62,18 @@ public class ExtensionInstaller { Object object = provider.provide(); if (object instanceof Iterable) { for (Object extension : (Iterable) object) { - doInstall(container, matcher, null, preview, extension); + doInstall(container, matcher, null, extension); } } else { - doInstall(container, matcher, null, preview, object); + doInstall(container, matcher, null, object); } } return this; } - private void doInstall(ComponentContainer container, ExtensionMatcher matcher, @Nullable PluginMetadata metadata, boolean dryRun, Object extension) { + private void doInstall(ComponentContainer container, ExtensionMatcher matcher, @Nullable PluginMetadata metadata, Object extension) { if (ExtensionUtils.supportsEnvironment(extension, env) - && (!dryRun || ExtensionUtils.supportsPreview(extension)) + && (!analysisMode.isPreview() || ExtensionUtils.supportsPreview(extension)) && matcher.accept(extension)) { container.addExtension(metadata, extension); } else { diff --git a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/TaskContainer.java b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/TaskContainer.java index 86122e7dec4..e7fd8427a2d 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/TaskContainer.java +++ b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/TaskContainer.java @@ -41,10 +41,12 @@ import java.util.Map; public class TaskContainer extends ComponentContainer { private final Map<String, String> taskProperties; + private final Object[] components; - public TaskContainer(ComponentContainer parent, Map<String, String> taskProperties) { + public TaskContainer(ComponentContainer parent, Map<String, String> taskProperties, Object... components) { super(parent); this.taskProperties = taskProperties; + this.components = components; } @Override @@ -52,6 +54,9 @@ public class TaskContainer extends ComponentContainer { installCoreTasks(); installTaskExtensions(); installComponentsUsingTaskExtensions(); + for (Object component : components) { + add(component); + } } void installCoreTasks() { diff --git a/sonar-batch/src/main/java/org/sonar/batch/bootstrapper/Batch.java b/sonar-batch/src/main/java/org/sonar/batch/bootstrapper/Batch.java index 972450aebde..ac107141bc3 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/bootstrapper/Batch.java +++ b/sonar-batch/src/main/java/org/sonar/batch/bootstrapper/Batch.java @@ -87,12 +87,12 @@ public final class Batch { /** * @since 4.4 */ - public Batch executeTask(Map<String, String> taskProperties) { + public Batch executeTask(Map<String, String> taskProperties, Object... components) { if (!started) { throw new IllegalStateException("Batch is not started. Unable to execute task."); } - bootstrapContainer.executeTask(taskProperties); + bootstrapContainer.executeTask(taskProperties, components); return this; } diff --git a/sonar-batch/src/main/java/org/sonar/batch/index/DefaultIndex.java b/sonar-batch/src/main/java/org/sonar/batch/index/DefaultIndex.java index 44db4e53f73..ae75f47f2a4 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/index/DefaultIndex.java +++ b/sonar-batch/src/main/java/org/sonar/batch/index/DefaultIndex.java @@ -178,7 +178,7 @@ public class DefaultIndex extends SonarIndex { } @Override - public Measure getMeasure(Resource resource, Metric metric) { + public Measure getMeasure(Resource resource, org.sonar.batch.api.measures.Metric<?> metric) { return getMeasures(resource, MeasuresFilters.metric(metric)); } diff --git a/sonar-batch/src/main/java/org/sonar/batch/index/ResourceKeyMigration.java b/sonar-batch/src/main/java/org/sonar/batch/index/ResourceKeyMigration.java index 99eeb05cac9..4e169391d11 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/index/ResourceKeyMigration.java +++ b/sonar-batch/src/main/java/org/sonar/batch/index/ResourceKeyMigration.java @@ -26,7 +26,7 @@ import org.slf4j.LoggerFactory; import org.sonar.api.BatchComponent; import org.sonar.api.batch.fs.FileSystem; import org.sonar.api.batch.fs.InputFile; -import org.sonar.api.batch.fs.internal.DefaultInputFile; +import org.sonar.api.batch.fs.internal.DeprecatedDefaultInputFile; import org.sonar.api.database.DatabaseSession; import org.sonar.api.database.model.ResourceModel; import org.sonar.api.resources.Directory; @@ -80,7 +80,7 @@ public class ResourceKeyMigration implements BatchComponent { Map<String, InputFile> deprecatedTestKeyMapper = new HashMap<String, InputFile>(); Map<String, String> deprecatedDirectoryKeyMapper = new HashMap<String, String>(); for (InputFile inputFile : inputFiles) { - String deprecatedKey = ((DefaultInputFile) inputFile).deprecatedKey(); + String deprecatedKey = ((DeprecatedDefaultInputFile) inputFile).deprecatedKey(); if (deprecatedKey != null) { if (InputFile.Type.TEST == inputFile.type() && !deprecatedTestKeyMapper.containsKey(deprecatedKey)) { deprecatedTestKeyMapper.put(deprecatedKey, inputFile); @@ -109,7 +109,7 @@ public class ResourceKeyMigration implements BatchComponent { boolean isTest = Qualifiers.UNIT_TEST_FILE.equals(resourceModel.getQualifier()); InputFile matchedFile = findInputFile(deprecatedFileKeyMapper, deprecatedTestKeyMapper, oldEffectiveKey, isTest); if (matchedFile != null) { - String newEffectiveKey = ((DefaultInputFile) matchedFile).key(); + String newEffectiveKey = ((DeprecatedDefaultInputFile) matchedFile).key(); // Now compute migration of the parent dir String oldKey = StringUtils.substringAfterLast(oldEffectiveKey, ":"); Resource sonarFile; diff --git a/sonar-batch/src/main/java/org/sonar/batch/issue/IssueFilters.java b/sonar-batch/src/main/java/org/sonar/batch/issue/IssueFilters.java index e896729663a..79b576d3398 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/issue/IssueFilters.java +++ b/sonar-batch/src/main/java/org/sonar/batch/issue/IssueFilters.java @@ -53,15 +53,34 @@ public class IssueFilters implements BatchExtension { this(deprecatedFilters, deprecatedViolations, new org.sonar.api.issue.IssueFilter[0]); } + /** + * Used by scan2 + */ + public IssueFilters(org.sonar.api.issue.IssueFilter[] exclusionFilters, IssueFilter[] filters) { + this(null, null, exclusionFilters, filters); + } + + public IssueFilters(org.sonar.api.issue.IssueFilter[] exclusionFilters) { + this(null, null, exclusionFilters, new IssueFilter[0]); + } + + public IssueFilters(IssueFilter[] filters) { + this(null, null, new org.sonar.api.issue.IssueFilter[0], filters); + } + + public IssueFilters() { + this(null, null, new org.sonar.api.issue.IssueFilter[0], new IssueFilter[0]); + } + public boolean accept(DefaultIssue issue, @Nullable Violation violation) { - if(new DefaultIssueFilterChain(filters).accept(issue)) { + if (new DefaultIssueFilterChain(filters).accept(issue)) { // Apply deprecated rules only if filter chain accepts the current issue for (org.sonar.api.issue.IssueFilter filter : exclusionFilters) { if (!filter.accept(issue)) { return false; } } - if (!deprecatedFilters.isEmpty()) { + if (deprecatedFilters != null && !deprecatedFilters.isEmpty()) { Violation v = violation != null ? violation : deprecatedViolations.toViolation(issue); return !deprecatedFilters.isIgnored(v); } diff --git a/sonar-batch/src/main/java/org/sonar/batch/issue/ModuleIssues.java b/sonar-batch/src/main/java/org/sonar/batch/issue/ModuleIssues.java index 6f46e2cc7a9..1e880a6b31d 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/issue/ModuleIssues.java +++ b/sonar-batch/src/main/java/org/sonar/batch/issue/ModuleIssues.java @@ -47,7 +47,7 @@ public class ModuleIssues { private final Project project; private final IssueFilters filters; - public ModuleIssues(ActiveRules activeRules, Rules rules, IssueCache cache, Project project, IssueFilters filters) { + public ModuleIssues(ActiveRules activeRules, Rules rules, IssueCache cache, @Nullable Project project, IssueFilters filters) { this.activeRules = activeRules; this.rules = rules; this.cache = cache; @@ -55,6 +55,13 @@ public class ModuleIssues { this.filters = filters; } + /** + * Used by scan2 + */ + public ModuleIssues(ActiveRules activeRules, Rules rules, IssueCache cache, IssueFilters filters) { + this(activeRules, rules, cache, null, filters); + } + public boolean initAndAddIssue(DefaultIssue issue) { return initAndAddIssue(issue, null); } @@ -67,6 +74,7 @@ public class ModuleIssues { private DefaultIssue newIssue(Violation violation) { return (DefaultIssue) new DefaultIssueBuilder() .componentKey(violation.getResource().getEffectiveKey()) + // Project can be null but Violation not used by scan2 .projectKey(project.getRoot().getEffectiveKey()) .ruleKey(RuleKey.of(violation.getRule().getRepositoryKey(), violation.getRule().getKey())) .effortToFix(violation.getCost()) @@ -107,8 +115,10 @@ public class ModuleIssues { if (Strings.isNullOrEmpty(issue.message())) { issue.setMessage(rule.name()); } - issue.setCreationDate(project.getAnalysisDate()); - issue.setUpdateDate(project.getAnalysisDate()); + if (project != null) { + issue.setCreationDate(project.getAnalysisDate()); + issue.setUpdateDate(project.getAnalysisDate()); + } if (issue.severity() == null) { issue.setSeverity(activeRule.severity()); } diff --git a/sonar-batch/src/main/java/org/sonar/batch/issue/ignore/scanner/IssueExclusionsLoader.java b/sonar-batch/src/main/java/org/sonar/batch/issue/ignore/scanner/IssueExclusionsLoader.java index 1dad68550bb..5f3e9c308e8 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/issue/ignore/scanner/IssueExclusionsLoader.java +++ b/sonar-batch/src/main/java/org/sonar/batch/issue/ignore/scanner/IssueExclusionsLoader.java @@ -22,7 +22,7 @@ package org.sonar.batch.issue.ignore.scanner; import org.sonar.api.batch.fs.FileSystem; import org.sonar.api.batch.fs.InputFile; -import org.sonar.api.batch.fs.internal.DefaultInputFile; +import org.sonar.api.batch.fs.internal.DeprecatedDefaultInputFile; import org.sonar.api.resources.Project; import org.sonar.api.utils.SonarException; import org.sonar.batch.issue.ignore.pattern.IssueExclusionPatternInitializer; @@ -59,7 +59,7 @@ public final class IssueExclusionsLoader { for (InputFile inputFile : fileSystem.inputFiles(fileSystem.predicates().all())) { try { - String componentEffectiveKey = ((DefaultInputFile) inputFile).key(); + String componentEffectiveKey = ((DeprecatedDefaultInputFile) inputFile).key(); if (componentEffectiveKey != null) { String path = inputFile.relativePath(); inclusionPatternInitializer.initializePatternsForPath(path, componentEffectiveKey); diff --git a/sonar-batch/src/main/java/org/sonar/batch/language/LanguageDistributionDecorator.java b/sonar-batch/src/main/java/org/sonar/batch/language/LanguageDistributionDecorator.java index ca77b7c239c..fcada30d053 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/language/LanguageDistributionDecorator.java +++ b/sonar-batch/src/main/java/org/sonar/batch/language/LanguageDistributionDecorator.java @@ -44,14 +44,14 @@ public class LanguageDistributionDecorator implements Decorator { @DependsUpon public List<Metric> dependsUponMetrics() { - return ImmutableList.of(CoreMetrics.LINES); + return ImmutableList.<Metric>of(CoreMetrics.LINES); } @DependedUpon public List<Metric> generatesMetrics() { return ImmutableList.of( CoreMetrics.NCLOC_LANGUAGE_DISTRIBUTION - ); + ); } public void decorate(Resource resource, DecoratorContext context) { diff --git a/sonar-batch/src/main/java/org/sonar/batch/languages/DeprecatedLanguagesReferential.java b/sonar-batch/src/main/java/org/sonar/batch/languages/DeprecatedLanguagesReferential.java new file mode 100644 index 00000000000..1084b7d49a2 --- /dev/null +++ b/sonar-batch/src/main/java/org/sonar/batch/languages/DeprecatedLanguagesReferential.java @@ -0,0 +1,63 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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.batch.languages; + +import org.sonar.api.resources.Languages; +import org.sonar.batch.api.languages.Language; + +import javax.annotation.CheckForNull; + +import java.util.ArrayList; +import java.util.Collection; + +/** + * Languages referential using {@link Languages} + * @since 4.4 + */ +public class DeprecatedLanguagesReferential implements LanguagesReferential { + + private Languages languages; + + public DeprecatedLanguagesReferential(Languages languages) { + this.languages = languages; + } + + /** + * Get language. + */ + @CheckForNull + public Language get(String languageKey) { + org.sonar.api.resources.Language language = languages.get(languageKey); + return language != null ? new Language(language.getKey(), language.getName(), language.getFileSuffixes()) : null; + } + + /** + * Get list of all supported languages. + */ + public Collection<Language> all() { + org.sonar.api.resources.Language[] all = languages.all(); + Collection<Language> result = new ArrayList<Language>(all.length); + for (org.sonar.api.resources.Language language : all) { + result.add(new Language(language.getKey(), language.getName(), language.getFileSuffixes())); + } + return result; + } + +} diff --git a/sonar-batch/src/main/java/org/sonar/batch/languages/LanguagesReferential.java b/sonar-batch/src/main/java/org/sonar/batch/languages/LanguagesReferential.java new file mode 100644 index 00000000000..bf9fcd00de5 --- /dev/null +++ b/sonar-batch/src/main/java/org/sonar/batch/languages/LanguagesReferential.java @@ -0,0 +1,46 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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.batch.languages; + +import org.sonar.api.BatchComponent; +import org.sonar.batch.api.languages.Language; + +import javax.annotation.CheckForNull; + +import java.util.Collection; + +/** + * Languages referential + * @since 4.4 + */ +public interface LanguagesReferential extends BatchComponent { + + /** + * Get language. + */ + @CheckForNull + Language get(String languageKey); + + /** + * Get list of all supported languages. + */ + Collection<Language> all(); + +} diff --git a/sonar-batch/src/main/java/org/sonar/batch/languages/package-info.java b/sonar-batch/src/main/java/org/sonar/batch/languages/package-info.java new file mode 100644 index 00000000000..5ce5bc10019 --- /dev/null +++ b/sonar-batch/src/main/java/org/sonar/batch/languages/package-info.java @@ -0,0 +1,20 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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.batch.languages;
\ No newline at end of file diff --git a/sonar-batch/src/main/java/org/sonar/batch/phases/SensorMatcher.java b/sonar-batch/src/main/java/org/sonar/batch/phases/SensorMatcher.java index 2ee73f61dfb..6328ac77a46 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/phases/SensorMatcher.java +++ b/sonar-batch/src/main/java/org/sonar/batch/phases/SensorMatcher.java @@ -19,12 +19,12 @@ */ package org.sonar.batch.phases; -import org.sonar.batch.bootstrap.ExtensionMatcher; - import org.apache.commons.lang.ClassUtils; import org.sonar.api.BatchExtension; import org.sonar.api.batch.InstantiationStrategy; import org.sonar.api.batch.Sensor; +import org.sonar.batch.api.analyzer.Analyzer; +import org.sonar.batch.bootstrap.ExtensionMatcher; /** * Allow to filter sensors that will be executed. @@ -36,7 +36,8 @@ public abstract class SensorMatcher implements BatchExtension, ExtensionMatcher @Override public final boolean accept(Object extension) { - return ClassUtils.isAssignable(extension.getClass(), Sensor.class) && acceptSensor((Sensor) extension); + return ClassUtils.isAssignable(extension.getClass(), Sensor.class) + && acceptSensor((Sensor) extension) || ClassUtils.isAssignable(extension.getClass(), Analyzer.class); } public abstract boolean acceptSensor(Sensor sensor); diff --git a/sonar-batch/src/main/java/org/sonar/batch/rule/ActiveRulesProvider.java b/sonar-batch/src/main/java/org/sonar/batch/rule/ActiveRulesProvider.java index 95762afd79d..a7aea325d48 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/rule/ActiveRulesProvider.java +++ b/sonar-batch/src/main/java/org/sonar/batch/rule/ActiveRulesProvider.java @@ -28,6 +28,8 @@ import org.sonar.api.batch.rule.internal.NewActiveRule; import org.sonar.api.rules.Rule; import org.sonar.api.rules.RuleFinder; import org.sonar.api.rules.RuleParam; +import org.sonar.batch.api.rules.QProfile; +import org.sonar.batch.rules.QProfileWithId; import org.sonar.core.qualityprofile.db.ActiveRuleDao; import org.sonar.core.qualityprofile.db.ActiveRuleDto; import org.sonar.core.qualityprofile.db.ActiveRuleParamDto; @@ -49,13 +51,14 @@ public class ActiveRulesProvider extends ProviderAdapter { private ActiveRules load(ModuleQProfiles qProfiles, ActiveRuleDao dao, RuleFinder ruleFinder) { ActiveRulesBuilder builder = new ActiveRulesBuilder(); - for (ModuleQProfiles.QProfile qProfile : qProfiles.findAll()) { + for (QProfile qProfile : qProfiles.findAll()) { + QProfileWithId qProfileWithId = (QProfileWithId) qProfile; ListMultimap<Integer, ActiveRuleParamDto> paramDtosByActiveRuleId = ArrayListMultimap.create(); - for (ActiveRuleParamDto dto : dao.selectParamsByProfileId(qProfile.id())) { + for (ActiveRuleParamDto dto : dao.selectParamsByProfileId(qProfileWithId.id())) { paramDtosByActiveRuleId.put(dto.getActiveRuleId(), dto); } - for (ActiveRuleDto activeDto : dao.selectByProfileId(qProfile.id())) { + for (ActiveRuleDto activeDto : dao.selectByProfileId(qProfileWithId.id())) { Rule rule = ruleFinder.findById(activeDto.getRulId()); if (rule != null) { NewActiveRule newActiveRule = builder.activate(rule.ruleKey()); diff --git a/sonar-batch/src/main/java/org/sonar/batch/rule/ModuleQProfiles.java b/sonar-batch/src/main/java/org/sonar/batch/rule/ModuleQProfiles.java index fb5027d923b..674fbb59a56 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/rule/ModuleQProfiles.java +++ b/sonar-batch/src/main/java/org/sonar/batch/rule/ModuleQProfiles.java @@ -23,11 +23,11 @@ import com.google.common.collect.ImmutableMap; import org.apache.commons.lang.StringUtils; import org.sonar.api.BatchComponent; import org.sonar.api.config.Settings; -import org.sonar.api.resources.Language; -import org.sonar.api.resources.Languages; import org.sonar.api.utils.MessageException; -import org.sonar.core.qualityprofile.db.QualityProfileDao; -import org.sonar.core.qualityprofile.db.QualityProfileDto; +import org.sonar.batch.api.languages.Language; +import org.sonar.batch.api.rules.QProfile; +import org.sonar.batch.languages.LanguagesReferential; +import org.sonar.batch.rules.QProfilesReferential; import javax.annotation.CheckForNull; @@ -41,55 +41,19 @@ public class ModuleQProfiles implements BatchComponent { public static final String SONAR_PROFILE_PROP = "sonar.profile"; - public static class QProfile { - private final String name, language; - private final Integer version; - private final int id; - - public QProfile(QualityProfileDto dto) { - this.id = dto.getId(); - this.name = dto.getName(); - this.language = dto.getLanguage(); - this.version = dto.getVersion(); - } - - QProfile(int id, String name, String language, Integer version) { - this.id = id; - this.name = name; - this.language = language; - this.version = version; - } - - public int id() { - return id; - } - - public String name() { - return name; - } - - public String language() { - return language; - } - - public Integer version() { - return version; - } - } - private final Map<String, QProfile> byLanguage; - public ModuleQProfiles(Settings settings, Languages languages, QualityProfileDao dao) { + public ModuleQProfiles(Settings settings, LanguagesReferential languages, QProfilesReferential qProfileRef) { ImmutableMap.Builder<String, QProfile> builder = ImmutableMap.builder(); String defaultName = settings.getString(SONAR_PROFILE_PROP); for (Language language : languages.all()) { QProfile profile = null; if (StringUtils.isNotBlank(defaultName)) { - profile = loadDefaultQProfile(dao, defaultName, language.getKey()); + profile = loadDefaultQProfile(qProfileRef, defaultName, language.key()); } if (profile == null) { - profile = loadQProfile(dao, settings, language.getKey()); + profile = loadQProfile(qProfileRef, settings, language.key()); } if (profile != null) { builder.put(profile.language(), profile); @@ -99,25 +63,21 @@ public class ModuleQProfiles implements BatchComponent { } @CheckForNull - private QProfile loadQProfile(QualityProfileDao dao, Settings settings, String language) { + private QProfile loadQProfile(QProfilesReferential qProfileRef, Settings settings, String language) { String profileName = settings.getString("sonar.profile." + language); if (profileName != null) { - QualityProfileDto dto = dao.selectByNameAndLanguage(profileName, language); + QProfile dto = qProfileRef.get(language, profileName); if (dto == null) { throw MessageException.of(String.format("Quality profile not found : '%s' on language '%s'", profileName, language)); } - return new QProfile(dto); + return dto; } return null; } @CheckForNull - private QProfile loadDefaultQProfile(QualityProfileDao dao, String profileName, String language) { - QualityProfileDto dto = dao.selectByNameAndLanguage(profileName, language); - if (dto != null) { - return new QProfile(dto); - } - return null; + private QProfile loadDefaultQProfile(QProfilesReferential qProfileRef, String profileName, String language) { + return qProfileRef.get(language, profileName); } public Collection<QProfile> findAll() { diff --git a/sonar-batch/src/main/java/org/sonar/batch/rule/QProfileEventsDecorator.java b/sonar-batch/src/main/java/org/sonar/batch/rule/QProfileEventsDecorator.java index ee67fcb31cd..e84dc342c17 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/rule/QProfileEventsDecorator.java +++ b/sonar-batch/src/main/java/org/sonar/batch/rule/QProfileEventsDecorator.java @@ -34,8 +34,7 @@ import org.sonar.api.resources.Languages; import org.sonar.api.resources.Project; import org.sonar.api.resources.Qualifiers; import org.sonar.api.resources.Resource; -import org.sonar.api.resources.ResourceUtils; -import org.sonar.batch.rule.ModuleQProfiles.QProfile; +import org.sonar.batch.rules.QProfileWithId; import org.sonar.core.qualityprofile.db.QualityProfileDao; import org.sonar.core.qualityprofile.db.QualityProfileDto; @@ -101,14 +100,14 @@ public class QProfileEventsDecorator implements Decorator { } else { pastProfileVersion = pastProfileVersionMeasure.getIntValue(); } - pastProfiles = UsedQProfiles.fromProfiles(new ModuleQProfiles.QProfile(pastProfileId, pastProfileName, pastProfileLanguage, pastProfileVersion)); + pastProfiles = UsedQProfiles.fromProfiles(new QProfileWithId(pastProfileId, pastProfileName, pastProfileLanguage, pastProfileVersion)); } // Now create appropriate events - Map<Integer, QProfile> pastProfilesById = Maps.newHashMap(pastProfiles.profilesById()); - for (QProfile profile : currentProfiles.profilesById().values()) { + Map<Integer, QProfileWithId> pastProfilesById = Maps.newHashMap(pastProfiles.profilesById()); + for (QProfileWithId profile : currentProfiles.profilesById().values()) { if (pastProfilesById.containsKey(profile.id())) { - QProfile pastProfile = pastProfilesById.get(profile.id()); + QProfileWithId pastProfile = pastProfilesById.get(profile.id()); if (pastProfile.version() < profile.version()) { // New version of the same QP usedProfile(context, profile); @@ -118,25 +117,25 @@ public class QProfileEventsDecorator implements Decorator { usedProfile(context, profile); } } - for (QProfile profile : pastProfilesById.values()) { + for (QProfileWithId profile : pastProfilesById.values()) { // Following profiles are no more used stopUsedProfile(context, profile); } } - private void stopUsedProfile(DecoratorContext context, QProfile profile) { + private void stopUsedProfile(DecoratorContext context, QProfileWithId profile) { Language language = languages.get(profile.language()); String languageName = language != null ? language.getName() : profile.language(); context.createEvent("Stop using " + format(profile) + " (" + languageName + ")", format(profile) + " no more used for " + languageName, Event.CATEGORY_PROFILE, null); } - private void usedProfile(DecoratorContext context, QProfile profile) { + private void usedProfile(DecoratorContext context, QProfileWithId profile) { Language language = languages.get(profile.language()); String languageName = language != null ? language.getName() : profile.language(); context.createEvent("Use " + format(profile) + " (" + languageName + ")", format(profile) + " used for " + languageName, Event.CATEGORY_PROFILE, null); } - private String format(QProfile profile) { + private String format(QProfileWithId profile) { return profile.name() + " version " + profile.version(); } diff --git a/sonar-batch/src/main/java/org/sonar/batch/rule/QProfileSensor.java b/sonar-batch/src/main/java/org/sonar/batch/rule/QProfileSensor.java index 0773a3c6472..620f769d8b7 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/rule/QProfileSensor.java +++ b/sonar-batch/src/main/java/org/sonar/batch/rule/QProfileSensor.java @@ -26,6 +26,7 @@ import org.sonar.api.batch.fs.FileSystem; import org.sonar.api.measures.CoreMetrics; import org.sonar.api.measures.Measure; import org.sonar.api.resources.Project; +import org.sonar.batch.rules.QProfileWithId; import org.sonar.core.qualityprofile.db.QualityProfileDao; import java.util.List; @@ -51,9 +52,9 @@ public class QProfileSensor implements Sensor { } public void analyse(Project project, SensorContext context) { - List<ModuleQProfiles.QProfile> profiles = Lists.newArrayList(); + List<QProfileWithId> profiles = Lists.newArrayList(); for (String language : fs.languages()) { - ModuleQProfiles.QProfile qProfile = moduleQProfiles.findByLanguage(language); + QProfileWithId qProfile = (QProfileWithId) moduleQProfiles.findByLanguage(language); if (qProfile != null) { dao.updateUsedColumn(qProfile.id(), true); profiles.add(qProfile); @@ -65,7 +66,7 @@ public class QProfileSensor implements Sensor { // For backward compatibility if (profiles.size() == 1) { - ModuleQProfiles.QProfile qProfile = profiles.get(0); + QProfileWithId qProfile = profiles.get(0); Measure measure = new Measure(CoreMetrics.PROFILE, qProfile.name()).setValue((double) qProfile.id()); Measure measureVersion = new Measure(CoreMetrics.PROFILE_VERSION, qProfile.version().doubleValue()); context.saveMeasure(measure); diff --git a/sonar-batch/src/main/java/org/sonar/batch/rule/QProfileVerifier.java b/sonar-batch/src/main/java/org/sonar/batch/rule/QProfileVerifier.java index ac8e51eb10e..10e110b6ee9 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/rule/QProfileVerifier.java +++ b/sonar-batch/src/main/java/org/sonar/batch/rule/QProfileVerifier.java @@ -27,7 +27,7 @@ import org.sonar.api.BatchComponent; import org.sonar.api.batch.fs.FileSystem; import org.sonar.api.config.Settings; import org.sonar.api.utils.MessageException; -import org.sonar.batch.rule.ModuleQProfiles.QProfile; +import org.sonar.batch.api.rules.QProfile; public class QProfileVerifier implements BatchComponent { diff --git a/sonar-batch/src/main/java/org/sonar/batch/rule/RulesProfileProvider.java b/sonar-batch/src/main/java/org/sonar/batch/rule/RulesProfileProvider.java index 2b778be21dc..2c5ec75a235 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/rule/RulesProfileProvider.java +++ b/sonar-batch/src/main/java/org/sonar/batch/rule/RulesProfileProvider.java @@ -30,6 +30,7 @@ import org.sonar.api.rules.ActiveRule; import org.sonar.api.rules.Rule; import org.sonar.api.rules.RuleFinder; import org.sonar.api.rules.RulePriority; +import org.sonar.batch.api.rules.QProfile; import java.util.Collection; import java.util.Map; @@ -55,8 +56,8 @@ public class RulesProfileProvider extends ProviderAdapter { } private RulesProfile loadSingleLanguageProfile(ModuleQProfiles qProfiles, ActiveRules activeRules, - RuleFinder ruleFinder, String language) { - ModuleQProfiles.QProfile qProfile = qProfiles.findByLanguage(language); + RuleFinder ruleFinder, String language) { + QProfile qProfile = qProfiles.findByLanguage(language); if (qProfile != null) { return new RulesProfileWrapper(select(qProfile, activeRules, ruleFinder)); } @@ -65,13 +66,13 @@ public class RulesProfileProvider extends ProviderAdapter { private RulesProfile loadProfiles(ModuleQProfiles qProfiles, ActiveRules activeRules, RuleFinder ruleFinder) { Collection<RulesProfile> dtos = Lists.newArrayList(); - for (ModuleQProfiles.QProfile qProfile : qProfiles.findAll()) { + for (QProfile qProfile : qProfiles.findAll()) { dtos.add(select(qProfile, activeRules, ruleFinder)); } return new RulesProfileWrapper(dtos); } - private RulesProfile select(ModuleQProfiles.QProfile qProfile, ActiveRules activeRules, RuleFinder ruleFinder) { + private RulesProfile select(QProfile qProfile, ActiveRules activeRules, RuleFinder ruleFinder) { RulesProfile deprecatedProfile = new RulesProfile(); deprecatedProfile.setVersion(qProfile.version()); deprecatedProfile.setName(qProfile.name()); diff --git a/sonar-batch/src/main/java/org/sonar/batch/rule/UsedQProfiles.java b/sonar-batch/src/main/java/org/sonar/batch/rule/UsedQProfiles.java index 1b1115ed18b..5973a74c593 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/rule/UsedQProfiles.java +++ b/sonar-batch/src/main/java/org/sonar/batch/rule/UsedQProfiles.java @@ -26,7 +26,7 @@ import com.google.gson.JsonElement; import com.google.gson.JsonObject; import com.google.gson.JsonParser; import org.sonar.api.utils.text.JsonWriter; -import org.sonar.batch.rule.ModuleQProfiles.QProfile; +import org.sonar.batch.rules.QProfileWithId; import javax.annotation.concurrent.Immutable; @@ -37,14 +37,14 @@ import java.util.Map; @Immutable public class UsedQProfiles { - private Map<Integer, ModuleQProfiles.QProfile> profilesById = Maps.newLinkedHashMap(); + private Map<Integer, QProfileWithId> profilesById = Maps.newLinkedHashMap(); private UsedQProfiles() { } - public static final UsedQProfiles fromProfiles(Iterable<QProfile> profiles) { + public static final UsedQProfiles fromProfiles(Iterable<QProfileWithId> profiles) { UsedQProfiles result = new UsedQProfiles(); - for (QProfile qProfile : profiles) { + for (QProfileWithId qProfile : profiles) { result.add(qProfile); } return result; @@ -54,7 +54,7 @@ public class UsedQProfiles { return new UsedQProfiles(); } - public static final UsedQProfiles fromProfiles(QProfile... profiles) { + public static final UsedQProfiles fromProfiles(QProfileWithId... profiles) { return fromProfiles(Arrays.asList(profiles)); } @@ -63,7 +63,7 @@ public class UsedQProfiles { JsonArray root = new JsonParser().parse(json).getAsJsonArray(); for (JsonElement elt : root) { JsonObject profile = elt.getAsJsonObject(); - result.add(new QProfile(profile.get("id").getAsInt(), profile.get("name").getAsString(), profile.get("language").getAsString(), profile.get("version").getAsInt())); + result.add(new QProfileWithId(profile.get("id").getAsInt(), profile.get("name").getAsString(), profile.get("language").getAsString(), profile.get("version").getAsInt())); } return result; } @@ -72,7 +72,7 @@ public class UsedQProfiles { StringWriter json = new StringWriter(); JsonWriter writer = JsonWriter.of(json); writer.beginArray(); - for (ModuleQProfiles.QProfile qProfile : profilesById.values()) { + for (QProfileWithId qProfile : profilesById.values()) { writer.beginObject() .prop("id", qProfile.id()) .prop("name", qProfile.name()) @@ -89,8 +89,8 @@ public class UsedQProfiles { return empty().mergeInPlace(this).mergeInPlace(other); } - private void add(ModuleQProfiles.QProfile profile) { - QProfile alreadyAdded = profilesById.get(profile.id()); + private void add(QProfileWithId profile) { + QProfileWithId alreadyAdded = profilesById.get(profile.id()); if (alreadyAdded == null // Keep only latest version || profile.version() > alreadyAdded.version()) { @@ -98,8 +98,8 @@ public class UsedQProfiles { } } - private UsedQProfiles addAll(Iterable<QProfile> profiles) { - for (QProfile profile : profiles) { + private UsedQProfiles addAll(Iterable<QProfileWithId> profiles) { + for (QProfileWithId profile : profiles) { this.add(profile); } return this; @@ -110,7 +110,7 @@ public class UsedQProfiles { return this; } - public Map<Integer, ModuleQProfiles.QProfile> profilesById() { + public Map<Integer, QProfileWithId> profilesById() { return ImmutableMap.copyOf(profilesById); } diff --git a/sonar-batch/src/main/java/org/sonar/batch/rules/DefaultQProfileReferential.java b/sonar-batch/src/main/java/org/sonar/batch/rules/DefaultQProfileReferential.java new file mode 100644 index 00000000000..936b17e63fe --- /dev/null +++ b/sonar-batch/src/main/java/org/sonar/batch/rules/DefaultQProfileReferential.java @@ -0,0 +1,46 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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.batch.rules; + +import org.sonar.batch.api.rules.QProfile; +import org.sonar.core.qualityprofile.db.QualityProfileDao; +import org.sonar.core.qualityprofile.db.QualityProfileDto; + +/** + * @since 4.4 + */ +public class DefaultQProfileReferential implements QProfilesReferential { + + private QualityProfileDao qualityProfileDao; + + public DefaultQProfileReferential(QualityProfileDao qualityProfileDao) { + this.qualityProfileDao = qualityProfileDao; + } + + @Override + public QProfile get(String language, String name) { + QualityProfileDto dto = qualityProfileDao.selectByNameAndLanguage(name, language); + if (dto == null) { + return null; + } + return new QProfileWithId(dto.getId(), dto.getName(), dto.getLanguage(), dto.getVersion()); + } + +} diff --git a/sonar-batch/src/main/java/org/sonar/batch/rules/QProfileWithId.java b/sonar-batch/src/main/java/org/sonar/batch/rules/QProfileWithId.java new file mode 100644 index 00000000000..4d2511676a9 --- /dev/null +++ b/sonar-batch/src/main/java/org/sonar/batch/rules/QProfileWithId.java @@ -0,0 +1,36 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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.batch.rules; + +import org.sonar.batch.api.rules.QProfile; + +public class QProfileWithId extends QProfile { + private final int id; + + public QProfileWithId(int id, String name, String language, Integer version) { + super(name, language, version); + this.id = id; + } + + public int id() { + return id; + } + +} diff --git a/sonar-batch/src/main/java/org/sonar/batch/rules/QProfilesReferential.java b/sonar-batch/src/main/java/org/sonar/batch/rules/QProfilesReferential.java new file mode 100644 index 00000000000..aec78dc14c8 --- /dev/null +++ b/sonar-batch/src/main/java/org/sonar/batch/rules/QProfilesReferential.java @@ -0,0 +1,39 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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.batch.rules; + +import org.sonar.api.BatchComponent; +import org.sonar.batch.api.rules.QProfile; + +import javax.annotation.CheckForNull; + +/** + * Quality profiles referential + * @since 4.4 + */ +public interface QProfilesReferential extends BatchComponent { + + /** + * Get quality profile + */ + @CheckForNull + QProfile get(String language, String name); + +} diff --git a/sonar-batch/src/main/java/org/sonar/batch/rules/package-info.java b/sonar-batch/src/main/java/org/sonar/batch/rules/package-info.java new file mode 100644 index 00000000000..819e886c070 --- /dev/null +++ b/sonar-batch/src/main/java/org/sonar/batch/rules/package-info.java @@ -0,0 +1,21 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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. + */ +@javax.annotation.ParametersAreNonnullByDefault +package org.sonar.batch.rules;
\ No newline at end of file diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan/AnalyzerContextAdaptor.java b/sonar-batch/src/main/java/org/sonar/batch/scan/AnalyzerContextAdaptor.java new file mode 100644 index 00000000000..a3f125d9c4f --- /dev/null +++ b/sonar-batch/src/main/java/org/sonar/batch/scan/AnalyzerContextAdaptor.java @@ -0,0 +1,169 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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.batch.scan; + +import org.sonar.api.batch.SensorContext; +import org.sonar.api.batch.fs.InputFile; +import org.sonar.api.component.ResourcePerspectives; +import org.sonar.api.issue.Issuable; +import org.sonar.api.measures.Measure; +import org.sonar.api.measures.MetricFinder; +import org.sonar.api.resources.File; +import org.sonar.api.resources.Project; +import org.sonar.api.resources.Resource; +import org.sonar.api.rule.RuleKey; +import org.sonar.batch.api.analyzer.AnalyzerContext; +import org.sonar.batch.api.analyzer.issue.AnalyzerIssue; +import org.sonar.batch.api.analyzer.measure.AnalyzerMeasure; +import org.sonar.batch.api.measures.Metric; + +import java.io.Serializable; +import java.util.Collection; + +public class AnalyzerContextAdaptor implements AnalyzerContext { + + private SensorContext sensorContext; + private MetricFinder metricFinder; + private Project project; + private ResourcePerspectives perspectives; + + public AnalyzerContextAdaptor(SensorContext sensorContext, MetricFinder metricFinder, Project project, ResourcePerspectives perspectives) { + this.sensorContext = sensorContext; + this.metricFinder = metricFinder; + this.project = project; + this.perspectives = perspectives; + } + + @Override + public AnalyzerMeasure<?> getMeasure(String metricKey) { + Metric<?> m = metricFinder.findByKey(metricKey); + if (m == null) { + throw new IllegalStateException("Unknow metric with key: " + metricKey); + } + return getMeasure(m); + } + + @Override + public <G extends Serializable> AnalyzerMeasure<G> getMeasure(Metric<G> metric) { + org.sonar.api.measures.Metric<G> m = metricFinder.findByKey(metric.key()); + Measure<G> measure = sensorContext.getMeasure(m); + if (measure == null) { + return null; + } + return AnalyzerMeasure.<G>builder() + .onProject() + .forMetric(metric) + .withValue(measure.value()) + .build(); + } + + @Override + public AnalyzerMeasure<?> getMeasure(InputFile file, String metricKey) { + Metric<?> m = metricFinder.findByKey(metricKey); + if (m == null) { + throw new IllegalStateException("Unknow metric with key: " + metricKey); + } + return getMeasure(file, m); + } + + @Override + public <G extends Serializable> AnalyzerMeasure<G> getMeasure(InputFile file, Metric<G> metric) { + File fileRes = File.fromIOFile(file.file(), project); + org.sonar.api.measures.Metric<G> m = metricFinder.findByKey(metric.key()); + Measure<G> measure = sensorContext.getMeasure(fileRes, m); + if (measure == null) { + return null; + } + return AnalyzerMeasure.<G>builder() + .onFile(file) + .forMetric(metric) + .withValue(measure.value()) + .build(); + } + + @Override + public void addMeasure(AnalyzerMeasure<?> measure) { + org.sonar.api.measures.Metric<?> m = metricFinder.findByKey(measure.metricKey()); + + Measure measureToSave = new Measure(m); + switch (m.getType()) { + case BOOL: + measureToSave.setValue(Boolean.TRUE.equals(measure.value()) ? 1.0 : 0.0); + break; + case INT: + case MILLISEC: + measureToSave.setValue(Double.valueOf(((Integer) measure.value()))); + break; + case FLOAT: + case PERCENT: + case RATING: + measureToSave.setValue(((Double) measure.value())); + break; + case STRING: + case LEVEL: + case DATA: + case DISTRIB: + measureToSave.setData(((String) measure.value())); + break; + case WORK_DUR: + measureToSave.setValue(Double.valueOf(((Long) measure.value()))); + break; + default: + if (m.isNumericType()) { + measureToSave.setValue(((Double) measure.value())); + } else if (m.isDataType()) { + measureToSave.setData(((String) measure.value())); + } else { + throw new UnsupportedOperationException("Unsupported type :" + m.getType()); + } + } + if (measure.inputFile() != null) { + File fileRes = File.fromIOFile(measure.inputFile().file(), project); + sensorContext.saveMeasure(fileRes, measureToSave); + } else { + sensorContext.saveMeasure(measureToSave); + } + } + + @Override + public void addIssue(AnalyzerIssue issue) { + Resource r; + if (issue.inputFile() != null) { + r = File.fromIOFile(issue.inputFile().file(), project); + } else { + r = project; + } + Issuable issuable = perspectives.as(Issuable.class, r); + issuable.addIssue(issuable.newIssueBuilder() + .ruleKey(RuleKey.of(issue.ruleKey().repository(), issue.ruleKey().rule())) + .effortToFix(issue.effortToFix()) + .line(issue.line()) + .message(issue.message()) + .build()); + } + + @Override + public void addIssues(Collection<AnalyzerIssue> issues) { + for (AnalyzerIssue analyzerIssue : issues) { + addIssue(analyzerIssue); + } + } + +} diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan/LanguageVerifier.java b/sonar-batch/src/main/java/org/sonar/batch/scan/LanguageVerifier.java index f64dd0d7219..7f32e03e98e 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/scan/LanguageVerifier.java +++ b/sonar-batch/src/main/java/org/sonar/batch/scan/LanguageVerifier.java @@ -25,9 +25,9 @@ import org.slf4j.LoggerFactory; import org.sonar.api.CoreProperties; import org.sonar.api.batch.fs.internal.DefaultFileSystem; import org.sonar.api.config.Settings; -import org.sonar.api.resources.Language; -import org.sonar.api.resources.Languages; import org.sonar.api.utils.MessageException; +import org.sonar.batch.api.languages.Language; +import org.sonar.batch.languages.LanguagesReferential; /** * Verifies that the property sonar.language is valid @@ -37,16 +37,15 @@ public class LanguageVerifier implements Startable { private static final Logger LOG = LoggerFactory.getLogger(LanguageVerifier.class); private final Settings settings; - private final Languages languages; + private final LanguagesReferential languages; private final DefaultFileSystem fs; - public LanguageVerifier(Settings settings, Languages languages, DefaultFileSystem fs) { + public LanguageVerifier(Settings settings, LanguagesReferential languages, DefaultFileSystem fs) { this.settings = settings; this.languages = languages; this.fs = fs; } - @Override public void start() { if (settings.hasKey(CoreProperties.PROJECT_LANGUAGE_PROPERTY)) { diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan/ModuleScanContainer.java b/sonar-batch/src/main/java/org/sonar/batch/scan/ModuleScanContainer.java index 6e4ebd39b6a..6b1e0e1a501 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/scan/ModuleScanContainer.java +++ b/sonar-batch/src/main/java/org/sonar/batch/scan/ModuleScanContainer.java @@ -39,6 +39,9 @@ import org.sonar.batch.bootstrap.ExtensionInstaller; import org.sonar.batch.bootstrap.ExtensionMatcher; import org.sonar.batch.bootstrap.ExtensionUtils; import org.sonar.batch.components.TimeMachineConfiguration; +import org.sonar.batch.debt.DebtDecorator; +import org.sonar.batch.debt.IssueChangelogDebtCalculator; +import org.sonar.batch.debt.NewDebtDecorator; import org.sonar.batch.events.EventBus; import org.sonar.batch.index.DefaultIndex; import org.sonar.batch.index.ResourcePersister; @@ -139,6 +142,7 @@ public class ModuleScanContainer extends ComponentContainer { TimeMachineConfiguration.class, DefaultSensorContext.class, + AnalyzerContextAdaptor.class, BatchExtensionDictionnary.class, DefaultTimeMachine.class, ViolationFilters.class, @@ -178,6 +182,11 @@ public class ModuleScanContainer extends ComponentContainer { // language LanguageDistributionDecorator.class, + // Debt + IssueChangelogDebtCalculator.class, + DebtDecorator.class, + NewDebtDecorator.class, + ScanPerspectives.class); } @@ -191,7 +200,8 @@ public class ModuleScanContainer extends ComponentContainer { // Example : C# plugin adds sub-projects at runtime, even if they are not defined in root pom. return !ExtensionUtils.isMavenExtensionOnly(extension) || module.getPom() != null; } - return false; + return ExtensionUtils.isType(extension, org.sonar.batch.api.BatchComponent.class) + && ExtensionUtils.isInstantiationStrategy(extension, org.sonar.batch.api.InstantiationStrategy.PER_PROJECT); } }); } diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan/ProjectScanContainer.java b/sonar-batch/src/main/java/org/sonar/batch/scan/ProjectScanContainer.java index b6dca14dafd..8d4dfa22df7 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/scan/ProjectScanContainer.java +++ b/sonar-batch/src/main/java/org/sonar/batch/scan/ProjectScanContainer.java @@ -40,7 +40,6 @@ import org.sonar.batch.bootstrap.ExtensionMatcher; import org.sonar.batch.bootstrap.ExtensionUtils; import org.sonar.batch.bootstrap.MetricProvider; import org.sonar.batch.components.PeriodsDefinition; -import org.sonar.batch.debt.DebtModelProvider; import org.sonar.batch.debt.IssueChangelogDebtCalculator; import org.sonar.batch.index.Caches; import org.sonar.batch.index.ComponentDataCache; @@ -61,9 +60,9 @@ import org.sonar.batch.issue.DeprecatedViolations; import org.sonar.batch.issue.IssueCache; import org.sonar.batch.issue.IssuePersister; import org.sonar.batch.issue.ScanIssueStorage; +import org.sonar.batch.languages.DeprecatedLanguagesReferential; import org.sonar.batch.phases.GraphPersister; import org.sonar.batch.profiling.PhasesSumUpTimeProfiler; -import org.sonar.batch.rule.RulesProvider; import org.sonar.batch.scan.filesystem.InputFileCache; import org.sonar.batch.scan.maven.FakeMavenPluginExecutor; import org.sonar.batch.scan.maven.MavenPluginExecutor; @@ -101,27 +100,23 @@ public class ProjectScanContainer extends ComponentContainer { } private void projectBootstrap() { - // Old versions of bootstrappers used to pass project reactor as an extension - // so check if it is already present in parent container - ProjectReactor reactor = getComponentByType(ProjectReactor.class); + ProjectReactor reactor; + // OK, not present, so look for a custom ProjectBootstrapper + ProjectBootstrapper bootstrapper = getComponentByType(ProjectBootstrapper.class); + Settings settings = getComponentByType(Settings.class); + if (bootstrapper == null + // Starting from Maven plugin 2.3 then only DefaultProjectBootstrapper should be used. + || "true".equals(settings.getString("sonar.mojoUseRunner"))) { + // Use default SonarRunner project bootstrapper + ProjectReactorBuilder builder = getComponentByType(ProjectReactorBuilder.class); + reactor = builder.execute(); + } else { + reactor = bootstrapper.bootstrap(); + } if (reactor == null) { - // OK, not present, so look for a custom ProjectBootstrapper - ProjectBootstrapper bootstrapper = getComponentByType(ProjectBootstrapper.class); - Settings settings = getComponentByType(Settings.class); - if (bootstrapper == null - // Starting from Maven plugin 2.3 then only DefaultProjectBootstrapper should be used. - || "true".equals(settings.getString("sonar.mojoUseRunner"))) { - // Use default SonarRunner project bootstrapper - ProjectReactorBuilder builder = getComponentByType(ProjectReactorBuilder.class); - reactor = builder.execute(); - } else { - reactor = bootstrapper.bootstrap(); - } - if (reactor == null) { - throw new SonarException(bootstrapper + " has returned null as ProjectReactor"); - } - add(reactor); + throw new SonarException(bootstrapper + " has returned null as ProjectReactor"); } + add(reactor); } private void addBatchComponents() { @@ -175,15 +170,12 @@ public class ProjectScanContainer extends ComponentContainer { // lang Languages.class, + DeprecatedLanguagesReferential.class, HighlightableBuilder.class, SymbolizableBuilder.class, // technical debt DefaultTechnicalDebtModel.class, - new DebtModelProvider(), - - // rules - new RulesProvider(), // Differential periods PeriodsDefinition.class, diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan/ScanTask.java b/sonar-batch/src/main/java/org/sonar/batch/scan/ScanTask.java index 1ccbb393522..33285ae2be6 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/scan/ScanTask.java +++ b/sonar-batch/src/main/java/org/sonar/batch/scan/ScanTask.java @@ -24,8 +24,10 @@ import org.sonar.api.platform.ComponentContainer; import org.sonar.api.task.Task; import org.sonar.api.task.TaskDefinition; import org.sonar.batch.DefaultProjectTree; +import org.sonar.batch.bootstrap.BootstrapProperties; import org.sonar.batch.bootstrap.TaskContainer; import org.sonar.batch.phases.Phases; +import org.sonar.batch.scan2.ProjectScanContainer; public class ScanTask implements Task { public static final TaskDefinition DEFINITION = TaskDefinition.builder() @@ -41,7 +43,12 @@ public class ScanTask implements Task { } public void execute() { - scan(new ProjectScanContainer(taskContainer)); + boolean sensorMode = CoreProperties.ANALYSIS_MODE_SENSOR.equals(taskContainer.getComponentByType(BootstrapProperties.class).property(CoreProperties.ANALYSIS_MODE)); + if (sensorMode) { + new ProjectScanContainer(taskContainer).execute(); + } else { + scan(new org.sonar.batch.scan.ProjectScanContainer(taskContainer)); + } } // Add components specific to project scan (views will use different ones) diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan/SensorWrapper.java b/sonar-batch/src/main/java/org/sonar/batch/scan/SensorWrapper.java new file mode 100644 index 00000000000..ae9a25c59dc --- /dev/null +++ b/sonar-batch/src/main/java/org/sonar/batch/scan/SensorWrapper.java @@ -0,0 +1,78 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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.batch.scan; + +import org.sonar.api.batch.DependedUpon; +import org.sonar.api.batch.DependsUpon; +import org.sonar.api.batch.Sensor; +import org.sonar.api.batch.SensorContext; +import org.sonar.api.batch.fs.FileSystem; +import org.sonar.api.resources.Project; +import org.sonar.batch.api.analyzer.Analyzer; +import org.sonar.batch.api.analyzer.AnalyzerContext; +import org.sonar.batch.api.measures.Metric; + +import java.util.Arrays; +import java.util.List; + +public class SensorWrapper implements Sensor { + + private Analyzer analyzer; + private AnalyzerContext adaptor; + private FileSystem fs; + + public SensorWrapper(Analyzer analyzer, AnalyzerContext adaptor, FileSystem fs) { + this.analyzer = analyzer; + this.adaptor = adaptor; + this.fs = fs; + } + + @DependedUpon + public List<Metric<?>> provides() { + return Arrays.asList(analyzer.describe().provides()); + } + + @DependsUpon + public List<Metric<?>> depends() { + return Arrays.asList(analyzer.describe().dependsOn()); + } + + @Override + public boolean shouldExecuteOnProject(Project project) { + if (!analyzer.describe().languages().isEmpty()) { + if (project.getLanguageKey() != null && !analyzer.describe().languages().contains(project.getLanguageKey())) { + return false; + } + boolean hasFile = false; + for (String languageKey : analyzer.describe().languages()) { + hasFile |= fs.hasFiles(fs.predicates().hasLanguage(languageKey)); + } + if (!hasFile) { + return false; + } + } + return true; + } + + @Override + public void analyse(Project module, SensorContext context) { + analyzer.analyse(adaptor); + } +} diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan/filesystem/AdditionalFilePredicates.java b/sonar-batch/src/main/java/org/sonar/batch/scan/filesystem/AdditionalFilePredicates.java index af44e9b8783..6332d51a2ed 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/scan/filesystem/AdditionalFilePredicates.java +++ b/sonar-batch/src/main/java/org/sonar/batch/scan/filesystem/AdditionalFilePredicates.java @@ -22,7 +22,7 @@ package org.sonar.batch.scan.filesystem; import org.apache.commons.io.FilenameUtils; import org.sonar.api.batch.fs.FilePredicate; import org.sonar.api.batch.fs.InputFile; -import org.sonar.api.batch.fs.internal.DefaultInputFile; +import org.sonar.api.batch.fs.internal.DeprecatedDefaultInputFile; /** * Additional {@link org.sonar.api.batch.fs.FilePredicate}s that are @@ -43,7 +43,7 @@ class AdditionalFilePredicates { @Override public boolean apply(InputFile f) { - return key.equals(((DefaultInputFile) f).key()); + return key.equals(((DeprecatedDefaultInputFile) f).key()); } } @@ -56,7 +56,7 @@ class AdditionalFilePredicates { @Override public boolean apply(InputFile f) { - return key.equals(((DefaultInputFile) f).deprecatedKey()); + return key.equals(((DeprecatedDefaultInputFile) f).deprecatedKey()); } } @@ -69,7 +69,7 @@ class AdditionalFilePredicates { @Override public boolean apply(InputFile f) { - return path.equals(((DefaultInputFile) f).pathRelativeToSourceDir()); + return path.equals(((DeprecatedDefaultInputFile) f).pathRelativeToSourceDir()); } } @@ -82,7 +82,7 @@ class AdditionalFilePredicates { @Override public boolean apply(InputFile f) { - return path.equals(((DefaultInputFile) f).sourceDirAbsolutePath()); + return path.equals(((DeprecatedDefaultInputFile) f).sourceDirAbsolutePath()); } } } diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan/filesystem/ComponentIndexer.java b/sonar-batch/src/main/java/org/sonar/batch/scan/filesystem/ComponentIndexer.java index 4729d7f0361..f7f289ddf64 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/scan/filesystem/ComponentIndexer.java +++ b/sonar-batch/src/main/java/org/sonar/batch/scan/filesystem/ComponentIndexer.java @@ -27,7 +27,7 @@ import org.sonar.api.CoreProperties; import org.sonar.api.batch.SonarIndex; import org.sonar.api.batch.fs.FileSystem; import org.sonar.api.batch.fs.InputFile; -import org.sonar.api.batch.fs.internal.DefaultInputFile; +import org.sonar.api.batch.fs.internal.DeprecatedDefaultInputFile; import org.sonar.api.config.Settings; import org.sonar.api.resources.File; import org.sonar.api.resources.Languages; @@ -65,7 +65,7 @@ public class ComponentIndexer implements BatchComponent { for (InputFile inputFile : fs.inputFiles(fs.predicates().all())) { String languageKey = inputFile.language(); boolean unitTest = InputFile.Type.TEST == inputFile.type(); - String pathFromSourceDir = ((DefaultInputFile) inputFile).pathRelativeToSourceDir(); + String pathFromSourceDir = ((DeprecatedDefaultInputFile) inputFile).pathRelativeToSourceDir(); if (pathFromSourceDir == null) { pathFromSourceDir = inputFile.relativePath(); } diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan/filesystem/DefaultModuleFileSystem.java b/sonar-batch/src/main/java/org/sonar/batch/scan/filesystem/DefaultModuleFileSystem.java index ea5692fb4b3..7205c1c483f 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/scan/filesystem/DefaultModuleFileSystem.java +++ b/sonar-batch/src/main/java/org/sonar/batch/scan/filesystem/DefaultModuleFileSystem.java @@ -27,13 +27,14 @@ import org.apache.commons.lang.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.sonar.api.CoreProperties; +import org.sonar.api.batch.bootstrap.ProjectDefinition; import org.sonar.api.batch.fs.FilePredicate; import org.sonar.api.batch.fs.internal.DefaultFileSystem; import org.sonar.api.config.Settings; import org.sonar.api.resources.Project; import org.sonar.api.scan.filesystem.FileQuery; import org.sonar.api.scan.filesystem.ModuleFileSystem; -import org.sonar.api.utils.SonarException; +import org.sonar.api.utils.MessageException; import javax.annotation.CheckForNull; import javax.annotation.Nullable; @@ -66,11 +67,24 @@ public class DefaultModuleFileSystem extends DefaultFileSystem implements Module private ComponentIndexer componentIndexer; private boolean initialized; - public DefaultModuleFileSystem(ModuleInputFileCache moduleInputFileCache, Project module, Settings settings, FileIndexer indexer, ModuleFileSystemInitializer initializer, + /** + * Used by scan2 + */ + public DefaultModuleFileSystem(ModuleInputFileCache moduleInputFileCache, ProjectDefinition def, Settings settings, FileIndexer indexer, ModuleFileSystemInitializer initializer) { + this(moduleInputFileCache, def.getKey(), settings, indexer, initializer, null); + } + + public DefaultModuleFileSystem(ModuleInputFileCache moduleInputFileCache, ProjectDefinition def, Project project, Settings settings, FileIndexer indexer, + ModuleFileSystemInitializer initializer, ComponentIndexer componentIndexer) { + this(moduleInputFileCache, project.getKey(), settings, indexer, initializer, componentIndexer); + } + + private DefaultModuleFileSystem(ModuleInputFileCache moduleInputFileCache, String moduleKey, Settings settings, FileIndexer indexer, ModuleFileSystemInitializer initializer, + @Nullable ComponentIndexer componentIndexer) { super(moduleInputFileCache); this.componentIndexer = componentIndexer; - this.moduleKey = module.getKey(); + this.moduleKey = moduleKey; this.settings = settings; this.indexer = indexer; if (initializer.baseDir() != null) { @@ -202,7 +216,7 @@ public class DefaultModuleFileSystem extends DefaultFileSystem implements Module public void resetDirs(File basedir, File buildDir, List<File> sourceDirs, List<File> testDirs, List<File> binaryDirs) { if (initialized) { - throw new SonarException("Module filesystem is already initialized. Modifications of filesystem are only allowed during Initializer phase."); + throw MessageException.of("Module filesystem is already initialized. Modifications of filesystem are only allowed during Initializer phase."); } setBaseDir(basedir); this.buildDir = buildDir; @@ -213,11 +227,13 @@ public class DefaultModuleFileSystem extends DefaultFileSystem implements Module public void index() { if (initialized) { - throw new SonarException("Module filesystem can only be indexed once"); + throw MessageException.of("Module filesystem can only be indexed once"); } initialized = true; indexer.index(this); - componentIndexer.execute(this); + if (componentIndexer != null) { + componentIndexer.execute(this); + } } private List<File> existingDirs(List<File> dirs) { diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan/filesystem/DeprecatedFileFilters.java b/sonar-batch/src/main/java/org/sonar/batch/scan/filesystem/DeprecatedFileFilters.java index 8545dc4ef45..d52e19b0b0b 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/scan/filesystem/DeprecatedFileFilters.java +++ b/sonar-batch/src/main/java/org/sonar/batch/scan/filesystem/DeprecatedFileFilters.java @@ -21,7 +21,7 @@ package org.sonar.batch.scan.filesystem; import org.sonar.api.batch.fs.InputFile; import org.sonar.api.batch.fs.InputFileFilter; -import org.sonar.api.batch.fs.internal.DefaultInputFile; +import org.sonar.api.batch.fs.internal.DeprecatedDefaultInputFile; import org.sonar.api.scan.filesystem.FileSystemFilter; import org.sonar.api.scan.filesystem.FileType; import org.sonar.api.scan.filesystem.ModuleFileSystem; @@ -72,12 +72,12 @@ public class DeprecatedFileFilters implements InputFileFilter { @Override public File relativeDir() { - return new File(((DefaultInputFile)inputFile).sourceDirAbsolutePath()); + return new File(((DeprecatedDefaultInputFile)inputFile).sourceDirAbsolutePath()); } @Override public String relativePath() { - return ((DefaultInputFile)inputFile).pathRelativeToSourceDir(); + return ((DeprecatedDefaultInputFile)inputFile).pathRelativeToSourceDir(); } @Override diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan/filesystem/FileIndexer.java b/sonar-batch/src/main/java/org/sonar/batch/scan/filesystem/FileIndexer.java index b9d784723fa..b3142c9cc05 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/scan/filesystem/FileIndexer.java +++ b/sonar-batch/src/main/java/org/sonar/batch/scan/filesystem/FileIndexer.java @@ -27,11 +27,12 @@ import org.apache.commons.io.filefilter.IOFileFilter; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.sonar.api.BatchComponent; +import org.sonar.api.batch.bootstrap.ProjectDefinition; import org.sonar.api.batch.fs.InputFile; import org.sonar.api.batch.fs.InputFileFilter; -import org.sonar.api.batch.fs.internal.DefaultInputFile; +import org.sonar.api.batch.fs.internal.DeprecatedDefaultInputFile; import org.sonar.api.resources.Project; -import org.sonar.api.utils.SonarException; +import org.sonar.api.utils.MessageException; import java.io.File; import java.util.Collection; @@ -44,31 +45,45 @@ import java.util.Set; */ public class FileIndexer implements BatchComponent { + private static final Logger LOG = LoggerFactory.getLogger(FileIndexer.class); + private static final IOFileFilter DIR_FILTER = FileFilterUtils.and(HiddenFileFilter.VISIBLE, FileFilterUtils.notFileFilter(FileFilterUtils.prefixFileFilter("."))); private static final IOFileFilter FILE_FILTER = HiddenFileFilter.VISIBLE; private final List<InputFileFilter> filters; private final InputFileCache fileCache; - private final Project module; + private final boolean isAggregator; private final ExclusionFilters exclusionFilters; private final InputFileBuilderFactory inputFileBuilderFactory; public FileIndexer(List<InputFileFilter> filters, ExclusionFilters exclusionFilters, InputFileBuilderFactory inputFileBuilderFactory, - InputFileCache cache, Project module) { + InputFileCache cache, Project module, ProjectDefinition def) { + this(filters, exclusionFilters, inputFileBuilderFactory, cache, !module.getModules().isEmpty()); + } + + /** + * Used by scan2 + */ + public FileIndexer(List<InputFileFilter> filters, ExclusionFilters exclusionFilters, InputFileBuilderFactory inputFileBuilderFactory, + InputFileCache cache, ProjectDefinition def) { + this(filters, exclusionFilters, inputFileBuilderFactory, cache, !def.getSubProjects().isEmpty()); + } + + private FileIndexer(List<InputFileFilter> filters, ExclusionFilters exclusionFilters, InputFileBuilderFactory inputFileBuilderFactory, + InputFileCache cache, boolean isAggregator) { this.filters = filters; this.exclusionFilters = exclusionFilters; this.inputFileBuilderFactory = inputFileBuilderFactory; this.fileCache = cache; - this.module = module; + this.isAggregator = isAggregator; } void index(DefaultModuleFileSystem fileSystem) { - Logger logger = LoggerFactory.getLogger(FileIndexer.class); - if (!module.getModules().isEmpty()) { + if (isAggregator) { // No indexing for an aggregator module return; } - logger.info("Index files"); + LOG.info("Index files"); exclusionFilters.prepare(); Progress progress = new Progress(fileCache.byModule(fileSystem.moduleKey())); @@ -93,13 +108,13 @@ public class FileIndexer implements BatchComponent { fileCache.remove(fileSystem.moduleKey(), removed); } - logger.info(String.format("%d files indexed", progress.count())); + LOG.info(String.format("%d files indexed", progress.count())); } private void indexFiles(InputFileBuilder inputFileBuilder, DefaultModuleFileSystem fileSystem, Progress progress, List<File> sourceFiles, InputFile.Type type) { for (File sourceFile : sourceFiles) { - DefaultInputFile inputFile = inputFileBuilder.create(sourceFile); + DeprecatedDefaultInputFile inputFile = inputFileBuilder.create(sourceFile); if (inputFile != null && exclusionFilters.accept(inputFile, type)) { indexFile(inputFileBuilder, fileSystem, progress, inputFile, type); } @@ -109,7 +124,7 @@ public class FileIndexer implements BatchComponent { private void indexDirectory(InputFileBuilder inputFileBuilder, DefaultModuleFileSystem fileSystem, Progress status, File dirToIndex, InputFile.Type type) { Collection<File> files = FileUtils.listFiles(dirToIndex, FILE_FILTER, DIR_FILTER); for (File file : files) { - DefaultInputFile inputFile = inputFileBuilder.create(file); + DeprecatedDefaultInputFile inputFile = inputFileBuilder.create(file); if (inputFile != null && exclusionFilters.accept(inputFile, type)) { indexFile(inputFileBuilder, fileSystem, status, inputFile, type); } @@ -117,7 +132,7 @@ public class FileIndexer implements BatchComponent { } private void indexFile(InputFileBuilder inputFileBuilder, DefaultModuleFileSystem fs, - Progress status, DefaultInputFile inputFile, InputFile.Type type) { + Progress status, DeprecatedDefaultInputFile inputFile, InputFile.Type type) { InputFile completedFile = inputFileBuilder.complete(inputFile, type); if (completedFile != null && accept(completedFile)) { fs.add(completedFile); @@ -146,7 +161,7 @@ public class FileIndexer implements BatchComponent { void markAsIndexed(InputFile inputFile) { if (indexed.contains(inputFile)) { - throw new SonarException("File " + inputFile + " can't be indexed twice. Please check that inclusion/exclusion patterns produce " + throw MessageException.of("File " + inputFile + " can't be indexed twice. Please check that inclusion/exclusion patterns produce " + "disjoint sets for main and test files"); } removed.remove(inputFile); diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan/filesystem/InputFileBuilder.java b/sonar-batch/src/main/java/org/sonar/batch/scan/filesystem/InputFileBuilder.java index 10b888344b9..cd7844fd4de 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/scan/filesystem/InputFileBuilder.java +++ b/sonar-batch/src/main/java/org/sonar/batch/scan/filesystem/InputFileBuilder.java @@ -24,7 +24,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.sonar.api.batch.fs.FileSystem; import org.sonar.api.batch.fs.InputFile; -import org.sonar.api.batch.fs.internal.DefaultInputFile; +import org.sonar.api.batch.fs.internal.DeprecatedDefaultInputFile; import org.sonar.api.scan.filesystem.PathResolver; import org.sonar.batch.bootstrap.AnalysisMode; import org.sonar.batch.util.DeprecatedKeyUtils; @@ -76,13 +76,13 @@ class InputFileBuilder { } @CheckForNull - DefaultInputFile create(File file) { + DeprecatedDefaultInputFile create(File file) { String relativePath = pathResolver.relativePath(fs.baseDir(), file); if (relativePath == null) { LOG.warn("File '{}' is ignored. It is not located in module basedir '{}'.", file.getAbsolutePath(), fs.baseDir()); return null; } - DefaultInputFile inputFile = new DefaultInputFile(relativePath); + DeprecatedDefaultInputFile inputFile = new DeprecatedDefaultInputFile(relativePath); inputFile.setBasedir(fs.baseDir()); inputFile.setFile(file); return inputFile; @@ -92,7 +92,7 @@ class InputFileBuilder { * Optimization to not set all InputFile data if the file is excluded from analysis. */ @CheckForNull - DefaultInputFile complete(DefaultInputFile inputFile, InputFile.Type type) { + DeprecatedDefaultInputFile complete(DeprecatedDefaultInputFile inputFile, InputFile.Type type) { inputFile.setType(type); inputFile.setKey(new StringBuilder().append(moduleKey).append(":").append(inputFile.relativePath()).toString()); inputFile.setBasedir(fs.baseDir()); @@ -112,7 +112,7 @@ class InputFileBuilder { return inputFile; } - private void fillDeprecatedData(DefaultInputFile inputFile) { + private void fillDeprecatedData(DeprecatedDefaultInputFile inputFile) { List<File> sourceDirs = InputFile.Type.MAIN == inputFile.type() ? fs.sourceDirs() : fs.testDirs(); for (File sourceDir : sourceDirs) { String sourceRelativePath = pathResolver.relativePath(sourceDir, inputFile.file()); diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan/filesystem/InputFileBuilderFactory.java b/sonar-batch/src/main/java/org/sonar/batch/scan/filesystem/InputFileBuilderFactory.java index 90dcfc870d7..772f773cb5f 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/scan/filesystem/InputFileBuilderFactory.java +++ b/sonar-batch/src/main/java/org/sonar/batch/scan/filesystem/InputFileBuilderFactory.java @@ -20,6 +20,7 @@ package org.sonar.batch.scan.filesystem; import org.sonar.api.BatchComponent; +import org.sonar.api.batch.bootstrap.ProjectDefinition; import org.sonar.api.resources.Project; import org.sonar.api.scan.filesystem.PathResolver; import org.sonar.batch.bootstrap.AnalysisMode; @@ -32,9 +33,22 @@ public class InputFileBuilderFactory implements BatchComponent { private final StatusDetectionFactory statusDetectionFactory; private final AnalysisMode analysisMode; - public InputFileBuilderFactory(Project moduleDef, PathResolver pathResolver, LanguageDetectionFactory langDetectionFactory, - StatusDetectionFactory statusDetectionFactory, AnalysisMode analysisMode) { - this.moduleKey = moduleDef.getEffectiveKey(); + public InputFileBuilderFactory(Project module, ProjectDefinition def, PathResolver pathResolver, LanguageDetectionFactory langDetectionFactory, + StatusDetectionFactory statusDetectionFactory, AnalysisMode analysisMode) { + this(module.getEffectiveKey(), pathResolver, langDetectionFactory, statusDetectionFactory, analysisMode); + } + + /** + * Used by scan2 + */ + public InputFileBuilderFactory(ProjectDefinition def, PathResolver pathResolver, LanguageDetectionFactory langDetectionFactory, + StatusDetectionFactory statusDetectionFactory, AnalysisMode analysisMode) { + this(def.getKey(), pathResolver, langDetectionFactory, statusDetectionFactory, analysisMode); + } + + private InputFileBuilderFactory(String effectiveKey, PathResolver pathResolver, LanguageDetectionFactory langDetectionFactory, + StatusDetectionFactory statusDetectionFactory, AnalysisMode analysisMode) { + this.moduleKey = effectiveKey; this.pathResolver = pathResolver; this.langDetectionFactory = langDetectionFactory; this.statusDetectionFactory = statusDetectionFactory; diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan/filesystem/InputFileCache.java b/sonar-batch/src/main/java/org/sonar/batch/scan/filesystem/InputFileCache.java index 3035f115c5c..3b12d8ba5f6 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/scan/filesystem/InputFileCache.java +++ b/sonar-batch/src/main/java/org/sonar/batch/scan/filesystem/InputFileCache.java @@ -21,8 +21,6 @@ package org.sonar.batch.scan.filesystem; import org.sonar.api.BatchComponent; import org.sonar.api.batch.fs.InputFile; -import org.sonar.api.batch.fs.internal.FileIndex; -import org.sonar.api.batch.fs.internal.RelativePathIndex; import org.sonar.batch.index.Cache; import org.sonar.batch.index.Caches; @@ -69,23 +67,8 @@ public class InputFileCache implements BatchComponent { return this; } - - public void index(String moduleKey, String indexId, Object indexValue, InputFile inputFile) { - // already indexed by relative path is already used - if (!indexId.equals(RelativePathIndex.ID)) { - // See limitation of org.sonar.batch.index.Cache -> fail - // to traverse a sub-tree, for example in order to - // have the following structure in InputFileCache : - // [index id|module key|index value] - throw new UnsupportedOperationException("Only relative path index is supported yet"); - } - } - @CheckForNull - public InputFile get(String moduleKey, String indexId, Object indexValue) { - if (!indexId.equals(RelativePathIndex.ID)) { - throw new UnsupportedOperationException("Only relative path index is supported yet"); - } - return cache.get(moduleKey, indexValue); + public InputFile get(String moduleKey, String relativePath) { + return cache.get(moduleKey, relativePath); } } diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan/filesystem/LanguageDetection.java b/sonar-batch/src/main/java/org/sonar/batch/scan/filesystem/LanguageDetection.java index da4900f2145..7256c5592a3 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/scan/filesystem/LanguageDetection.java +++ b/sonar-batch/src/main/java/org/sonar/batch/scan/filesystem/LanguageDetection.java @@ -29,14 +29,13 @@ import org.sonar.api.CoreProperties; import org.sonar.api.batch.fs.InputFile; import org.sonar.api.batch.fs.internal.PathPattern; import org.sonar.api.config.Settings; -import org.sonar.api.resources.Language; -import org.sonar.api.resources.Languages; import org.sonar.api.utils.MessageException; +import org.sonar.batch.api.languages.Language; +import org.sonar.batch.languages.LanguagesReferential; import javax.annotation.CheckForNull; import java.text.MessageFormat; -import java.util.Arrays; import java.util.List; import java.util.Map; @@ -54,23 +53,23 @@ class LanguageDetection { private final List<String> languagesToConsider = Lists.newArrayList(); private final String forcedLanguage; - LanguageDetection(Settings settings, Languages languages) { + LanguageDetection(Settings settings, LanguagesReferential languages) { for (Language language : languages.all()) { - String[] filePatterns = settings.getStringArray(getFileLangPatternPropKey(language.getKey())); + String[] filePatterns = settings.getStringArray(getFileLangPatternPropKey(language.key())); PathPattern[] pathPatterns = PathPattern.create(filePatterns); if (pathPatterns.length > 0) { - patternsByLanguage.put(language.getKey(), pathPatterns); + patternsByLanguage.put(language.key(), pathPatterns); } else { // If no custom language pattern is defined then fallback to suffixes declared by language - String[] patterns = Arrays.copyOf(language.getFileSuffixes(), language.getFileSuffixes().length); + String[] patterns = language.fileSuffixes().toArray(new String[language.fileSuffixes().size()]); for (int i = 0; i < patterns.length; i++) { String suffix = patterns[i]; String extension = sanitizeExtension(suffix); patterns[i] = "**/*." + extension; } PathPattern[] defaultLanguagePatterns = PathPattern.create(patterns); - patternsByLanguage.put(language.getKey(), defaultLanguagePatterns); - LOG.debug("Declared extensions of language " + language + " were converted to " + getDetails(language.getKey())); + patternsByLanguage.put(language.key(), defaultLanguagePatterns); + LOG.debug("Declared extensions of language " + language + " were converted to " + getDetails(language.key())); } } diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan/filesystem/LanguageDetectionFactory.java b/sonar-batch/src/main/java/org/sonar/batch/scan/filesystem/LanguageDetectionFactory.java index 814b6e380ed..6ff579fd769 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/scan/filesystem/LanguageDetectionFactory.java +++ b/sonar-batch/src/main/java/org/sonar/batch/scan/filesystem/LanguageDetectionFactory.java @@ -21,13 +21,13 @@ package org.sonar.batch.scan.filesystem; import org.sonar.api.BatchComponent; import org.sonar.api.config.Settings; -import org.sonar.api.resources.Languages; +import org.sonar.batch.languages.LanguagesReferential; public class LanguageDetectionFactory implements BatchComponent { private final Settings settings; - private final Languages languages; + private final LanguagesReferential languages; - public LanguageDetectionFactory(Settings settings, Languages languages) { + public LanguageDetectionFactory(Settings settings, LanguagesReferential languages) { this.settings = settings; this.languages = languages; } diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan/filesystem/ModuleInputFileCache.java b/sonar-batch/src/main/java/org/sonar/batch/scan/filesystem/ModuleInputFileCache.java index 4a909f29cf4..d555074db79 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/scan/filesystem/ModuleInputFileCache.java +++ b/sonar-batch/src/main/java/org/sonar/batch/scan/filesystem/ModuleInputFileCache.java @@ -20,9 +20,10 @@ package org.sonar.batch.scan.filesystem; import org.sonar.api.BatchComponent; +import org.sonar.api.batch.bootstrap.ProjectDefinition; import org.sonar.api.batch.fs.InputFile; -import org.sonar.api.batch.fs.internal.UniqueIndexPredicate; import org.sonar.api.batch.fs.internal.DefaultFileSystem; +import org.sonar.api.batch.fs.internal.RelativePathPredicate; import org.sonar.api.resources.Project; public class ModuleInputFileCache extends DefaultFileSystem.Cache implements BatchComponent { @@ -30,28 +31,31 @@ public class ModuleInputFileCache extends DefaultFileSystem.Cache implements Bat private final String moduleKey; private final InputFileCache projectCache; - public ModuleInputFileCache(Project module, InputFileCache projectCache) { + public ModuleInputFileCache(Project module, ProjectDefinition projectDef, InputFileCache projectCache) { this.moduleKey = module.getKey(); this.projectCache = projectCache; } + /** + * Used by scan2 + */ + public ModuleInputFileCache(ProjectDefinition projectDef, InputFileCache projectCache) { + this.moduleKey = projectDef.getKey(); + this.projectCache = projectCache; + } + @Override protected Iterable<InputFile> inputFiles() { return projectCache.byModule(moduleKey); } @Override - protected InputFile inputFile(UniqueIndexPredicate predicate) { - return projectCache.get(moduleKey, predicate.indexId(), predicate.value()); + protected InputFile inputFile(RelativePathPredicate predicate) { + return projectCache.get(moduleKey, predicate.path()); } @Override protected void doAdd(InputFile inputFile) { projectCache.put(moduleKey, inputFile); } - - @Override - protected void doIndex(String indexId, Object value, InputFile inputFile) { - projectCache.index(moduleKey, indexId, value, inputFile); - } } diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan/filesystem/StatusDetectionFactory.java b/sonar-batch/src/main/java/org/sonar/batch/scan/filesystem/StatusDetectionFactory.java index dd1e4a247c2..53729dde592 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/scan/filesystem/StatusDetectionFactory.java +++ b/sonar-batch/src/main/java/org/sonar/batch/scan/filesystem/StatusDetectionFactory.java @@ -21,6 +21,8 @@ package org.sonar.batch.scan.filesystem; import org.sonar.api.BatchComponent; +import java.util.Collections; + public class StatusDetectionFactory implements BatchComponent { private final PreviousFileHashLoader previousFileHashLoader; @@ -29,7 +31,14 @@ public class StatusDetectionFactory implements BatchComponent { this.previousFileHashLoader = l; } + /** + * Used by scan2 + */ + public StatusDetectionFactory() { + this.previousFileHashLoader = null; + } + StatusDetection create() { - return new StatusDetection(previousFileHashLoader.hashByRelativePath()); + return new StatusDetection(previousFileHashLoader != null ? previousFileHashLoader.hashByRelativePath() : Collections.<String, String>emptyMap()); } } diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan/measure/MeasureCache.java b/sonar-batch/src/main/java/org/sonar/batch/scan/measure/MeasureCache.java index a2056966ef2..e3732308cf5 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/scan/measure/MeasureCache.java +++ b/sonar-batch/src/main/java/org/sonar/batch/scan/measure/MeasureCache.java @@ -34,11 +34,9 @@ import org.sonar.batch.index.Caches; public class MeasureCache implements BatchComponent { private final Cache<Measure> cache; - private final Cache<String> dataCache; public MeasureCache(Caches caches) { cache = caches.createCache("measures"); - dataCache = caches.createCache("measuresData"); } public Iterable<Entry<Measure>> entries() { @@ -50,7 +48,11 @@ public class MeasureCache implements BatchComponent { } public Iterable<Measure> byMetric(Resource r, String metricKey) { - return cache.values(r.getEffectiveKey(), metricKey); + return byMetric(r.getEffectiveKey(), metricKey); + } + + public Iterable<Measure> byMetric(String resourceKey, String metricKey) { + return cache.values(resourceKey, metricKey); } public MeasureCache put(Resource resource, Measure measure) { @@ -85,4 +87,5 @@ public class MeasureCache implements BatchComponent { } return sb.toString(); } + } diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan/report/JsonReport.java b/sonar-batch/src/main/java/org/sonar/batch/scan/report/JsonReport.java index 20731c631a3..fe8ddc7826d 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/scan/report/JsonReport.java +++ b/sonar-batch/src/main/java/org/sonar/batch/scan/report/JsonReport.java @@ -27,7 +27,7 @@ import org.slf4j.LoggerFactory; import org.sonar.api.BatchComponent; import org.sonar.api.batch.fs.FileSystem; import org.sonar.api.batch.fs.InputFile; -import org.sonar.api.batch.fs.internal.DefaultInputFile; +import org.sonar.api.batch.fs.internal.DeprecatedDefaultInputFile; import org.sonar.api.config.Settings; import org.sonar.api.issue.internal.DefaultIssue; import org.sonar.api.platform.Server; @@ -169,7 +169,7 @@ public class JsonReport implements BatchComponent { writeJsonModuleComponents(json, rootModule); // TODO we need to dump directories for (InputFile inputFile : fileCache.all()) { - String key = ((DefaultInputFile) inputFile).key(); + String key = ((DeprecatedDefaultInputFile) inputFile).key(); json .beginObject() .prop("key", key) diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan2/AnalyzersExecutor.java b/sonar-batch/src/main/java/org/sonar/batch/scan2/AnalyzersExecutor.java new file mode 100644 index 00000000000..c0ae6dbbaab --- /dev/null +++ b/sonar-batch/src/main/java/org/sonar/batch/scan2/AnalyzersExecutor.java @@ -0,0 +1,60 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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.batch.scan2; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.sonar.api.BatchComponent; +import org.sonar.api.platform.ComponentContainer; +import org.sonar.batch.api.analyzer.Analyzer; +import org.sonar.batch.api.analyzer.AnalyzerContext; +import org.sonar.batch.api.analyzer.AnalyzerDescriptor; + +import java.util.Collection; + +public class AnalyzersExecutor implements BatchComponent { + + private static final Logger LOG = LoggerFactory.getLogger(AnalyzersExecutor.class); + + private ComponentContainer container; + + public AnalyzersExecutor(ComponentContainer container) { + this.container = container; + } + + public void execute(AnalyzerContext context) { + Collection<Analyzer> analyzers = container.getComponentsByType(Analyzer.class); + + for (Analyzer analyzer : analyzers) { + + AnalyzerDescriptor descriptor = analyzer.describe(); + + LOG.info("Execute analyzer: " + descriptor.name()); + + executeSensor(context, analyzer); + } + + } + + private void executeSensor(AnalyzerContext context, Analyzer analyzer) { + analyzer.analyse(context); + } + +} diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan2/DefaultAnalyzerContext.java b/sonar-batch/src/main/java/org/sonar/batch/scan2/DefaultAnalyzerContext.java new file mode 100644 index 00000000000..253bf0cab41 --- /dev/null +++ b/sonar-batch/src/main/java/org/sonar/batch/scan2/DefaultAnalyzerContext.java @@ -0,0 +1,104 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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.batch.scan2; + +import org.sonar.api.batch.bootstrap.ProjectDefinition; +import org.sonar.api.batch.fs.InputFile; +import org.sonar.api.issue.internal.DefaultIssue; +import org.sonar.api.rule.RuleKey; +import org.sonar.batch.api.analyzer.AnalyzerContext; +import org.sonar.batch.api.analyzer.issue.AnalyzerIssue; +import org.sonar.batch.api.analyzer.measure.AnalyzerMeasure; +import org.sonar.batch.api.measures.Metric; +import org.sonar.batch.issue.ModuleIssues; +import org.sonar.core.component.ComponentKeys; +import org.sonar.core.issue.DefaultIssueBuilder; + +import java.io.Serializable; +import java.util.Collection; + +public class DefaultAnalyzerContext implements AnalyzerContext { + + private final MeasureCache measureCache; + private ProjectDefinition def; + private ModuleIssues moduleIssues; + + public DefaultAnalyzerContext(ProjectDefinition def, MeasureCache measureCache, ModuleIssues moduleIssues) { + this.def = def; + this.measureCache = measureCache; + this.moduleIssues = moduleIssues; + } + + @Override + public AnalyzerMeasure getMeasure(String metricKey) { + return measureCache.byMetric(def.getKey(), metricKey); + } + + @Override + public <G extends Serializable> AnalyzerMeasure<G> getMeasure(Metric<G> metric) { + return (AnalyzerMeasure<G>) measureCache.byMetric(def.getKey(), metric.key()); + } + + @Override + public AnalyzerMeasure getMeasure(InputFile file, String metricKey) { + return measureCache.byMetric(ComponentKeys.createEffectiveKey(def.getKey(), file), metricKey); + } + + @Override + public <G extends Serializable> AnalyzerMeasure<G> getMeasure(InputFile file, Metric<G> metric) { + return (AnalyzerMeasure<G>) measureCache.byMetric(ComponentKeys.createEffectiveKey(def.getKey(), file), metric.key()); + } + + @Override + public void addMeasure(org.sonar.batch.api.analyzer.measure.AnalyzerMeasure<?> measure) { + if (measure.inputFile() != null) { + measureCache.put(ComponentKeys.createEffectiveKey(def.getKey(), measure.inputFile()), measure); + } else { + measureCache.put(def.getKey(), measure); + } + } + + @Override + public void addIssue(AnalyzerIssue issue) { + DefaultIssueBuilder builder = new DefaultIssueBuilder() + .projectKey(def.getKey()); + if (issue.inputFile() != null) { + builder.componentKey(ComponentKeys.createEffectiveKey(def.getKey(), issue.inputFile())); + } else { + builder.componentKey(def.getKey()); + } + + moduleIssues.initAndAddIssue((DefaultIssue) builder + .ruleKey(RuleKey.of(issue.ruleKey().repository(), issue.ruleKey().rule())) + .message(issue.message()) + .line(issue.line()) + .effortToFix(issue.effortToFix()) + .build()); + } + + @Override + public void addIssues(Collection<AnalyzerIssue> issues) { + for (AnalyzerIssue analyzerIssue : issues) { + addIssue(analyzerIssue); + } + + } + +} diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan2/MeasureCache.java b/sonar-batch/src/main/java/org/sonar/batch/scan2/MeasureCache.java new file mode 100644 index 00000000000..96ab8adc9de --- /dev/null +++ b/sonar-batch/src/main/java/org/sonar/batch/scan2/MeasureCache.java @@ -0,0 +1,65 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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.batch.scan2; + +import com.google.common.base.Preconditions; +import org.sonar.api.BatchComponent; +import org.sonar.batch.api.analyzer.measure.AnalyzerMeasure; +import org.sonar.batch.index.Cache; +import org.sonar.batch.index.Cache.Entry; +import org.sonar.batch.index.Caches; + +/** + * Cache of all measures. This cache is shared amongst all project modules. + */ +public class MeasureCache implements BatchComponent { + + private final Cache<AnalyzerMeasure<?>> cache; + + public MeasureCache(Caches caches) { + cache = caches.createCache("measures"); + } + + public Iterable<Entry<AnalyzerMeasure<?>>> entries() { + return cache.entries(); + } + + public AnalyzerMeasure<?> byMetric(String resourceKey, String metricKey) { + return cache.get(resourceKey, metricKey); + } + + public MeasureCache put(String resourceKey, AnalyzerMeasure<?> measure) { + Preconditions.checkNotNull(resourceKey); + Preconditions.checkNotNull(measure.metricKey()); + cache.put(resourceKey, measure.metricKey(), measure); + return this; + } + + public boolean contains(String resourceKey, AnalyzerMeasure<?> measure) { + Preconditions.checkNotNull(resourceKey); + Preconditions.checkNotNull(measure); + return cache.containsKey(resourceKey, measure.metricKey()); + } + + public Iterable<AnalyzerMeasure<?>> all() { + return cache.values(); + } + +} diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan2/ModuleScanContainer.java b/sonar-batch/src/main/java/org/sonar/batch/scan2/ModuleScanContainer.java index 44bcadc309c..24435c0dc55 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/scan2/ModuleScanContainer.java +++ b/sonar-batch/src/main/java/org/sonar/batch/scan2/ModuleScanContainer.java @@ -21,27 +21,17 @@ package org.sonar.batch.scan2; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.sonar.api.BatchComponent; -import org.sonar.api.batch.InstantiationStrategy; import org.sonar.api.batch.bootstrap.ProjectDefinition; import org.sonar.api.batch.rule.CheckFactory; import org.sonar.api.platform.ComponentContainer; -import org.sonar.api.resources.Project; import org.sonar.api.scan.filesystem.FileExclusions; -import org.sonar.batch.DefaultProjectClasspath; -import org.sonar.batch.DefaultSensorContext; -import org.sonar.batch.DefaultTimeMachine; -import org.sonar.batch.ProjectTree; -import org.sonar.batch.ResourceFilters; -import org.sonar.batch.ViolationFilters; +import org.sonar.batch.api.BatchComponent; +import org.sonar.batch.api.InstantiationStrategy; import org.sonar.batch.bootstrap.BatchExtensionDictionnary; import org.sonar.batch.bootstrap.ExtensionInstaller; import org.sonar.batch.bootstrap.ExtensionMatcher; import org.sonar.batch.bootstrap.ExtensionUtils; -import org.sonar.batch.components.TimeMachineConfiguration; import org.sonar.batch.events.EventBus; -import org.sonar.batch.index.DefaultIndex; -import org.sonar.batch.index.ResourcePersister; import org.sonar.batch.issue.IssuableFactory; import org.sonar.batch.issue.IssueFilters; import org.sonar.batch.issue.ModuleIssues; @@ -51,23 +41,10 @@ import org.sonar.batch.issue.ignore.pattern.IssueExclusionPatternInitializer; import org.sonar.batch.issue.ignore.pattern.IssueInclusionPatternInitializer; import org.sonar.batch.issue.ignore.scanner.IssueExclusionsLoader; import org.sonar.batch.issue.ignore.scanner.IssueExclusionsRegexpScanner; -import org.sonar.batch.language.LanguageDistributionDecorator; -import org.sonar.batch.phases.Phase2Executor; -import org.sonar.batch.phases.PhaseExecutor; -import org.sonar.batch.phases.PhasesTimeProfiler; -import org.sonar.batch.qualitygate.GenerateQualityGateEvents; -import org.sonar.batch.qualitygate.QualityGateProvider; -import org.sonar.batch.qualitygate.QualityGateVerifier; -import org.sonar.batch.rule.ActiveRulesProvider; import org.sonar.batch.rule.ModuleQProfiles; -import org.sonar.batch.rule.QProfileDecorator; -import org.sonar.batch.rule.QProfileEventsDecorator; -import org.sonar.batch.rule.QProfileSensor; import org.sonar.batch.rule.QProfileVerifier; -import org.sonar.batch.rule.RulesProfileProvider; import org.sonar.batch.scan.LanguageVerifier; import org.sonar.batch.scan.ModuleSettings; -import org.sonar.batch.scan.filesystem.ComponentIndexer; import org.sonar.batch.scan.filesystem.DefaultModuleFileSystem; import org.sonar.batch.scan.filesystem.DeprecatedFileFilters; import org.sonar.batch.scan.filesystem.ExclusionFilters; @@ -77,46 +54,34 @@ import org.sonar.batch.scan.filesystem.InputFileBuilderFactory; import org.sonar.batch.scan.filesystem.LanguageDetectionFactory; import org.sonar.batch.scan.filesystem.ModuleFileSystemInitializer; import org.sonar.batch.scan.filesystem.ModuleInputFileCache; -import org.sonar.batch.scan.filesystem.PreviousFileHashLoader; -import org.sonar.batch.scan.filesystem.ProjectFileSystemAdapter; import org.sonar.batch.scan.filesystem.StatusDetectionFactory; -import org.sonar.batch.scan.report.JsonReport; -import org.sonar.core.component.ScanPerspectives; -import org.sonar.core.measure.MeasurementFilters; public class ModuleScanContainer extends ComponentContainer { private static final Logger LOG = LoggerFactory.getLogger(ModuleScanContainer.class); - private final Project module; + private final ProjectDefinition moduleDefinition; - public ModuleScanContainer(ProjectScanContainer parent, Project module) { + public ModuleScanContainer(ProjectScanContainer parent, ProjectDefinition moduleDefinition) { super(parent); - this.module = module; + this.moduleDefinition = moduleDefinition; } @Override protected void doBeforeStart() { - LOG.info("------------- Scan {}", module.getName()); + LOG.info("------------- Scan {}", moduleDefinition.getName()); addCoreComponents(); addExtensions(); } private void addCoreComponents() { - ProjectDefinition moduleDefinition = getComponentByType(ProjectTree.class).getProjectDefinition(module); add( moduleDefinition, - module.getConfiguration(), - module, - ModuleSettings.class); + ModuleSettings.class, - // hack to initialize commons-configuration before ExtensionProviders - getComponentByType(ModuleSettings.class); - - add( EventBus.class, Phase2Executor.class, - PhasesTimeProfiler.class, Phase2Executor.getPhaseClasses(), moduleDefinition.getContainerExtensions(), + AnalyzersExecutor.class, // file system ModuleInputFileCache.class, @@ -126,46 +91,21 @@ public class ModuleScanContainer extends ComponentContainer { InputFileBuilderFactory.class, StatusDetectionFactory.class, LanguageDetectionFactory.class, - PreviousFileHashLoader.class, FileIndexer.class, - ComponentIndexer.class, LanguageVerifier.class, FileSystemLogger.class, - DefaultProjectClasspath.class, DefaultModuleFileSystem.class, ModuleFileSystemInitializer.class, - ProjectFileSystemAdapter.class, QProfileVerifier.class, - // the Snapshot component will be removed when asynchronous measures are improved (required for AsynchronousMeasureSensor) - getComponentByType(ResourcePersister.class).getSnapshot(module), - - TimeMachineConfiguration.class, - DefaultSensorContext.class, + DefaultAnalyzerContext.class, BatchExtensionDictionnary.class, - DefaultTimeMachine.class, - ViolationFilters.class, IssueFilters.class, - MeasurementFilters.class, - ResourceFilters.class, - - // quality gates - new QualityGateProvider(), - QualityGateVerifier.class, - GenerateQualityGateEvents.class, // rules ModuleQProfiles.class, - new ActiveRulesProvider(), - new RulesProfileProvider(), - QProfileSensor.class, - QProfileDecorator.class, - QProfileEventsDecorator.class, CheckFactory.class, - // report - JsonReport.class, - // issues IssuableFactory.class, ModuleIssues.class, @@ -176,36 +116,22 @@ public class ModuleScanContainer extends ComponentContainer { IssueExclusionsRegexpScanner.class, IssueExclusionsLoader.class, EnforceIssuesFilter.class, - IgnoreIssuesFilter.class, - - // language - LanguageDistributionDecorator.class, - - ScanPerspectives.class); + IgnoreIssuesFilter.class); } private void addExtensions() { ExtensionInstaller installer = getComponentByType(ExtensionInstaller.class); installer.install(this, new ExtensionMatcher() { public boolean accept(Object extension) { - if (ExtensionUtils.isType(extension, BatchComponent.class) && ExtensionUtils.isInstantiationStrategy(extension, InstantiationStrategy.PER_PROJECT)) { - // Special use-case: the extension point ProjectBuilder is used in a Maven environment to define some - // new sub-projects without pom. - // Example : C# plugin adds sub-projects at runtime, even if they are not defined in root pom. - return !ExtensionUtils.isMavenExtensionOnly(extension) || module.getPom() != null; - } - return false; + return ExtensionUtils.isType(extension, BatchComponent.class) + && ExtensionUtils.isInstantiationStrategy(extension, InstantiationStrategy.PER_PROJECT); } }); } @Override protected void doAfterStart() { - DefaultIndex index = getComponentByType(DefaultIndex.class); - index.setCurrentProject(module, - getComponentByType(ModuleIssues.class)); - - getComponentByType(PhaseExecutor.class).execute(module); + getComponentByType(Phase2Executor.class).execute(moduleDefinition); } } diff --git a/sonar-batch/src/main/java/org/sonar/batch/phases/Phase2Executor.java b/sonar-batch/src/main/java/org/sonar/batch/scan2/Phase2Executor.java index 87d1348ae3b..fcbec9bf4b4 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/phases/Phase2Executor.java +++ b/sonar-batch/src/main/java/org/sonar/batch/scan2/Phase2Executor.java @@ -17,19 +17,18 @@ * 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.batch.phases; +package org.sonar.batch.scan2; import com.google.common.collect.Lists; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.sonar.api.batch.SensorContext; -import org.sonar.api.resources.Project; -import org.sonar.batch.events.EventBus; +import org.sonar.api.batch.bootstrap.ProjectDefinition; +import org.sonar.batch.api.analyzer.AnalyzerContext; import org.sonar.batch.issue.ignore.scanner.IssueExclusionsLoader; +import org.sonar.batch.phases.SensorsExecutor; import org.sonar.batch.rule.QProfileVerifier; import org.sonar.batch.scan.filesystem.DefaultModuleFileSystem; import org.sonar.batch.scan.filesystem.FileSystemLogger; -import org.sonar.batch.scan.maven.MavenPluginsConfigurator; import java.util.Collection; @@ -37,32 +36,19 @@ public final class Phase2Executor { public static final Logger LOGGER = LoggerFactory.getLogger(Phase2Executor.class); - private final EventBus eventBus; - private final Phases phases; - private final MavenPluginsConfigurator mavenPluginsConfigurator; - private final InitializersExecutor initializersExecutor; - private final SensorsExecutor sensorsExecutor; - private final SensorContext sensorContext; - private final ProjectInitializer pi; + private final AnalyzersExecutor analyzersExecutor; + private final AnalyzerContext analyzerContext; private final FileSystemLogger fsLogger; private final DefaultModuleFileSystem fs; private final QProfileVerifier profileVerifier; private final IssueExclusionsLoader issueExclusionsLoader; - public Phase2Executor(Phases phases, - MavenPluginsConfigurator mavenPluginsConfigurator, InitializersExecutor initializersExecutor, - SensorsExecutor sensorsExecutor, - SensorContext sensorContext, - EventBus eventBus, ProjectInitializer pi, + public Phase2Executor(AnalyzersExecutor analyzersExecutor, + AnalyzerContext analyzerContext, FileSystemLogger fsLogger, DefaultModuleFileSystem fs, QProfileVerifier profileVerifier, IssueExclusionsLoader issueExclusionsLoader) { - this.phases = phases; - this.mavenPluginsConfigurator = mavenPluginsConfigurator; - this.initializersExecutor = initializersExecutor; - this.sensorsExecutor = sensorsExecutor; - this.sensorContext = sensorContext; - this.eventBus = eventBus; - this.pi = pi; + this.analyzersExecutor = analyzersExecutor; + this.analyzerContext = analyzerContext; this.fsLogger = fsLogger; this.fs = fs; this.profileVerifier = profileVerifier; @@ -70,20 +56,14 @@ public final class Phase2Executor { } public static Collection<Class> getPhaseClasses() { - return Lists.<Class>newArrayList(SensorsExecutor.class, InitializersExecutor.class, ProjectInitializer.class); + return Lists.<Class>newArrayList(SensorsExecutor.class); } /** * Executed on each module */ - public void execute(Project module) { - pi.execute(module); - - eventBus.fireEvent(new ProjectAnalysisEvent(module, true)); - - executeMavenPhase(module); - - executeInitializersPhase(); + public void execute(ProjectDefinition moduleDefinition) { + fsLogger.log(); // Index and lock the filesystem fs.index(); @@ -94,23 +74,6 @@ public final class Phase2Executor { // Initialize issue exclusions issueExclusionsLoader.execute(); - sensorsExecutor.execute(sensorContext); - - eventBus.fireEvent(new ProjectAnalysisEvent(module, false)); - } - - private void executeInitializersPhase() { - if (phases.isEnabled(Phases.Phase.INIT)) { - initializersExecutor.execute(); - fsLogger.log(); - } - } - - private void executeMavenPhase(Project module) { - if (phases.isEnabled(Phases.Phase.MAVEN)) { - eventBus.fireEvent(new MavenPhaseEvent(true)); - mavenPluginsConfigurator.execute(module); - eventBus.fireEvent(new MavenPhaseEvent(false)); - } + analyzersExecutor.execute(analyzerContext); } } diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan2/ProjectScanContainer.java b/sonar-batch/src/main/java/org/sonar/batch/scan2/ProjectScanContainer.java index 3ca92f4bc5b..6a3d9bfcfac 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/scan2/ProjectScanContainer.java +++ b/sonar-batch/src/main/java/org/sonar/batch/scan2/ProjectScanContainer.java @@ -20,41 +20,25 @@ package org.sonar.batch.scan2; import com.google.common.annotations.VisibleForTesting; -import org.sonar.api.BatchComponent; import org.sonar.api.CoreProperties; -import org.sonar.api.batch.InstantiationStrategy; import org.sonar.api.batch.bootstrap.ProjectBootstrapper; +import org.sonar.api.batch.bootstrap.ProjectDefinition; import org.sonar.api.batch.bootstrap.ProjectReactor; import org.sonar.api.config.Settings; import org.sonar.api.platform.ComponentContainer; -import org.sonar.api.resources.Languages; -import org.sonar.api.resources.Project; import org.sonar.api.scan.filesystem.PathResolver; import org.sonar.api.utils.SonarException; -import org.sonar.batch.DefaultFileLinesContextFactory; -import org.sonar.batch.ProjectConfigurator; -import org.sonar.batch.ProjectTree; +import org.sonar.batch.api.BatchComponent; +import org.sonar.batch.api.InstantiationStrategy; import org.sonar.batch.bootstrap.ExtensionInstaller; import org.sonar.batch.bootstrap.ExtensionMatcher; import org.sonar.batch.bootstrap.ExtensionUtils; -import org.sonar.batch.bootstrap.MetricProvider; -import org.sonar.batch.components.PeriodsDefinition; -import org.sonar.batch.debt.DebtModelProvider; import org.sonar.batch.debt.IssueChangelogDebtCalculator; import org.sonar.batch.index.Caches; import org.sonar.batch.index.ComponentDataCache; import org.sonar.batch.index.ComponentDataPersister; -import org.sonar.batch.index.DefaultIndex; -import org.sonar.batch.index.DefaultPersistenceManager; -import org.sonar.batch.index.DefaultResourcePersister; -import org.sonar.batch.index.DependencyPersister; -import org.sonar.batch.index.EventPersister; -import org.sonar.batch.index.LinkPersister; -import org.sonar.batch.index.MeasurePersister; import org.sonar.batch.index.ResourceCache; -import org.sonar.batch.index.ResourceKeyMigration; import org.sonar.batch.index.SnapshotCache; -import org.sonar.batch.index.SourcePersister; import org.sonar.batch.issue.DefaultProjectIssues; import org.sonar.batch.issue.DeprecatedViolations; import org.sonar.batch.issue.IssueCache; @@ -62,13 +46,10 @@ import org.sonar.batch.issue.IssuePersister; import org.sonar.batch.issue.ScanIssueStorage; import org.sonar.batch.phases.GraphPersister; import org.sonar.batch.profiling.PhasesSumUpTimeProfiler; -import org.sonar.batch.rule.RulesProvider; import org.sonar.batch.scan.ProjectReactorBuilder; -import org.sonar.batch.scan.ProjectSettingsReady; import org.sonar.batch.scan.filesystem.InputFileCache; import org.sonar.batch.scan.maven.FakeMavenPluginExecutor; import org.sonar.batch.scan.maven.MavenPluginExecutor; -import org.sonar.batch.scan.measure.MeasureCache; import org.sonar.batch.source.HighlightableBuilder; import org.sonar.batch.source.SymbolizableBuilder; import org.sonar.core.component.ScanGraph; @@ -76,13 +57,10 @@ import org.sonar.core.issue.IssueNotifications; import org.sonar.core.issue.IssueUpdater; import org.sonar.core.issue.workflow.FunctionExecutor; import org.sonar.core.issue.workflow.IssueWorkflow; -import org.sonar.core.notification.DefaultNotificationManager; -import org.sonar.core.technicaldebt.DefaultTechnicalDebtModel; import org.sonar.core.test.TestPlanBuilder; import org.sonar.core.test.TestPlanPerspectiveLoader; import org.sonar.core.test.TestableBuilder; import org.sonar.core.test.TestablePerspectiveLoader; -import org.sonar.core.user.DefaultUserFinder; public class ProjectScanContainer extends ComponentContainer { public ProjectScanContainer(ComponentContainer taskContainer) { @@ -102,50 +80,32 @@ public class ProjectScanContainer extends ComponentContainer { } private void projectBootstrap() { - // Old versions of bootstrappers used to pass project reactor as an extension - // so check if it is already present in parent container - ProjectReactor reactor = getComponentByType(ProjectReactor.class); + ProjectReactor reactor; + ProjectBootstrapper bootstrapper = getComponentByType(ProjectBootstrapper.class); + Settings settings = getComponentByType(Settings.class); + if (bootstrapper == null + // Starting from Maven plugin 2.3 then only DefaultProjectBootstrapper should be used. + || "true".equals(settings.getString("sonar.mojoUseRunner"))) { + // Use default SonarRunner project bootstrapper + ProjectReactorBuilder builder = getComponentByType(ProjectReactorBuilder.class); + reactor = builder.execute(); + } else { + reactor = bootstrapper.bootstrap(); + } if (reactor == null) { - // OK, not present, so look for a custom ProjectBootstrapper - ProjectBootstrapper bootstrapper = getComponentByType(ProjectBootstrapper.class); - Settings settings = getComponentByType(Settings.class); - if (bootstrapper == null - // Starting from Maven plugin 2.3 then only DefaultProjectBootstrapper should be used. - || "true".equals(settings.getString("sonar.mojoUseRunner"))) { - // Use default SonarRunner project bootstrapper - ProjectReactorBuilder builder = getComponentByType(ProjectReactorBuilder.class); - reactor = builder.execute(); - } else { - reactor = bootstrapper.bootstrap(); - } - if (reactor == null) { - throw new SonarException(bootstrapper + " has returned null as ProjectReactor"); - } - add(reactor); + throw new SonarException(bootstrapper + " has returned null as ProjectReactor"); } + add(reactor); } private void addBatchComponents() { add( - DefaultPersistenceManager.class, - DependencyPersister.class, - EventPersister.class, - LinkPersister.class, - MeasurePersister.class, - DefaultResourcePersister.class, - SourcePersister.class, - DefaultNotificationManager.class, - MetricProvider.class, - ProjectConfigurator.class, - DefaultIndex.class, - ResourceKeyMigration.class, - DefaultFileLinesContextFactory.class, Caches.class, SnapshotCache.class, ResourceCache.class, ComponentDataCache.class, ComponentDataPersister.class, - DefaultUserFinder.class, + MeasureCache.class, // file system InputFileCache.class, @@ -172,24 +132,10 @@ public class ProjectScanContainer extends ComponentContainer { GraphPersister.class, // lang - Languages.class, HighlightableBuilder.class, SymbolizableBuilder.class, - // technical debt - DefaultTechnicalDebtModel.class, - new DebtModelProvider(), - - // rules - new RulesProvider(), - - // Differential periods - PeriodsDefinition.class, - - // Measures - MeasureCache.class, - - ProjectSettingsReady.class); + ScanTaskObservers.class); } private void fixMavenExecutor() { @@ -204,19 +150,20 @@ public class ProjectScanContainer extends ComponentContainer { @Override protected void doAfterStart() { - ProjectTree tree = getComponentByType(ProjectTree.class); - scanRecursively(tree.getRootProject()); + ProjectReactor tree = getComponentByType(ProjectReactor.class); + scanRecursively(tree.getRoot()); + getComponentByType(ScanTaskObservers.class).notifyEndOfScanTask(); } - private void scanRecursively(Project module) { - for (Project subModules : module.getModules()) { + private void scanRecursively(ProjectDefinition module) { + for (ProjectDefinition subModules : module.getSubProjects()) { scanRecursively(subModules); } scan(module); } @VisibleForTesting - void scan(Project module) { + void scan(ProjectDefinition module) { new ModuleScanContainer(this, module).execute(); } diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan2/ScanTaskObserver.java b/sonar-batch/src/main/java/org/sonar/batch/scan2/ScanTaskObserver.java new file mode 100644 index 00000000000..89f5c7694cc --- /dev/null +++ b/sonar-batch/src/main/java/org/sonar/batch/scan2/ScanTaskObserver.java @@ -0,0 +1,28 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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.batch.scan2; + +import org.sonar.batch.api.BatchExtension; + +public interface ScanTaskObserver extends BatchExtension { + + void scanTaskCompleted(ProjectScanContainer container); + +} diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan2/ScanTaskObservers.java b/sonar-batch/src/main/java/org/sonar/batch/scan2/ScanTaskObservers.java new file mode 100644 index 00000000000..6dc8fa6fd40 --- /dev/null +++ b/sonar-batch/src/main/java/org/sonar/batch/scan2/ScanTaskObservers.java @@ -0,0 +1,42 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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.batch.scan2; + +public class ScanTaskObservers { + + private ScanTaskObserver[] observers; + private ProjectScanContainer projectScanContainer; + + public ScanTaskObservers(ProjectScanContainer projectScanContainer, ScanTaskObserver... observers) { + this.projectScanContainer = projectScanContainer; + this.observers = observers; + } + + public ScanTaskObservers(ProjectScanContainer projectScanContainer) { + this(projectScanContainer, new ScanTaskObserver[0]); + } + + public void notifyEndOfScanTask() { + for (ScanTaskObserver scanTaskObserver : observers) { + scanTaskObserver.scanTaskCompleted(projectScanContainer); + } + } + +} diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan2/package-info.java b/sonar-batch/src/main/java/org/sonar/batch/scan2/package-info.java new file mode 100644 index 00000000000..d5d167bf737 --- /dev/null +++ b/sonar-batch/src/main/java/org/sonar/batch/scan2/package-info.java @@ -0,0 +1,21 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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. + */ +@javax.annotation.ParametersAreNonnullByDefault +package org.sonar.batch.scan2;
\ No newline at end of file diff --git a/sonar-batch/src/main/java/org/sonar/batch/settings/package-info.java b/sonar-batch/src/main/java/org/sonar/batch/settings/package-info.java new file mode 100644 index 00000000000..6d2df16d3ab --- /dev/null +++ b/sonar-batch/src/main/java/org/sonar/batch/settings/package-info.java @@ -0,0 +1,21 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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. + */ +@javax.annotation.ParametersAreNonnullByDefault +package org.sonar.batch.settings;
\ No newline at end of file diff --git a/sonar-batch/src/test/java/org/sonar/batch/bootstrap/BatchExtensionDictionnaryTest.java b/sonar-batch/src/test/java/org/sonar/batch/bootstrap/BatchExtensionDictionnaryTest.java index 79af9782d6d..d7f5df2e761 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/bootstrap/BatchExtensionDictionnaryTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/bootstrap/BatchExtensionDictionnaryTest.java @@ -23,14 +23,17 @@ import org.junit.Test; import org.sonar.api.BatchExtension; import org.sonar.api.batch.Sensor; import org.sonar.api.batch.SensorContext; +import org.sonar.api.batch.fs.FileSystem; import org.sonar.api.platform.ComponentContainer; import org.sonar.api.resources.Project; +import org.sonar.batch.api.analyzer.AnalyzerContext; import java.util.Collection; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertThat; import static org.junit.internal.matchers.IsCollectionContaining.hasItem; +import static org.mockito.Mockito.mock; public class BatchExtensionDictionnaryTest { @@ -39,7 +42,7 @@ public class BatchExtensionDictionnaryTest { for (BatchExtension extension : extensions) { iocContainer.addSingleton(extension); } - return new BatchExtensionDictionnary(iocContainer); + return new BatchExtensionDictionnary(iocContainer, mock(FileSystem.class), mock(AnalyzerContext.class)); } @Test diff --git a/sonar-batch/src/test/java/org/sonar/batch/bootstrap/MetricProviderTest.java b/sonar-batch/src/test/java/org/sonar/batch/bootstrap/MetricProviderTest.java index 37b6736a89e..1af98413155 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/bootstrap/MetricProviderTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/bootstrap/MetricProviderTest.java @@ -41,12 +41,12 @@ public class MetricProviderTest { @Test public void should_provide_plugin_metrics() { - Metrics factory = new Metrics(){ + Metrics factory = new Metrics() { public List<Metric> getMetrics() { - return Arrays.asList(new Metric.Builder("custom", "Custom", Metric.ValueType.FLOAT).create()); + return Arrays.<Metric>asList(new Metric.Builder("custom", "Custom", Metric.ValueType.FLOAT).create()); } }; - MetricProvider provider = new MetricProvider(new Metrics[]{factory}); + MetricProvider provider = new MetricProvider(new Metrics[] {factory}); List<Metric> metrics = provider.provide(); assertThat(metrics.size()).isEqualTo(1 + CoreMetrics.getMetrics().size()); diff --git a/sonar-batch/src/test/java/org/sonar/batch/index/ResourceKeyMigrationTest.java b/sonar-batch/src/test/java/org/sonar/batch/index/ResourceKeyMigrationTest.java index 564a6845a04..1fe27bc91b1 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/index/ResourceKeyMigrationTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/index/ResourceKeyMigrationTest.java @@ -28,6 +28,7 @@ import org.junit.rules.TemporaryFolder; import org.slf4j.Logger; import org.sonar.api.batch.fs.InputFile; import org.sonar.api.batch.fs.internal.DefaultInputFile; +import org.sonar.api.batch.fs.internal.DeprecatedDefaultInputFile; import org.sonar.api.resources.Project; import org.sonar.jpa.test.AbstractDbUnitTestCase; @@ -86,9 +87,10 @@ public class ResourceKeyMigrationTest extends AbstractDbUnitTestCase { File file = new File(baseDir, path); String effectiveKey = module.getKey() + ":" + path; String deprecatedEffectiveKey = module.getKey() + ":" + deprecatedKey; - return new DefaultInputFile(path).setFile(file) - .setKey(effectiveKey) + return new DeprecatedDefaultInputFile(path) .setDeprecatedKey(deprecatedEffectiveKey) + .setFile(file) + .setKey(effectiveKey) .setType(isTest ? InputFile.Type.TEST : InputFile.Type.MAIN); } @@ -99,7 +101,7 @@ public class ResourceKeyMigrationTest extends AbstractDbUnitTestCase { Logger logger = mock(Logger.class); ResourceKeyMigration migration = new ResourceKeyMigration(getSession(), logger); migration.checkIfMigrationNeeded(multiModuleProject); - + migration.migrateIfNeeded(javaModule, javaInputFiles); migration.migrateIfNeeded(phpModule, phpInputFiles); @@ -110,7 +112,7 @@ public class ResourceKeyMigrationTest extends AbstractDbUnitTestCase { verify(logger).info("Component {} changed to {}", "b:org/foo", "b:src/main/java/org/foo"); verify(logger).info("Component {} changed to {}", "b:[root]", "b:src/main/java"); - checkTables("shouldMigrateResourceKeys", new String[]{"build_date", "created_at"}, "projects"); + checkTables("shouldMigrateResourceKeys", new String[] {"build_date", "created_at"}, "projects"); } private static Project newProject(String key, String language) { diff --git a/sonar-batch/src/test/java/org/sonar/batch/issue/ignore/scanner/IssueExclusionsLoaderTest.java b/sonar-batch/src/test/java/org/sonar/batch/issue/ignore/scanner/IssueExclusionsLoaderTest.java index 065601b9a91..5b97df2c7f5 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/issue/ignore/scanner/IssueExclusionsLoaderTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/issue/ignore/scanner/IssueExclusionsLoaderTest.java @@ -29,7 +29,7 @@ import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.sonar.api.batch.fs.InputFile; import org.sonar.api.batch.fs.internal.DefaultFileSystem; -import org.sonar.api.batch.fs.internal.DefaultInputFile; +import org.sonar.api.batch.fs.internal.DeprecatedDefaultInputFile; import org.sonar.api.utils.SonarException; import org.sonar.batch.issue.ignore.pattern.IssueExclusionPatternInitializer; import org.sonar.batch.issue.ignore.pattern.IssueInclusionPatternInitializer; @@ -101,12 +101,12 @@ public class IssueExclusionsLoaderTest { @Test public void shouldAnalyzeProject() throws IOException { File javaFile1 = new File(baseDir, "src/main/java/Foo.java"); - fs.add(new DefaultInputFile("src/main/java/Foo.java") + fs.add(new DeprecatedDefaultInputFile("src/main/java/Foo.java") .setFile(javaFile1) .setType(InputFile.Type.MAIN) .setKey("polop:src/main/java/Foo.java")); File javaTestFile1 = new File(baseDir, "src/test/java/FooTest.java"); - fs.add(new DefaultInputFile("src/test/java/FooTest.java") + fs.add(new DeprecatedDefaultInputFile("src/test/java/FooTest.java") .setFile(javaTestFile1) .setType(InputFile.Type.TEST) .setKey("polop:src/test/java/FooTest.java")); @@ -126,12 +126,12 @@ public class IssueExclusionsLoaderTest { @Test public void shouldAnalyseFilesOnlyWhenRegexConfigured() throws IOException { File javaFile1 = new File(baseDir, "src/main/java/Foo.java"); - fs.add(new DefaultInputFile("src/main/java/Foo.java") + fs.add(new DeprecatedDefaultInputFile("src/main/java/Foo.java") .setFile(javaFile1) .setType(InputFile.Type.MAIN) .setKey("polop:src/main/java/Foo.java")); File javaTestFile1 = new File(baseDir, "src/test/java/FooTest.java"); - fs.add(new DefaultInputFile("src/test/java/FooTest.java") + fs.add(new DeprecatedDefaultInputFile("src/test/java/FooTest.java") .setFile(javaTestFile1) .setType(InputFile.Type.TEST) .setKey("polop:src/test/java/FooTest.java")); @@ -149,7 +149,7 @@ public class IssueExclusionsLoaderTest { @Test public void shouldReportFailure() throws IOException { File phpFile1 = new File(baseDir, "src/Foo.php"); - fs.add(new DefaultInputFile("src/Foo.php") + fs.add(new DeprecatedDefaultInputFile("src/Foo.php") .setFile(phpFile1) .setType(InputFile.Type.MAIN) .setKey("polop:src/Foo.php")); diff --git a/sonar-batch/src/test/java/org/sonar/batch/medium/Scan2MediumTest.java b/sonar-batch/src/test/java/org/sonar/batch/medium/Scan2MediumTest.java deleted file mode 100644 index ae4a9ec02bb..00000000000 --- a/sonar-batch/src/test/java/org/sonar/batch/medium/Scan2MediumTest.java +++ /dev/null @@ -1,168 +0,0 @@ -/* - * SonarQube, open source software quality management tool. - * Copyright (C) 2008-2014 SonarSource - * mailto:contact AT sonarsource DOT com - * - * SonarQube 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. - * - * SonarQube 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.batch.medium; - -import com.google.common.collect.BiMap; -import com.google.common.collect.HashBiMap; -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.Lists; -import com.google.common.collect.Maps; -import org.junit.Test; -import org.sonar.api.measures.Metric; -import org.sonar.api.measures.MetricFinder; -import org.sonar.api.rule.RuleKey; -import org.sonar.api.rules.Rule; -import org.sonar.api.rules.RuleFinder; -import org.sonar.api.rules.RuleQuery; -import org.sonar.batch.bootstrap.PluginsReferential; -import org.sonar.batch.bootstrapper.Batch; -import org.sonar.batch.bootstrapper.EnvironmentInformation; -import org.sonar.batch.settings.SettingsReferential; -import org.sonar.core.plugins.RemotePlugin; - -import java.io.File; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -public class Scan2MediumTest { - - @Test - public void mediumTest() { - Batch batch = Batch.builder() - .setEnableLoggingConfiguration(true) - .addComponent(new EnvironmentInformation("mediumTest", "1.0")) - .addComponent(new MockSettingsReferential()) - .addComponent(new MockPluginsReferential()) - .addComponent(new MockMetricFinder()) - .addComponent(new MockRuleFinder()) - .setBootstrapProperties(ImmutableMap.of("sonar.analysis.mode", "sensor")) - .build(); - - batch.start(); - - // batch.executeTask(ImmutableMap.<String, String>builder().put("sonar.task", "scan").build()); - - batch.stop(); - } - - private static class MockSettingsReferential implements SettingsReferential { - - private Map<String, String> globalSettings = new HashMap<String, String>(); - private Map<String, Map<String, String>> projectSettings = new HashMap<String, Map<String, String>>(); - - @Override - public Map<String, String> globalSettings() { - return globalSettings; - } - - @Override - public Map<String, String> projectSettings(String projectKey) { - return projectSettings.containsKey(projectKey) ? projectSettings.get(projectKey) : Collections.<String, String>emptyMap(); - } - - } - - private static class MockPluginsReferential implements PluginsReferential { - - private List<RemotePlugin> pluginList = new ArrayList<RemotePlugin>(); - private Map<RemotePlugin, File> pluginFiles = new HashMap<RemotePlugin, File>(); - - @Override - public List<RemotePlugin> pluginList() { - return pluginList; - } - - @Override - public File pluginFile(RemotePlugin remote) { - return pluginFiles.get(remote); - } - - } - - private static class MockMetricFinder implements MetricFinder { - - private Map<String, Metric> metricsByKey = Maps.newLinkedHashMap(); - private Map<Integer, Metric> metricsById = Maps.newLinkedHashMap(); - - @Override - public Metric findById(int metricId) { - return metricsById.get(metricId); - } - - @Override - public Metric findByKey(String key) { - return metricsByKey.get(key); - } - - @Override - public Collection<Metric> findAll(List<String> metricKeys) { - List<Metric> result = Lists.newLinkedList(); - for (String metricKey : metricKeys) { - Metric metric = findByKey(metricKey); - if (metric != null) { - result.add(metric); - } - } - return result; - } - - @Override - public Collection<Metric> findAll() { - return metricsByKey.values(); - } - - } - - private static class MockRuleFinder implements RuleFinder { - private BiMap<Integer, Rule> rulesById = HashBiMap.create(); - private Map<String, Map<String, Rule>> rulesByRepoKeyAndRuleKey = Maps.newHashMap(); - - @Override - public Rule findById(int ruleId) { - return rulesById.get(ruleId); - } - - @Override - public Rule findByKey(String repositoryKey, String ruleKey) { - Map<String, Rule> repository = rulesByRepoKeyAndRuleKey.get(repositoryKey); - return repository != null ? repository.get(ruleKey) : null; - } - - @Override - public Rule findByKey(RuleKey key) { - return findByKey(key.repository(), key.rule()); - } - - @Override - public Rule find(RuleQuery query) { - throw new UnsupportedOperationException(); - } - - @Override - public Collection<Rule> findAll(RuleQuery query) { - throw new UnsupportedOperationException(); - } - } - -} diff --git a/sonar-batch/src/test/java/org/sonar/batch/rule/ActiveRulesProviderTest.java b/sonar-batch/src/test/java/org/sonar/batch/rule/ActiveRulesProviderTest.java index c2039e71bf2..205fe2e8a8c 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/rule/ActiveRulesProviderTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/rule/ActiveRulesProviderTest.java @@ -27,9 +27,10 @@ import org.sonar.api.rule.RuleKey; import org.sonar.api.rule.Severity; import org.sonar.api.rules.Rule; import org.sonar.api.rules.RuleFinder; +import org.sonar.batch.api.rules.QProfile; +import org.sonar.batch.rules.QProfileWithId; import org.sonar.core.persistence.AbstractDaoTestCase; import org.sonar.core.qualityprofile.db.ActiveRuleDao; -import org.sonar.core.qualityprofile.db.QualityProfileDao; import java.util.Arrays; @@ -53,13 +54,12 @@ public class ActiveRulesProviderTest extends AbstractDaoTestCase { @Test public void build_active_rules() throws Exception { setupData("shared"); - QualityProfileDao profileDao = new QualityProfileDao(getMyBatis()); - when(qProfiles.findAll()).thenReturn(Arrays.asList( + when(qProfiles.findAll()).thenReturn(Arrays.<QProfile>asList( // 1 rule is enabled on java with severity INFO - new ModuleQProfiles.QProfile(profileDao.selectById(2)), + new QProfileWithId(2, "Java Two", "java", 20), // 1 rule is enabled on php with severity BLOCKER - new ModuleQProfiles.QProfile(profileDao.selectById(3)) - )); + new QProfileWithId(3, "Php One", "php", 30) + )); ActiveRulesProvider provider = new ActiveRulesProvider(); ActiveRuleDao activeRuleDao = new ActiveRuleDao(getMyBatis()); diff --git a/sonar-batch/src/test/java/org/sonar/batch/rule/ModuleQProfilesTest.java b/sonar-batch/src/test/java/org/sonar/batch/rule/ModuleQProfilesTest.java index 99b39d19986..6b3102206f3 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/rule/ModuleQProfilesTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/rule/ModuleQProfilesTest.java @@ -25,6 +25,12 @@ import org.sonar.api.config.Settings; import org.sonar.api.resources.Language; import org.sonar.api.resources.Languages; import org.sonar.api.utils.MessageException; +import org.sonar.batch.api.rules.QProfile; +import org.sonar.batch.languages.DeprecatedLanguagesReferential; +import org.sonar.batch.languages.LanguagesReferential; +import org.sonar.batch.rules.DefaultQProfileReferential; +import org.sonar.batch.rules.QProfilesReferential; +import org.sonar.batch.rules.QProfileWithId; import org.sonar.core.persistence.AbstractDaoTestCase; import org.sonar.core.qualityprofile.db.QualityProfileDao; @@ -35,31 +41,32 @@ import static org.fest.assertions.Fail.fail; public class ModuleQProfilesTest extends AbstractDaoTestCase { - Languages languages = new Languages(new SimpleLanguage("java"), new SimpleLanguage("php")); + LanguagesReferential languages = new DeprecatedLanguagesReferential(new Languages(new SimpleLanguage("java"), new SimpleLanguage("php"))); Settings settings = new Settings(); @Test public void find_profiles() throws Exception { setupData("shared"); QualityProfileDao dao = new QualityProfileDao(getMyBatis()); + QProfilesReferential ref = new DefaultQProfileReferential(dao); settings.setProperty("sonar.profile.java", "Java Two"); settings.setProperty("sonar.profile.abap", "Abap One"); settings.setProperty("sonar.profile.php", "Php One"); - ModuleQProfiles moduleQProfiles = new ModuleQProfiles(settings, languages, dao); - List<ModuleQProfiles.QProfile> qProfiles = Lists.newArrayList(moduleQProfiles.findAll()); + ModuleQProfiles moduleQProfiles = new ModuleQProfiles(settings, languages, ref); + List<QProfile> qProfiles = Lists.newArrayList(moduleQProfiles.findAll()); assertThat(qProfiles).hasSize(2); assertThat(moduleQProfiles.findByLanguage("java")).isNotNull(); assertThat(moduleQProfiles.findByLanguage("php")).isNotNull(); assertThat(moduleQProfiles.findByLanguage("abap")).isNull(); - ModuleQProfiles.QProfile javaProfile = qProfiles.get(0); + QProfileWithId javaProfile = (QProfileWithId) qProfiles.get(0); assertThat(javaProfile.id()).isEqualTo(2); assertThat(javaProfile.name()).isEqualTo("Java Two"); assertThat(javaProfile.language()).isEqualTo("java"); assertThat(javaProfile.version()).isEqualTo(20); - ModuleQProfiles.QProfile phpProfile = qProfiles.get(1); + QProfileWithId phpProfile = (QProfileWithId) qProfiles.get(1); assertThat(phpProfile.id()).isEqualTo(3); assertThat(phpProfile.name()).isEqualTo("Php One"); assertThat(phpProfile.language()).isEqualTo("php"); @@ -71,22 +78,23 @@ public class ModuleQProfilesTest extends AbstractDaoTestCase { public void use_sonar_profile_property() throws Exception { setupData("shared"); QualityProfileDao dao = new QualityProfileDao(getMyBatis()); + QProfilesReferential ref = new DefaultQProfileReferential(dao); settings.setProperty("sonar.profile", "Java Two"); settings.setProperty("sonar.profile.php", "Php One"); - ModuleQProfiles moduleQProfiles = new ModuleQProfiles(settings, languages, dao); - List<ModuleQProfiles.QProfile> qProfiles = Lists.newArrayList(moduleQProfiles.findAll()); + ModuleQProfiles moduleQProfiles = new ModuleQProfiles(settings, languages, ref); + List<QProfile> qProfiles = Lists.newArrayList(moduleQProfiles.findAll()); assertThat(qProfiles).hasSize(2); - ModuleQProfiles.QProfile javaProfile = qProfiles.get(0); + QProfileWithId javaProfile = (QProfileWithId) qProfiles.get(0); assertThat(javaProfile.id()).isEqualTo(2); assertThat(javaProfile.name()).isEqualTo("Java Two"); assertThat(javaProfile.language()).isEqualTo("java"); assertThat(javaProfile.version()).isEqualTo(20); // Fallback to sonar.profile.php if no match for sonar.profile - ModuleQProfiles.QProfile phpProfile = qProfiles.get(1); + QProfileWithId phpProfile = (QProfileWithId) qProfiles.get(1); assertThat(phpProfile.id()).isEqualTo(3); assertThat(phpProfile.name()).isEqualTo("Php One"); assertThat(phpProfile.language()).isEqualTo("php"); @@ -98,12 +106,13 @@ public class ModuleQProfilesTest extends AbstractDaoTestCase { public void fail_if_unknown_profile() throws Exception { setupData("shared"); QualityProfileDao dao = new QualityProfileDao(getMyBatis()); + QProfilesReferential ref = new DefaultQProfileReferential(dao); settings.setProperty("sonar.profile.java", "Unknown"); settings.setProperty("sonar.profile.php", "Php One"); try { - new ModuleQProfiles(settings, languages, dao); + new ModuleQProfiles(settings, languages, ref); fail(); } catch (MessageException e) { assertThat(e).hasMessage("Quality profile not found : 'Unknown' on language 'java'"); diff --git a/sonar-batch/src/test/java/org/sonar/batch/rule/QProfileSensorTest.java b/sonar-batch/src/test/java/org/sonar/batch/rule/QProfileSensorTest.java index a074f7185df..04ba7b1c251 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/rule/QProfileSensorTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/rule/QProfileSensorTest.java @@ -25,6 +25,8 @@ import org.sonar.api.batch.fs.internal.DefaultFileSystem; import org.sonar.api.measures.CoreMetrics; import org.sonar.api.resources.Project; import org.sonar.api.test.IsMeasure; +import org.sonar.batch.api.rules.QProfile; +import org.sonar.batch.rules.QProfileWithId; import org.sonar.core.persistence.AbstractDaoTestCase; import org.sonar.core.qualityprofile.db.QualityProfileDao; @@ -54,7 +56,7 @@ public class QProfileSensorTest extends AbstractDaoTestCase { public void no_qprofiles() throws Exception { setupData("shared"); QualityProfileDao dao = new QualityProfileDao(getMyBatis()); - when(moduleQProfiles.findAll()).thenReturn(Collections.<ModuleQProfiles.QProfile>emptyList()); + when(moduleQProfiles.findAll()).thenReturn(Collections.<QProfile>emptyList()); QProfileSensor sensor = new QProfileSensor(moduleQProfiles, fs, dao); assertThat(sensor.shouldExecuteOnProject(project)).isTrue(); @@ -69,8 +71,8 @@ public class QProfileSensorTest extends AbstractDaoTestCase { setupData("shared"); QualityProfileDao dao = new QualityProfileDao(getMyBatis()); - when(moduleQProfiles.findByLanguage("java")).thenReturn(new ModuleQProfiles.QProfile(dao.selectById(2))); - when(moduleQProfiles.findByLanguage("php")).thenReturn(new ModuleQProfiles.QProfile(dao.selectById(3))); + when(moduleQProfiles.findByLanguage("java")).thenReturn(new QProfileWithId(2, "Java Two", "java", 20)); + when(moduleQProfiles.findByLanguage("php")).thenReturn(new QProfileWithId(3, "Php One", "php", 30)); when(moduleQProfiles.findByLanguage("abap")).thenReturn(null); fs.addLanguages("java", "php", "abap"); @@ -86,8 +88,8 @@ public class QProfileSensorTest extends AbstractDaoTestCase { setupData("shared"); QualityProfileDao dao = new QualityProfileDao(getMyBatis()); - when(moduleQProfiles.findByLanguage("java")).thenReturn(new ModuleQProfiles.QProfile(dao.selectById(2))); - when(moduleQProfiles.findByLanguage("php")).thenReturn(new ModuleQProfiles.QProfile(dao.selectById(3))); + when(moduleQProfiles.findByLanguage("java")).thenReturn(new QProfileWithId(2, "Java Two", "java", 20)); + when(moduleQProfiles.findByLanguage("php")).thenReturn(new QProfileWithId(3, "Php One", "php", 30)); when(moduleQProfiles.findByLanguage("abap")).thenReturn(null); fs.addLanguages("java"); @@ -106,8 +108,8 @@ public class QProfileSensorTest extends AbstractDaoTestCase { setupData("shared"); QualityProfileDao dao = new QualityProfileDao(getMyBatis()); - when(moduleQProfiles.findByLanguage("java")).thenReturn(new ModuleQProfiles.QProfile(dao.selectById(2))); - when(moduleQProfiles.findByLanguage("php")).thenReturn(new ModuleQProfiles.QProfile(dao.selectById(3))); + when(moduleQProfiles.findByLanguage("java")).thenReturn(new QProfileWithId(2, "Java Two", "java", 20)); + when(moduleQProfiles.findByLanguage("php")).thenReturn(new QProfileWithId(3, "Php One", "php", 30)); when(moduleQProfiles.findByLanguage("abap")).thenReturn(null); fs.addLanguages("java", "php"); diff --git a/sonar-batch/src/test/java/org/sonar/batch/rule/QProfileVerifierTest.java b/sonar-batch/src/test/java/org/sonar/batch/rule/QProfileVerifierTest.java index 0fd8c58d040..483b6c7e397 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/rule/QProfileVerifierTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/rule/QProfileVerifierTest.java @@ -28,9 +28,11 @@ import org.sonar.api.batch.fs.internal.DefaultFileSystem; import org.sonar.api.config.Settings; import org.sonar.api.profiles.RulesProfile; import org.sonar.api.utils.MessageException; -import org.sonar.batch.rule.ModuleQProfiles.QProfile; +import org.sonar.batch.rules.QProfileWithId; -import static org.mockito.Mockito.*; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; public class QProfileVerifierTest { @@ -46,11 +48,11 @@ public class QProfileVerifierTest { @Before public void before() { profiles = mock(ModuleQProfiles.class); - QProfile javaProfile = mock(QProfile.class); + QProfileWithId javaProfile = mock(QProfileWithId.class); when(javaProfile.name()).thenReturn("My Java profile"); javaRulesProfile = mock(RulesProfile.class); when(profiles.findByLanguage("java")).thenReturn(javaProfile); - QProfile cobolProfile = mock(QProfile.class); + QProfileWithId cobolProfile = mock(QProfileWithId.class); when(cobolProfile.name()).thenReturn("My Cobol profile"); cobolRulesProfile = mock(RulesProfile.class); when(profiles.findByLanguage("cobol")).thenReturn(cobolProfile); diff --git a/sonar-batch/src/test/java/org/sonar/batch/rule/RulesProfileProviderTest.java b/sonar-batch/src/test/java/org/sonar/batch/rule/RulesProfileProviderTest.java index 3a980631b1c..789f4a35485 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/rule/RulesProfileProviderTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/rule/RulesProfileProviderTest.java @@ -24,6 +24,8 @@ import org.sonar.api.batch.rule.ActiveRules; import org.sonar.api.config.Settings; import org.sonar.api.profiles.RulesProfile; import org.sonar.api.rules.RuleFinder; +import org.sonar.batch.api.rules.QProfile; +import org.sonar.batch.rules.QProfileWithId; import java.util.Arrays; @@ -42,8 +44,8 @@ public class RulesProfileProviderTest { @Test public void merge_profiles() throws Exception { - ModuleQProfiles.QProfile qProfile = new ModuleQProfiles.QProfile(33, "Sonar way", "java", 12); - when(qProfiles.findAll()).thenReturn(Arrays.asList(qProfile)); + QProfileWithId qProfile = new QProfileWithId(33, "Sonar way", "java", 12); + when(qProfiles.findAll()).thenReturn(Arrays.<QProfile>asList(qProfile)); RulesProfile profile = provider.provide(qProfiles, activeRules, ruleFinder, settings); @@ -64,7 +66,7 @@ public class RulesProfileProviderTest { public void keep_compatibility_with_single_language_projects() throws Exception { settings.setProperty("sonar.language", "java"); - ModuleQProfiles.QProfile qProfile = new ModuleQProfiles.QProfile(33, "Sonar way", "java", 12); + QProfileWithId qProfile = new QProfileWithId(33, "Sonar way", "java", 12); when(qProfiles.findByLanguage("java")).thenReturn(qProfile); RulesProfile profile = provider.provide(qProfiles, activeRules, ruleFinder, settings); diff --git a/sonar-batch/src/test/java/org/sonar/batch/rule/UsedQProfilesTest.java b/sonar-batch/src/test/java/org/sonar/batch/rule/UsedQProfilesTest.java index b3cab37a325..1e9d47db0ec 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/rule/UsedQProfilesTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/rule/UsedQProfilesTest.java @@ -20,6 +20,7 @@ package org.sonar.batch.rule; import org.junit.Test; +import org.sonar.batch.rules.QProfileWithId; import static org.fest.assertions.Assertions.assertThat; @@ -28,8 +29,8 @@ public class UsedQProfilesTest { @Test public void serialization() throws Exception { - ModuleQProfiles.QProfile java = new ModuleQProfiles.QProfile(1, "Sonar Way", "java", 1); - ModuleQProfiles.QProfile php = new ModuleQProfiles.QProfile(2, "Sonar Way", "php", 1); + QProfileWithId java = new QProfileWithId(1, "Sonar Way", "java", 1); + QProfileWithId php = new QProfileWithId(2, "Sonar Way", "php", 1); UsedQProfiles used = UsedQProfiles.fromProfiles(java, php); assertThat(used.toJSON()).isEqualTo( diff --git a/sonar-batch/src/test/java/org/sonar/batch/scan/LanguageVerifierTest.java b/sonar-batch/src/test/java/org/sonar/batch/scan/LanguageVerifierTest.java index 8ea87446d82..30b6b571883 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/scan/LanguageVerifierTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/scan/LanguageVerifierTest.java @@ -27,13 +27,15 @@ import org.sonar.api.config.Settings; import org.sonar.api.resources.Java; import org.sonar.api.resources.Languages; import org.sonar.api.utils.MessageException; +import org.sonar.batch.languages.DeprecatedLanguagesReferential; +import org.sonar.batch.languages.LanguagesReferential; import static org.fest.assertions.Assertions.assertThat; public class LanguageVerifierTest { Settings settings = new Settings(); - Languages languages = new Languages(Java.INSTANCE); + LanguagesReferential languages = new DeprecatedLanguagesReferential(new Languages(Java.INSTANCE)); DefaultFileSystem fs = new DefaultFileSystem(); @Rule diff --git a/sonar-batch/src/test/java/org/sonar/batch/scan/filesystem/AdditionalFilePredicatesTest.java b/sonar-batch/src/test/java/org/sonar/batch/scan/filesystem/AdditionalFilePredicatesTest.java index 86121955485..0bb4b243226 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/scan/filesystem/AdditionalFilePredicatesTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/scan/filesystem/AdditionalFilePredicatesTest.java @@ -24,6 +24,7 @@ import org.junit.Test; import org.junit.rules.TemporaryFolder; import org.sonar.api.batch.fs.FilePredicate; import org.sonar.api.batch.fs.internal.DefaultInputFile; +import org.sonar.api.batch.fs.internal.DeprecatedDefaultInputFile; import java.io.File; @@ -38,10 +39,10 @@ public class AdditionalFilePredicatesTest { public void key() throws Exception { FilePredicate predicate = new AdditionalFilePredicates.KeyPredicate("struts:Action.java"); - DefaultInputFile inputFile = new DefaultInputFile("Action.java").setKey("struts:Action.java"); + DefaultInputFile inputFile = new DeprecatedDefaultInputFile("Action.java").setKey("struts:Action.java"); assertThat(predicate.apply(inputFile)).isTrue(); - inputFile = new DefaultInputFile("Filter.java").setKey("struts:Filter.java"); + inputFile = new DeprecatedDefaultInputFile("Filter.java").setKey("struts:Filter.java"); assertThat(predicate.apply(inputFile)).isFalse(); } @@ -49,10 +50,10 @@ public class AdditionalFilePredicatesTest { public void deprecated_key() throws Exception { FilePredicate predicate = new AdditionalFilePredicates.DeprecatedKeyPredicate("struts:Action.java"); - DefaultInputFile inputFile = new DefaultInputFile("Action.java").setDeprecatedKey("struts:Action.java"); + DeprecatedDefaultInputFile inputFile = new DeprecatedDefaultInputFile("Action.java").setDeprecatedKey("struts:Action.java"); assertThat(predicate.apply(inputFile)).isTrue(); - inputFile = new DefaultInputFile("Filter.java").setDeprecatedKey("struts:Filter.java"); + inputFile = new DeprecatedDefaultInputFile("Filter.java").setDeprecatedKey("struts:Filter.java"); assertThat(predicate.apply(inputFile)).isFalse(); } @@ -61,10 +62,10 @@ public class AdditionalFilePredicatesTest { File dir = temp.newFolder(); FilePredicate predicate = new AdditionalFilePredicates.SourceDirPredicate(dir.getAbsolutePath()); - DefaultInputFile inputFile = new DefaultInputFile("Action.java").setSourceDirAbsolutePath(dir.getAbsolutePath()); + DeprecatedDefaultInputFile inputFile = new DeprecatedDefaultInputFile("Action.java").setSourceDirAbsolutePath(dir.getAbsolutePath()); assertThat(predicate.apply(inputFile)).isTrue(); - inputFile = new DefaultInputFile("Filter.java").setSourceDirAbsolutePath(temp.newFolder().getAbsolutePath()); + inputFile = new DeprecatedDefaultInputFile("Filter.java").setSourceDirAbsolutePath(temp.newFolder().getAbsolutePath()); assertThat(predicate.apply(inputFile)).isFalse(); } @@ -72,10 +73,10 @@ public class AdditionalFilePredicatesTest { public void path_relative_to_source_dir() throws Exception { FilePredicate predicate = new AdditionalFilePredicates.SourceRelativePathPredicate("foo/Bar.php"); - DefaultInputFile inputFile = new DefaultInputFile("src/php/foo/Bar.php").setPathRelativeToSourceDir("foo/Bar.php"); + DeprecatedDefaultInputFile inputFile = new DeprecatedDefaultInputFile("src/php/foo/Bar.php").setPathRelativeToSourceDir("foo/Bar.php"); assertThat(predicate.apply(inputFile)).isTrue(); - inputFile = new DefaultInputFile("foo/Bar.php").setPathRelativeToSourceDir("Bar.php"); + inputFile = new DeprecatedDefaultInputFile("foo/Bar.php").setPathRelativeToSourceDir("Bar.php"); assertThat(predicate.apply(inputFile)).isFalse(); } } diff --git a/sonar-batch/src/test/java/org/sonar/batch/scan/filesystem/ComponentIndexerTest.java b/sonar-batch/src/test/java/org/sonar/batch/scan/filesystem/ComponentIndexerTest.java index 4ae7bf09d6c..122b9c618de 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/scan/filesystem/ComponentIndexerTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/scan/filesystem/ComponentIndexerTest.java @@ -33,6 +33,7 @@ import org.sonar.api.batch.SonarIndex; import org.sonar.api.batch.fs.InputFile; import org.sonar.api.batch.fs.internal.DefaultFileSystem; import org.sonar.api.batch.fs.internal.DefaultInputFile; +import org.sonar.api.batch.fs.internal.DeprecatedDefaultInputFile; import org.sonar.api.config.Settings; import org.sonar.api.resources.AbstractLanguage; import org.sonar.api.resources.Java; @@ -160,8 +161,9 @@ public class ComponentIndexerTest { File javaFile1 = new File(baseDir, "src/main/java/foo/bar/Foo.java"); FileUtils.write(javaFile1, "\uFEFFpublic class Test", Charsets.UTF_8); - fs.add(new DefaultInputFile("src/main/java/foo/bar/Foo.java").setFile(javaFile1) + fs.add(new DeprecatedDefaultInputFile("src/main/java/foo/bar/Foo.java") .setPathRelativeToSourceDir("foo/bar/Foo.java") + .setFile(javaFile1) .setLanguage("java")); Languages languages = new Languages(Java.INSTANCE); ComponentIndexer indexer = new ComponentIndexer(project, languages, sonarIndex, settings, mock(ResourceKeyMigration.class)); @@ -184,9 +186,9 @@ public class ComponentIndexerTest { File javaFile1 = new File(baseDir, "src/main/java/foo/bar/Foo.java"); FileUtils.copyFile(getFile(testFile), javaFile1); - fs.add(new DefaultInputFile("src/main/java/foo/bar/Foo.java") - .setFile(javaFile1) + fs.add(new DeprecatedDefaultInputFile("src/main/java/foo/bar/Foo.java") .setPathRelativeToSourceDir("foo/bar/Foo.java") + .setFile(javaFile1) .setLanguage("java")); Languages languages = new Languages(Java.INSTANCE); ComponentIndexer indexer = new ComponentIndexer(project, languages, sonarIndex, settings, mock(ResourceKeyMigration.class)); @@ -210,8 +212,9 @@ public class ComponentIndexerTest { private DefaultInputFile newInputFile(String path, String content, String sourceRelativePath, String languageKey, boolean unitTest) throws IOException { File file = new File(baseDir, path); FileUtils.write(file, content); - return new DefaultInputFile(path).setFile(file) + return new DeprecatedDefaultInputFile(path) .setPathRelativeToSourceDir(sourceRelativePath) + .setFile(file) .setLanguage(languageKey) .setType(unitTest ? InputFile.Type.TEST : InputFile.Type.MAIN); } diff --git a/sonar-batch/src/test/java/org/sonar/batch/scan/filesystem/DefaultModuleFileSystemTest.java b/sonar-batch/src/test/java/org/sonar/batch/scan/filesystem/DefaultModuleFileSystemTest.java index 594a777095d..0de8ac80c56 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/scan/filesystem/DefaultModuleFileSystemTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/scan/filesystem/DefaultModuleFileSystemTest.java @@ -26,8 +26,9 @@ import org.junit.rules.ExpectedException; import org.junit.rules.TemporaryFolder; import org.mockito.Mockito; import org.sonar.api.CoreProperties; +import org.sonar.api.batch.bootstrap.ProjectDefinition; import org.sonar.api.batch.fs.InputFile; -import org.sonar.api.batch.fs.internal.DefaultInputFile; +import org.sonar.api.batch.fs.internal.DeprecatedDefaultInputFile; import org.sonar.api.config.Settings; import org.sonar.api.resources.Project; @@ -58,13 +59,13 @@ public class DefaultModuleFileSystemTest { @Test public void test_equals_and_hashCode() throws Exception { - DefaultModuleFileSystem foo1 = new DefaultModuleFileSystem(moduleInputFileCache, + DefaultModuleFileSystem foo1 = new DefaultModuleFileSystem(moduleInputFileCache, ProjectDefinition.create(), new Project("foo"), settings, fileIndexer, initializer, componentIndexer); - DefaultModuleFileSystem foo2 = new DefaultModuleFileSystem(moduleInputFileCache, + DefaultModuleFileSystem foo2 = new DefaultModuleFileSystem(moduleInputFileCache, ProjectDefinition.create(), new Project("foo"), settings, fileIndexer, initializer, componentIndexer); - DefaultModuleFileSystem bar = new DefaultModuleFileSystem(moduleInputFileCache, + DefaultModuleFileSystem bar = new DefaultModuleFileSystem(moduleInputFileCache, ProjectDefinition.create(), new Project("bar"), settings, fileIndexer, initializer, componentIndexer); - DefaultModuleFileSystem branch = new DefaultModuleFileSystem(moduleInputFileCache, + DefaultModuleFileSystem branch = new DefaultModuleFileSystem(moduleInputFileCache, ProjectDefinition.create(), new Project("bar", "branch", "My project"), settings, fileIndexer, initializer, componentIndexer); assertThat(foo1.moduleKey()).isEqualTo("foo"); @@ -79,7 +80,7 @@ public class DefaultModuleFileSystemTest { @Test public void default_source_encoding() { - DefaultModuleFileSystem fs = new DefaultModuleFileSystem(moduleInputFileCache, + DefaultModuleFileSystem fs = new DefaultModuleFileSystem(moduleInputFileCache, ProjectDefinition.create(), new Project("foo"), settings, fileIndexer, initializer, componentIndexer); assertThat(fs.sourceCharset()).isEqualTo(Charset.defaultCharset()); @@ -89,7 +90,7 @@ public class DefaultModuleFileSystemTest { @Test public void source_encoding_is_set() { settings.setProperty(CoreProperties.ENCODING_PROPERTY, "Cp1124"); - DefaultModuleFileSystem fs = new DefaultModuleFileSystem(moduleInputFileCache, + DefaultModuleFileSystem fs = new DefaultModuleFileSystem(moduleInputFileCache, ProjectDefinition.create(), new Project("foo"), settings, fileIndexer, initializer, componentIndexer); assertThat(fs.encoding()).isEqualTo(Charset.forName("Cp1124")); @@ -115,7 +116,7 @@ public class DefaultModuleFileSystemTest { when(initializer.additionalSourceFiles()).thenReturn(Arrays.asList(additionalFile)); when(initializer.additionalTestFiles()).thenReturn(Arrays.asList(additionalTest)); - DefaultModuleFileSystem fs = new DefaultModuleFileSystem(moduleInputFileCache, + DefaultModuleFileSystem fs = new DefaultModuleFileSystem(moduleInputFileCache, ProjectDefinition.create(), new Project("foo"), settings, fileIndexer, initializer, componentIndexer); assertThat(fs.baseDir().getCanonicalPath()).isEqualTo(basedir.getCanonicalPath()); @@ -135,7 +136,7 @@ public class DefaultModuleFileSystemTest { when(initializer.workingDir()).thenReturn(basedir); when(initializer.sourceDirs()).thenReturn(Arrays.asList(new File(basedir, "src/main/java"))); - DefaultModuleFileSystem fs = new DefaultModuleFileSystem(moduleInputFileCache, + DefaultModuleFileSystem fs = new DefaultModuleFileSystem(moduleInputFileCache, ProjectDefinition.create(), new Project("foo"), settings, fileIndexer, initializer, componentIndexer); File existingDir = temp.newFolder("new_folder"); @@ -156,12 +157,12 @@ public class DefaultModuleFileSystemTest { @Test public void should_search_input_files() throws Exception { - DefaultModuleFileSystem fs = new DefaultModuleFileSystem(moduleInputFileCache, + DefaultModuleFileSystem fs = new DefaultModuleFileSystem(moduleInputFileCache, ProjectDefinition.create(), new Project("foo"), settings, fileIndexer, initializer, componentIndexer); File mainFile = temp.newFile(); - InputFile mainInput = new DefaultInputFile("Main.java").setFile(mainFile).setType(InputFile.Type.MAIN); - InputFile testInput = new DefaultInputFile("Test.java").setFile(temp.newFile()).setType(InputFile.Type.TEST); + InputFile mainInput = new DeprecatedDefaultInputFile("Main.java").setFile(mainFile).setType(InputFile.Type.MAIN); + InputFile testInput = new DeprecatedDefaultInputFile("Test.java").setFile(temp.newFile()).setType(InputFile.Type.TEST); when(moduleInputFileCache.inputFiles()).thenReturn(Lists.newArrayList(mainInput, testInput)); fs.index(); @@ -174,7 +175,7 @@ public class DefaultModuleFileSystemTest { @Test public void should_index() throws Exception { - DefaultModuleFileSystem fs = new DefaultModuleFileSystem(moduleInputFileCache, + DefaultModuleFileSystem fs = new DefaultModuleFileSystem(moduleInputFileCache, ProjectDefinition.create(), new Project("foo"), settings, fileIndexer, initializer, componentIndexer); verifyZeroInteractions(fileIndexer); diff --git a/sonar-batch/src/test/java/org/sonar/batch/scan/filesystem/DeprecatedFileFiltersTest.java b/sonar-batch/src/test/java/org/sonar/batch/scan/filesystem/DeprecatedFileFiltersTest.java index cc909035c1a..02f314e6b71 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/scan/filesystem/DeprecatedFileFiltersTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/scan/filesystem/DeprecatedFileFiltersTest.java @@ -25,7 +25,7 @@ import org.junit.Test; import org.junit.rules.TemporaryFolder; import org.mockito.ArgumentCaptor; import org.sonar.api.batch.fs.InputFile; -import org.sonar.api.batch.fs.internal.DefaultInputFile; +import org.sonar.api.batch.fs.internal.DeprecatedDefaultInputFile; import org.sonar.api.scan.filesystem.FileSystemFilter; import org.sonar.api.scan.filesystem.FileType; @@ -34,7 +34,9 @@ import java.io.File; import static org.fest.assertions.Assertions.assertThat; import static org.mockito.Matchers.any; import static org.mockito.Matchers.eq; -import static org.mockito.Mockito.*; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; public class DeprecatedFileFiltersTest { @@ -47,7 +49,7 @@ public class DeprecatedFileFiltersTest { public void no_filters() throws Exception { DeprecatedFileFilters filters = new DeprecatedFileFilters(); - InputFile inputFile = new DefaultInputFile("src/main/java/Foo.java").setFile(temp.newFile()); + InputFile inputFile = new DeprecatedDefaultInputFile("src/main/java/Foo.java").setFile(temp.newFile()); assertThat(filters.accept(inputFile)).isTrue(); } @@ -57,11 +59,11 @@ public class DeprecatedFileFiltersTest { File basedir = temp.newFolder(); File file = temp.newFile(); - InputFile inputFile = new DefaultInputFile("src/main/java/Foo.java") - .setFile(file) - .setType(InputFile.Type.MAIN) + InputFile inputFile = new DeprecatedDefaultInputFile("src/main/java/Foo.java") .setSourceDirAbsolutePath(new File(basedir, "src/main/java").getAbsolutePath()) - .setPathRelativeToSourceDir("Foo.java"); + .setPathRelativeToSourceDir("Foo.java") + .setFile(file) + .setType(InputFile.Type.MAIN); when(filter.accept(eq(file), any(DeprecatedFileFilters.DeprecatedContext.class))).thenReturn(false); assertThat(filters.accept(inputFile)).isFalse(); diff --git a/sonar-batch/src/test/java/org/sonar/batch/scan/filesystem/ExclusionFiltersTest.java b/sonar-batch/src/test/java/org/sonar/batch/scan/filesystem/ExclusionFiltersTest.java index d84fdce8563..6255bd6629b 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/scan/filesystem/ExclusionFiltersTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/scan/filesystem/ExclusionFiltersTest.java @@ -63,7 +63,6 @@ public class ExclusionFiltersTest { assertThat(filter.accept(inputFile, InputFile.Type.MAIN)).isFalse(); } - @Test public void match_at_least_one_inclusion() throws IOException { Settings settings = new Settings(); diff --git a/sonar-batch/src/test/java/org/sonar/batch/scan/filesystem/InputFileBuilderFactoryTest.java b/sonar-batch/src/test/java/org/sonar/batch/scan/filesystem/InputFileBuilderFactoryTest.java index 268f007e1b9..e38081b62be 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/scan/filesystem/InputFileBuilderFactoryTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/scan/filesystem/InputFileBuilderFactoryTest.java @@ -21,6 +21,7 @@ package org.sonar.batch.scan.filesystem; import org.junit.Test; import org.mockito.Mockito; +import org.sonar.api.batch.bootstrap.ProjectDefinition; import org.sonar.api.resources.Project; import org.sonar.api.scan.filesystem.PathResolver; import org.sonar.batch.bootstrap.AnalysisMode; @@ -39,7 +40,7 @@ public class InputFileBuilderFactoryTest { AnalysisMode analysisMode = mock(AnalysisMode.class); InputFileBuilderFactory factory = new InputFileBuilderFactory( - project, pathResolver, langDetectionFactory, + project, ProjectDefinition.create(), pathResolver, langDetectionFactory, statusDetectionFactory, analysisMode); InputFileBuilder builder = factory.create(fs); diff --git a/sonar-batch/src/test/java/org/sonar/batch/scan/filesystem/InputFileBuilderTest.java b/sonar-batch/src/test/java/org/sonar/batch/scan/filesystem/InputFileBuilderTest.java index 5193101ff38..067f1f99d58 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/scan/filesystem/InputFileBuilderTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/scan/filesystem/InputFileBuilderTest.java @@ -25,7 +25,7 @@ import org.junit.Rule; import org.junit.Test; import org.junit.rules.TemporaryFolder; import org.sonar.api.batch.fs.InputFile; -import org.sonar.api.batch.fs.internal.DefaultInputFile; +import org.sonar.api.batch.fs.internal.DeprecatedDefaultInputFile; import org.sonar.api.scan.filesystem.PathResolver; import org.sonar.api.utils.PathUtils; import org.sonar.batch.bootstrap.AnalysisMode; @@ -67,7 +67,7 @@ public class InputFileBuilderTest { InputFileBuilder builder = new InputFileBuilder("struts", new PathResolver(), langDetection, statusDetection, fs, analysisMode); - DefaultInputFile inputFile = builder.create(srcFile); + DeprecatedDefaultInputFile inputFile = builder.create(srcFile); inputFile = builder.complete(inputFile, InputFile.Type.MAIN); assertThat(inputFile.type()).isEqualTo(InputFile.Type.MAIN); @@ -93,7 +93,7 @@ public class InputFileBuilderTest { InputFileBuilder builder = new InputFileBuilder("struts", new PathResolver(), langDetection, statusDetection, fs, analysisMode); - DefaultInputFile inputFile = builder.create(srcFile); + DeprecatedDefaultInputFile inputFile = builder.create(srcFile); assertThat(inputFile).isNull(); } @@ -113,7 +113,7 @@ public class InputFileBuilderTest { InputFileBuilder builder = new InputFileBuilder("struts", new PathResolver(), langDetection, statusDetection, fs, analysisMode); - DefaultInputFile inputFile = builder.create(srcFile); + DeprecatedDefaultInputFile inputFile = builder.create(srcFile); inputFile = builder.complete(inputFile, InputFile.Type.MAIN); assertThat(inputFile).isNull(); @@ -140,7 +140,7 @@ public class InputFileBuilderTest { InputFileBuilder builder = new InputFileBuilder("struts", new PathResolver(), langDetection, statusDetection, fs, analysisMode); - DefaultInputFile inputFile = builder.create(srcFile); + DeprecatedDefaultInputFile inputFile = builder.create(srcFile); inputFile = builder.complete(inputFile, InputFile.Type.MAIN); assertThat(inputFile.pathRelativeToSourceDir()).isEqualTo("foo/Bar.java"); @@ -169,7 +169,7 @@ public class InputFileBuilderTest { InputFileBuilder builder = new InputFileBuilder("struts", new PathResolver(), langDetection, statusDetection, fs, analysisMode); - DefaultInputFile inputFile = builder.create(srcFile); + DeprecatedDefaultInputFile inputFile = builder.create(srcFile); inputFile = builder.complete(inputFile, InputFile.Type.MAIN); assertThat(inputFile.pathRelativeToSourceDir()).isEqualTo("foo/Bar.php"); diff --git a/sonar-batch/src/test/java/org/sonar/batch/scan/filesystem/InputFileCacheTest.java b/sonar-batch/src/test/java/org/sonar/batch/scan/filesystem/InputFileCacheTest.java index 1dedd839828..3da4eeba2c0 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/scan/filesystem/InputFileCacheTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/scan/filesystem/InputFileCacheTest.java @@ -26,12 +26,11 @@ import org.junit.Test; import org.junit.rules.TemporaryFolder; import org.sonar.api.batch.fs.InputFile; import org.sonar.api.batch.fs.internal.DefaultInputFile; -import org.sonar.api.batch.fs.internal.RelativePathIndex; +import org.sonar.api.batch.fs.internal.DeprecatedDefaultInputFile; import org.sonar.batch.index.Caches; import org.sonar.batch.index.CachesTest; import static org.fest.assertions.Assertions.assertThat; -import static org.fest.assertions.Fail.fail; public class InputFileCacheTest { @@ -56,10 +55,9 @@ public class InputFileCacheTest { InputFileCache cache = new InputFileCache(caches); DefaultInputFile fooFile = new DefaultInputFile("src/main/java/Foo.java").setFile(temp.newFile("Foo.java")); cache.put("struts", fooFile); - cache.put("struts-core", new DefaultInputFile("src/main/java/Bar.java").setFile(temp.newFile("Bar.java"))); + cache.put("struts-core", new DeprecatedDefaultInputFile("src/main/java/Bar.java").setFile(temp.newFile("Bar.java"))); - // index by relative path is automatically fed - assertThat(cache.get("struts", RelativePathIndex.ID, "src/main/java/Foo.java").relativePath()) + assertThat(cache.get("struts", "src/main/java/Foo.java").relativePath()) .isEqualTo("src/main/java/Foo.java"); assertThat(cache.byModule("struts")).hasSize(1); @@ -78,23 +76,4 @@ public class InputFileCacheTest { assertThat(cache.all()).hasSize(1); } - @Test - public void only_relative_path_index_is_supported() throws Exception { - InputFileCache cache = new InputFileCache(caches); - DefaultInputFile input = new DefaultInputFile("src/main/java/Foo.java").setFile(temp.newFile("Foo.java")); - - try { - cache.index("struts", "unsupported-index", "index-value", input); - fail(); - } catch (UnsupportedOperationException e) { - assertThat(e).hasMessage("Only relative path index is supported yet"); - } - - try { - cache.get("struts", "unsupported-index", "index-value"); - fail(); - } catch (UnsupportedOperationException e) { - assertThat(e).hasMessage("Only relative path index is supported yet"); - } - } } diff --git a/sonar-batch/src/test/java/org/sonar/batch/scan/filesystem/LanguageDetectionFactoryTest.java b/sonar-batch/src/test/java/org/sonar/batch/scan/filesystem/LanguageDetectionFactoryTest.java index 35d09f661d6..cda01e16881 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/scan/filesystem/LanguageDetectionFactoryTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/scan/filesystem/LanguageDetectionFactoryTest.java @@ -23,13 +23,15 @@ import org.junit.Test; import org.sonar.api.config.Settings; import org.sonar.api.resources.Java; import org.sonar.api.resources.Languages; +import org.sonar.batch.languages.DeprecatedLanguagesReferential; +import org.sonar.batch.languages.LanguagesReferential; import static org.fest.assertions.Assertions.assertThat; public class LanguageDetectionFactoryTest { @Test public void testCreate() throws Exception { - Languages languages = new Languages(Java.INSTANCE); + LanguagesReferential languages = new DeprecatedLanguagesReferential(new Languages(Java.INSTANCE)); LanguageDetectionFactory factory = new LanguageDetectionFactory(new Settings(), languages); LanguageDetection languageDetection = factory.create(); assertThat(languageDetection).isNotNull(); diff --git a/sonar-batch/src/test/java/org/sonar/batch/scan/filesystem/LanguageDetectionTest.java b/sonar-batch/src/test/java/org/sonar/batch/scan/filesystem/LanguageDetectionTest.java index f1500b541c2..7c6eb7ff4f2 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/scan/filesystem/LanguageDetectionTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/scan/filesystem/LanguageDetectionTest.java @@ -30,6 +30,8 @@ import org.sonar.api.config.Settings; import org.sonar.api.resources.Language; import org.sonar.api.resources.Languages; import org.sonar.api.utils.MessageException; +import org.sonar.batch.languages.DeprecatedLanguagesReferential; +import org.sonar.batch.languages.LanguagesReferential; import java.io.File; import java.io.IOException; @@ -56,7 +58,7 @@ public class LanguageDetectionTest { @Test public void search_by_file_extension() throws Exception { - Languages languages = new Languages(new MockLanguage("java", "java", "jav"), new MockLanguage("cobol", "cbl", "cob")); + LanguagesReferential languages = new DeprecatedLanguagesReferential(new Languages(new MockLanguage("java", "java", "jav"), new MockLanguage("cobol", "cbl", "cob"))); LanguageDetection detection = new LanguageDetection(new Settings(), languages); assertThat(detection.language(newInputFile("Foo.java"))).isEqualTo("java"); @@ -74,13 +76,13 @@ public class LanguageDetectionTest { @Test public void should_not_fail_if_no_language() throws Exception { - LanguageDetection detection = spy(new LanguageDetection(new Settings(), new Languages())); + LanguageDetection detection = spy(new LanguageDetection(new Settings(), new DeprecatedLanguagesReferential(new Languages()))); assertThat(detection.language(newInputFile("Foo.java"))).isNull(); } @Test public void plugin_can_declare_a_file_extension_twice_for_case_sensitivity() throws Exception { - Languages languages = new Languages(new MockLanguage("abap", "abap", "ABAP")); + LanguagesReferential languages = new DeprecatedLanguagesReferential(new Languages(new MockLanguage("abap", "abap", "ABAP"))); LanguageDetection detection = new LanguageDetection(new Settings(), languages); assertThat(detection.language(newInputFile("abc.abap"))).isEqualTo("abap"); @@ -90,7 +92,7 @@ public class LanguageDetectionTest { public void language_with_no_extension() throws Exception { // abap does not declare any file extensions. // When analyzing an ABAP project, then all source files must be parsed. - Languages languages = new Languages(new MockLanguage("java", "java"), new MockLanguage("abap")); + LanguagesReferential languages = new DeprecatedLanguagesReferential(new Languages(new MockLanguage("java", "java"), new MockLanguage("abap"))); // No side-effect on non-ABAP projects LanguageDetection detection = new LanguageDetection(new Settings(), languages); @@ -108,7 +110,7 @@ public class LanguageDetectionTest { @Test public void force_language_using_deprecated_property() throws Exception { - Languages languages = new Languages(new MockLanguage("java", "java"), new MockLanguage("php", "php")); + LanguagesReferential languages = new DeprecatedLanguagesReferential(new Languages(new MockLanguage("java", "java"), new MockLanguage("php", "php"))); Settings settings = new Settings(); settings.setProperty(CoreProperties.PROJECT_LANGUAGE_PROPERTY, "java"); @@ -124,7 +126,7 @@ public class LanguageDetectionTest { thrown.expect(MessageException.class); thrown.expectMessage("No language is installed with key 'unknown'. Please update property 'sonar.language'"); - Languages languages = new Languages(new MockLanguage("java", "java"), new MockLanguage("php", "php")); + LanguagesReferential languages = new DeprecatedLanguagesReferential(new Languages(new MockLanguage("java", "java"), new MockLanguage("php", "php"))); Settings settings = new Settings(); settings.setProperty(CoreProperties.PROJECT_LANGUAGE_PROPERTY, "unknown"); new LanguageDetection(settings, languages); @@ -132,7 +134,7 @@ public class LanguageDetectionTest { @Test public void fail_if_conflicting_language_suffix() throws Exception { - Languages languages = new Languages(new MockLanguage("xml", "xhtml"), new MockLanguage("web", "xhtml")); + LanguagesReferential languages = new DeprecatedLanguagesReferential(new Languages(new MockLanguage("xml", "xhtml"), new MockLanguage("web", "xhtml"))); LanguageDetection detection = new LanguageDetection(new Settings(), languages); try { detection.language(newInputFile("abc.xhtml")); @@ -147,7 +149,7 @@ public class LanguageDetectionTest { @Test public void solve_conflict_using_filepattern() throws Exception { - Languages languages = new Languages(new MockLanguage("xml", "xhtml"), new MockLanguage("web", "xhtml")); + LanguagesReferential languages = new DeprecatedLanguagesReferential(new Languages(new MockLanguage("xml", "xhtml"), new MockLanguage("web", "xhtml"))); Settings settings = new Settings(); settings.setProperty("sonar.lang.patterns.xml", "xml/**"); @@ -159,7 +161,7 @@ public class LanguageDetectionTest { @Test public void fail_if_conflicting_filepattern() throws Exception { - Languages languages = new Languages(new MockLanguage("abap", "abap"), new MockLanguage("cobol", "cobol")); + LanguagesReferential languages = new DeprecatedLanguagesReferential(new Languages(new MockLanguage("abap", "abap"), new MockLanguage("cobol", "cobol"))); Settings settings = new Settings(); settings.setProperty("sonar.lang.patterns.abap", "*.abap,*.txt"); settings.setProperty("sonar.lang.patterns.cobol", "*.cobol,*.txt"); diff --git a/sonar-batch/src/test/java/org/sonar/batch/scan/report/JsonReportTest.java b/sonar-batch/src/test/java/org/sonar/batch/scan/report/JsonReportTest.java index c232c3344f5..6f4f306a0c5 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/scan/report/JsonReportTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/scan/report/JsonReportTest.java @@ -29,7 +29,7 @@ import org.junit.rules.TemporaryFolder; import org.skyscreamer.jsonassert.JSONAssert; import org.sonar.api.batch.fs.InputFile; import org.sonar.api.batch.fs.internal.DefaultFileSystem; -import org.sonar.api.batch.fs.internal.DefaultInputFile; +import org.sonar.api.batch.fs.internal.DeprecatedDefaultInputFile; import org.sonar.api.config.Settings; import org.sonar.api.issue.Issue; import org.sonar.api.issue.internal.DefaultIssue; @@ -85,7 +85,7 @@ public class JsonReportTest { mode = mock(AnalysisMode.class); when(mode.isPreview()).thenReturn(true); userFinder = mock(UserFinder.class); - DefaultInputFile inputFile = new DefaultInputFile("src/main/java/org/apache/struts/Action.java"); + DeprecatedDefaultInputFile inputFile = new DeprecatedDefaultInputFile("src/main/java/org/apache/struts/Action.java"); inputFile.setKey("struts:src/main/java/org/apache/struts/Action.java"); inputFile.setStatus(InputFile.Status.CHANGED); InputFileCache fileCache = mock(InputFileCache.class); diff --git a/sonar-batch/src/test/resources/org/sonar/batch/medium/simple-project/sonar-project.properties b/sonar-batch/src/test/resources/org/sonar/batch/medium/simple-project/sonar-project.properties new file mode 100644 index 00000000000..69ccd8d1411 --- /dev/null +++ b/sonar-batch/src/test/resources/org/sonar/batch/medium/simple-project/sonar-project.properties @@ -0,0 +1,7 @@ +sonar.projectKey=com.foo.project +sonar.projectName=Foo Project +sonar.projectVersion=1.0-SNAPSHOT +sonar.projectDescription=Description of Foo Project + +sonar.sources=sources +sonar.libraries=libs/*.txt diff --git a/sonar-batch/src/test/resources/org/sonar/batch/medium/simple-project/sources/Fake.java b/sonar-batch/src/test/resources/org/sonar/batch/medium/simple-project/sources/Fake.java new file mode 100644 index 00000000000..b2e6462a3f9 --- /dev/null +++ b/sonar-batch/src/test/resources/org/sonar/batch/medium/simple-project/sources/Fake.java @@ -0,0 +1 @@ +Fake |