From: Simon Brandhof Date: Wed, 26 Feb 2014 11:15:38 +0000 (+0100) Subject: SONAR-926 remove ModuleLanguages from API. Replaced by FileSystem#languages() X-Git-Tag: 4.3~678 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=40f8b2e97602948cec51fb7c21f2c261c85e9a68;p=sonarqube.git SONAR-926 remove ModuleLanguages from API. Replaced by FileSystem#languages() --- diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/ProfileEventsSensor.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/ProfileEventsSensor.java index 642b7e3ae0e..8437ea7dfe5 100644 --- a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/ProfileEventsSensor.java +++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/ProfileEventsSensor.java @@ -19,12 +19,8 @@ */ package org.sonar.plugins.core.sensors; -import org.sonar.api.batch.Event; -import org.sonar.api.batch.ModuleLanguages; -import org.sonar.api.batch.Sensor; -import org.sonar.api.batch.SensorContext; -import org.sonar.api.batch.TimeMachine; -import org.sonar.api.batch.TimeMachineQuery; +import org.sonar.api.batch.*; +import org.sonar.api.batch.fs.FileSystem; import org.sonar.api.measures.CoreMetrics; import org.sonar.api.measures.Measure; import org.sonar.api.measures.Metric; @@ -38,12 +34,12 @@ public class ProfileEventsSensor implements Sensor { private final RulesProfile profile; private final TimeMachine timeMachine; - private final ModuleLanguages moduleLanguages; + private final FileSystem fs; - public ProfileEventsSensor(RulesProfile profile, TimeMachine timeMachine, ModuleLanguages moduleLanguages) { + public ProfileEventsSensor(RulesProfile profile, TimeMachine timeMachine, FileSystem fs) { this.profile = profile; this.timeMachine = timeMachine; - this.moduleLanguages = moduleLanguages; + this.fs = fs; } public boolean shouldExecuteOnProject(Project project) { @@ -53,7 +49,7 @@ public class ProfileEventsSensor implements Sensor { public void analyse(Project project, SensorContext context) { RulesProfileWrapper profileWrapper = (RulesProfileWrapper) profile; - for (String languageKey : moduleLanguages.keys()) { + for (String languageKey : fs.languages()) { RulesProfile realProfile = profileWrapper.getProfileByLanguage(languageKey); Measure pastProfileMeasure = getPreviousMeasure(project, CoreMetrics.PROFILE); if (pastProfileMeasure == null) { diff --git a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/sensors/ProfileEventsSensorTest.java b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/sensors/ProfileEventsSensorTest.java index 7ebb236e586..60dc1f9666f 100644 --- a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/sensors/ProfileEventsSensorTest.java +++ b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/sensors/ProfileEventsSensorTest.java @@ -25,15 +25,13 @@ import org.sonar.api.batch.Event; import org.sonar.api.batch.SensorContext; import org.sonar.api.batch.TimeMachine; import org.sonar.api.batch.TimeMachineQuery; -import org.sonar.api.config.Settings; +import org.sonar.api.batch.fs.FileSystem; +import org.sonar.api.batch.fs.internal.DefaultFileSystem; import org.sonar.api.measures.CoreMetrics; import org.sonar.api.measures.Measure; import org.sonar.api.profiles.RulesProfile; -import org.sonar.api.resources.Java; -import org.sonar.api.resources.Languages; import org.sonar.api.resources.Project; import org.sonar.batch.rule.RulesProfileWrapper; -import org.sonar.batch.scan.language.DefaultModuleLanguages; import java.util.Arrays; import java.util.Collections; @@ -49,7 +47,7 @@ public class ProfileEventsSensorTest { Project project; SensorContext context; - DefaultModuleLanguages moduleLanguages; + FileSystem fs; RulesProfileWrapper wrapper; RulesProfile profile; @@ -58,8 +56,7 @@ public class ProfileEventsSensorTest { project = mock(Project.class); context = mock(SensorContext.class); - moduleLanguages = new DefaultModuleLanguages(new Settings(), new Languages(Java.INSTANCE)); - moduleLanguages.addLanguage("java"); + fs = new DefaultFileSystem().addLanguages("java"); profile = mock(RulesProfile.class); when(profile.getLanguage()).thenReturn("java"); wrapper = new RulesProfileWrapper(profile); @@ -68,7 +65,7 @@ public class ProfileEventsSensorTest { @Test public void shouldExecuteWhenProfileWithId() { when(profile.getId()).thenReturn(123); - ProfileEventsSensor sensor = new ProfileEventsSensor(wrapper, null, moduleLanguages); + ProfileEventsSensor sensor = new ProfileEventsSensor(wrapper, null, fs); assertThat(sensor.shouldExecuteOnProject(project)).isTrue(); verifyZeroInteractions(project); @@ -78,7 +75,7 @@ public class ProfileEventsSensorTest { public void shouldNotExecuteIfProfileIsNotWrapper() { RulesProfile profile = mock(RulesProfile.class); when(profile.getId()).thenReturn(null); - ProfileEventsSensor sensor = new ProfileEventsSensor(profile, null, moduleLanguages); + ProfileEventsSensor sensor = new ProfileEventsSensor(profile, null, fs); assertThat(sensor.shouldExecuteOnProject(project)).isFalse(); verifyZeroInteractions(project); @@ -88,7 +85,7 @@ public class ProfileEventsSensorTest { public void shouldDoNothingIfNoProfileChange() { mockProfileWithVersion(1); TimeMachine timeMachine = mockTM(22.0, "Foo", 1.0); // Same profile, same version - ProfileEventsSensor sensor = new ProfileEventsSensor(wrapper, timeMachine, moduleLanguages); + ProfileEventsSensor sensor = new ProfileEventsSensor(wrapper, timeMachine, fs); sensor.analyse(project, context); @@ -99,7 +96,7 @@ public class ProfileEventsSensorTest { public void shouldCreateEventIfProfileChange() { mockProfileWithVersion(1); TimeMachine timeMachine = mockTM(21.0, "Bar", 1.0); // Different profile - ProfileEventsSensor sensor = new ProfileEventsSensor(wrapper, timeMachine, moduleLanguages); + ProfileEventsSensor sensor = new ProfileEventsSensor(wrapper, timeMachine, fs); sensor.analyse(project, context); @@ -113,7 +110,7 @@ public class ProfileEventsSensorTest { public void shouldCreateEventIfProfileVersionChange() { mockProfileWithVersion(2); TimeMachine timeMachine = mockTM(22.0, "Foo", 1.0); // Same profile, different version - ProfileEventsSensor sensor = new ProfileEventsSensor(wrapper, timeMachine, moduleLanguages); + ProfileEventsSensor sensor = new ProfileEventsSensor(wrapper, timeMachine, fs); sensor.analyse(project, context); @@ -127,7 +124,7 @@ public class ProfileEventsSensorTest { public void shouldNotCreateEventIfFirstAnalysis() { mockProfileWithVersion(2); TimeMachine timeMachine = mockTM(null, null); - ProfileEventsSensor sensor = new ProfileEventsSensor(wrapper, timeMachine, moduleLanguages); + ProfileEventsSensor sensor = new ProfileEventsSensor(wrapper, timeMachine, fs); sensor.analyse(project, context); @@ -138,7 +135,7 @@ public class ProfileEventsSensorTest { public void shouldCreateEventIfFirstAnalysisWithVersionsAndVersionMoreThan1() { mockProfileWithVersion(2); TimeMachine timeMachine = mockTM(22.0, "Foo", null); - ProfileEventsSensor sensor = new ProfileEventsSensor(wrapper, timeMachine, moduleLanguages); + ProfileEventsSensor sensor = new ProfileEventsSensor(wrapper, timeMachine, fs); sensor.analyse(project, context); diff --git a/plugins/sonar-cpd-plugin/src/main/java/org/sonar/plugins/cpd/CpdSensor.java b/plugins/sonar-cpd-plugin/src/main/java/org/sonar/plugins/cpd/CpdSensor.java index 0488a9b63af..b305052e7de 100644 --- a/plugins/sonar-cpd-plugin/src/main/java/org/sonar/plugins/cpd/CpdSensor.java +++ b/plugins/sonar-cpd-plugin/src/main/java/org/sonar/plugins/cpd/CpdSensor.java @@ -23,9 +23,9 @@ import com.google.common.annotations.VisibleForTesting; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.sonar.api.CoreProperties; -import org.sonar.api.batch.ModuleLanguages; import org.sonar.api.batch.Sensor; import org.sonar.api.batch.SensorContext; +import org.sonar.api.batch.fs.FileSystem; import org.sonar.api.config.Settings; import org.sonar.api.resources.Project; @@ -36,13 +36,13 @@ public class CpdSensor implements Sensor { private CpdEngine sonarEngine; private CpdEngine sonarBridgeEngine; private Settings settings; - private ModuleLanguages moduleLanguages; + private FileSystem fs; - public CpdSensor(SonarEngine sonarEngine, SonarBridgeEngine sonarBridgeEngine, Settings settings, ModuleLanguages moduleLanguages) { + public CpdSensor(SonarEngine sonarEngine, SonarBridgeEngine sonarBridgeEngine, Settings settings, FileSystem fs) { this.sonarEngine = sonarEngine; this.sonarBridgeEngine = sonarBridgeEngine; this.settings = settings; - this.moduleLanguages = moduleLanguages; + this.fs = fs; } public boolean shouldExecuteOnProject(Project project) { @@ -67,7 +67,7 @@ public class CpdSensor implements Sensor { } public void analyse(Project project, SensorContext context) { - for (String language : moduleLanguages.keys()) { + for (String language : fs.languages()) { if (isSkipped(language)) { LOG.info("Detection of duplicated code is skipped for {}", language); continue; diff --git a/plugins/sonar-cpd-plugin/src/test/java/org/sonar/plugins/cpd/CpdSensorTest.java b/plugins/sonar-cpd-plugin/src/test/java/org/sonar/plugins/cpd/CpdSensorTest.java index 5fb30de0227..0d6429dce62 100644 --- a/plugins/sonar-cpd-plugin/src/test/java/org/sonar/plugins/cpd/CpdSensorTest.java +++ b/plugins/sonar-cpd-plugin/src/test/java/org/sonar/plugins/cpd/CpdSensorTest.java @@ -21,13 +21,10 @@ package org.sonar.plugins.cpd; import org.junit.Before; import org.junit.Test; +import org.sonar.api.batch.fs.internal.DefaultFileSystem; import org.sonar.api.config.PropertyDefinitions; import org.sonar.api.config.Settings; -import org.sonar.api.resources.AbstractLanguage; import org.sonar.api.resources.Java; -import org.sonar.api.resources.Language; -import org.sonar.api.resources.Languages; -import org.sonar.batch.scan.language.DefaultModuleLanguages; import org.sonar.plugins.cpd.index.IndexFactory; import static org.fest.assertions.Assertions.assertThat; @@ -46,7 +43,9 @@ public class CpdSensorTest { sonarEngine = new SonarEngine(indexFactory, null, null); sonarBridgeEngine = new SonarBridgeEngine(indexFactory, null, null); settings = new Settings(new PropertyDefinitions(CpdPlugin.class)); - sensor = new CpdSensor(sonarEngine, sonarBridgeEngine, settings, new DefaultModuleLanguages(settings, new Languages())); + + DefaultFileSystem fs = new DefaultFileSystem(); + sensor = new CpdSensor(sonarEngine, sonarBridgeEngine, settings, fs); } @Test diff --git a/sonar-batch/src/main/java/org/sonar/batch/phases/ProfileLogger.java b/sonar-batch/src/main/java/org/sonar/batch/phases/ProfileLogger.java index dea11280d8a..0aa232db26f 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/phases/ProfileLogger.java +++ b/sonar-batch/src/main/java/org/sonar/batch/phases/ProfileLogger.java @@ -24,7 +24,7 @@ import org.apache.commons.lang.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.sonar.api.BatchComponent; -import org.sonar.api.batch.ModuleLanguages; +import org.sonar.api.batch.fs.FileSystem; import org.sonar.api.config.Settings; import org.sonar.api.profiles.Alert; import org.sonar.api.profiles.RulesProfile; @@ -39,15 +39,15 @@ public class ProfileLogger implements BatchComponent { private static final Logger LOG = LoggerFactory.getLogger(ProfileLogger.class); private final Settings settings; - private final ModuleLanguages languages; + private final FileSystem fs; private final ModuleQProfiles profiles; private final ProjectAlerts projectAlerts; private final RulesProfile rulesProfile; - public ProfileLogger(Settings settings, ModuleLanguages languages, ModuleQProfiles profiles, ProjectAlerts projectAlerts, RulesProfile rulesProfile) { + public ProfileLogger(Settings settings, FileSystem fs, ModuleQProfiles profiles, ProjectAlerts projectAlerts, RulesProfile rulesProfile) { this.settings = settings; - this.languages = languages; + this.fs = fs; this.profiles = profiles; this.projectAlerts = projectAlerts; this.rulesProfile = rulesProfile; @@ -61,7 +61,7 @@ public class ProfileLogger implements BatchComponent { void execute(Logger logger) { String defaultName = settings.getString(ModuleQProfiles.SONAR_PROFILE_PROP); boolean defaultNameUsed = StringUtils.isBlank(defaultName); - for (String lang : languages.keys()) { + for (String lang : fs.languages()) { QProfile profile = profiles.findByLanguage(lang); if (profile == null) { logger.warn("No Quality profile found for language " + lang); @@ -72,7 +72,7 @@ public class ProfileLogger implements BatchComponent { } } } - if (!defaultNameUsed && !languages.keys().isEmpty()) { + if (!defaultNameUsed && !fs.languages().isEmpty()) { throw MessageException.of("sonar.profile was set to '" + defaultName + "' but didn't match any profile for any language. Please check your configuration."); } @@ -81,7 +81,7 @@ public class ProfileLogger implements BatchComponent { private void addModuleAlertsToProjectAlerts() { RulesProfileWrapper profileWrapper = (RulesProfileWrapper) rulesProfile; - for (String lang : languages.keys()) { + for (String lang : fs.languages()) { RulesProfile profile = profileWrapper.getProfileByLanguage(lang); for (Alert alert : profile.getAlerts()) { projectAlerts.add(alert); 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 ec98d3b88ca..3233425f34b 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 @@ -19,9 +19,10 @@ */ package org.sonar.batch.rule; -import org.sonar.api.batch.ModuleLanguages; +import com.google.common.collect.Iterables; import org.sonar.api.batch.Sensor; import org.sonar.api.batch.SensorContext; +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; @@ -33,12 +34,12 @@ import org.sonar.core.qualityprofile.db.QualityProfileDao; public class QProfileSensor implements Sensor { private final ModuleQProfiles moduleQProfiles; - private final ModuleLanguages moduleLanguages; + private final FileSystem fs; private final QualityProfileDao dao; - public QProfileSensor(ModuleQProfiles moduleQProfiles, ModuleLanguages moduleLanguages, QualityProfileDao dao) { + public QProfileSensor(ModuleQProfiles moduleQProfiles, FileSystem fs, QualityProfileDao dao) { this.moduleQProfiles = moduleQProfiles; - this.moduleLanguages = moduleLanguages; + this.fs = fs; this.dao = dao; } @@ -47,14 +48,14 @@ public class QProfileSensor implements Sensor { } public void analyse(Project project, SensorContext context) { - for (String language : moduleLanguages.keys()) { + for (String language : fs.languages()) { ModuleQProfiles.QProfile qProfile = moduleQProfiles.findByLanguage(language); if (qProfile != null) { dao.updateUsedColumn(qProfile.id(), true); } } - if (moduleLanguages.keys().size() == 1) { - String language = moduleLanguages.keys().iterator().next(); + if (fs.languages().size() == 1) { + String language = Iterables.getOnlyElement(fs.languages()); ModuleQProfiles.QProfile qProfile = moduleQProfiles.findByLanguage(language); if (qProfile != null) { Measure measure = new Measure(CoreMetrics.PROFILE, qProfile.name()).setValue((double)qProfile.id()); 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 new file mode 100644 index 00000000000..b99fbd5ba7d --- /dev/null +++ b/sonar-batch/src/main/java/org/sonar/batch/scan/LanguageVerifier.java @@ -0,0 +1,63 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2013 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.picocontainer.Startable; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.sonar.api.CoreProperties; +import org.sonar.api.config.Settings; +import org.sonar.api.resources.Language; +import org.sonar.api.resources.Languages; +import org.sonar.api.utils.MessageException; + +/** + * Verifies that the property sonar.language is valid + */ +public class LanguageVerifier implements Startable { + + private static final Logger LOG = LoggerFactory.getLogger(LanguageVerifier.class); + + private final Settings settings; + private final Languages languages; + + public LanguageVerifier(Settings settings, Languages languages) { + this.settings = settings; + this.languages = languages; + } + + + @Override + public void start() { + if (settings.hasKey(CoreProperties.PROJECT_LANGUAGE_PROPERTY)) { + String languageKey = settings.getString(CoreProperties.PROJECT_LANGUAGE_PROPERTY); + LOG.info("Language is forced to {}", languageKey); + Language language = languages.get(languageKey); + if (language == null) { + throw MessageException.of("You must install a plugin that supports the language '" + languageKey + "'"); + } + } + } + + @Override + public void stop() { + // nothing to do + } +} 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 c8ac7bb558e..4fca5d3596f 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 @@ -61,7 +61,6 @@ import org.sonar.batch.rule.QProfileSensor; import org.sonar.batch.rule.RulesProfileProvider; import org.sonar.batch.scan.filesystem.*; import org.sonar.batch.scan.filesystem.FileIndexer; -import org.sonar.batch.scan.language.DefaultModuleLanguages; import org.sonar.batch.scan.report.JsonReport; import org.sonar.core.component.ScanPerspectives; import org.sonar.core.measure.MeasurementFilters; @@ -112,7 +111,7 @@ public class ModuleScanContainer extends ComponentContainer { PreviousFileHashLoader.class, FileIndexer.class, ComponentIndexer.class, - DefaultModuleLanguages.class, + LanguageVerifier.class, FileSystemLogger.class, DefaultProjectClasspath.class, DefaultModuleFileSystem.class, 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 25cda6e9fb1..4751c2f10f5 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 @@ -30,10 +30,12 @@ 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.config.Settings; -import org.sonar.api.resources.*; +import org.sonar.api.resources.File; +import org.sonar.api.resources.Languages; +import org.sonar.api.resources.Project; +import org.sonar.api.resources.Resource; import org.sonar.api.utils.SonarException; import org.sonar.batch.index.ResourceKeyMigration; -import org.sonar.batch.scan.language.DefaultModuleLanguages; /** * Index all files/directories of the module in SQ database and importing source code. @@ -46,17 +48,15 @@ public class ComponentIndexer implements BatchComponent { private final SonarIndex sonarIndex; private final ResourceKeyMigration migration; private final Project module; - private final DefaultModuleLanguages moduleLanguages; private InputFileCache fileCache; public ComponentIndexer(Project module, Languages languages, SonarIndex sonarIndex, Settings settings, ResourceKeyMigration migration, - DefaultModuleLanguages moduleLanguages, InputFileCache fileCache) { + InputFileCache fileCache) { this.module = module; this.languages = languages; this.sonarIndex = sonarIndex; this.settings = settings; this.migration = migration; - this.moduleLanguages = moduleLanguages; this.fileCache = fileCache; } @@ -73,8 +73,7 @@ public class ComponentIndexer implements BatchComponent { } Resource sonarFile = File.create(inputFile.relativePath(), pathFromSourceDir, languages.get(languageKey), unitTest); if (sonarFile != null) { - sonarFile.setDeprecatedKey(((DefaultInputFile)inputFile).deprecatedKey()); - moduleLanguages.addLanguage(languageKey); + sonarFile.setDeprecatedKey(((DefaultInputFile) inputFile).deprecatedKey()); sonarIndex.index(sonarFile); importSources(fs, shouldImportSource, inputFile, sonarFile); } diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan/language/DefaultModuleLanguages.java b/sonar-batch/src/main/java/org/sonar/batch/scan/language/DefaultModuleLanguages.java deleted file mode 100644 index 8f5049ae62c..00000000000 --- a/sonar-batch/src/main/java/org/sonar/batch/scan/language/DefaultModuleLanguages.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * SonarQube, open source software quality management tool. - * Copyright (C) 2008-2013 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.language; - -import com.google.common.collect.Sets; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.sonar.api.CoreProperties; -import org.sonar.api.batch.ModuleLanguages; -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 java.util.Collection; -import java.util.Set; - -/** - * Give access to all languages detected on the current module - * - * @since 4.2 - */ -public class DefaultModuleLanguages implements ModuleLanguages { - - private static final Logger LOG = LoggerFactory.getLogger(DefaultModuleLanguages.class); - - private final Set moduleLanguages = Sets.newTreeSet(); - - public DefaultModuleLanguages(Settings settings, Languages languages) { - if (settings.hasKey(CoreProperties.PROJECT_LANGUAGE_PROPERTY)) { - String languageKey = settings.getString(CoreProperties.PROJECT_LANGUAGE_PROPERTY); - LOG.info("Language is forced to {}", languageKey); - Language language = languages.get(languageKey); - if (language == null) { - throw MessageException.of("You must install a plugin that supports the language key '" + languageKey + "'"); - } - addLanguage(languageKey); - } - } - - public void addLanguage(String languageKey) { - moduleLanguages.add(languageKey); - } - - @Override - public Collection keys() { - return moduleLanguages; - } -} diff --git a/sonar-batch/src/test/java/org/sonar/batch/phases/ProfileLoggerTest.java b/sonar-batch/src/test/java/org/sonar/batch/phases/ProfileLoggerTest.java index deb1096215b..e3bcc49929e 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/phases/ProfileLoggerTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/phases/ProfileLoggerTest.java @@ -19,13 +19,12 @@ */ package org.sonar.batch.phases; -import com.google.common.collect.Lists; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; import org.slf4j.Logger; -import org.sonar.api.batch.ModuleLanguages; +import org.sonar.api.batch.fs.internal.DefaultFileSystem; import org.sonar.api.config.Settings; import org.sonar.api.profiles.Alert; import org.sonar.api.profiles.RulesProfile; @@ -39,28 +38,23 @@ import java.util.Arrays; import java.util.Collections; import static org.fest.assertions.Assertions.assertThat; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; +import static org.mockito.Mockito.*; public class ProfileLoggerTest { @Rule public ExpectedException thrown = ExpectedException.none(); - private ModuleLanguages languages; - private ModuleQProfiles profiles; - private Settings settings = new Settings(); - private ProjectAlerts projectAlerts = new ProjectAlerts(); - private RulesProfileWrapper rulesProfile = mock(RulesProfileWrapper.class); - private RulesProfile javaRulesProfile; - private RulesProfile cobolRulesProfile; + DefaultFileSystem fs = new DefaultFileSystem(); + ModuleQProfiles profiles; + Settings settings = new Settings(); + ProjectAlerts projectAlerts = new ProjectAlerts(); + RulesProfileWrapper rulesProfile = mock(RulesProfileWrapper.class); + RulesProfile javaRulesProfile; + RulesProfile cobolRulesProfile; @Before public void before() { - languages = mock(ModuleLanguages.class); - when(languages.keys()).thenReturn(Lists.newArrayList("java", "cobol")); - profiles = mock(ModuleQProfiles.class); QProfile javaProfile = mock(QProfile.class); when(javaProfile.name()).thenReturn("My Java profile"); @@ -76,7 +70,8 @@ public class ProfileLoggerTest { @Test public void should_log_all_used_profiles() { - ProfileLogger profileLogger = new ProfileLogger(settings, languages, profiles, projectAlerts, rulesProfile); + fs.addLanguages("java", "cobol"); + ProfileLogger profileLogger = new ProfileLogger(settings, fs, profiles, projectAlerts, rulesProfile); Logger logger = mock(Logger.class); profileLogger.execute(logger); @@ -86,9 +81,10 @@ public class ProfileLoggerTest { @Test public void should_fail_if_default_profile_not_used() { + fs.addLanguages("java", "cobol"); settings.setProperty("sonar.profile", "Unknown"); - ProfileLogger profileLogger = new ProfileLogger(settings, languages, profiles, projectAlerts, rulesProfile); + ProfileLogger profileLogger = new ProfileLogger(settings, fs, profiles, projectAlerts, rulesProfile); thrown.expect(MessageException.class); thrown.expectMessage("sonar.profile was set to 'Unknown' but didn't match any profile for any language. Please check your configuration."); @@ -99,9 +95,8 @@ public class ProfileLoggerTest { @Test public void should_not_fail_if_no_language_on_project() { settings.setProperty("sonar.profile", "Unknown"); - when(languages.keys()).thenReturn(Collections.emptyList()); - ProfileLogger profileLogger = new ProfileLogger(settings, languages, profiles, projectAlerts, rulesProfile); + ProfileLogger profileLogger = new ProfileLogger(settings, fs, profiles, projectAlerts, rulesProfile); profileLogger.execute(); @@ -109,15 +104,17 @@ public class ProfileLoggerTest { @Test public void should_not_fail_if_default_profile_used_at_least_once() { + fs.addLanguages("java", "cobol"); settings.setProperty("sonar.profile", "My Java profile"); - ProfileLogger profileLogger = new ProfileLogger(settings, languages, profiles, projectAlerts, rulesProfile); + ProfileLogger profileLogger = new ProfileLogger(settings, fs, profiles, projectAlerts, rulesProfile); profileLogger.execute(); } @Test public void should_collect_alerts() { + fs.addLanguages("java", "cobol"); Alert javaAlert1 = new Alert(); Alert javaAlert2 = new Alert(); Alert cobolAlert1 = new Alert(); @@ -125,10 +122,10 @@ public class ProfileLoggerTest { when(javaRulesProfile.getAlerts()).thenReturn(Arrays.asList(javaAlert1, javaAlert2)); when(cobolRulesProfile.getAlerts()).thenReturn(Arrays.asList(cobolAlert1, cobolAlert2)); - ProfileLogger profileLogger = new ProfileLogger(settings, languages, profiles, projectAlerts, rulesProfile); + ProfileLogger profileLogger = new ProfileLogger(settings, fs, profiles, projectAlerts, rulesProfile); profileLogger.execute(); - assertThat(projectAlerts.all()).containsExactly(javaAlert1, javaAlert2, cobolAlert1, cobolAlert2); + assertThat(projectAlerts.all()).containsExactly(cobolAlert1, cobolAlert2, javaAlert1, javaAlert2); } } 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 bda70b4e5ee..e33feb243c0 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 @@ -19,17 +19,16 @@ */ package org.sonar.batch.rule; -import java.util.Collections; import org.junit.Test; -import org.sonar.api.batch.ModuleLanguages; import org.sonar.api.batch.SensorContext; +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.core.persistence.AbstractDaoTestCase; import org.sonar.core.qualityprofile.db.QualityProfileDao; -import java.util.Arrays; +import java.util.Collections; import static org.fest.assertions.Assertions.assertThat; import static org.mockito.Mockito.*; @@ -37,14 +36,14 @@ import static org.mockito.Mockito.*; public class QProfileSensorTest extends AbstractDaoTestCase { ModuleQProfiles moduleQProfiles = mock(ModuleQProfiles.class); - ModuleLanguages moduleLanguages = mock(ModuleLanguages.class); Project project = mock(Project.class); SensorContext sensorContext = mock(SensorContext.class); + DefaultFileSystem fs = new DefaultFileSystem(); @Test public void to_string() throws Exception { QualityProfileDao dao = mock(QualityProfileDao.class); - QProfileSensor sensor = new QProfileSensor(moduleQProfiles, moduleLanguages, dao); + QProfileSensor sensor = new QProfileSensor(moduleQProfiles, fs, dao); assertThat(sensor.toString()).isEqualTo("QProfileSensor"); } @@ -54,7 +53,7 @@ public class QProfileSensorTest extends AbstractDaoTestCase { QualityProfileDao dao = new QualityProfileDao(getMyBatis()); when(moduleQProfiles.findAll()).thenReturn(Collections.emptyList()); - QProfileSensor sensor = new QProfileSensor(moduleQProfiles, moduleLanguages, dao); + QProfileSensor sensor = new QProfileSensor(moduleQProfiles, fs, dao); assertThat(sensor.shouldExecuteOnProject(project)).isTrue(); sensor.analyse(project, sensorContext); @@ -70,9 +69,9 @@ public class QProfileSensorTest extends AbstractDaoTestCase { 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("abap")).thenReturn(null); - when(moduleLanguages.keys()).thenReturn(Arrays.asList("java", "php", "abap")); + fs.addLanguages("java", "php", "abap"); - QProfileSensor sensor = new QProfileSensor(moduleQProfiles, moduleLanguages, dao); + QProfileSensor sensor = new QProfileSensor(moduleQProfiles, fs, dao); assertThat(sensor.shouldExecuteOnProject(project)).isTrue(); sensor.analyse(project, sensorContext); @@ -90,9 +89,9 @@ public class QProfileSensorTest extends AbstractDaoTestCase { 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("abap")).thenReturn(null); - when(moduleLanguages.keys()).thenReturn(Arrays.asList("java")); + fs.addLanguages("java"); - QProfileSensor sensor = new QProfileSensor(moduleQProfiles, moduleLanguages, dao); + QProfileSensor sensor = new QProfileSensor(moduleQProfiles, fs, dao); assertThat(sensor.shouldExecuteOnProject(project)).isTrue(); sensor.analyse(project, sensorContext); 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 new file mode 100644 index 00000000000..0ef69de6f4d --- /dev/null +++ b/sonar-batch/src/test/java/org/sonar/batch/scan/LanguageVerifierTest.java @@ -0,0 +1,69 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2013 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.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.sonar.api.config.Settings; +import org.sonar.api.resources.Java; +import org.sonar.api.resources.Languages; +import org.sonar.api.utils.MessageException; + +public class LanguageVerifierTest { + + Settings settings = new Settings(); + Languages languages = new Languages(Java.INSTANCE); + + @Rule + public ExpectedException thrown = ExpectedException.none(); + + @Test + public void language_is_not_set() throws Exception { + LanguageVerifier verifier = new LanguageVerifier(settings, languages); + verifier.start(); + + // no failure + + verifier.stop(); + } + + @Test + public void language_is_valid() throws Exception { + settings.setProperty("sonar.language", "java"); + + LanguageVerifier verifier = new LanguageVerifier(settings, languages); + verifier.start(); + + // no failure + + verifier.stop(); + } + + @Test + public void language_is_not_valid() throws Exception { + thrown.expect(MessageException.class); + thrown.expectMessage("You must install a plugin that supports the language 'php'"); + + settings.setProperty("sonar.language", "php"); + LanguageVerifier verifier = new LanguageVerifier(settings, languages); + verifier.start(); + } +} 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 aef24d43e0b..ceff337ce0e 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 @@ -36,7 +36,7 @@ import org.sonar.api.batch.fs.internal.DefaultInputFile; import org.sonar.api.config.Settings; import org.sonar.api.resources.*; import org.sonar.batch.index.ResourceKeyMigration; -import org.sonar.batch.scan.language.DefaultModuleLanguages; +import org.sonar.batch.scan.LanguageVerifier; import java.io.File; import java.io.IOException; @@ -84,8 +84,7 @@ public class ComponentIndexerTest { fs.add(newInputFile("src/main/java2/foo/bar/Foo.java", "", "foo/bar/Foo.java", "java", false)); fs.add(newInputFile("src/test/java/foo/bar/FooTest.java", "", "foo/bar/FooTest.java", "java", true)); Languages languages = new Languages(Java.INSTANCE); - ComponentIndexer indexer = new ComponentIndexer(project, languages, sonarIndex, settings, mock(ResourceKeyMigration.class), new DefaultModuleLanguages(settings, languages), - mock(InputFileCache.class)); + ComponentIndexer indexer = new ComponentIndexer(project, languages, sonarIndex, settings, mock(ResourceKeyMigration.class), mock(InputFileCache.class)); indexer.execute(fs); verify(sonarIndex).index(org.sonar.api.resources.File.create("src/main/java/foo/bar/Foo.java", "foo/bar/Foo.java", Java.INSTANCE, false)); @@ -108,7 +107,7 @@ public class ComponentIndexerTest { fs.add(newInputFile("src/test/foo/bar/FooTest.cbl", "", "foo/bar/FooTest.cbl", "cobol", true)); Languages languages = new Languages(cobolLanguage); - ComponentIndexer indexer = new ComponentIndexer(project, languages, sonarIndex, settings, mock(ResourceKeyMigration.class), new DefaultModuleLanguages(settings, languages), + ComponentIndexer indexer = new ComponentIndexer(project, languages, sonarIndex, settings, mock(ResourceKeyMigration.class), mock(InputFileCache.class)); indexer.execute(fs); @@ -123,7 +122,7 @@ public class ComponentIndexerTest { fs.add(newInputFile("src/main/java/foo/bar/Foo.java", "sample code", "foo/bar/Foo.java", "java", false)); Languages languages = new Languages(Java.INSTANCE); - ComponentIndexer indexer = new ComponentIndexer(project, languages, sonarIndex, settings, mock(ResourceKeyMigration.class), new DefaultModuleLanguages(settings, languages), + ComponentIndexer indexer = new ComponentIndexer(project, languages, sonarIndex, settings, mock(ResourceKeyMigration.class), mock(InputFileCache.class)); indexer.execute(fs); @@ -163,7 +162,7 @@ public class ComponentIndexerTest { .setPathRelativeToSourceDir("foo/bar/Foo.java") .setLanguage("java")); Languages languages = new Languages(Java.INSTANCE); - ComponentIndexer indexer = new ComponentIndexer(project, languages, sonarIndex, settings, mock(ResourceKeyMigration.class), new DefaultModuleLanguages(settings, languages), + ComponentIndexer indexer = new ComponentIndexer(project, languages, sonarIndex, settings, mock(ResourceKeyMigration.class), mock(InputFileCache.class)); indexer.execute(fs); @@ -189,7 +188,7 @@ public class ComponentIndexerTest { .setPathRelativeToSourceDir("foo/bar/Foo.java") .setLanguage("java")); Languages languages = new Languages(Java.INSTANCE); - ComponentIndexer indexer = new ComponentIndexer(project, languages, sonarIndex, settings, mock(ResourceKeyMigration.class), new DefaultModuleLanguages(settings, languages), + ComponentIndexer indexer = new ComponentIndexer(project, languages, sonarIndex, settings, mock(ResourceKeyMigration.class), mock(InputFileCache.class)); indexer.execute(fs); diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/ModuleLanguages.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/ModuleLanguages.java deleted file mode 100644 index e91b9d76739..00000000000 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/ModuleLanguages.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * SonarQube, open source software quality management tool. - * Copyright (C) 2008-2013 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.api.batch; - -import org.sonar.api.BatchComponent; -import org.sonar.api.resources.Language; - -import java.util.Collection; - -/** - * Give access to all languages detected on the current module. - * - * @since 4.2 - */ -public interface ModuleLanguages extends BatchComponent { - - Collection keys(); - -} diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/FileSystem.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/FileSystem.java index 4ee79a17481..fd7cdc9f701 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/FileSystem.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/FileSystem.java @@ -24,7 +24,7 @@ import org.sonar.api.BatchComponent; import javax.annotation.CheckForNull; import java.io.File; import java.nio.charset.Charset; -import java.util.Set; +import java.util.SortedSet; /** *

The unit tests needing an instance of FileSystem can use the implementation @@ -94,5 +94,5 @@ public interface FileSystem extends BatchComponent { /** * Languages detected in all files, whatever their type (main or test) */ - Set languages(); + SortedSet languages(); } diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/DefaultFileSystem.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/DefaultFileSystem.java index c95c2d43da1..92c1f0156f2 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/DefaultFileSystem.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/DefaultFileSystem.java @@ -26,7 +26,6 @@ import com.google.common.collect.Iterables; import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.google.common.collect.Sets; -import org.apache.commons.io.Charsets; import org.sonar.api.batch.fs.FilePredicate; import org.sonar.api.batch.fs.FileSystem; import org.sonar.api.batch.fs.InputFile; @@ -36,7 +35,10 @@ import javax.annotation.CheckForNull; import javax.annotation.Nullable; import java.io.File; import java.nio.charset.Charset; -import java.util.*; +import java.util.List; +import java.util.Map; +import java.util.NoSuchElementException; +import java.util.SortedSet; /** * @since 4.2 @@ -44,10 +46,9 @@ import java.util.*; public class DefaultFileSystem implements FileSystem { private final Cache cache; - private final Set languages = Sets.newTreeSet(); + private final SortedSet languages = Sets.newTreeSet(); private File baseDir, workDir; - private Charset encoding = Charsets.UTF_8; - private boolean isDefaultJvmEncoding = false; + private Charset encoding; /** * Only for testing @@ -71,22 +72,18 @@ public class DefaultFileSystem implements FileSystem { return baseDir; } - public DefaultFileSystem setEncoding(Charset e) { + public DefaultFileSystem setEncoding(@Nullable Charset e) { this.encoding = e; return this; } @Override public Charset encoding() { - return encoding; + return encoding == null ? Charset.defaultCharset() : encoding; } public boolean isDefaultJvmEncoding() { - return isDefaultJvmEncoding; - } - - public void setIsDefaultJvmEncoding(boolean b) { - this.isDefaultJvmEncoding = b; + return encoding == null; } public DefaultFileSystem setWorkDir(File d) { @@ -137,15 +134,31 @@ public class DefaultFileSystem implements FileSystem { }); } - public void add(InputFile inputFile) { + /** + * Adds InputFile to the list and registers its language, if present. + */ + public DefaultFileSystem add(InputFile inputFile) { cache.add(inputFile); if (inputFile.language() != null) { languages.add(inputFile.language()); } + return this; + } + + /** + * Adds a language to the list. To be used only for unit tests that need to use {@link #languages()} without + * using {@link #add(org.sonar.api.batch.fs.InputFile)}. + */ + public DefaultFileSystem addLanguages(String language, String... others) { + languages.add(language); + for (String other : others) { + languages.add(other); + } + return this; } @Override - public Set languages() { + public SortedSet languages() { doPreloadFiles(); return languages; } diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/DefaultInputFile.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/DefaultInputFile.java index 63e3c9ec01d..ab12a9dd895 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/DefaultInputFile.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/DefaultInputFile.java @@ -20,7 +20,6 @@ package org.sonar.api.batch.fs.internal; import org.apache.commons.io.FilenameUtils; -import org.apache.commons.lang.StringUtils; import org.sonar.api.batch.fs.InputFile; import org.sonar.api.utils.PathUtils; @@ -66,6 +65,9 @@ public class DefaultInputFile implements InputFile, org.sonar.api.resources.Inpu @Override public File file() { + if (absolutePath == null) { + throw new IllegalStateException("Can not return the java.io.File because absolute path is not set (see method setFile(java.io.File))"); + } return new File(absolutePath); } diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/resources/Project.java b/sonar-plugin-api/src/main/java/org/sonar/api/resources/Project.java index cfc451e014f..ba31b9a3383 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/resources/Project.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/resources/Project.java @@ -26,7 +26,6 @@ import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.builder.ToStringBuilder; import org.apache.maven.project.MavenProject; import org.sonar.api.CoreProperties; -import org.sonar.api.batch.ModuleLanguages; import org.sonar.api.component.Component; import java.util.ArrayList; @@ -241,7 +240,7 @@ public class Project extends Resource implements Component { /** * @return the project language when there is only one language - * @deprecated since 4.2 use {@link ModuleLanguages} + * @deprecated since 4.2 use {@link org.sonar.api.batch.fs.FileSystem#languages()} */ @Deprecated @Override @@ -259,7 +258,7 @@ public class Project extends Resource implements Component { /** * @return the language key or empty if no language is specified - * @deprecated since 4.2 use {@link ModuleLanguages} + * @deprecated since 4.2 use {@link org.sonar.api.batch.fs.FileSystem#languages()} */ @Deprecated public String getLanguageKey() { diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/batch/fs/internal/DefaultFileSystemTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/batch/fs/internal/DefaultFileSystemTest.java new file mode 100644 index 00000000000..e0b780591a6 --- /dev/null +++ b/sonar-plugin-api/src/test/java/org/sonar/api/batch/fs/internal/DefaultFileSystemTest.java @@ -0,0 +1,137 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2013 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.api.batch.fs.internal; + +import com.google.common.base.Charsets; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.junit.rules.TemporaryFolder; +import org.sonar.api.batch.fs.FilePredicates; + +import java.io.File; +import java.nio.charset.Charset; + +import static org.fest.assertions.Assertions.assertThat; + +public class DefaultFileSystemTest { + + @Rule + public TemporaryFolder temp = new TemporaryFolder(); + + @Rule + public ExpectedException thrown = ExpectedException.none(); + + @Test + public void test_directories() throws Exception { + DefaultFileSystem fs = new DefaultFileSystem(); + + File basedir = temp.newFolder(); + fs.setBaseDir(basedir); + assertThat(fs.baseDir()).isAbsolute().isDirectory().exists(); + assertThat(fs.baseDir().getCanonicalPath()).isEqualTo(basedir.getCanonicalPath()); + + File workdir = temp.newFolder(); + fs.setWorkDir(workdir); + assertThat(fs.workDir()).isAbsolute().isDirectory().exists(); + assertThat(fs.workDir().getCanonicalPath()).isEqualTo(workdir.getCanonicalPath()); + } + + @Test + public void test_encoding() throws Exception { + DefaultFileSystem fs = new DefaultFileSystem(); + + assertThat(fs.isDefaultJvmEncoding()).isTrue(); + assertThat(fs.encoding()).isEqualTo(Charset.defaultCharset()); + + fs.setEncoding(Charsets.ISO_8859_1); + assertThat(fs.encoding()).isEqualTo(Charsets.ISO_8859_1); + assertThat(fs.isDefaultJvmEncoding()).isFalse(); + } + + @Test + public void add_languages() throws Exception { + DefaultFileSystem fs = new DefaultFileSystem(); + + assertThat(fs.languages()).isEmpty(); + + fs.addLanguages("java", "php", "cobol"); + assertThat(fs.languages()).containsOnly("cobol", "java", "php"); + } + + @Test + public void files() throws Exception { + DefaultFileSystem fs = new DefaultFileSystem(); + + assertThat(fs.inputFiles(FilePredicates.all())).isEmpty(); + + fs.add(new DefaultInputFile("src/Foo.php").setLanguage("php").setFile(temp.newFile())); + fs.add(new DefaultInputFile("src/Bar.java").setLanguage("java").setFile(temp.newFile())); + fs.add(new DefaultInputFile("src/Baz.java").setLanguage("java").setFile(temp.newFile())); + + // no language + fs.add(new DefaultInputFile("src/readme.txt").setFile(temp.newFile())); + + assertThat(fs.inputFile(FilePredicates.hasRelativePath("src/Bar.java"))).isNotNull(); + assertThat(fs.inputFile(FilePredicates.hasRelativePath("does/not/exist"))).isNull(); + + assertThat(fs.files(FilePredicates.all())).hasSize(4); + assertThat(fs.files(FilePredicates.hasLanguage("java"))).hasSize(2); + assertThat(fs.files(FilePredicates.hasLanguage("cobol"))).isEmpty(); + + assertThat(fs.hasFiles(FilePredicates.all())).isTrue(); + assertThat(fs.hasFiles(FilePredicates.hasLanguage("java"))).isTrue(); + assertThat(fs.hasFiles(FilePredicates.hasLanguage("cobol"))).isFalse(); + + assertThat(fs.inputFiles(FilePredicates.all())).hasSize(4); + assertThat(fs.inputFiles(FilePredicates.hasLanguage("php"))).hasSize(1); + assertThat(fs.inputFiles(FilePredicates.hasLanguage("java"))).hasSize(2); + assertThat(fs.inputFiles(FilePredicates.hasLanguage("cobol"))).isEmpty(); + + assertThat(fs.languages()).containsOnly("java", "php"); + } + + @Test + public void input_file_returns_null_if_file_not_found() throws Exception { + DefaultFileSystem fs = new DefaultFileSystem(); + assertThat(fs.inputFile(FilePredicates.hasRelativePath("src/Bar.java"))).isNull(); + } + + @Test + public void input_file_fails_if_too_many_results() throws Exception { + thrown.expect(IllegalArgumentException.class); + thrown.expectMessage("expected one element"); + + DefaultFileSystem fs = new DefaultFileSystem(); + fs.add(new DefaultInputFile("src/Bar.java").setLanguage("java").setFile(temp.newFile())); + fs.add(new DefaultInputFile("src/Baz.java").setLanguage("java").setFile(temp.newFile())); + + fs.inputFile(FilePredicates.all()); + } + + @Test + public void input_file_supports_non_indexed_predicates() throws Exception { + DefaultFileSystem fs = new DefaultFileSystem(); + fs.add(new DefaultInputFile("src/Bar.java").setLanguage("java").setFile(temp.newFile())); + + // it would fail if more than one java file + assertThat(fs.inputFile(FilePredicates.hasLanguage("java"))).isNotNull(); + } +}