From: simonbrandhof Date: Sun, 26 Sep 2010 21:46:58 +0000 (+0000) Subject: SONAR-1711 Allow to exclude sources from code analysis based on cutoff date X-Git-Tag: 2.6~941 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=36e81898a5a6e2b2029a2279a257d2ac06345f73;p=sonarqube.git SONAR-1711 Allow to exclude sources from code analysis based on cutoff date --- diff --git a/sonar-batch/src/main/java/org/sonar/batch/MavenProjectBuilder.java b/sonar-batch/src/main/java/org/sonar/batch/MavenProjectBuilder.java new file mode 100644 index 00000000000..3feb2258463 --- /dev/null +++ b/sonar-batch/src/main/java/org/sonar/batch/MavenProjectBuilder.java @@ -0,0 +1,150 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar 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. + * + * Sonar 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 Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.batch; + +import org.apache.commons.configuration.*; +import org.apache.commons.lang.time.DateUtils; +import org.apache.maven.project.MavenProject; +import org.sonar.api.CoreProperties; +import org.sonar.api.database.DatabaseSession; +import org.sonar.api.database.model.ResourceModel; +import org.sonar.api.database.model.Snapshot; +import org.sonar.api.resources.DefaultProjectFileSystem; +import org.sonar.api.resources.Java; +import org.sonar.api.resources.Project; +import org.sonar.api.utils.SonarException; + +import java.text.DateFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; + +public class MavenProjectBuilder { + + private DatabaseSession databaseSession; + + public MavenProjectBuilder(DatabaseSession databaseSession) { + this.databaseSession = databaseSession; + } + + public Project create(MavenProject pom) { + Configuration configuration = getStartupConfiguration(pom); + return new Project(loadProjectKey(pom), loadProjectBranch(configuration), pom.getName()) + .setPom(pom) + .setDescription(pom.getDescription()) + .setPackaging(pom.getPackaging()); + } + + Configuration getStartupConfiguration(MavenProject pom) { + CompositeConfiguration configuration = new CompositeConfiguration(); + configuration.addConfiguration(new SystemConfiguration()); + configuration.addConfiguration(new EnvironmentConfiguration()); + configuration.addConfiguration(new MapConfiguration(pom.getModel().getProperties())); + return configuration; + } + + String loadProjectKey(MavenProject pom) { + return new StringBuilder().append(pom.getGroupId()).append(":").append(pom.getArtifactId()).toString(); + } + + String loadProjectBranch(Configuration configuration) { + return configuration.getString(CoreProperties.PROJECT_BRANCH_PROPERTY, configuration.getString("branch" /* deprecated property */)); + } + + + public void configure(Project project) { + ProjectConfiguration projectConfiguration = new ProjectConfiguration(databaseSession, project); + configure(project, projectConfiguration); + } + + + void configure(Project project, Configuration projectConfiguration) { + Date analysisDate = loadAnalysisDate(projectConfiguration); + project.setConfiguration(projectConfiguration) + .setExclusionPatterns(loadExclusionPatterns(projectConfiguration)) + .setAnalysisDate(analysisDate) + .setLatestAnalysis(isLatestAnalysis(project.getKey(), analysisDate)) + .setAnalysisVersion(loadAnalysisVersion(projectConfiguration, project.getPom())) + .setAnalysisType(loadAnalysisType(projectConfiguration)) + .setLanguageKey(loadLanguageKey(projectConfiguration)) + .setFileSystem(new DefaultProjectFileSystem(project)); + } + + static String[] loadExclusionPatterns(Configuration configuration) { + String[] exclusionPatterns = configuration.getStringArray(CoreProperties.PROJECT_EXCLUSIONS_PROPERTY); + if (exclusionPatterns == null) { + exclusionPatterns = new String[0]; + } + return exclusionPatterns; + } + + boolean isLatestAnalysis(String projectKey, Date analysisDate) { + ResourceModel persistedProject = databaseSession.getSingleResult(ResourceModel.class, "key", projectKey, "enabled", true); + if (persistedProject != null) { + Snapshot lastSnapshot = databaseSession.getSingleResult(Snapshot.class, "resourceId", persistedProject.getId(), "last", true); + return lastSnapshot == null || lastSnapshot.getCreatedAt().before(analysisDate); + } + return true; + } + + + Date loadAnalysisDate(Configuration configuration) { + String formattedDate = configuration.getString(CoreProperties.PROJECT_DATE_PROPERTY); + if (formattedDate == null) { + return new Date(); + } + + DateFormat format = new SimpleDateFormat("yyyy-MM-dd"); + try { + // see SONAR-908 make sure that a time is defined for the date. + Date date = DateUtils.setHours(format.parse(formattedDate), 0); + return DateUtils.setMinutes(date, 1); + + } catch (ParseException e) { + throw new SonarException("The property " + CoreProperties.PROJECT_DATE_PROPERTY + " does not respect the format yyyy-MM-dd (for example 2008-05-23) : " + formattedDate, e); + } + } + + Project.AnalysisType loadAnalysisType(Configuration configuration) { + String value = configuration.getString(CoreProperties.DYNAMIC_ANALYSIS_PROPERTY); + if (value == null) { + return (configuration.getBoolean("sonar.light", false) ? Project.AnalysisType.STATIC : Project.AnalysisType.DYNAMIC); + } + if ("true".equals(value)) { + return Project.AnalysisType.DYNAMIC; + } + if ("reuseReports".equals(value)) { + return Project.AnalysisType.REUSE_REPORTS; + } + return Project.AnalysisType.STATIC; + } + + String loadAnalysisVersion(Configuration configuration, MavenProject pom) { + String version = configuration.getString(CoreProperties.PROJECT_VERSION_PROPERTY); + if (version == null && pom != null) { + version = pom.getVersion(); + } + return version; + } + + String loadLanguageKey(Configuration configuration) { + return configuration.getString(CoreProperties.PROJECT_LANGUAGE_PROPERTY, Java.KEY); + } +} diff --git a/sonar-batch/src/main/java/org/sonar/batch/ProjectBatch.java b/sonar-batch/src/main/java/org/sonar/batch/ProjectBatch.java index fbe69040a35..eb0f9b18db8 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/ProjectBatch.java +++ b/sonar-batch/src/main/java/org/sonar/batch/ProjectBatch.java @@ -22,13 +22,14 @@ package org.sonar.batch; import org.picocontainer.Characteristics; import org.picocontainer.MutablePicoContainer; import org.sonar.api.batch.BatchExtensionDictionnary; +import org.sonar.api.batch.FileFilter; import org.sonar.api.batch.ProjectClasspath; -import org.sonar.api.batch.ResourceCreationLock; import org.sonar.api.batch.SensorContext; import org.sonar.api.database.DatabaseSession; import org.sonar.api.measures.CoreMetrics; import org.sonar.api.measures.Metric; import org.sonar.api.measures.Metrics; +import org.sonar.api.resources.DefaultProjectFileSystem; import org.sonar.api.resources.Languages; import org.sonar.api.resources.Project; import org.sonar.api.rules.DefaultRulesManager; @@ -38,6 +39,8 @@ import org.sonar.core.qualitymodel.DefaultModelFinder; import org.sonar.core.rule.DefaultRuleFinder; import org.sonar.jpa.dao.*; +import java.util.List; + public class ProjectBatch { private MutablePicoContainer globalContainer; @@ -98,8 +101,15 @@ public class ProjectBatch { batchContainer.start(); // post-initializations + prepareProject(project, index); + } + + private void prepareProject(Project project, DefaultSonarIndex index) { project.setLanguage(getComponent(Languages.class).get(project.getLanguageKey())); index.selectProject(project, getComponent(ResourceFilters.class), getComponent(ViolationFilters.class), getComponent(MeasuresDao.class), getComponent(ViolationsDao.class)); + + List fileFilters = batchContainer.getComponents(FileFilter.class); + ((DefaultProjectFileSystem)project.getFileSystem()).addFileFilters(fileFilters); } private void loadCoreComponents(MutablePicoContainer container) { @@ -122,7 +132,7 @@ public class ProjectBatch { try { globalContainer.removeChildContainer(batchContainer); batchContainer.stop(); - batchContainer=null; + batchContainer = null; } catch (Exception e) { // do not log } diff --git a/sonar-batch/src/main/java/org/sonar/batch/ProjectBuilder.java b/sonar-batch/src/main/java/org/sonar/batch/ProjectBuilder.java deleted file mode 100644 index 3389db5e268..00000000000 --- a/sonar-batch/src/main/java/org/sonar/batch/ProjectBuilder.java +++ /dev/null @@ -1,150 +0,0 @@ -/* - * Sonar, open source software quality management tool. - * Copyright (C) 2009 SonarSource SA - * mailto:contact AT sonarsource DOT com - * - * Sonar 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. - * - * Sonar 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 Sonar; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 - */ -package org.sonar.batch; - -import org.apache.commons.configuration.*; -import org.apache.commons.lang.time.DateUtils; -import org.apache.maven.project.MavenProject; -import org.sonar.api.CoreProperties; -import org.sonar.api.database.DatabaseSession; -import org.sonar.api.database.model.ResourceModel; -import org.sonar.api.database.model.Snapshot; -import org.sonar.api.resources.DefaultProjectFileSystem; -import org.sonar.api.resources.Java; -import org.sonar.api.resources.Project; -import org.sonar.api.utils.SonarException; - -import java.text.DateFormat; -import java.text.ParseException; -import java.text.SimpleDateFormat; -import java.util.Date; - -public class ProjectBuilder { - - private DatabaseSession databaseSession; - - public ProjectBuilder(DatabaseSession databaseSession) { - this.databaseSession = databaseSession; - } - - public Project create(MavenProject pom) { - Configuration configuration = getStartupConfiguration(pom); - return new Project(loadProjectKey(pom), loadProjectBranch(configuration), pom.getName()) - .setPom(pom) - .setDescription(pom.getDescription()) - .setPackaging(pom.getPackaging()); - } - - Configuration getStartupConfiguration(MavenProject pom) { - CompositeConfiguration configuration = new CompositeConfiguration(); - configuration.addConfiguration(new SystemConfiguration()); - configuration.addConfiguration(new EnvironmentConfiguration()); - configuration.addConfiguration(new MapConfiguration(pom.getModel().getProperties())); - return configuration; - } - - String loadProjectKey(MavenProject pom) { - return new StringBuilder().append(pom.getGroupId()).append(":").append(pom.getArtifactId()).toString(); - } - - String loadProjectBranch(Configuration configuration) { - return configuration.getString(CoreProperties.PROJECT_BRANCH_PROPERTY, configuration.getString("branch" /* deprecated property */)); - } - - - public void configure(Project project) { - ProjectConfiguration projectConfiguration = new ProjectConfiguration(databaseSession, project); - configure(project, projectConfiguration); - } - - - void configure(Project project, Configuration projectConfiguration) { - Date analysisDate = loadAnalysisDate(projectConfiguration); - project.setConfiguration(projectConfiguration) - .setExclusionPatterns(loadExclusionPatterns(projectConfiguration)) - .setAnalysisDate(analysisDate) - .setLatestAnalysis(isLatestAnalysis(project.getKey(), analysisDate)) - .setAnalysisVersion(loadAnalysisVersion(projectConfiguration, project.getPom())) - .setAnalysisType(loadAnalysisType(projectConfiguration)) - .setLanguageKey(loadLanguageKey(projectConfiguration)) - .setFileSystem(new DefaultProjectFileSystem(project)); - } - - static String[] loadExclusionPatterns(Configuration configuration) { - String[] exclusionPatterns = configuration.getStringArray(CoreProperties.PROJECT_EXCLUSIONS_PROPERTY); - if (exclusionPatterns == null) { - exclusionPatterns = new String[0]; - } - return exclusionPatterns; - } - - boolean isLatestAnalysis(String projectKey, Date analysisDate) { - ResourceModel persistedProject = databaseSession.getSingleResult(ResourceModel.class, "key", projectKey, "enabled", true); - if (persistedProject != null) { - Snapshot lastSnapshot = databaseSession.getSingleResult(Snapshot.class, "resourceId", persistedProject.getId(), "last", true); - return lastSnapshot == null || lastSnapshot.getCreatedAt().before(analysisDate); - } - return true; - } - - - Date loadAnalysisDate(Configuration configuration) { - String formattedDate = configuration.getString(CoreProperties.PROJECT_DATE_PROPERTY); - if (formattedDate == null) { - return new Date(); - } - - DateFormat format = new SimpleDateFormat("yyyy-MM-dd"); - try { - // see SONAR-908 make sure that a time is defined for the date. - Date date = DateUtils.setHours(format.parse(formattedDate), 0); - return DateUtils.setMinutes(date, 1); - - } catch (ParseException e) { - throw new SonarException("The property " + CoreProperties.PROJECT_DATE_PROPERTY + " does not respect the format yyyy-MM-dd (for example 2008-05-23) : " + formattedDate, e); - } - } - - Project.AnalysisType loadAnalysisType(Configuration configuration) { - String value = configuration.getString(CoreProperties.DYNAMIC_ANALYSIS_PROPERTY); - if (value == null) { - return (configuration.getBoolean("sonar.light", false) ? Project.AnalysisType.STATIC : Project.AnalysisType.DYNAMIC); - } - if ("true".equals(value)) { - return Project.AnalysisType.DYNAMIC; - } - if ("reuseReports".equals(value)) { - return Project.AnalysisType.REUSE_REPORTS; - } - return Project.AnalysisType.STATIC; - } - - String loadAnalysisVersion(Configuration configuration, MavenProject pom) { - String version = configuration.getString(CoreProperties.PROJECT_VERSION_PROPERTY); - if (version == null && pom != null) { - version = pom.getVersion(); - } - return version; - } - - String loadLanguageKey(Configuration configuration) { - return configuration.getString(CoreProperties.PROJECT_LANGUAGE_PROPERTY, Java.KEY); - } -} diff --git a/sonar-batch/src/main/java/org/sonar/batch/ProjectTree.java b/sonar-batch/src/main/java/org/sonar/batch/ProjectTree.java index 497c4656f58..e586106b310 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/ProjectTree.java +++ b/sonar-batch/src/main/java/org/sonar/batch/ProjectTree.java @@ -35,17 +35,17 @@ public class ProjectTree { private List projects; private List poms; - private ProjectBuilder projectBuilder; + private MavenProjectBuilder projectBuilder; public ProjectTree(MavenSession mavenSession, DatabaseSession databaseSession) { this.poms = mavenSession.getSortedProjects(); - this.projectBuilder = new ProjectBuilder(databaseSession); + this.projectBuilder = new MavenProjectBuilder(databaseSession); } /** * for unit tests */ - protected ProjectTree(ProjectBuilder projectBuilder, List poms) { + protected ProjectTree(MavenProjectBuilder projectBuilder, List poms) { this.projectBuilder = projectBuilder; this.poms = poms; } diff --git a/sonar-batch/src/test/java/org/sonar/batch/MavenProjectBuilderTest.java b/sonar-batch/src/test/java/org/sonar/batch/MavenProjectBuilderTest.java new file mode 100644 index 00000000000..a35b692270a --- /dev/null +++ b/sonar-batch/src/test/java/org/sonar/batch/MavenProjectBuilderTest.java @@ -0,0 +1,210 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar 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. + * + * Sonar 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 Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.batch; + +import org.apache.commons.configuration.PropertiesConfiguration; +import org.junit.Before; +import org.junit.Test; +import org.sonar.api.CoreProperties; +import org.sonar.jpa.test.AbstractDbUnitTestCase; +import org.sonar.api.resources.Java; +import org.sonar.api.resources.Project; + +import java.text.SimpleDateFormat; +import java.util.Date; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.core.Is.is; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +public class MavenProjectBuilderTest extends AbstractDbUnitTestCase { + + private MavenProjectBuilder builder = null; + + @Before + public void before() { + builder = new MavenProjectBuilder(getSession()); + } + + @Test + public void noExclusionPatterns() { + Project project = new Project("key"); + builder.configure(project, new PropertiesConfiguration()); + + assertThat(project.getExclusionPatterns().length, is(0)); + } + + @Test + public void manyExclusionPatterns() { + PropertiesConfiguration configuration = new PropertiesConfiguration(); + configuration.setProperty(CoreProperties.PROJECT_EXCLUSIONS_PROPERTY, "**/*,foo,*/bar"); + + Project project = new Project("key"); + builder.configure(project, configuration); + + assertThat(project.getExclusionPatterns().length, is(3)); + assertThat(project.getExclusionPatterns()[0], is("**/*")); + assertThat(project.getExclusionPatterns()[1], is("foo")); + assertThat(project.getExclusionPatterns()[2], is("*/bar")); + } + + @Test + public void getLanguageFromConfiguration() { + PropertiesConfiguration configuration = new PropertiesConfiguration(); + configuration.setProperty(CoreProperties.PROJECT_LANGUAGE_PROPERTY, "foo"); + + Project project = new Project("key"); + builder.configure(project, configuration); + + assertThat(project.getLanguageKey(), is("foo")); + } + + @Test + public void defaultLanguageIsJava() { + Project project = new Project("key"); + builder.configure(project, new PropertiesConfiguration()); + + assertThat(project.getLanguageKey(), is(Java.KEY)); + } + + @Test + public void analysisIsTodayByDefault() { + Project project = new Project("key"); + builder.configure(project, new PropertiesConfiguration()); + Date today = new Date(); + assertTrue(today.getTime() - project.getAnalysisDate().getTime() < 1000); + } + + @Test + public void analysisDateCouldBeExplicitlySet() { + PropertiesConfiguration configuration = new PropertiesConfiguration(); + configuration.setProperty(CoreProperties.PROJECT_DATE_PROPERTY, "2005-01-30"); + Project project = new Project("key"); + builder.configure(project, configuration); + + assertEquals("30012005", new SimpleDateFormat("ddMMyyyy").format(project.getAnalysisDate())); + } + + @Test(expected = RuntimeException.class) + public void failIfAnalyisDateIsNotValid() { + PropertiesConfiguration configuration = new PropertiesConfiguration(); + configuration.setProperty(CoreProperties.PROJECT_DATE_PROPERTY, "2005/30/01"); + Project project = new Project("key"); + builder.configure(project, configuration); + + project.getAnalysisDate(); + } + + @Test + public void sonarLightIsDeprecated() { + PropertiesConfiguration configuration = new PropertiesConfiguration(); + configuration.setProperty("sonar.light", "true"); + Project project = new Project("key"); + builder.configure(project, configuration); + + assertThat(project.getAnalysisType(), is(Project.AnalysisType.STATIC)); + } + + @Test + public void defaultAnalysisTypeIsDynamic() { + Project project = new Project("key"); + builder.configure(project, new PropertiesConfiguration()); + assertThat(project.getAnalysisType(), is(Project.AnalysisType.DYNAMIC)); + } + + @Test + public void explicitDynamicAnalysis() { + PropertiesConfiguration configuration = new PropertiesConfiguration(); + configuration.setProperty(CoreProperties.DYNAMIC_ANALYSIS_PROPERTY, "true"); + Project project = new Project("key"); + builder.configure(project, configuration); + assertThat(project.getAnalysisType(), is(Project.AnalysisType.DYNAMIC)); + } + + @Test + public void explicitStaticAnalysis() { + PropertiesConfiguration configuration = new PropertiesConfiguration(); + configuration.setProperty(CoreProperties.DYNAMIC_ANALYSIS_PROPERTY, "false"); + Project project = new Project("key"); + builder.configure(project, configuration); + assertThat(project.getAnalysisType(), is(Project.AnalysisType.STATIC)); + } + + @Test + public void explicitDynamicAnalysisReusingReports() { + PropertiesConfiguration configuration = new PropertiesConfiguration(); + configuration.setProperty(CoreProperties.DYNAMIC_ANALYSIS_PROPERTY, "reuseReports"); + Project project = new Project("key"); + builder.configure(project, configuration); + assertThat(project.getAnalysisType(), is(Project.AnalysisType.REUSE_REPORTS)); + } + + @Test + public void isDynamicAnalysis() { + assertThat(Project.AnalysisType.DYNAMIC.isDynamic(false), is(true)); + assertThat(Project.AnalysisType.DYNAMIC.isDynamic(true), is(true)); + + assertThat(Project.AnalysisType.STATIC.isDynamic(false), is(false)); + assertThat(Project.AnalysisType.STATIC.isDynamic(true), is(false)); + + assertThat(Project.AnalysisType.REUSE_REPORTS.isDynamic(false), is(false)); + assertThat(Project.AnalysisType.REUSE_REPORTS.isDynamic(true), is(true)); + } + + @Test + public void isLatestAnalysis() { + setupData("isLatestAnalysis"); + + PropertiesConfiguration configuration = new PropertiesConfiguration(); + configuration.setProperty(CoreProperties.PROJECT_DATE_PROPERTY, "2010-12-25"); + + Project project = new Project("my:key"); + builder.configure(project, configuration); + + assertThat(project.isLatestAnalysis(), is(true)); + } + + @Test + public void isLatestAnalysisIfNeverAnalysed() { + setupData("isLatestAnalysisIfNeverAnalysed"); + + PropertiesConfiguration configuration = new PropertiesConfiguration(); + configuration.setProperty(CoreProperties.PROJECT_DATE_PROPERTY, "2010-12-25"); + + Project project = new Project("my:key"); + builder.configure(project, configuration); + + assertThat(project.isLatestAnalysis(), is(true)); + } + + @Test + public void isNotLatestAnalysis() { + setupData("isNotLatestAnalysis"); + + PropertiesConfiguration configuration = new PropertiesConfiguration(); + configuration.setProperty(CoreProperties.PROJECT_DATE_PROPERTY, "2005-12-25"); + + Project project = new Project("my:key"); + builder.configure(project, configuration); + + assertThat(project.isLatestAnalysis(), is(false)); + } +} diff --git a/sonar-batch/src/test/java/org/sonar/batch/ProjectBuilderTest.java b/sonar-batch/src/test/java/org/sonar/batch/ProjectBuilderTest.java deleted file mode 100644 index 586edaa9300..00000000000 --- a/sonar-batch/src/test/java/org/sonar/batch/ProjectBuilderTest.java +++ /dev/null @@ -1,210 +0,0 @@ -/* - * Sonar, open source software quality management tool. - * Copyright (C) 2009 SonarSource SA - * mailto:contact AT sonarsource DOT com - * - * Sonar 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. - * - * Sonar 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 Sonar; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 - */ -package org.sonar.batch; - -import org.apache.commons.configuration.PropertiesConfiguration; -import org.junit.Before; -import org.junit.Test; -import org.sonar.api.CoreProperties; -import org.sonar.jpa.test.AbstractDbUnitTestCase; -import org.sonar.api.resources.Java; -import org.sonar.api.resources.Project; - -import java.text.SimpleDateFormat; -import java.util.Date; - -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.core.Is.is; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - -public class ProjectBuilderTest extends AbstractDbUnitTestCase { - - private ProjectBuilder builder = null; - - @Before - public void before() { - builder = new ProjectBuilder(getSession()); - } - - @Test - public void noExclusionPatterns() { - Project project = new Project("key"); - builder.configure(project, new PropertiesConfiguration()); - - assertThat(project.getExclusionPatterns().length, is(0)); - } - - @Test - public void manyExclusionPatterns() { - PropertiesConfiguration configuration = new PropertiesConfiguration(); - configuration.setProperty(CoreProperties.PROJECT_EXCLUSIONS_PROPERTY, "**/*,foo,*/bar"); - - Project project = new Project("key"); - builder.configure(project, configuration); - - assertThat(project.getExclusionPatterns().length, is(3)); - assertThat(project.getExclusionPatterns()[0], is("**/*")); - assertThat(project.getExclusionPatterns()[1], is("foo")); - assertThat(project.getExclusionPatterns()[2], is("*/bar")); - } - - @Test - public void getLanguageFromConfiguration() { - PropertiesConfiguration configuration = new PropertiesConfiguration(); - configuration.setProperty(CoreProperties.PROJECT_LANGUAGE_PROPERTY, "foo"); - - Project project = new Project("key"); - builder.configure(project, configuration); - - assertThat(project.getLanguageKey(), is("foo")); - } - - @Test - public void defaultLanguageIsJava() { - Project project = new Project("key"); - builder.configure(project, new PropertiesConfiguration()); - - assertThat(project.getLanguageKey(), is(Java.KEY)); - } - - @Test - public void analysisIsTodayByDefault() { - Project project = new Project("key"); - builder.configure(project, new PropertiesConfiguration()); - Date today = new Date(); - assertTrue(today.getTime() - project.getAnalysisDate().getTime() < 1000); - } - - @Test - public void analysisDateCouldBeExplicitlySet() { - PropertiesConfiguration configuration = new PropertiesConfiguration(); - configuration.setProperty(CoreProperties.PROJECT_DATE_PROPERTY, "2005-01-30"); - Project project = new Project("key"); - builder.configure(project, configuration); - - assertEquals("30012005", new SimpleDateFormat("ddMMyyyy").format(project.getAnalysisDate())); - } - - @Test(expected = RuntimeException.class) - public void failIfAnalyisDateIsNotValid() { - PropertiesConfiguration configuration = new PropertiesConfiguration(); - configuration.setProperty(CoreProperties.PROJECT_DATE_PROPERTY, "2005/30/01"); - Project project = new Project("key"); - builder.configure(project, configuration); - - project.getAnalysisDate(); - } - - @Test - public void sonarLightIsDeprecated() { - PropertiesConfiguration configuration = new PropertiesConfiguration(); - configuration.setProperty("sonar.light", "true"); - Project project = new Project("key"); - builder.configure(project, configuration); - - assertThat(project.getAnalysisType(), is(Project.AnalysisType.STATIC)); - } - - @Test - public void defaultAnalysisTypeIsDynamic() { - Project project = new Project("key"); - builder.configure(project, new PropertiesConfiguration()); - assertThat(project.getAnalysisType(), is(Project.AnalysisType.DYNAMIC)); - } - - @Test - public void explicitDynamicAnalysis() { - PropertiesConfiguration configuration = new PropertiesConfiguration(); - configuration.setProperty(CoreProperties.DYNAMIC_ANALYSIS_PROPERTY, "true"); - Project project = new Project("key"); - builder.configure(project, configuration); - assertThat(project.getAnalysisType(), is(Project.AnalysisType.DYNAMIC)); - } - - @Test - public void explicitStaticAnalysis() { - PropertiesConfiguration configuration = new PropertiesConfiguration(); - configuration.setProperty(CoreProperties.DYNAMIC_ANALYSIS_PROPERTY, "false"); - Project project = new Project("key"); - builder.configure(project, configuration); - assertThat(project.getAnalysisType(), is(Project.AnalysisType.STATIC)); - } - - @Test - public void explicitDynamicAnalysisReusingReports() { - PropertiesConfiguration configuration = new PropertiesConfiguration(); - configuration.setProperty(CoreProperties.DYNAMIC_ANALYSIS_PROPERTY, "reuseReports"); - Project project = new Project("key"); - builder.configure(project, configuration); - assertThat(project.getAnalysisType(), is(Project.AnalysisType.REUSE_REPORTS)); - } - - @Test - public void isDynamicAnalysis() { - assertThat(Project.AnalysisType.DYNAMIC.isDynamic(false), is(true)); - assertThat(Project.AnalysisType.DYNAMIC.isDynamic(true), is(true)); - - assertThat(Project.AnalysisType.STATIC.isDynamic(false), is(false)); - assertThat(Project.AnalysisType.STATIC.isDynamic(true), is(false)); - - assertThat(Project.AnalysisType.REUSE_REPORTS.isDynamic(false), is(false)); - assertThat(Project.AnalysisType.REUSE_REPORTS.isDynamic(true), is(true)); - } - - @Test - public void isLatestAnalysis() { - setupData("isLatestAnalysis"); - - PropertiesConfiguration configuration = new PropertiesConfiguration(); - configuration.setProperty(CoreProperties.PROJECT_DATE_PROPERTY, "2010-12-25"); - - Project project = new Project("my:key"); - builder.configure(project, configuration); - - assertThat(project.isLatestAnalysis(), is(true)); - } - - @Test - public void isLatestAnalysisIfNeverAnalysed() { - setupData("isLatestAnalysisIfNeverAnalysed"); - - PropertiesConfiguration configuration = new PropertiesConfiguration(); - configuration.setProperty(CoreProperties.PROJECT_DATE_PROPERTY, "2010-12-25"); - - Project project = new Project("my:key"); - builder.configure(project, configuration); - - assertThat(project.isLatestAnalysis(), is(true)); - } - - @Test - public void isNotLatestAnalysis() { - setupData("isNotLatestAnalysis"); - - PropertiesConfiguration configuration = new PropertiesConfiguration(); - configuration.setProperty(CoreProperties.PROJECT_DATE_PROPERTY, "2005-12-25"); - - Project project = new Project("my:key"); - builder.configure(project, configuration); - - assertThat(project.isLatestAnalysis(), is(false)); - } -} diff --git a/sonar-batch/src/test/java/org/sonar/batch/ProjectTreeTest.java b/sonar-batch/src/test/java/org/sonar/batch/ProjectTreeTest.java index 8473b959f3d..8030c946b19 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/ProjectTreeTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/ProjectTreeTest.java @@ -203,7 +203,7 @@ public class ProjectTreeTest extends AbstractDbUnitTestCase { return pom; } - private ProjectBuilder newProjectBuilder() { - return new ProjectBuilder(getSession()); + private MavenProjectBuilder newProjectBuilder() { + return new MavenProjectBuilder(getSession()); } } diff --git a/sonar-batch/src/test/resources/org/sonar/batch/MavenProjectBuilderTest/isLatestAnalysis.xml b/sonar-batch/src/test/resources/org/sonar/batch/MavenProjectBuilderTest/isLatestAnalysis.xml new file mode 100644 index 00000000000..0d69b6587a4 --- /dev/null +++ b/sonar-batch/src/test/resources/org/sonar/batch/MavenProjectBuilderTest/isLatestAnalysis.xml @@ -0,0 +1,15 @@ + + + + + + + + \ No newline at end of file diff --git a/sonar-batch/src/test/resources/org/sonar/batch/MavenProjectBuilderTest/isLatestAnalysisIfNeverAnalysed.xml b/sonar-batch/src/test/resources/org/sonar/batch/MavenProjectBuilderTest/isLatestAnalysisIfNeverAnalysed.xml new file mode 100644 index 00000000000..0eecd371324 --- /dev/null +++ b/sonar-batch/src/test/resources/org/sonar/batch/MavenProjectBuilderTest/isLatestAnalysisIfNeverAnalysed.xml @@ -0,0 +1,12 @@ + + + + + + + \ No newline at end of file diff --git a/sonar-batch/src/test/resources/org/sonar/batch/MavenProjectBuilderTest/isNotLatestAnalysis.xml b/sonar-batch/src/test/resources/org/sonar/batch/MavenProjectBuilderTest/isNotLatestAnalysis.xml new file mode 100644 index 00000000000..98d5825cc37 --- /dev/null +++ b/sonar-batch/src/test/resources/org/sonar/batch/MavenProjectBuilderTest/isNotLatestAnalysis.xml @@ -0,0 +1,15 @@ + + + + + + + + \ No newline at end of file diff --git a/sonar-batch/src/test/resources/org/sonar/batch/ProjectBuilderTest/isLatestAnalysis.xml b/sonar-batch/src/test/resources/org/sonar/batch/ProjectBuilderTest/isLatestAnalysis.xml deleted file mode 100644 index 0d69b6587a4..00000000000 --- a/sonar-batch/src/test/resources/org/sonar/batch/ProjectBuilderTest/isLatestAnalysis.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/sonar-batch/src/test/resources/org/sonar/batch/ProjectBuilderTest/isLatestAnalysisIfNeverAnalysed.xml b/sonar-batch/src/test/resources/org/sonar/batch/ProjectBuilderTest/isLatestAnalysisIfNeverAnalysed.xml deleted file mode 100644 index 0eecd371324..00000000000 --- a/sonar-batch/src/test/resources/org/sonar/batch/ProjectBuilderTest/isLatestAnalysisIfNeverAnalysed.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/sonar-batch/src/test/resources/org/sonar/batch/ProjectBuilderTest/isNotLatestAnalysis.xml b/sonar-batch/src/test/resources/org/sonar/batch/ProjectBuilderTest/isNotLatestAnalysis.xml deleted file mode 100644 index 98d5825cc37..00000000000 --- a/sonar-batch/src/test/resources/org/sonar/batch/ProjectBuilderTest/isNotLatestAnalysis.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/DefaultFormulaData.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/DefaultFormulaData.java index 79a4d3ff634..3fa3da535c6 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/DefaultFormulaData.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/DefaultFormulaData.java @@ -19,12 +19,12 @@ */ package org.sonar.api.batch; +import com.google.common.collect.Lists; import org.sonar.api.measures.FormulaData; import org.sonar.api.measures.Measure; import org.sonar.api.measures.MeasuresFilter; import org.sonar.api.measures.Metric; -import java.util.ArrayList; import java.util.Collection; import java.util.List; @@ -56,7 +56,7 @@ public class DefaultFormulaData implements FormulaData { } public Collection getChildren() { - List result = new ArrayList(); + List result = Lists.newArrayList(); for (DecoratorContext childContext : decoratorContext.getChildren()) { result.add(new DefaultFormulaData(childContext)); } diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/FileFilter.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/FileFilter.java new file mode 100644 index 00000000000..5be1d69f32d --- /dev/null +++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/FileFilter.java @@ -0,0 +1,26 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar 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. + * + * Sonar 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 Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.api.batch; + +import org.sonar.api.BatchExtension; + +public abstract class FileFilter implements java.io.FileFilter, BatchExtension { + +} diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/ProjectClasspath.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/ProjectClasspath.java index 18a86fd9893..03337afa5e7 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/ProjectClasspath.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/ProjectClasspath.java @@ -19,6 +19,7 @@ */ package org.sonar.api.batch; +import com.google.common.collect.Lists; import org.apache.maven.artifact.DependencyResolutionRequiredException; import org.apache.maven.project.MavenProject; import org.sonar.api.BatchComponent; @@ -28,7 +29,6 @@ import java.io.File; import java.net.MalformedURLException; import java.net.URL; import java.net.URLClassLoader; -import java.util.ArrayList; import java.util.List; /** @@ -63,7 +63,7 @@ public class ProjectClasspath implements BatchComponent { protected URLClassLoader createClassLoader() { try { - List urls = new ArrayList(); + List urls = Lists.newArrayList(); for (File file : getElements()) { urls.add(file.toURI().toURL()); } @@ -76,7 +76,7 @@ public class ProjectClasspath implements BatchComponent { protected List createElements() { try { - List files = new ArrayList(); + List files = Lists.newArrayList(); if (pom.getCompileClasspathElements() != null) { for (String classPathString : (List) pom.getCompileClasspathElements()) { files.add(new File(classPathString)); diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/resources/DefaultProjectFileSystem.java b/sonar-plugin-api/src/main/java/org/sonar/api/resources/DefaultProjectFileSystem.java index 1c04e67b0a5..d66011d11a1 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/resources/DefaultProjectFileSystem.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/resources/DefaultProjectFileSystem.java @@ -19,11 +19,13 @@ */ package org.sonar.api.resources; +import com.google.common.collect.Lists; import org.apache.commons.io.FileUtils; import org.apache.commons.io.FilenameUtils; import org.apache.commons.io.filefilter.*; import org.apache.commons.lang.CharEncoding; import org.apache.commons.lang.StringUtils; +import org.sonar.api.batch.FileFilter; import org.sonar.api.batch.maven.MavenUtils; import org.sonar.api.utils.SonarException; import org.sonar.api.utils.WildcardPattern; @@ -43,6 +45,7 @@ import java.util.List; public class DefaultProjectFileSystem implements ProjectFileSystem { private Project project; + private List filters = Lists.newArrayList(); /** * Creates a DefaultProjectFileSystem based on a project @@ -61,6 +64,18 @@ public class DefaultProjectFileSystem implements ProjectFileSystem { } + public DefaultProjectFileSystem addFileFilters(List l) { + for (FileFilter fileFilter : l) { + addFileFilter(fileFilter); + } + return this; + } + + public DefaultProjectFileSystem addFileFilter(FileFilter fileFilter) { + filters.add(new DelegateFileFilter(fileFilter)); + return this; + } + /** * Basedir is the project root directory. */ @@ -214,8 +229,9 @@ public class DefaultProjectFileSystem implements ProjectFileSystem { if (dir.exists()) { IOFileFilter exclusionFilter = new ExclusionFilter(dir, exclusionPatterns); IOFileFilter visibleFileFilter = HiddenFileFilter.VISIBLE; - AndFileFilter filters = new AndFileFilter(new AndFileFilter(exclusionFilter, suffixFilter), visibleFileFilter); - result.addAll(FileUtils.listFiles(dir, filters, HiddenFileFilter.VISIBLE)); + List dirFilters = Lists.newArrayList(visibleFileFilter, suffixFilter, exclusionFilter); + dirFilters.addAll(this.filters); + result.addAll(FileUtils.listFiles(dir, new AndFileFilter(dirFilters), HiddenFileFilter.VISIBLE)); } } return result; @@ -233,7 +249,7 @@ public class DefaultProjectFileSystem implements ProjectFileSystem { private IOFileFilter getFileSuffixFilter(Language... langs) { IOFileFilter suffixFilter = FileFilterUtils.trueFileFilter(); - if (langs != null && langs.length>0) { + if (langs != null && langs.length > 0) { List suffixes = new ArrayList(); for (Language lang : langs) { if (lang.getFileSuffixes() != null) { @@ -346,5 +362,4 @@ public class DefaultProjectFileSystem implements ProjectFileSystem { } return false; } - } diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/resources/DefaultProjectFileSystemTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/resources/DefaultProjectFileSystemTest.java index 82e6574c544..4aa606b97e4 100644 --- a/sonar-plugin-api/src/test/java/org/sonar/api/resources/DefaultProjectFileSystemTest.java +++ b/sonar-plugin-api/src/test/java/org/sonar/api/resources/DefaultProjectFileSystemTest.java @@ -19,12 +19,14 @@ */ package org.sonar.api.resources; +import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.SystemUtils; import org.hamcrest.Description; import org.hamcrest.Matcher; import org.hamcrest.TypeSafeMatcher; import org.junit.Before; import org.junit.Test; +import org.sonar.api.batch.FileFilter; import org.sonar.api.test.MavenTestUtils; import java.io.File; @@ -32,6 +34,7 @@ import java.util.List; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.Matchers.hasItem; +import static org.hamcrest.Matchers.not; import static org.junit.Assert.assertThat; public class DefaultProjectFileSystemTest { @@ -156,6 +159,22 @@ public class DefaultProjectFileSystemTest { } } + + @Test + public void shouldAddExtendedFilters() { + DefaultProjectFileSystem fs = new DefaultProjectFileSystem(project); + assertThat(fs.getSourceFiles().size(), is(2)); + assertThat(fs.getSourceFiles(), hasItem(named("Bar.java"))); + + fs.addFileFilter(new FileFilter() { + public boolean accept(File file) { + return !StringUtils.equals(file.getName(), "Bar.java"); + } + }); + assertThat(fs.getSourceFiles().size(), is(1)); + assertThat(fs.getSourceFiles(), not(hasItem(named("Bar.java")))); + } + private static Matcher named(final String name) { return new TypeSafeMatcher() { java.io.File fileTested;