diff options
Diffstat (limited to 'sonar-batch')
11 files changed, 300 insertions, 116 deletions
diff --git a/sonar-batch/src/main/java/org/sonar/batch/components/PastSnapshot.java b/sonar-batch/src/main/java/org/sonar/batch/components/PastSnapshot.java index 24c0ae618c8..eb70abbbc0e 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/components/PastSnapshot.java +++ b/sonar-batch/src/main/java/org/sonar/batch/components/PastSnapshot.java @@ -26,6 +26,7 @@ import org.sonar.api.database.model.Snapshot; import org.sonar.api.utils.DateUtils; import javax.annotation.Nullable; + import java.util.Calendar; import java.util.Date; @@ -76,6 +77,11 @@ public class PastSnapshot { return projectSnapshot != null ? projectSnapshot.getCreatedAt() : null; } + public PastSnapshot setMode(String mode) { + this.mode = mode; + return this; + } + public String getMode() { return mode; } diff --git a/sonar-batch/src/main/java/org/sonar/batch/components/PastSnapshotFinderByDate.java b/sonar-batch/src/main/java/org/sonar/batch/components/PastSnapshotFinderByDate.java index 0af30a75648..dae7a48cff4 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/components/PastSnapshotFinderByDate.java +++ b/sonar-batch/src/main/java/org/sonar/batch/components/PastSnapshotFinderByDate.java @@ -43,18 +43,27 @@ public class PastSnapshotFinderByDate implements BatchExtension { PastSnapshot findByDate(Snapshot projectSnapshot, Date date) { Snapshot snapshot = null; if (projectSnapshot != null) { - snapshot = findSnapshot(projectSnapshot, date); + snapshot = findSnapshot(projectSnapshot.getResourceId(), date); + } + SimpleDateFormat format = new SimpleDateFormat(DateUtils.DATE_FORMAT); + return new PastSnapshot(CoreProperties.TIMEMACHINE_MODE_DATE, date, snapshot).setModeParameter(format.format(date)); + } + + PastSnapshot findByDate(Integer projectId, Date date) { + Snapshot snapshot = null; + if (projectId != null) { + snapshot = findSnapshot(projectId, date); } SimpleDateFormat format = new SimpleDateFormat(DateUtils.DATE_FORMAT); return new PastSnapshot(CoreProperties.TIMEMACHINE_MODE_DATE, date, snapshot).setModeParameter(format.format(date)); } @Nullable - private Snapshot findSnapshot(Snapshot projectSnapshot, Date date) { + private Snapshot findSnapshot(Integer projectId, Date date) { String hql = "from " + Snapshot.class.getSimpleName() + " where createdAt>=:date AND resourceId=:resourceId AND status=:status AND qualifier<>:lib order by createdAt asc"; List<Snapshot> snapshots = session.createQuery(hql) .setParameter("date", date) - .setParameter("resourceId", projectSnapshot.getResourceId()) + .setParameter("resourceId", projectId) .setParameter("status", Snapshot.STATUS_PROCESSED) .setParameter("lib", Qualifiers.LIBRARY) .setMaxResults(1) diff --git a/sonar-batch/src/main/java/org/sonar/batch/components/Period.java b/sonar-batch/src/main/java/org/sonar/batch/components/Period.java new file mode 100644 index 00000000000..04bdc89418f --- /dev/null +++ b/sonar-batch/src/main/java/org/sonar/batch/components/Period.java @@ -0,0 +1,48 @@ +/* + * 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.components; + +import java.util.Date; + +public class Period { + + private int index; + private Date targetDate; + private Date date; + + public Period(int index, Date targetDate, Date date) { + this.index = index; + this.targetDate = targetDate; + this.date = date; + } + + public int getIndex() { + return index; + } + + public Date getTargetDate() { + return targetDate; + } + + public Date getDate() { + return date; + } +} diff --git a/sonar-batch/src/main/java/org/sonar/batch/components/PeriodsDefinition.java b/sonar-batch/src/main/java/org/sonar/batch/components/PeriodsDefinition.java new file mode 100644 index 00000000000..cbbc943e728 --- /dev/null +++ b/sonar-batch/src/main/java/org/sonar/batch/components/PeriodsDefinition.java @@ -0,0 +1,97 @@ +/* + * 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.components; + +import org.sonar.api.BatchComponent; +import org.sonar.api.config.Settings; +import org.sonar.api.database.DatabaseSession; +import org.sonar.api.database.model.Snapshot; +import org.sonar.api.resources.Qualifiers; +import org.sonar.batch.ProjectTree; + +import javax.persistence.Query; + +import java.util.Date; +import java.util.List; + +import static com.google.common.collect.Lists.newLinkedList; + +public class PeriodsDefinition implements BatchComponent { + + public static final int CORE_TENDENCY_DEPTH_DEFAULT_VALUE = 30; + private static final int NUMBER_OF_VARIATION_SNAPSHOTS = 5; + + private DatabaseSession session; + + private ProjectTree projectTree; + private final Settings settings; + + private List<PastSnapshot> projectPastSnapshots; + + public PeriodsDefinition(DatabaseSession session, ProjectTree projectTree, Settings settings, + PastSnapshotFinder pastSnapshotFinder) { + this.session = session; + this.projectTree = projectTree; + this.settings = settings; + initPastSnapshots(pastSnapshotFinder, projectTree.getRootProject().getQualifier()); + } + + private void initPastSnapshots(PastSnapshotFinder pastSnapshotFinder, String rootQualifier) { + Snapshot projectSnapshot = buildProjectSnapshot(); + projectPastSnapshots = newLinkedList(); + if (projectSnapshot != null) { + for (int index = 1; index <= NUMBER_OF_VARIATION_SNAPSHOTS; index++) { + PastSnapshot pastSnapshot = pastSnapshotFinder.find(projectSnapshot, rootQualifier, settings, index); + // SONAR-4700 Add a past snapshot only if it exists + if (pastSnapshot != null && pastSnapshot.getProjectSnapshot() != null) { + projectPastSnapshots.add(pastSnapshot); + } + } + } + } + + private Snapshot buildProjectSnapshot() { + Query query = session + .createNativeQuery("select p.id from projects p where p.kee=:resourceKey and p.qualifier<>:lib and p.enabled=:enabled"); + query.setParameter("resourceKey", projectTree.getRootProject().getKey()); + query.setParameter("lib", Qualifiers.LIBRARY); + query.setParameter("enabled", Boolean.TRUE); + + Snapshot snapshot = null; + Number projectId = session.getSingleResult(query, null); + if (projectId != null) { + snapshot = new Snapshot(); + snapshot.setResourceId(projectId.intValue()); + snapshot.setCreatedAt(projectTree.getRootProject().getAnalysisDate()); + snapshot.setBuildDate(new Date()); + snapshot.setVersion(projectTree.getRootProject().getAnalysisVersion()); + } + return snapshot; + } + + /** + * @return past snapshots of root project + */ + public List<PastSnapshot> projectPastSnapshots() { + return projectPastSnapshots; + } + +} diff --git a/sonar-batch/src/main/java/org/sonar/batch/components/TimeMachineConfiguration.java b/sonar-batch/src/main/java/org/sonar/batch/components/TimeMachineConfiguration.java index 89d83f939ea..8ef7570ff6a 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/components/TimeMachineConfiguration.java +++ b/sonar-batch/src/main/java/org/sonar/batch/components/TimeMachineConfiguration.java @@ -19,84 +19,49 @@ */ package org.sonar.batch.components; -import com.google.common.collect.Lists; import org.apache.commons.lang.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.sonar.api.BatchExtension; -import org.sonar.api.config.Settings; -import org.sonar.api.database.DatabaseSession; -import org.sonar.api.database.model.Snapshot; import org.sonar.api.resources.Project; import org.sonar.api.resources.Qualifiers; -import javax.persistence.Query; - -import java.util.Date; import java.util.List; +import static com.google.common.collect.Lists.newLinkedList; + public class TimeMachineConfiguration implements BatchExtension { private static final Logger LOG = LoggerFactory.getLogger(TimeMachineConfiguration.class); - private static final int NUMBER_OF_VARIATION_SNAPSHOTS = 5; - private static final int CORE_TENDENCY_DEPTH_DEFAULT_VALUE = 30; - private Project project; - private final Settings settings; - private List<PastSnapshot> projectPastSnapshots; - private DatabaseSession session; + private final PeriodsDefinition periodsDefinition; - public TimeMachineConfiguration(DatabaseSession session, Project project, Settings settings, - PastSnapshotFinder pastSnapshotFinder) { - this.session = session; - this.project = project; - this.settings = settings; - initPastSnapshots(pastSnapshotFinder, getRootProject(project).getQualifier()); - } + private List<Period> periods; + private List<PastSnapshot> modulePastSnapshots; - private Project getRootProject(Project project) { - if (!project.isRoot()) { - return getRootProject(project.getRoot()); - } - return project; + public TimeMachineConfiguration(Project project, PeriodsDefinition periodsDefinition, PastSnapshotFinderByDate pastSnapshotFinderByDate) { + this.project = project; + this.periodsDefinition = periodsDefinition; + initModulePastSnapshots(pastSnapshotFinderByDate); } - private void initPastSnapshots(PastSnapshotFinder pastSnapshotFinder, String rootQualifier) { - Snapshot projectSnapshot = buildProjectSnapshot(); - - projectPastSnapshots = Lists.newLinkedList(); - if (projectSnapshot != null) { - for (int index = 1; index <= NUMBER_OF_VARIATION_SNAPSHOTS; index++) { - PastSnapshot pastSnapshot = pastSnapshotFinder.find(projectSnapshot, rootQualifier, settings, index); - // SONAR-4700 Add a past snapshot only if it exists - if (pastSnapshot != null && pastSnapshot.getProjectSnapshot() != null) { - log(pastSnapshot); - projectPastSnapshots.add(pastSnapshot); - } + private void initModulePastSnapshots(PastSnapshotFinderByDate pastSnapshotFinderByDate) { + periods = newLinkedList(); + modulePastSnapshots = newLinkedList(); + for (PastSnapshot projectPastSnapshot : periodsDefinition.projectPastSnapshots()) { + PastSnapshot pastSnapshot = pastSnapshotFinderByDate.findByDate(project.getId(), projectPastSnapshot.getTargetDate()); + if (pastSnapshot != null) { + pastSnapshot.setIndex(projectPastSnapshot.getIndex()); + pastSnapshot.setMode(projectPastSnapshot.getMode()); + pastSnapshot.setModeParameter(projectPastSnapshot.getModeParameter()); + modulePastSnapshots.add(pastSnapshot); + periods.add(new Period(projectPastSnapshot.getIndex(), pastSnapshot.getTargetDate(), pastSnapshot.getDate())); + log(pastSnapshot); } } } - private Snapshot buildProjectSnapshot() { - Query query = session - .createNativeQuery("select p.id from projects p where p.kee=:resourceKey and p.qualifier<>:lib and p.enabled=:enabled"); - query.setParameter("resourceKey", project.getKey()); - query.setParameter("lib", Qualifiers.LIBRARY); - query.setParameter("enabled", Boolean.TRUE); - - Snapshot snapshot = null; - Number projectId = session.getSingleResult(query, null); - if (projectId != null) { - snapshot = new Snapshot(); - snapshot.setResourceId(projectId.intValue()); - snapshot.setCreatedAt(project.getAnalysisDate()); - snapshot.setBuildDate(new Date()); - snapshot.setVersion(project.getAnalysisVersion()); - } - return snapshot; - } - private void log(PastSnapshot pastSnapshot) { String qualifier = pastSnapshot.getQualifier(); // hack to avoid too many logs when the views plugin is installed @@ -107,11 +72,14 @@ public class TimeMachineConfiguration implements BatchExtension { } } - public int getTendencyPeriodInDays() { - return CORE_TENDENCY_DEPTH_DEFAULT_VALUE; + public List<Period> periods() { + return periods; } - public List<PastSnapshot> getProjectPastSnapshots() { - return projectPastSnapshots; + /** + * Only used by VariationDecorator + */ + public List<PastSnapshot> modulePastSnapshots() { + return modulePastSnapshots; } } 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 1cbea0605f8..293ad2c065f 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 @@ -28,13 +28,7 @@ import org.sonar.api.platform.ComponentContainer; import org.sonar.api.resources.Languages; import org.sonar.api.resources.Project; import org.sonar.api.scan.filesystem.FileExclusions; -import org.sonar.batch.DefaultProjectClasspath; -import org.sonar.batch.DefaultSensorContext; -import org.sonar.batch.DefaultTimeMachine; -import org.sonar.batch.ProfileProvider; -import org.sonar.batch.ProjectTree; -import org.sonar.batch.ResourceFilters; -import org.sonar.batch.ViolationFilters; +import org.sonar.batch.*; import org.sonar.batch.bootstrap.BatchExtensionDictionnary; import org.sonar.batch.bootstrap.ExtensionInstaller; import org.sonar.batch.bootstrap.ExtensionMatcher; diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan/ProjectScanContainer.java b/sonar-batch/src/main/java/org/sonar/batch/scan/ProjectScanContainer.java index 4b8a82fbe4b..c936b06376b 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/scan/ProjectScanContainer.java +++ b/sonar-batch/src/main/java/org/sonar/batch/scan/ProjectScanContainer.java @@ -35,6 +35,7 @@ import org.sonar.batch.DefaultResourceCreationLock; import org.sonar.batch.ProjectConfigurator; import org.sonar.batch.ProjectTree; import org.sonar.batch.bootstrap.*; +import org.sonar.batch.components.PeriodsDefinition; import org.sonar.batch.index.*; import org.sonar.batch.issue.*; import org.sonar.batch.phases.GraphPersister; @@ -155,6 +156,9 @@ public class ProjectScanContainer extends ComponentContainer { LinearWithThresholdFunction.class, Functions.class, + // Differential periods + PeriodsDefinition.class, + ProjectSettingsReady.class); } diff --git a/sonar-batch/src/test/java/org/sonar/batch/components/PastSnapshotFinderTest.java b/sonar-batch/src/test/java/org/sonar/batch/components/PastSnapshotFinderTest.java index 9348eb38cef..f8d947435c0 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/components/PastSnapshotFinderTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/components/PastSnapshotFinderTest.java @@ -144,7 +144,7 @@ public class PastSnapshotFinderTest { public void should_find_by_date() throws ParseException { final SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd"); final Date date = format.parse("2010-05-18"); - when(finderByDate.findByDate(null, date)).thenReturn(new PastSnapshot("date", date, new Snapshot())); + when(finderByDate.findByDate((Snapshot)null, date)).thenReturn(new PastSnapshot("date", date, new Snapshot())); PastSnapshot variationSnapshot = finder.find(null, 2, "2010-05-18"); diff --git a/sonar-batch/src/test/java/org/sonar/batch/components/PeriodsDefinitionTest.java b/sonar-batch/src/test/java/org/sonar/batch/components/PeriodsDefinitionTest.java new file mode 100644 index 00000000000..a5ffc91b1a1 --- /dev/null +++ b/sonar-batch/src/test/java/org/sonar/batch/components/PeriodsDefinitionTest.java @@ -0,0 +1,72 @@ +/* + * 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.components; + +import org.junit.Before; +import org.junit.Test; +import org.mockito.ArgumentMatcher; +import org.sonar.api.config.Settings; +import org.sonar.api.database.model.Snapshot; +import org.sonar.api.resources.Project; +import org.sonar.batch.ProjectTree; +import org.sonar.jpa.test.AbstractDbUnitTestCase; + +import static org.mockito.Matchers.anyString; +import static org.mockito.Matchers.argThat; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.*; + +public class PeriodsDefinitionTest extends AbstractDbUnitTestCase { + + private Settings settings; + private PastSnapshotFinder pastSnapshotFinder; + + @Before + public void before() { + setupData("shared"); + settings = new Settings(); + pastSnapshotFinder = mock(PastSnapshotFinder.class); + } + + @Test + public void should_init_past_snapshots() { + ProjectTree projectTree = mock(ProjectTree.class); + when(projectTree.getRootProject()).thenReturn(new Project("my:project")); + new PeriodsDefinition(getSession(), projectTree, settings, pastSnapshotFinder); + + verify(pastSnapshotFinder).find(argThat(new ArgumentMatcher<Snapshot>() { + @Override + public boolean matches(Object o) { + return ((Snapshot) o).getResourceId() == 2 /* see database in shared.xml */; + } + }), anyString(), eq(settings), eq(1)); + } + + @Test + public void should_not_init_past_snapshots_if_first_analysis() { + ProjectTree projectTree = mock(ProjectTree.class); + when(projectTree.getRootProject()).thenReturn(new Project("new:project")); + + new PeriodsDefinition(getSession(), projectTree, settings, pastSnapshotFinder); + + verifyZeroInteractions(pastSnapshotFinder); + } +} diff --git a/sonar-batch/src/test/java/org/sonar/batch/components/TimeMachineConfigurationTest.java b/sonar-batch/src/test/java/org/sonar/batch/components/TimeMachineConfigurationTest.java index dd64e3697ed..78a5b3d2e36 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/components/TimeMachineConfigurationTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/components/TimeMachineConfigurationTest.java @@ -19,50 +19,36 @@ */ package org.sonar.batch.components; -import org.junit.Before; -import org.junit.Test; -import org.mockito.ArgumentMatcher; -import org.sonar.api.config.Settings; -import org.sonar.api.database.model.Snapshot; -import org.sonar.api.resources.Project; -import org.sonar.jpa.test.AbstractDbUnitTestCase; - -import static org.mockito.Matchers.anyString; -import static org.mockito.Matchers.argThat; -import static org.mockito.Matchers.eq; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.verifyZeroInteractions; - -public class TimeMachineConfigurationTest extends AbstractDbUnitTestCase { - - private Settings settings; - private PastSnapshotFinder pastSnapshotFinder; - - @Before - public void before() { - setupData("shared"); - settings = new Settings(); - pastSnapshotFinder = mock(PastSnapshotFinder.class); - } - - @Test - public void should_init_past_snapshots() { - new TimeMachineConfiguration(getSession(), new Project("my:project"), settings, pastSnapshotFinder); - - verify(pastSnapshotFinder).find(argThat(new ArgumentMatcher<Snapshot>() { - @Override - public boolean matches(Object o) { - return ((Snapshot) o).getResourceId() == 2 /* see database in shared.xml */; - } - }), anyString(), eq(settings), eq(1)); - } - - @Test - public void should_not_init_past_snapshots_if_first_analysis() { - new TimeMachineConfiguration(getSession(), new Project("new:project"), settings, pastSnapshotFinder); - - verifyZeroInteractions(pastSnapshotFinder); - } +public class TimeMachineConfigurationTest { + + private PeriodsDefinition periodsDefinition; + private PastSnapshotFinderByDate pastSnapshotFinderByDate; + +// @Before +// public void before() { +// periodsDefinition = mock(PeriodsDefinition.class); +// pastSnapshotFinderByDate = mock(PastSnapshotFinderByDate.class); +// } +// +// @Test +// public void should_init_past_snapshots() { +// Integer projectId = 1; +// Date date = new Date(); +// +// PastSnapshot projectPastSnapshot = new PastSnapshot("mode", projectId); +// +// when(periodsDefinition.projectPastSnapshots()).thenReturn(newArrayList(new PastSnapshot("mode", projectId))); +// when(pastSnapshotFinderByDate.findByDate(projectId, date)).thenReturn(newArrayList(new PastSnapshot("mode", new Date()))); +// +// TimeMachineConfiguration timeMachineConfiguration = new TimeMachineConfiguration((Project) new Project("my:project").setId(projectId), periodsDefinition, pastSnapshotFinderByDate); +// assertThat(timeMachineConfiguration.periods()).hasSize(1); +// } +// +// @Test +// public void should_not_init_past_snapshots_if_first_analysis() { +//// new TimeMachineConfiguration(new Project("new:project"), settings, pastSnapshotFinder); +//// +//// verifyZeroInteractions(pastSnapshotFinder); +// } } diff --git a/sonar-batch/src/test/resources/org/sonar/batch/components/TimeMachineConfigurationTest/shared.xml b/sonar-batch/src/test/resources/org/sonar/batch/components/PeriodsDefinitionTest/shared.xml index c8796e2bb80..c8796e2bb80 100644 --- a/sonar-batch/src/test/resources/org/sonar/batch/components/TimeMachineConfigurationTest/shared.xml +++ b/sonar-batch/src/test/resources/org/sonar/batch/components/PeriodsDefinitionTest/shared.xml |