description = "Period used to compare measures and track new violations. Values are : <ul class='bullet'><li>Number of days before analysis, for example 5.</li><li>A custom date. Format is yyyy-MM-dd, for example 2010-12-25</li><li>'previous_analysis' to compare to previous analysis</li><li>A version, for example 1.2</li></ul>",
project = false,
global = true,
- defaultValue = PastSnapshotFinder.DEFAULT_VALUE_1
+ defaultValue = CoreProperties.TIMEMACHINE_DEFAULT_PERIOD_1
),
@Property(
key = "sonar.timemachine.period2",
description = "See the property 'Period 1'",
project = false,
global = true,
- defaultValue = PastSnapshotFinder.DEFAULT_VALUE_2
+ defaultValue = CoreProperties.TIMEMACHINE_DEFAULT_PERIOD_2
),
@Property(
key = "sonar.timemachine.period3",
description = "See the property 'Period 1'",
project = false,
global = true,
- defaultValue = PastSnapshotFinder.DEFAULT_VALUE_3
+ defaultValue = CoreProperties.TIMEMACHINE_DEFAULT_PERIOD_3
),
@Property(
key = "sonar.timemachine.period4",
name = "Period 4",
description = "Period used to compare measures and track new violations. This property is specific to the project. Values are : <ul class='bullet'><li>Number of days before analysis, for example 5.</li><li>A custom date. Format is yyyy-MM-dd, for example 2010-12-25</li><li>'previous_analysis' to compare to previous analysis</li><li>A version, for example 1.2</li></ul>",
project = true,
- global = false
+ global = false,
+ defaultValue = CoreProperties.TIMEMACHINE_DEFAULT_PERIOD_4
),
@Property(
key = "sonar.timemachine.period5",
name = "Period 5",
description = "See the property 'Period 4'",
project = true,
- global = false
+ global = false,
+ defaultValue = CoreProperties.TIMEMACHINE_DEFAULT_PERIOD_5
)
})
public class CorePlugin implements Plugin {
// time machine
extensions.add(TendencyDecorator.class);
- extensions.add(PastSnapshotFinderByDate.class);
- extensions.add(PastSnapshotFinderByDays.class);
- extensions.add(PastSnapshotFinderByPreviousAnalysis.class);
- extensions.add(PastSnapshotFinderByVersion.class);
- extensions.add(PastMeasuresLoader.class);
- extensions.add(PastSnapshotFinder.class);
- extensions.add(TimeMachineConfiguration.class);
extensions.add(VariationDecorator.class);
- extensions.add(PastViolationsLoader.class);
extensions.add(ViolationPersisterDecorator.class);
extensions.add(NewViolationsDecorator.class);
extensions.add(TimeMachineConfigurationPersister.class);
package org.sonar.plugins.core.timemachine;
import com.google.common.collect.*;
-import org.apache.commons.lang.time.DateUtils;
import org.sonar.api.batch.Decorator;
import org.sonar.api.batch.DecoratorContext;
import org.sonar.api.batch.DependedUpon;
import org.sonar.api.rules.Rule;
import org.sonar.api.rules.RulePriority;
import org.sonar.api.rules.Violation;
+import org.sonar.batch.components.PastSnapshot;
+import org.sonar.batch.components.TimeMachineConfiguration;
import java.util.*;
+++ /dev/null
-/*
- * 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.plugins.core.timemachine;
-
-import com.google.common.collect.Maps;
-import org.apache.commons.lang.ObjectUtils;
-import org.sonar.api.BatchExtension;
-import org.sonar.api.database.DatabaseSession;
-import org.sonar.api.database.model.MeasureModel;
-import org.sonar.api.database.model.Snapshot;
-import org.sonar.api.measures.Metric;
-import org.sonar.api.measures.MetricFinder;
-import org.sonar.api.resources.Resource;
-
-import java.util.Collection;
-import java.util.List;
-import java.util.Map;
-
-public class PastMeasuresLoader implements BatchExtension {
-
- private Map<Integer, Metric> metricByIds;
- private DatabaseSession session;
-
- public PastMeasuresLoader(DatabaseSession session, MetricFinder metricFinder) {
- this(session, metricFinder.findAll());
- }
-
- PastMeasuresLoader(DatabaseSession session, Collection<Metric> metrics) {
- this.session = session;
- this.metricByIds = Maps.newHashMap();
- for (Metric metric : metrics) {
- if (metric.isNumericType()) {
- metricByIds.put(metric.getId(), metric);
- }
- }
- }
-
- public Collection<Metric> getMetrics() {
- return metricByIds.values();
- }
-
- public List<MeasureModel> getPastMeasures(Resource resource, PastSnapshot projectPastSnapshot) {
- return getPastMeasures(resource, projectPastSnapshot.getProjectSnapshot());
- }
-
- public List<MeasureModel> getPastMeasures(Resource resource, Snapshot projectSnapshot) {
- // assume that the resource has already been saved
- return getPastMeasures(resource.getId(), projectSnapshot);
- }
-
- public List<MeasureModel> getPastMeasures(int resourceId, Snapshot projectSnapshot) {
- // TODO improvement : select only some columns
- // TODO support measure on characteristics
- String hql = "select m from " + MeasureModel.class.getSimpleName() + " m, " + Snapshot.class.getSimpleName() + " s " +
- "where m.snapshotId=s.id and m.metricId in (:metricIds) and m.ruleId=null and m.rulePriority=null and m.characteristic=null "
- + "and (s.rootId=:rootSnapshotId or s.id=:rootSnapshotId) and s.resourceId=:resourceId and s.status=:status";
- return session.createQuery(hql)
- .setParameter("metricIds", metricByIds.keySet())
- .setParameter("rootSnapshotId", ObjectUtils.defaultIfNull(projectSnapshot.getRootId(), projectSnapshot.getId()))
- .setParameter("resourceId", resourceId)
- .setParameter("status", Snapshot.STATUS_PROCESSED)
- .getResultList();
- }
-}
+++ /dev/null
-/*
- * 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.plugins.core.timemachine;
-
-import org.apache.commons.lang.builder.ReflectionToStringBuilder;
-import org.sonar.api.database.model.Snapshot;
-
-import java.util.Date;
-
-public class PastSnapshot {
-
- private int index;
- private String mode, modeParameter;
- private Snapshot projectSnapshot;
- private Date targetDate;
-
- public PastSnapshot(String mode, Date targetDate, Snapshot projectSnapshot) {
- this.mode = mode;
- this.targetDate = targetDate;
- this.projectSnapshot = projectSnapshot;
- }
-
- public PastSnapshot(String mode, Snapshot projectSnapshot) {
- this.mode = mode;
- this.projectSnapshot = projectSnapshot;
- }
-
- public PastSnapshot setIndex(int index) {
- this.index = index;
- return this;
- }
-
- public int getIndex() {
- return index;
- }
-
- public Snapshot getProjectSnapshot() {
- return projectSnapshot;
- }
-
- public Date getDate() {
- return projectSnapshot.getCreatedAt();
- }
-
- public String getMode() {
- return mode;
- }
-
- public String getModeParameter() {
- return modeParameter;
- }
-
- public PastSnapshot setModeParameter(String s) {
- this.modeParameter = s;
- return this;
- }
-
- public Integer getProjectSnapshotId() {
- return (projectSnapshot!=null ? projectSnapshot.getId() : null);
- }
-
- public Date getTargetDate() {
- return targetDate;
- }
-
- public PastSnapshot setTargetDate(Date d) {
- this.targetDate = d;
- return this;
- }
-
- @Override
- public String toString() {
- return ReflectionToStringBuilder.toString(this);
- }
-}
+++ /dev/null
-/*
- * 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.plugins.core.timemachine;
-
-import org.apache.commons.configuration.Configuration;
-import org.apache.commons.lang.StringUtils;
-import org.sonar.api.BatchExtension;
-import org.sonar.api.utils.Logs;
-
-import java.text.ParseException;
-import java.text.SimpleDateFormat;
-import java.util.Date;
-
-public class PastSnapshotFinder implements BatchExtension {
-
- /**
- * IMPORTANT : please update default values in the ruby side too. See app/helpers/FiltersHelper.rb, method period_names()
- */
- public static final String DEFAULT_VALUE_1 = PastSnapshotFinderByPreviousAnalysis.MODE;
- public static final String DEFAULT_VALUE_2 = "5";
- public static final String DEFAULT_VALUE_3 = "30";
- public static final String PROPERTY_PREFIX = "sonar.timemachine.period";
-
- private PastSnapshotFinderByDays finderByDays;
- private PastSnapshotFinderByVersion finderByVersion;
- private PastSnapshotFinderByDate finderByDate;
- private PastSnapshotFinderByPreviousAnalysis finderByPreviousAnalysis;
-
- public PastSnapshotFinder(PastSnapshotFinderByDays finderByDays, PastSnapshotFinderByVersion finderByVersion,
- PastSnapshotFinderByDate finderByDate, PastSnapshotFinderByPreviousAnalysis finderByPreviousAnalysis) {
- this.finderByDays = finderByDays;
- this.finderByVersion = finderByVersion;
- this.finderByDate = finderByDate;
- this.finderByPreviousAnalysis = finderByPreviousAnalysis;
- }
-
- public PastSnapshot find(Configuration conf, int index) {
- String propertyValue = getPropertyValue(conf, index);
- PastSnapshot pastSnapshot = find(index, propertyValue);
- if (pastSnapshot==null && StringUtils.isNotBlank(propertyValue)) {
- Logs.INFO.warn("The property " + PROPERTY_PREFIX + index + " has an unvalid value: " + propertyValue);
- }
- return pastSnapshot;
- }
-
- static String getPropertyValue(Configuration conf, int index) {
- String defaultValue = null;
- switch (index) {
- // only global settings (from 1 to 3) have default values
- case 1: defaultValue = DEFAULT_VALUE_1; break;
- case 2: defaultValue = DEFAULT_VALUE_2; break;
- case 3: defaultValue = DEFAULT_VALUE_3; break;
- }
- return conf.getString(PROPERTY_PREFIX + index, defaultValue);
- }
-
- public PastSnapshot find(int index, String property) {
- if (StringUtils.isBlank(property)) {
- return null;
- }
-
- PastSnapshot result = findByDays(property);
- if (result == null) {
- result = findByDate(property);
- if (result == null) {
- result = findByPreviousAnalysis(property);
- if (result == null) {
- result = findByVersion(property);
- }
- }
- }
-
- if (result != null) {
- result.setIndex(index);
- }
-
- return result;
- }
-
- private PastSnapshot findByPreviousAnalysis(String property) {
- PastSnapshot pastSnapshot = null;
- if (StringUtils.equals(PastSnapshotFinderByPreviousAnalysis.MODE, property)) {
- pastSnapshot = finderByPreviousAnalysis.findByPreviousAnalysis();
- }
- return pastSnapshot;
- }
-
- private PastSnapshot findByDate(String property) {
- SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
- try {
- Date date = format.parse(property);
- return finderByDate.findByDate(date);
-
- } catch (ParseException e) {
- return null;
- }
- }
-
- private PastSnapshot findByVersion(String property) {
- return finderByVersion.findByVersion(property);
- }
-
- private PastSnapshot findByDays(String property) {
- try {
- int days = Integer.parseInt(property);
- return finderByDays.findFromDays(days);
-
- } catch (NumberFormatException e) {
- return null;
- }
- }
-
-}
+++ /dev/null
-/*
- * 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.plugins.core.timemachine;
-
-import org.sonar.api.BatchExtension;
-import org.sonar.api.database.DatabaseSession;
-import org.sonar.api.database.model.Snapshot;
-
-import java.text.SimpleDateFormat;
-import java.util.Date;
-import java.util.List;
-
-public class PastSnapshotFinderByDate implements BatchExtension{
-
- public static final String MODE = "date";
-
-
- private Snapshot projectSnapshot; // TODO replace by PersistenceManager
- private DatabaseSession session;
-
- public PastSnapshotFinderByDate(Snapshot projectSnapshot, DatabaseSession session) {
- this.projectSnapshot = projectSnapshot;
- this.session = session;
- }
-
- PastSnapshot findByDate(Date date) {
- String hql = "from " + Snapshot.class.getSimpleName() + " where createdAt>=:date AND resourceId=:resourceId AND status=:status order by createdAt asc";
- List<Snapshot> snapshots = session.createQuery(hql)
- .setParameter("date", date)
- .setParameter("resourceId", projectSnapshot.getResourceId())
- .setParameter("status", Snapshot.STATUS_PROCESSED)
- .setMaxResults(1)
- .getResultList();
- if (snapshots.isEmpty()) {
- return null;
- }
-
- SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
- return new PastSnapshot(MODE, date, snapshots.get(0)).setModeParameter(format.format(date));
- }
-
-}
+++ /dev/null
-/*
- * 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.plugins.core.timemachine;
-
-import org.apache.commons.lang.time.DateUtils;
-import org.sonar.api.BatchExtension;
-import org.sonar.api.database.DatabaseSession;
-import org.sonar.api.database.model.Snapshot;
-
-import java.util.Date;
-import java.util.List;
-
-public class PastSnapshotFinderByDays implements BatchExtension {
-
- public static final String MODE = "days";
-
-
- private Snapshot projectSnapshot; // TODO replace by PersistenceManager
- private DatabaseSession session;
-
- public PastSnapshotFinderByDays(Snapshot projectSnapshot, DatabaseSession session) {
- this.projectSnapshot = projectSnapshot;
- this.session = session;
- }
-
- PastSnapshot findFromDays(int days) {
- Date targetDate = DateUtils.addDays(projectSnapshot.getCreatedAt(), -days);
- String hql = "from " + Snapshot.class.getSimpleName() + " where resourceId=:resourceId AND status=:status AND createdAt>=:from AND createdAt<:to order by createdAt asc";
- List<Snapshot> snapshots = session.createQuery(hql)
- .setParameter("from", targetDate)
- .setParameter("to", projectSnapshot.getCreatedAt())
- .setParameter("resourceId", projectSnapshot.getResourceId())
- .setParameter("status", Snapshot.STATUS_PROCESSED)
- .setMaxResults(1)
- .getResultList();
-
- if (snapshots.isEmpty()) {
- return null;
- }
- return new PastSnapshot(MODE, targetDate, snapshots.get(0)).setModeParameter(String.valueOf(days));
- }
-}
+++ /dev/null
-/*
- * 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.plugins.core.timemachine;
-
-import org.sonar.api.BatchExtension;
-import org.sonar.api.database.DatabaseSession;
-import org.sonar.api.database.model.Snapshot;
-
-import java.text.SimpleDateFormat;
-import java.util.List;
-
-public class PastSnapshotFinderByPreviousAnalysis implements BatchExtension {
- public static final String MODE = "previous_analysis";
-
- private Snapshot projectSnapshot; // TODO replace by PersistenceManager
- private DatabaseSession session;
-
- public PastSnapshotFinderByPreviousAnalysis(Snapshot projectSnapshot, DatabaseSession session) {
- this.projectSnapshot = projectSnapshot;
- this.session = session;
- }
-
- PastSnapshot findByPreviousAnalysis() {
- String hql = "from " + Snapshot.class.getSimpleName() + " where createdAt<:date AND resourceId=:resourceId AND status=:status and last=true order by createdAt desc";
- List<Snapshot> snapshots = session.createQuery(hql)
- .setParameter("date", projectSnapshot.getCreatedAt())
- .setParameter("resourceId", projectSnapshot.getResourceId())
- .setParameter("status", Snapshot.STATUS_PROCESSED)
- .setMaxResults(1)
- .getResultList();
-
- if (snapshots.isEmpty()) {
- return null;
- }
- Snapshot snapshot = snapshots.get(0);
- SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
- return new PastSnapshot(MODE, snapshot.getCreatedAt(), snapshot).setModeParameter(format.format(snapshot.getCreatedAt()));
- }
-
-}
+++ /dev/null
-/*
- * 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.plugins.core.timemachine;
-
-import org.sonar.api.BatchExtension;
-import org.sonar.api.database.DatabaseSession;
-import org.sonar.api.database.model.Snapshot;
-
-import java.util.List;
-
-public class PastSnapshotFinderByVersion implements BatchExtension {
-
- public static final String MODE = "version";
-
- private Snapshot projectSnapshot; // TODO replace by PersistenceManager
- private DatabaseSession session;
-
- public PastSnapshotFinderByVersion(Snapshot projectSnapshot, DatabaseSession session) {
- this.projectSnapshot = projectSnapshot;
- this.session = session;
- }
-
- PastSnapshot findByVersion(String version) {
- String hql = "from " + Snapshot.class.getSimpleName() + " where version=:version AND resourceId=:resourceId AND status=:status order by createdAt desc";
- List<Snapshot> snapshots = session.createQuery(hql)
- .setParameter("version", version)
- .setParameter("resourceId", projectSnapshot.getResourceId())
- .setParameter("status", Snapshot.STATUS_PROCESSED)
- .setMaxResults(1)
- .getResultList();
-
- if (snapshots.isEmpty()) {
- return null;
- }
- Snapshot snapshot = snapshots.get(0);
- return new PastSnapshot(MODE, snapshot.getCreatedAt(), snapshot).setModeParameter(snapshot.getVersion());
- }
-
-}
+++ /dev/null
-package org.sonar.plugins.core.timemachine;
-
-import org.sonar.api.BatchExtension;
-import org.sonar.api.database.DatabaseSession;
-import org.sonar.api.database.model.RuleFailureModel;
-import org.sonar.api.database.model.Snapshot;
-import org.sonar.api.database.model.SnapshotSource;
-import org.sonar.api.resources.Resource;
-import org.sonar.api.utils.SonarException;
-import org.sonar.batch.index.ResourcePersister;
-
-import java.util.Collections;
-import java.util.List;
-
-public class PastViolationsLoader implements BatchExtension {
-
- private DatabaseSession session;
- private ResourcePersister resourcePersister;
-
- public PastViolationsLoader(DatabaseSession session, ResourcePersister resourcePersister) {
- this.session = session;
- this.resourcePersister = resourcePersister;
- }
-
- public List<RuleFailureModel> getPastViolations(Resource resource) {
- if (resource == null) {
- return Collections.emptyList();
- }
-
- Snapshot snapshot = resourcePersister.getSnapshot(resource);
- if (snapshot == null) {
- throw new SonarException("This resource has no snapshot ???" + resource);
- }
- Snapshot previousLastSnapshot = resourcePersister.getLastSnapshot(snapshot, true);
- if (previousLastSnapshot == null) {
- return Collections.emptyList();
- }
- return session.getResults(RuleFailureModel.class,
- "snapshotId", previousLastSnapshot.getId());
- }
-
- public SnapshotSource getSource(Resource resource) {
- Snapshot snapshot = resourcePersister.getSnapshot(resource);
- return session.getSingleResult(SnapshotSource.class,
- "snapshotId", snapshot.getId());
- }
-
-}
import org.sonar.api.resources.Project;
import org.sonar.api.resources.Resource;
import org.sonar.api.resources.ResourceUtils;
+import org.sonar.batch.components.TimeMachineConfiguration;
import java.util.List;
+++ /dev/null
-/*
- * 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.plugins.core.timemachine;
-
-import com.google.common.collect.Lists;
-import org.apache.commons.configuration.Configuration;
-import org.sonar.api.BatchExtension;
-import org.sonar.api.CoreProperties;
-import org.sonar.api.utils.Logs;
-
-import java.util.Collections;
-import java.util.List;
-
-public class TimeMachineConfiguration implements BatchExtension {
-
- private static final int NUMBER_OF_VARIATION_SNAPSHOTS = 5;
-
- private final Configuration configuration;
- private List<PastSnapshot> projectPastSnapshots;
-
- public TimeMachineConfiguration(Configuration configuration, PastSnapshotFinder variationSnapshotFinder) {
- this.configuration = configuration;
- initVariationSnapshots(variationSnapshotFinder);
- }
-
- private void initVariationSnapshots(PastSnapshotFinder variationSnapshotFinder) {
- projectPastSnapshots = Lists.newLinkedList();
- for (int index = 1; index <= NUMBER_OF_VARIATION_SNAPSHOTS; index++) {
- PastSnapshot variationSnapshot = variationSnapshotFinder.find(configuration, index);
- if (variationSnapshot != null) {
- Logs.INFO.info("Comparison date: " + variationSnapshot.getDate());
- projectPastSnapshots.add(variationSnapshot);
- }
- }
- }
-
-
- /**
- * for unit tests
- */
- TimeMachineConfiguration(Configuration configuration) {
- this.configuration = configuration;
- this.projectPastSnapshots = Collections.emptyList();
- }
-
-
- public boolean skipTendencies() {
- return configuration.getBoolean(CoreProperties.SKIP_TENDENCIES_PROPERTY, CoreProperties.SKIP_TENDENCIES_DEFAULT_VALUE);
- }
-
- public int getTendencyPeriodInDays() {
- return configuration.getInt(CoreProperties.CORE_TENDENCY_DEPTH_PROPERTY, CoreProperties.CORE_TENDENCY_DEPTH_DEFAULT_VALUE);
- }
-
- public List<PastSnapshot> getProjectPastSnapshots() {
- return projectPastSnapshots;
- }
-}
import org.sonar.api.BatchExtension;
import org.sonar.api.database.DatabaseSession;
import org.sonar.api.database.model.Snapshot;
+import org.sonar.batch.components.PastSnapshot;
+import org.sonar.batch.components.TimeMachineConfiguration;
import java.util.List;
import com.google.common.collect.Maps;
import org.sonar.api.batch.*;
import org.sonar.api.database.model.MeasureModel;
-import org.sonar.api.measures.Measure;
-import org.sonar.api.measures.MeasuresFilters;
-import org.sonar.api.measures.Metric;
-import org.sonar.api.measures.RuleMeasure;
+import org.sonar.api.measures.*;
import org.sonar.api.qualitymodel.Characteristic;
import org.sonar.api.resources.Project;
import org.sonar.api.resources.Resource;
import org.sonar.api.resources.ResourceUtils;
import org.sonar.api.rules.RulePriority;
+import org.sonar.batch.components.PastMeasuresLoader;
+import org.sonar.batch.components.PastSnapshot;
+import org.sonar.batch.components.TimeMachineConfiguration;
import java.util.Collection;
import java.util.List;
private List<PastSnapshot> projectPastSnapshots;
private PastMeasuresLoader pastMeasuresLoader;
+ private MetricFinder metricFinder;
+
+ public VariationDecorator(PastMeasuresLoader pastMeasuresLoader, MetricFinder metricFinder, TimeMachineConfiguration configuration) {
+ this(pastMeasuresLoader, metricFinder, configuration.getProjectPastSnapshots());
- public VariationDecorator(PastMeasuresLoader pastMeasuresLoader, TimeMachineConfiguration configuration) {
- this(pastMeasuresLoader, configuration.getProjectPastSnapshots());
}
- VariationDecorator(PastMeasuresLoader pastMeasuresLoader, List<PastSnapshot> projectPastSnapshots) {
+ VariationDecorator(PastMeasuresLoader pastMeasuresLoader, MetricFinder metricFinder, List<PastSnapshot> projectPastSnapshots) {
this.pastMeasuresLoader = pastMeasuresLoader;
this.projectPastSnapshots = projectPastSnapshots;
+ this.metricFinder = metricFinder;
}
public boolean shouldExecuteOnProject(Project project) {
// for each measure, search equivalent past measure
for (Measure measure : context.getMeasures(MeasuresFilters.all())) {
// compare with past measure
- MeasureModel pastMeasure = pastMeasuresByKey.get(new MeasureKey(measure));
+ Integer metricId = (measure.getMetric().getId()!=null ? measure.getMetric().getId() : metricFinder.findByKey(measure.getMetric().getKey()).getId());
+ MeasureModel pastMeasure = pastMeasuresByKey.get(new MeasureKey(measure, metricId));
if (updateVariation(measure, pastMeasure, index)) {
context.saveMeasure(measure);
}
characteristic = model.getCharacteristic();
}
- MeasureKey(Measure measure) {
- metricId = measure.getMetric().getId();
- characteristic = measure.getCharacteristic();
+ MeasureKey(Measure measure, Integer metricId) {
+ this.metricId = metricId;
+ this.characteristic = measure.getCharacteristic();
// TODO merge RuleMeasure into Measure
if (measure instanceof RuleMeasure) {
RuleMeasure rm = (RuleMeasure) measure;
- ruleId = (rm.getRule() == null ? null : rm.getRule().getId());
- priority = rm.getRulePriority();
+ this.ruleId = (rm.getRule() == null ? null : rm.getRule().getId());
+ this.priority = rm.getRulePriority();
}
}
import org.sonar.api.rules.RuleFinder;
import org.sonar.api.rules.Violation;
import org.sonar.api.utils.SonarException;
+import org.sonar.batch.components.PastViolationsLoader;
import org.sonar.batch.index.ViolationPersister;
import java.io.IOException;
import org.sonar.api.rules.Rule;
import org.sonar.api.rules.RulePriority;
import org.sonar.api.rules.Violation;
+import org.sonar.batch.components.PastSnapshot;
+import org.sonar.batch.components.TimeMachineConfiguration;
-import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
+++ /dev/null
-/*
- * 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.plugins.core.timemachine;
-
-import org.junit.Test;
-import org.sonar.api.database.model.MeasureModel;
-import org.sonar.api.database.model.Snapshot;
-import org.sonar.api.measures.Metric;
-import org.sonar.jpa.test.AbstractDbUnitTestCase;
-
-import java.util.Arrays;
-import java.util.List;
-
-import static org.hamcrest.CoreMatchers.anyOf;
-import static org.hamcrest.CoreMatchers.is;
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.junit.internal.matchers.IsCollectionContaining.hasItems;
-
-public class PastMeasuresLoaderTest extends AbstractDbUnitTestCase {
-
- private static final int PROJECT_SNAPSHOT_ID = 1000;
- private static final int PROJECT_ID = 1;
- private static final int FILE_ID = 3;
-
- @Test
- public void shouldGetPastResourceMeasures() {
- setupData("shared");
-
- List<Metric> metrics = selectMetrics();
- Snapshot projectSnapshot = getSession().getSingleResult(Snapshot.class, "id", PROJECT_SNAPSHOT_ID);
-
- PastMeasuresLoader loader = new PastMeasuresLoader(getSession(), metrics);
- List<MeasureModel> measures = loader.getPastMeasures(FILE_ID, projectSnapshot);
- assertThat(measures.size(), is(2));
-
- for (MeasureModel measure : measures) {
- assertThat(measure.getId(), anyOf(is(5L), is(6L)));
- assertThat(measure.getValue(), anyOf(is(5.0), is(60.0)));
- }
- }
-
- @Test
- public void shouldGetPastProjectMeasures() {
- setupData("shared");
-
- List<Metric> metrics = selectMetrics();
- Snapshot projectSnapshot = getSession().getSingleResult(Snapshot.class, "id", PROJECT_SNAPSHOT_ID);
-
- PastMeasuresLoader loader = new PastMeasuresLoader(getSession(), metrics);
- List<MeasureModel> measures = loader.getPastMeasures(PROJECT_ID, projectSnapshot);
- assertThat(measures.size(), is(2));
-
- for (MeasureModel measure : measures) {
- assertThat(measure.getId(), anyOf(is(1L), is(2L)));
- assertThat(measure.getValue(), anyOf(is(60.0), is(80.0)));
- }
- }
-
- @Test
- public void shouldKeepOnlyNumericalMetrics() {
- Metric ncloc = new Metric("ncloc", Metric.ValueType.INT);
- ncloc.setId(1);
- Metric complexity = new Metric("complexity", Metric.ValueType.INT);
- complexity.setId(2);
- Metric data = new Metric("data", Metric.ValueType.DATA);
- data.setId(3);
- List<Metric> metrics = Arrays.asList(ncloc, complexity, data);
-
- PastMeasuresLoader loader = new PastMeasuresLoader(getSession(), metrics);
-
- assertThat(loader.getMetrics().size(), is(2));
- assertThat(loader.getMetrics(), hasItems(ncloc, complexity));
- }
-
- private List<Metric> selectMetrics() {
- return getSession().getResults(Metric.class);
- }
-}
+++ /dev/null
-/*
- * 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.plugins.core.timemachine;
-
-import org.junit.Test;
-import org.sonar.api.database.model.Snapshot;
-import org.sonar.jpa.test.AbstractDbUnitTestCase;
-
-import java.text.ParseException;
-import java.text.SimpleDateFormat;
-import java.util.Date;
-
-import static org.hamcrest.CoreMatchers.is;
-import static org.junit.Assert.assertThat;
-
-public class PastSnapshotFinderByDateTest extends AbstractDbUnitTestCase {
- public static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd");
-
- @Test
- public void shouldFindDate() throws ParseException {
- setupData("shared");
-
- Snapshot projectSnapshot = getSession().getSingleResult(Snapshot.class, "id", 1010);
- PastSnapshotFinderByDate finder = new PastSnapshotFinderByDate(projectSnapshot, getSession());
-
- Date date = DATE_FORMAT.parse("2008-11-22");
-
- PastSnapshot pastSnapshot = finder.findByDate(date);
- assertThat(pastSnapshot.getProjectSnapshotId(), is(1006));
- }
-
- @Test
- public void shouldFindNearestLaterDate() throws ParseException {
- setupData("shared");
-
- Snapshot projectSnapshot = getSession().getSingleResult(Snapshot.class, "id", 1010);
- PastSnapshotFinderByDate finder = new PastSnapshotFinderByDate(projectSnapshot, getSession());
-
- Date date = DATE_FORMAT.parse("2008-11-24");
-
- PastSnapshot pastSnapshot = finder.findByDate(date);
- assertThat(pastSnapshot.getProjectSnapshotId(), is(1009));
- }
-}
+++ /dev/null
-/*
- * 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.plugins.core.timemachine;
-
-import org.hamcrest.core.IsNull;
-import org.junit.Test;
-import org.sonar.api.database.model.Snapshot;
-import org.sonar.jpa.test.AbstractDbUnitTestCase;
-
-import java.text.ParseException;
-
-import static org.hamcrest.CoreMatchers.is;
-import static org.hamcrest.Matchers.nullValue;
-import static org.junit.Assert.assertThat;
-
-public class PastSnapshotFinderByDaysTest extends AbstractDbUnitTestCase {
-
- @Test
- public void shouldGetNextSnapshot() throws ParseException {
- setupData("shared");
-
- Snapshot projectSnapshot = getSession().getSingleResult(Snapshot.class, "id", 1009); // 2008-11-16
- PastSnapshotFinderByDays finder = new PastSnapshotFinderByDays(projectSnapshot, getSession());
-
- assertThat(finder.findFromDays(50).getProjectSnapshotId(), is(1000));
- }
-
- @Test
- public void shouldIgnoreUnprocessedSnapshots() throws ParseException {
- setupData("shared");
-
- Snapshot projectSnapshot = getSession().getSingleResult(Snapshot.class, "id", 1009); // 2008-11-16
- PastSnapshotFinderByDays finder = new PastSnapshotFinderByDays(projectSnapshot, getSession());
-
- assertThat(finder.findFromDays(7).getProjectSnapshotId(), is(1006));
- }
-
- @Test
- public void shouldNotFindSelf() throws ParseException {
- setupData("shared");
-
- Snapshot projectSnapshot = getSession().getSingleResult(Snapshot.class, "id", 1009); // 2008-11-16
- PastSnapshotFinderByDays finder = new PastSnapshotFinderByDays(projectSnapshot, getSession());
-
- assertThat(finder.findFromDays(1), nullValue());
- }
-
-}
+++ /dev/null
-/*
- * 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.plugins.core.timemachine;
-
-import org.junit.Test;
-import org.sonar.api.database.model.Snapshot;
-import org.sonar.jpa.test.AbstractDbUnitTestCase;
-
-import java.text.ParseException;
-
-import static org.hamcrest.CoreMatchers.is;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertThat;
-
-public class PastSnapshotFinderByPreviousAnalysisTest extends AbstractDbUnitTestCase {
-
- @Test
- public void shouldFindPreviousAnalysis() throws ParseException {
- setupData("shouldFindPreviousAnalysis");
-
- Snapshot projectSnapshot = getSession().getSingleResult(Snapshot.class, "id", 1010);
- PastSnapshotFinderByPreviousAnalysis finder = new PastSnapshotFinderByPreviousAnalysis(projectSnapshot, getSession());
-
- PastSnapshot pastSnapshot = finder.findByPreviousAnalysis();
- assertThat(pastSnapshot.getProjectSnapshotId(), is(1009));
- }
-
- @Test
- public void shouldNotFindPreviousAnalysis() throws ParseException {
- setupData("shouldNotFindPreviousAnalysis");
-
- Snapshot projectSnapshot = getSession().getSingleResult(Snapshot.class, "id", 1010);
- PastSnapshotFinderByPreviousAnalysis finder = new PastSnapshotFinderByPreviousAnalysis(projectSnapshot, getSession());
-
- assertNull(finder.findByPreviousAnalysis());
- }
-}
+++ /dev/null
-/*
- * 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.plugins.core.timemachine;
-
-import org.junit.Test;
-import org.sonar.api.database.model.Snapshot;
-import org.sonar.jpa.test.AbstractDbUnitTestCase;
-
-import static org.hamcrest.CoreMatchers.is;
-import static org.hamcrest.core.IsNull.nullValue;
-import static org.junit.Assert.assertThat;
-
-public class PastSnapshotFinderByVersionTest extends AbstractDbUnitTestCase {
-
- @Test
- public void shouldFindByVersion() {
- setupData("shared");
-
- Snapshot currentProjectSnapshot = getSession().getSingleResult(Snapshot.class, "id", 1010);
- PastSnapshotFinderByVersion finder = new PastSnapshotFinderByVersion(currentProjectSnapshot, getSession());
-
- assertThat(finder.findByVersion("1.1").getProjectSnapshotId(), is(1009));
- }
-
- @Test
- public void shouldNotFindVersion() {
- setupData("shared");
-
- Snapshot currentProjectSnapshot = getSession().getSingleResult(Snapshot.class, "id", 1010);
- PastSnapshotFinderByVersion finder = new PastSnapshotFinderByVersion(currentProjectSnapshot, getSession());
-
- assertThat(finder.findByVersion("1.0"), nullValue());
- }
-}
+++ /dev/null
-/*
- * 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.plugins.core.timemachine;
-
-import org.apache.commons.configuration.PropertiesConfiguration;
-import org.hamcrest.BaseMatcher;
-import org.hamcrest.Description;
-import org.junit.Before;
-import org.junit.Test;
-import org.sonar.api.database.model.Snapshot;
-
-import java.text.ParseException;
-import java.text.SimpleDateFormat;
-import java.util.Date;
-
-import static junit.framework.Assert.assertNull;
-import static org.hamcrest.Matchers.nullValue;
-import static org.hamcrest.core.Is.is;
-import static org.hamcrest.core.IsNot.not;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertThat;
-import static org.mockito.Mockito.*;
-
-public class PastSnapshotFinderTest {
-
- private PastSnapshotFinderByDays finderByDays;
- private PastSnapshotFinderByDate finderByDate;
- private PastSnapshotFinderByVersion finderByVersion;
- private PastSnapshotFinderByPreviousAnalysis finderByPreviousAnalysis;
- private PastSnapshotFinder finder;
-
- @Before
- public void initFinders() {
- finderByDays = mock(PastSnapshotFinderByDays.class);
- finderByDate = mock(PastSnapshotFinderByDate.class);
- finderByVersion = mock(PastSnapshotFinderByVersion.class);
- finderByPreviousAnalysis = mock(PastSnapshotFinderByPreviousAnalysis.class);
- finder = new PastSnapshotFinder(finderByDays, finderByVersion, finderByDate, finderByPreviousAnalysis);
- }
-
- @Test
- public void shouldFindByNumberOfDays() {
- when(finderByDays.findFromDays(30)).thenReturn(new PastSnapshot("days", null).setModeParameter("30"));
-
- PastSnapshot variationSnapshot = finder.find(1, "30");
-
- verify(finderByDays).findFromDays(30);
- assertNotNull(variationSnapshot);
- assertThat(variationSnapshot.getIndex(), is(1));
- assertThat(variationSnapshot.getMode(), is("days"));
- assertThat(variationSnapshot.getModeParameter(), is("30"));
- }
-
- @Test
- public void shouldNotFindByNumberOfDays() {
- PastSnapshot variationSnapshot = finder.find(1, "30");
-
- verify(finderByDays).findFromDays(30);
- assertNull(variationSnapshot);
- }
-
- @Test
- public void shouldFindByDate() throws ParseException {
- final SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
- final Date date = format.parse("2010-05-18");
- when(finderByDate.findByDate(date)).thenReturn(new PastSnapshot("date", new Snapshot()));
-
- PastSnapshot variationSnapshot = finder.find(2, "2010-05-18");
-
- verify(finderByDate).findByDate(argThat(new BaseMatcher<Date>() {
- public boolean matches(Object o) {
- return o.equals(date);
- }
-
- public void describeTo(Description description) {
-
- }
- }));
- assertThat(variationSnapshot.getIndex(), is(2));
- assertThat(variationSnapshot.getMode(), is("date"));
- assertThat(variationSnapshot.getProjectSnapshot(), not(nullValue()));
- }
-
- @Test
- public void shouldNotFindByDate() throws ParseException {
- when(finderByDate.findByDate((Date) anyObject())).thenReturn(null);
-
- PastSnapshot variationSnapshot = finder.find(2, "2010-05-18");
-
- verify(finderByDate).findByDate((Date) anyObject());
- assertNull(variationSnapshot);
- }
-
- @Test
- public void shouldFindByPreviousAnalysis() throws ParseException {
- final SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
- final Date date = format.parse("2010-05-18");
- Snapshot snapshot = new Snapshot();
- snapshot.setCreatedAt(date);
- when(finderByPreviousAnalysis.findByPreviousAnalysis()).thenReturn(new PastSnapshot(PastSnapshotFinderByPreviousAnalysis.MODE, snapshot));
-
- PastSnapshot variationSnapshot = finder.find(2, PastSnapshotFinderByPreviousAnalysis.MODE);
-
- verify(finderByPreviousAnalysis).findByPreviousAnalysis();
- assertThat(variationSnapshot.getIndex(), is(2));
- assertThat(variationSnapshot.getMode(), is(PastSnapshotFinderByPreviousAnalysis.MODE));
- assertThat(variationSnapshot.getProjectSnapshot(), not(nullValue()));
- }
-
- @Test
- public void shouldNotFindPreviousAnalysis() {
- when(finderByPreviousAnalysis.findByPreviousAnalysis()).thenReturn(null);
-
- PastSnapshot variationSnapshot = finder.find(2, PastSnapshotFinderByPreviousAnalysis.MODE);
-
- verify(finderByPreviousAnalysis).findByPreviousAnalysis();
-
- assertNull(variationSnapshot);
- }
-
- @Test
- public void shouldFindByVersion() {
- when(finderByVersion.findByVersion("1.2")).thenReturn(new PastSnapshot("version", new Snapshot()));
-
- PastSnapshot variationSnapshot = finder.find(2, "1.2");
-
- verify(finderByVersion).findByVersion("1.2");
- assertThat(variationSnapshot.getIndex(), is(2));
- assertThat(variationSnapshot.getMode(), is("version"));
- assertThat(variationSnapshot.getProjectSnapshot(), not(nullValue()));
- }
-
- @Test
- public void shouldNotFindVersion() {
- when(finderByVersion.findByVersion("1.2")).thenReturn(null);
-
- PastSnapshot variationSnapshot = finder.find(2, "1.2");
-
- verify(finderByVersion).findByVersion("1.2");
- assertNull(variationSnapshot);
- }
-
- @Test
- public void shouldNotFailIfUnknownFormat() {
- when(finderByPreviousAnalysis.findByPreviousAnalysis()).thenReturn(new PastSnapshot(PastSnapshotFinderByPreviousAnalysis.MODE, new Snapshot())); // should not be called
- assertNull(finder.find(2, "foooo"));
- }
-
- @Test
- public void shouldGetPropertyValue() {
- PropertiesConfiguration conf = new PropertiesConfiguration();
- conf.setProperty("sonar.timemachine.period1", "5");
-
- assertThat(PastSnapshotFinder.getPropertyValue(conf, 1), is("5"));
- assertThat(PastSnapshotFinder.getPropertyValue(conf, 999), nullValue());
- }
-
- @Test
- public void shouldGetDefaultPropertyValue() {
- PropertiesConfiguration conf = new PropertiesConfiguration();
- conf.setProperty("sonar.timemachine.period1", "5");
-
- assertThat(PastSnapshotFinder.getPropertyValue(conf, 2), is(PastSnapshotFinder.DEFAULT_VALUE_2));
- }
-}
+++ /dev/null
-package org.sonar.plugins.core.timemachine;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.sonar.api.database.model.RuleFailureModel;
-import org.sonar.api.database.model.Snapshot;
-import org.sonar.api.resources.JavaFile;
-import org.sonar.api.resources.Resource;
-import org.sonar.batch.index.ResourcePersister;
-import org.sonar.jpa.test.AbstractDbUnitTestCase;
-
-import java.util.List;
-
-import static org.hamcrest.CoreMatchers.is;
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.hamcrest.Matchers.notNullValue;
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anyBoolean;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
-
-public class PastViolationsLoaderTest extends AbstractDbUnitTestCase {
-
- private ResourcePersister resourcePersister;
- private PastViolationsLoader loader;
-
- @Before
- public void setUp() {
- setupData("shared");
- resourcePersister = mock(ResourcePersister.class);
- loader = new PastViolationsLoader(getSession(), resourcePersister);
- }
-
- @Test
- public void shouldGetPastResourceViolations() {
- Snapshot snapshot = getSession().getSingleResult(Snapshot.class, "id", 1000);
- doReturn(snapshot).when(resourcePersister)
- .getSnapshot(any(Resource.class));
- doReturn(snapshot).when(resourcePersister)
- .getLastSnapshot(any(Snapshot.class), anyBoolean());
-
- List<RuleFailureModel> violations = loader.getPastViolations(new JavaFile("file"));
-
- assertThat(violations.size(), is(2));
- }
-
- @Test
- public void shouldReturnEmptyList() {
- List<RuleFailureModel> violations = loader.getPastViolations(null);
-
- assertThat(violations, notNullValue());
- assertThat(violations.size(), is(0));
- }
-
-}
import org.sonar.api.measures.MetricFinder;
import org.sonar.api.resources.JavaPackage;
import org.sonar.api.resources.Project;
+import org.sonar.batch.components.TimeMachineConfiguration;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import org.junit.Test;
import org.sonar.api.database.model.Snapshot;
+import org.sonar.batch.components.PastSnapshot;
+import org.sonar.batch.components.TimeMachineConfiguration;
import org.sonar.jpa.test.AbstractDbUnitTestCase;
import java.text.ParseException;
import org.junit.Test;
import org.sonar.api.CoreProperties;
import org.sonar.api.database.model.Snapshot;
+import org.sonar.batch.components.PastSnapshot;
+import org.sonar.batch.components.PastSnapshotFinder;
+import org.sonar.batch.components.TimeMachineConfiguration;
import org.sonar.jpa.test.AbstractDbUnitTestCase;
import java.text.ParseException;
}
@Test
- public void shouldInitVariationSnapshots() throws ParseException {
+ public void shouldInitPastSnapshots() throws ParseException {
PropertiesConfiguration conf = new PropertiesConfiguration();
- PastSnapshotFinder snapshotReferenceFinder = mock(PastSnapshotFinder.class);
- when(snapshotReferenceFinder.find(conf, 1)).thenReturn(new PastSnapshot("days", null, newSnapshot("2010-10-15")));
- when(snapshotReferenceFinder.find(conf, 3)).thenReturn(new PastSnapshot("days", null, newSnapshot("2010-10-13")));
+ PastSnapshotFinder pastSnapshotFinder = mock(PastSnapshotFinder.class);
+ when(pastSnapshotFinder.find(null, conf, 1)).thenReturn(new PastSnapshot("days", null, newSnapshot("2010-10-15")));
+ when(pastSnapshotFinder.find(null, conf, 3)).thenReturn(new PastSnapshot("days", null, newSnapshot("2010-10-13")));
- TimeMachineConfiguration timeMachineConfiguration = new TimeMachineConfiguration(conf, snapshotReferenceFinder);
+ TimeMachineConfiguration timeMachineConfiguration = new TimeMachineConfiguration(conf, pastSnapshotFinder, null);
- verify(snapshotReferenceFinder).find(conf, 1);
- verify(snapshotReferenceFinder).find(conf, 2);
- verify(snapshotReferenceFinder).find(conf, 3);
+ verify(pastSnapshotFinder).find(null, conf, 1);
+ verify(pastSnapshotFinder).find(null, conf, 2);
+ verify(pastSnapshotFinder).find(null, conf, 3);
assertThat(timeMachineConfiguration.getProjectPastSnapshots().size(), is(2));
}
import org.sonar.api.measures.Measure;
import org.sonar.api.measures.MeasuresFilter;
import org.sonar.api.measures.Metric;
+import org.sonar.api.measures.MetricFinder;
import org.sonar.api.resources.*;
+import org.sonar.batch.components.PastMeasuresLoader;
+import org.sonar.batch.components.PastSnapshot;
import org.sonar.jpa.test.AbstractDbUnitTestCase;
import java.util.Arrays;
Measure currentCoverage = newMeasure(COVERAGE, 80.0);
when(context.getMeasures(Matchers.<MeasuresFilter>anyObject())).thenReturn(Arrays.asList(currentNcloc, currentCoverage));
- VariationDecorator decorator = new VariationDecorator(pastMeasuresLoader, Arrays.asList(pastSnapshot1, pastSnapshot3));
+ VariationDecorator decorator = new VariationDecorator(pastMeasuresLoader, mock(MetricFinder.class), Arrays.asList(pastSnapshot1, pastSnapshot3));
decorator.decorate(javaPackage, context);
// context updated for each variation : 2 times for ncloc and 1 time for coverage
+++ /dev/null
-<dataset>
-
- <metrics id="1" name="ncloc" VAL_TYPE="INT" DESCRIPTION="[null]" domain="[null]" short_name=""
- enabled="true" worst_value="[null]" optimized_best_value="[null]" best_value="[null]" direction="0" hidden="false"/>
- <metrics id="2" name="coverage" VAL_TYPE="INT" DESCRIPTION="[null]" domain="[null]" short_name=""
- enabled="true" worst_value="0" optimized_best_value="true" best_value="100" direction="1" hidden="false"/>
-
-
- <rules_categories id="1" name="Efficiency" description="[null]"/>
- <rules_categories id="6" name="Usability" description="[null]"/>
-
- <rules id="30" name="Check Header" plugin_rule_key="com.puppycrawl.tools.checkstyle.checks.header.HeaderCheck"
- plugin_config_key="Checker/Treewalker/HeaderCheck" plugin_name="checkstyle" description="[null]" priority="4" enabled="true"
- cardinality="SINGLE" parent_id="[null]"/>
-
- <rules id="31" name="Equals Avoid Null" plugin_rule_key="com.puppycrawl.tools.checkstyle.checks.coding.EqualsAvoidNullCheck"
- plugin_config_key="Checker/TreeWalker/EqualsAvoidNull" plugin_name="checkstyle" description="[null]" priority="4" enabled="true"
- cardinality="SINGLE" parent_id="[null]"/>
-
- <!-- project -->
- <projects long_name="[null]" id="1" scope="PRJ" qualifier="TRK" kee="project" name="project"
- root_id="[null]"
- description="[null]"
- enabled="true" language="java" copy_resource_id="[null]"/>
-
- <!-- package -->
- <projects long_name="[null]" id="2" scope="DIR" qualifier="PAC" kee="project:org.foo" name="org.foo"
- root_id="1"
- description="[null]"
- enabled="true" language="java" copy_resource_id="[null]"/>
-
- <!-- file -->
- <projects long_name="org.foo.Bar" id="3" scope="FIL" qualifier="CLA" kee="project:org.foo.Bar"
- name="Bar" root_id="[null]"
- description="[null]"
- enabled="true" language="java" copy_resource_id="[null]"/>
-
-
- <!-- snapshots -->
- <snapshots period1_mode="[null]" period1_param="[null]" period1_date="[null]" period2_mode="[null]" period2_param="[null]" period2_date="[null]" period3_mode="[null]" period3_param="[null]" period3_date="[null]" period4_mode="[null]" period4_param="[null]" period4_date="[null]" period5_mode="[null]" period5_param="[null]" period5_date="[null]" id="1000" project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[null]"
- scope="PRJ" qualifier="TRK" created_at="2008-11-01 13:58:00.00" version="[null]" path=""
- status="P" islast="false" depth="0" />
-
- <snapshots period1_mode="[null]" period1_param="[null]" period1_date="[null]" period2_mode="[null]" period2_param="[null]" period2_date="[null]" period3_mode="[null]" period3_param="[null]" period3_date="[null]" period4_mode="[null]" period4_param="[null]" period4_date="[null]" period5_mode="[null]" period5_param="[null]" period5_date="[null]" id="1001" project_id="2" parent_snapshot_id="1000" root_project_id="1" root_snapshot_id="1000"
- scope="DIR" qualifier="PAC" created_at="2008-11-01 13:58:00.00" version="[null]" path="1000."
- status="P" islast="false" depth="1" />
-
- <snapshots period1_mode="[null]" period1_param="[null]" period1_date="[null]" period2_mode="[null]" period2_param="[null]" period2_date="[null]" period3_mode="[null]" period3_param="[null]" period3_date="[null]" period4_mode="[null]" period4_param="[null]" period4_date="[null]" period5_mode="[null]" period5_param="[null]" period5_date="[null]" id="1002" project_id="3" parent_snapshot_id="1001" root_project_id="1" root_snapshot_id="1000"
- scope="FIL" qualifier="CLA" created_at="2008-11-01 13:58:00.00" version="[null]" path="1000.1001."
- status="P" islast="false" depth="2" />
-
-
- <!-- project measures -->
- <project_measures id="1" VALUE="60" METRIC_ID="1" SNAPSHOT_ID="1000" alert_text="[null]" RULES_CATEGORY_ID="[null]"
- RULE_ID="[null]" text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]"
- alert_status="[null]" description="[null]" rule_priority="[null]" characteristic_id="[null]" url="[null]"
- variation_value_1="[null]" variation_value_2="[null]" variation_value_3="[null]" variation_value_4="[null]" variation_value_5="[null]"/>
-
- <project_measures id="2" VALUE="80" METRIC_ID="2" SNAPSHOT_ID="1000" alert_text="[null]" RULES_CATEGORY_ID="[null]"
- RULE_ID="[null]" text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]"
- alert_status="[null]" description="[null]" rule_priority="[null]" characteristic_id="[null]" url="[null]"
- variation_value_1="[null]" variation_value_2="[null]" variation_value_3="[null]" variation_value_4="[null]" variation_value_5="[null]"/>
-
- <!-- package measures -->
- <project_measures id="3" VALUE="20" METRIC_ID="1" SNAPSHOT_ID="1001" alert_text="[null]" RULES_CATEGORY_ID="[null]"
- RULE_ID="[null]" text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]"
- alert_status="[null]" description="[null]" rule_priority="[null]" characteristic_id="[null]" url="[null]"
- variation_value_1="[null]" variation_value_2="[null]" variation_value_3="[null]" variation_value_4="[null]" variation_value_5="[null]"/>
-
- <project_measures id="4" VALUE="70" METRIC_ID="2" SNAPSHOT_ID="1001" alert_text="[null]" RULES_CATEGORY_ID="[null]"
- RULE_ID="[null]" text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]"
- alert_status="[null]" description="[null]" rule_priority="[null]" characteristic_id="[null]" url="[null]"
- variation_value_1="[null]" variation_value_2="[null]" variation_value_3="[null]" variation_value_4="[null]" variation_value_5="[null]"/>
-
- <!-- file measures -->
- <project_measures id="5" VALUE="5" METRIC_ID="1" SNAPSHOT_ID="1002" alert_text="[null]" RULES_CATEGORY_ID="[null]"
- RULE_ID="[null]" text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]"
- alert_status="[null]" description="[null]" rule_priority="[null]" characteristic_id="[null]" url="[null]"
- variation_value_1="[null]" variation_value_2="[null]" variation_value_3="[null]" variation_value_4="[null]" variation_value_5="[null]"/>
-
- <project_measures id="6" VALUE="60" METRIC_ID="2" SNAPSHOT_ID="1002" alert_text="[null]" RULES_CATEGORY_ID="[null]"
- RULE_ID="[null]" text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]"
- alert_status="[null]" description="[null]" rule_priority="[null]" characteristic_id="[null]" url="[null]"
- variation_value_1="[null]" variation_value_2="[null]" variation_value_3="[null]" variation_value_4="[null]" variation_value_5="[null]"/>
-</dataset>
\ No newline at end of file
+++ /dev/null
-<dataset>
-
- <projects long_name="[null]" id="1" scope="PRJ" qualifier="TRK" kee="project" name="project"
- root_id="[null]"
- description="[null]"
- enabled="true" language="java" copy_resource_id="[null]"/>
-
-
- <!-- 2008-11-01 -->
- <snapshots period1_mode="[null]" period1_param="[null]" period1_date="[null]" period2_mode="[null]" period2_param="[null]" period2_date="[null]" period3_mode="[null]" period3_param="[null]" period3_date="[null]" period4_mode="[null]" period4_param="[null]" period4_date="[null]" period5_mode="[null]" period5_param="[null]" period5_date="[null]" id="1000"
- project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[null]"
- scope="PRJ" qualifier="TRK" created_at="2008-11-01 13:58:00.00" version="1.1-SNAPSHOT" path=""
- status="P" islast="false" depth="0" />
-
-
- <!-- 2008-11-12 -->
- <snapshots period1_mode="[null]" period1_param="[null]" period1_date="[null]" period2_mode="[null]" period2_param="[null]" period2_date="[null]" period3_mode="[null]" period3_param="[null]" period3_date="[null]" period4_mode="[null]" period4_param="[null]" period4_date="[null]" period5_mode="[null]" period5_param="[null]" period5_date="[null]" id="1003"
- project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[null]"
- scope="PRJ" qualifier="TRK" created_at="2008-11-12 13:58:00.00" version="1.1-SNAPSHOT" path=""
- status="P" islast="true" depth="0" />
-
-
- <!-- 2008-11-22 -->
- <snapshots period1_mode="[null]" period1_param="[null]" period1_date="[null]" period2_mode="[null]" period2_param="[null]" period2_date="[null]" period3_mode="[null]" period3_param="[null]" period3_date="[null]" period4_mode="[null]" period4_param="[null]" period4_date="[null]" period5_mode="[null]" period5_param="[null]" period5_date="[null]" id="1006"
- project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[null]"
- scope="PRJ" qualifier="TRK" created_at="2008-11-22 13:58:00.00" version="1.1" path=""
- status="P" islast="false" depth="0" />
-
-
- <!-- 2008-11-25-->
- <snapshots period1_mode="[null]" period1_param="[null]" period1_date="[null]" period2_mode="[null]" period2_param="[null]" period2_date="[null]" period3_mode="[null]" period3_param="[null]" period3_date="[null]" period4_mode="[null]" period4_param="[null]" period4_date="[null]" period5_mode="[null]" period5_param="[null]" period5_date="[null]" id="1009"
- project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[null]"
- scope="PRJ" qualifier="TRK" created_at="2008-11-25 13:58:00.00" version="1.1" path=""
- status="P" islast="false" depth="0" />
-
- <!-- current analysis -->
- <snapshots period1_mode="[null]" period1_param="[null]" period1_date="[null]" period2_mode="[null]" period2_param="[null]" period2_date="[null]" period3_mode="[null]" period3_param="[null]" period3_date="[null]" period4_mode="[null]" period4_param="[null]" period4_date="[null]" period5_mode="[null]" period5_param="[null]" period5_date="[null]" id="1010"
- project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[null]"
- scope="PRJ" qualifier="TRK" created_at="2008-11-27 13:58:00.00" version="1.2-SNAPSHOT" path=""
- status="U" islast="false" depth="0" />
-
-</dataset>
\ No newline at end of file
+++ /dev/null
-<dataset>
-
- <!-- project -->
- <projects long_name="[null]" id="1" scope="PRJ" qualifier="TRK" kee="project" name="project"
- root_id="[null]"
- description="[null]"
- enabled="true" language="java" copy_resource_id="[null]"/>
-
- <!-- package -->
- <projects long_name="[null]" id="2" scope="DIR" qualifier="PAC" kee="project:org.foo" name="org.foo"
- root_id="1"
- description="[null]"
- enabled="true" language="java" copy_resource_id="[null]"/>
-
- <!-- file -->
- <projects long_name="org.foo.Bar" id="3" scope="FIL" qualifier="CLA" kee="project:org.foo.Bar"
- name="Bar" root_id="[null]"
- description="[null]"
- enabled="true" language="java" copy_resource_id="[null]"/>
-
-
- <!-- first analysis : 2008-11-01-->
- <snapshots period1_mode="[null]" period1_param="[null]" period1_date="[null]" period2_mode="[null]" period2_param="[null]" period2_date="[null]" period3_mode="[null]" period3_param="[null]" period3_date="[null]" period4_mode="[null]" period4_param="[null]" period4_date="[null]" period5_mode="[null]" period5_param="[null]" period5_date="[null]" id="1000" project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[null]"
- scope="PRJ" qualifier="TRK" created_at="2008-11-01 13:58:00.00" version="[null]" path=""
- status="P" islast="false" depth="0" />
-
- <snapshots period1_mode="[null]" period1_param="[null]" period1_date="[null]" period2_mode="[null]" period2_param="[null]" period2_date="[null]" period3_mode="[null]" period3_param="[null]" period3_date="[null]" period4_mode="[null]" period4_param="[null]" period4_date="[null]" period5_mode="[null]" period5_param="[null]" period5_date="[null]" id="1001" project_id="2" parent_snapshot_id="1000" root_project_id="1" root_snapshot_id="1000"
- scope="DIR" qualifier="PAC" created_at="2008-11-01 13:58:00.00" version="[null]" path="1000."
- status="P" islast="false" depth="1" />
-
- <snapshots period1_mode="[null]" period1_param="[null]" period1_date="[null]" period2_mode="[null]" period2_param="[null]" period2_date="[null]" period3_mode="[null]" period3_param="[null]" period3_date="[null]" period4_mode="[null]" period4_param="[null]" period4_date="[null]" period5_mode="[null]" period5_param="[null]" period5_date="[null]" id="1002" project_id="3" parent_snapshot_id="1001" root_project_id="1" root_snapshot_id="1000"
- scope="FIL" qualifier="CLA" created_at="2008-11-01 13:58:00.00" version="[null]" path="1000.1001."
- status="P" islast="false" depth="2" />
-
-
- <!-- second unprocessed analysis - to ignore: 2008-11-12 -->
- <snapshots period1_mode="[null]" period1_param="[null]" period1_date="[null]" period2_mode="[null]" period2_param="[null]" period2_date="[null]" period3_mode="[null]" period3_param="[null]" period3_date="[null]" period4_mode="[null]" period4_param="[null]" period4_date="[null]" period5_mode="[null]" period5_param="[null]" period5_date="[null]" id="1003" project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[null]"
- scope="PRJ" qualifier="TRK" created_at="2008-11-12 13:58:00.00" version="[null]" path=""
- status="U" islast="false" depth="0" />
-
- <snapshots period1_mode="[null]" period1_param="[null]" period1_date="[null]" period2_mode="[null]" period2_param="[null]" period2_date="[null]" period3_mode="[null]" period3_param="[null]" period3_date="[null]" period4_mode="[null]" period4_param="[null]" period4_date="[null]" period5_mode="[null]" period5_param="[null]" period5_date="[null]" id="1004" project_id="2" parent_snapshot_id="1003" root_project_id="1" root_snapshot_id="1003"
- scope="DIR" qualifier="PAC" created_at="2008-11-12 13:58:00.00" version="[null]" path="1003."
- status="U" islast="false" depth="1" />
-
- <snapshots period1_mode="[null]" period1_param="[null]" period1_date="[null]" period2_mode="[null]" period2_param="[null]" period2_date="[null]" period3_mode="[null]" period3_param="[null]" period3_date="[null]" period4_mode="[null]" period4_param="[null]" period4_date="[null]" period5_mode="[null]" period5_param="[null]" period5_date="[null]" id="1005" project_id="3" parent_snapshot_id="1004" root_project_id="1" root_snapshot_id="1003"
- scope="FIL" qualifier="CLA" created_at="2008-11-12 13:58:00.00" version="[null]" path="1003.1004."
- status="P" islast="false" depth="2" />
-
-
- <!-- second analysis : 2008-11-13-->
- <snapshots period1_mode="[null]" period1_param="[null]" period1_date="[null]" period2_mode="[null]" period2_param="[null]" period2_date="[null]" period3_mode="[null]" period3_param="[null]" period3_date="[null]" period4_mode="[null]" period4_param="[null]" period4_date="[null]" period5_mode="[null]" period5_param="[null]" period5_date="[null]" id="1006" project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[null]"
- scope="PRJ" qualifier="TRK" created_at="2008-11-13 13:58:00.00" version="[null]" path=""
- status="P" islast="true" depth="0" />
-
- <snapshots period1_mode="[null]" period1_param="[null]" period1_date="[null]" period2_mode="[null]" period2_param="[null]" period2_date="[null]" period3_mode="[null]" period3_param="[null]" period3_date="[null]" period4_mode="[null]" period4_param="[null]" period4_date="[null]" period5_mode="[null]" period5_param="[null]" period5_date="[null]" id="1007" project_id="2" parent_snapshot_id="1006" root_project_id="1" root_snapshot_id="1006"
- scope="DIR" qualifier="PAC" created_at="2008-11-13 13:58:00.00" version="[null]" path="1006."
- status="P" islast="true" depth="1" />
-
- <snapshots period1_mode="[null]" period1_param="[null]" period1_date="[null]" period2_mode="[null]" period2_param="[null]" period2_date="[null]" period3_mode="[null]" period3_param="[null]" period3_date="[null]" period4_mode="[null]" period4_param="[null]" period4_date="[null]" period5_mode="[null]" period5_param="[null]" period5_date="[null]" id="1008" project_id="3" parent_snapshot_id="1007" root_project_id="1" root_snapshot_id="1006"
- scope="FIL" qualifier="CLA" created_at="2008-11-13 13:58:00.00" version="[null]" path="1006.1007."
- status="P" islast="true" depth="2" />
-
-
- <!-- current analysis : 2008-11-16 -->
- <snapshots period1_mode="[null]" period1_param="[null]" period1_date="[null]" period2_mode="[null]" period2_param="[null]" period2_date="[null]" period3_mode="[null]" period3_param="[null]" period3_date="[null]" period4_mode="[null]" period4_param="[null]" period4_date="[null]" period5_mode="[null]" period5_param="[null]" period5_date="[null]" id="1009" project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[null]"
- scope="PRJ" qualifier="TRK" created_at="2008-11-16 13:58:00.00" version="[null]" path=""
- status="U" islast="false" depth="0" />
-
- <snapshots period1_mode="[null]" period1_param="[null]" period1_date="[null]" period2_mode="[null]" period2_param="[null]" period2_date="[null]" period3_mode="[null]" period3_param="[null]" period3_date="[null]" period4_mode="[null]" period4_param="[null]" period4_date="[null]" period5_mode="[null]" period5_param="[null]" period5_date="[null]" id="1010" project_id="2" parent_snapshot_id="1009" root_project_id="1" root_snapshot_id="1009"
- scope="DIR" qualifier="PAC" created_at="2008-11-16 13:58:00.00" version="[null]" path="1009."
- status="U" islast="false" depth="1" />
-
- <snapshots period1_mode="[null]" period1_param="[null]" period1_date="[null]" period2_mode="[null]" period2_param="[null]" period2_date="[null]" period3_mode="[null]" period3_param="[null]" period3_date="[null]" period4_mode="[null]" period4_param="[null]" period4_date="[null]" period5_mode="[null]" period5_param="[null]" period5_date="[null]" id="1011" project_id="3" parent_snapshot_id="1010" root_project_id="1" root_snapshot_id="1009"
- scope="FIL" qualifier="CLA" created_at="2008-11-16 13:58:00.00" version="[null]" path="1009.1010."
- status="U" islast="false" depth="2" />
-</dataset>
\ No newline at end of file
+++ /dev/null
-<dataset>
-
- <projects long_name="[null]" id="1" scope="PRJ" qualifier="TRK" kee="project" name="project"
- root_id="[null]"
- description="[null]"
- enabled="true" language="java" copy_resource_id="[null]"/>
-
- <snapshots period1_mode="[null]" period1_param="[null]" period1_date="[null]" period2_mode="[null]" period2_param="[null]" period2_date="[null]" period3_mode="[null]" period3_param="[null]" period3_date="[null]" period4_mode="[null]" period4_param="[null]" period4_date="[null]" period5_mode="[null]" period5_param="[null]" period5_date="[null]" id="1006"
- project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[null]"
- scope="PRJ" qualifier="TRK" created_at="2008-11-22 13:58:00.00" version="1.1" path=""
- status="P" islast="false" depth="0" />
-
-
- <!-- last analysis -->
- <snapshots period1_mode="[null]" period1_param="[null]" period1_date="[null]" period2_mode="[null]" period2_param="[null]" period2_date="[null]" period3_mode="[null]" period3_param="[null]" period3_date="[null]" period4_mode="[null]" period4_param="[null]" period4_date="[null]" period5_mode="[null]" period5_param="[null]" period5_date="[null]" id="1009"
- project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[null]"
- scope="PRJ" qualifier="TRK" created_at="2008-11-25 13:58:00.00" version="1.1" path=""
- status="P" islast="true" depth="0" />
-
- <!-- current analysis -->
- <snapshots period1_mode="[null]" period1_param="[null]" period1_date="[null]" period2_mode="[null]" period2_param="[null]" period2_date="[null]" period3_mode="[null]" period3_param="[null]" period3_date="[null]" period4_mode="[null]" period4_param="[null]" period4_date="[null]" period5_mode="[null]" period5_param="[null]" period5_date="[null]" id="1010"
- project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[null]"
- scope="PRJ" qualifier="TRK" created_at="2008-11-27 13:58:00.00" version="1.2-SNAPSHOT" path=""
- status="U" islast="false" depth="0" />
-
-</dataset>
\ No newline at end of file
+++ /dev/null
-<dataset>
-
- <projects long_name="[null]" id="1" scope="PRJ" qualifier="TRK" kee="project" name="project"
- root_id="[null]"
- description="[null]"
- enabled="true" language="java" copy_resource_id="[null]"/>
-
-
- <!-- unprocessed analysis -->
- <snapshots period1_mode="[null]" period1_param="[null]" period1_date="[null]" period2_mode="[null]" period2_param="[null]" period2_date="[null]" period3_mode="[null]" period3_param="[null]" period3_date="[null]" period4_mode="[null]" period4_param="[null]" period4_date="[null]" period5_mode="[null]" period5_param="[null]" period5_date="[null]" id="1009"
- project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[null]"
- scope="PRJ" qualifier="TRK" created_at="2008-11-25 13:58:00.00" version="1.1" path=""
- status="U" islast="false" depth="0" />
-
- <!-- current analysis -->
- <snapshots period1_mode="[null]" period1_param="[null]" period1_date="[null]" period2_mode="[null]" period2_param="[null]" period2_date="[null]" period3_mode="[null]" period3_param="[null]" period3_date="[null]" period4_mode="[null]" period4_param="[null]" period4_date="[null]" period5_mode="[null]" period5_param="[null]" period5_date="[null]" id="1010"
- project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[null]"
- scope="PRJ" qualifier="TRK" created_at="2008-11-27 13:58:00.00" version="1.2-SNAPSHOT" path=""
- status="U" islast="false" depth="0" />
-
-</dataset>
\ No newline at end of file
+++ /dev/null
-<dataset>
-
- <projects long_name="[null]" id="1" scope="PRJ" qualifier="TRK" kee="project" name="project"
- root_id="[null]"
- description="[null]"
- enabled="true" language="java" copy_resource_id="[null]"/>
-
-
- <!-- version 1.1-SNAPSHOT -->
- <snapshots period1_mode="[null]" period1_param="[null]" period1_date="[null]" period2_mode="[null]" period2_param="[null]" period2_date="[null]" period3_mode="[null]" period3_param="[null]" period3_date="[null]" period4_mode="[null]" period4_param="[null]" period4_date="[null]" period5_mode="[null]" period5_param="[null]" period5_date="[null]" id="1000"
- project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[null]"
- scope="PRJ" qualifier="TRK" created_at="2008-11-01 13:58:00.00" version="1.1-SNAPSHOT" path=""
- status="P" islast="false" depth="0" />
-
-
- <!-- version 1.1-SNAPSHOT -->
- <snapshots period1_mode="[null]" period1_param="[null]" period1_date="[null]" period2_mode="[null]" period2_param="[null]" period2_date="[null]" period3_mode="[null]" period3_param="[null]" period3_date="[null]" period4_mode="[null]" period4_param="[null]" period4_date="[null]" period5_mode="[null]" period5_param="[null]" period5_date="[null]" id="1003"
- project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[null]"
- scope="PRJ" qualifier="TRK" created_at="2008-11-02 13:58:00.00" version="1.1-SNAPSHOT" path=""
- status="P" islast="true" depth="0" />
-
-
- <!-- unprocessed version 1.1 (to ignore) -->
- <snapshots period1_mode="[null]" period1_param="[null]" period1_date="[null]" period2_mode="[null]" period2_param="[null]" period2_date="[null]" period3_mode="[null]" period3_param="[null]" period3_date="[null]" period4_mode="[null]" period4_param="[null]" period4_date="[null]" period5_mode="[null]" period5_param="[null]" period5_date="[null]" id="1006"
- project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[null]"
- scope="PRJ" qualifier="TRK" created_at="2008-11-03 13:58:00.00" version="1.1" path=""
- status="U" islast="false" depth="0" />
-
-
- <!-- version 1.1 -->
- <snapshots period1_mode="[null]" period1_param="[null]" period1_date="[null]" period2_mode="[null]" period2_param="[null]" period2_date="[null]" period3_mode="[null]" period3_param="[null]" period3_date="[null]" period4_mode="[null]" period4_param="[null]" period4_date="[null]" period5_mode="[null]" period5_param="[null]" period5_date="[null]" id="1009"
- project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[null]"
- scope="PRJ" qualifier="TRK" created_at="2008-11-04 13:58:00.00" version="1.1" path=""
- status="P" islast="false" depth="0" />
-
- <!-- current analysis -->
- <snapshots period1_mode="[null]" period1_param="[null]" period1_date="[null]" period2_mode="[null]" period2_param="[null]" period2_date="[null]" period3_mode="[null]" period3_param="[null]" period3_date="[null]" period4_mode="[null]" period4_param="[null]" period4_date="[null]" period5_mode="[null]" period5_param="[null]" period5_date="[null]" id="1010"
- project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[null]"
- scope="PRJ" qualifier="TRK" created_at="2008-11-05 13:58:00.00" version="1.2-SNAPSHOT" path=""
- status="U" islast="false" depth="0" />
-
-</dataset>
\ No newline at end of file
+++ /dev/null
-<dataset>
-
- <rules_categories id="1" name="Efficiency" description="[null]"/>
- <rules_categories id="6" name="Usability" description="[null]"/>
-
- <rules id="30" name="Check Header" plugin_rule_key="com.puppycrawl.tools.checkstyle.checks.header.HeaderCheck"
- plugin_config_key="Checker/Treewalker/HeaderCheck" plugin_name="checkstyle" description="[null]" priority="4" enabled="true"
- cardinality="SINGLE" parent_id="[null]"/>
-
- <rules id="31" name="Equals Avoid Null" plugin_rule_key="com.puppycrawl.tools.checkstyle.checks.coding.EqualsAvoidNullCheck"
- plugin_config_key="Checker/TreeWalker/EqualsAvoidNull" plugin_name="checkstyle" description="[null]" priority="4" enabled="true"
- cardinality="SINGLE" parent_id="[null]"/>
-
- <projects id="200" scope="FIL" qualifier="CLA" kee="project:org.foo.Bar" root_id="[null]"
- name="Bar" long_name="org.foo.Bar" description="[null]"
- enabled="true" language="java" copy_resource_id="[null]" profile_id="[null]"/>
-
- <snapshots period1_mode="[null]" period1_param="[null]" period1_date="[null]" period2_mode="[null]" period2_param="[null]" period2_date="[null]" period3_mode="[null]" period3_param="[null]" period3_date="[null]" period4_mode="[null]" period4_param="[null]" period4_date="[null]" period5_mode="[null]" period5_param="[null]" period5_date="[null]" id="1000" project_id="200" parent_snapshot_id="[null]" root_project_id="100" root_snapshot_id="[null]"
- scope="FIL" qualifier="CLA" created_at="2008-11-01 13:58:00.00" version="[null]" path=""
- status="U" islast="false" depth="3" />
-
- <RULE_FAILURES ID="1" SNAPSHOT_ID="1000" RULE_ID="30" FAILURE_LEVEL="3" MESSAGE="old message" LINE="10" COST="[null]" created_at="2008-11-01 13:58:00.00" />
- <RULE_FAILURES ID="2" SNAPSHOT_ID="1000" RULE_ID="30" FAILURE_LEVEL="3" MESSAGE="old message" LINE="10" COST="[null]" created_at="2008-11-01 13:58:00.00" />
-</dataset>
import org.sonar.batch.bootstrap.BootstrapClassLoader;
import org.sonar.batch.bootstrap.ExtensionDownloader;
import org.sonar.batch.bootstrap.TempDirectories;
+import org.sonar.batch.components.*;
import org.sonar.batch.index.*;
import org.sonar.core.components.CacheMetricFinder;
import org.sonar.core.components.CacheRuleFinder;
batchContainer.as(Characteristics.CACHE).addComponent(MeasuresDao.class);
batchContainer.as(Characteristics.CACHE).addComponent(CacheRuleFinder.class);
batchContainer.as(Characteristics.CACHE).addComponent(CacheMetricFinder.class);
+ batchContainer.as(Characteristics.CACHE).addComponent(PastSnapshotFinderByDate.class);
+ batchContainer.as(Characteristics.CACHE).addComponent(PastSnapshotFinderByDays.class);
+ batchContainer.as(Characteristics.CACHE).addComponent(PastSnapshotFinderByPreviousAnalysis.class);
+ batchContainer.as(Characteristics.CACHE).addComponent(PastSnapshotFinderByVersion.class);
+ batchContainer.as(Characteristics.CACHE).addComponent(PastMeasuresLoader.class);
+ batchContainer.as(Characteristics.CACHE).addComponent(PastSnapshotFinder.class);
batchContainer.start();
ProjectTree projectTree = batchContainer.getComponent(ProjectTree.class);
import org.sonar.api.utils.IocContainer;
import org.sonar.api.utils.SonarException;
import org.sonar.batch.bootstrap.BatchPluginRepository;
+import org.sonar.batch.components.PastViolationsLoader;
+import org.sonar.batch.components.TimeMachineConfiguration;
import org.sonar.batch.index.DefaultIndex;
import org.sonar.batch.index.DefaultResourcePersister;
import org.sonar.batch.phases.Phases;
batchContainer.as(Characteristics.CACHE).addComponent(ViolationFilters.class);
batchContainer.as(Characteristics.CACHE).addComponent(ResourceFilters.class);
batchContainer.as(Characteristics.CACHE).addComponent(DefaultModelFinder.class);
+ batchContainer.as(Characteristics.CACHE).addComponent(TimeMachineConfiguration.class);
+ batchContainer.as(Characteristics.CACHE).addComponent(PastViolationsLoader.class);
batchContainer.addAdapter(new ProfileProvider());
batchContainer.addAdapter(new CheckProfileProvider());
loadCoreComponents(batchContainer);
--- /dev/null
+/*
+ * 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.components;
+
+import com.google.common.collect.Maps;
+import org.apache.commons.lang.ObjectUtils;
+import org.sonar.api.BatchExtension;
+import org.sonar.api.database.DatabaseSession;
+import org.sonar.api.database.model.MeasureModel;
+import org.sonar.api.database.model.Snapshot;
+import org.sonar.api.measures.Metric;
+import org.sonar.api.measures.MetricFinder;
+import org.sonar.api.resources.Resource;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+public class PastMeasuresLoader implements BatchExtension {
+
+ private Map<Integer, Metric> metricByIds;
+ private DatabaseSession session;
+
+ public PastMeasuresLoader(DatabaseSession session, MetricFinder metricFinder) {
+ this(session, metricFinder.findAll());
+ }
+
+ PastMeasuresLoader(DatabaseSession session, Collection<Metric> metrics) {
+ this.session = session;
+ this.metricByIds = Maps.newHashMap();
+ for (Metric metric : metrics) {
+ if (metric.isNumericType()) {
+ metricByIds.put(metric.getId(), metric);
+ }
+ }
+ }
+
+ public Collection<Metric> getMetrics() {
+ return metricByIds.values();
+ }
+
+ public List<MeasureModel> getPastMeasures(Resource resource, PastSnapshot projectPastSnapshot) {
+ return getPastMeasures(resource, projectPastSnapshot.getProjectSnapshot());
+ }
+
+ public List<MeasureModel> getPastMeasures(Resource resource, Snapshot projectSnapshot) {
+ // assume that the resource has already been saved
+ return getPastMeasures(resource.getId(), projectSnapshot);
+ }
+
+ public List<MeasureModel> getPastMeasures(int resourceId, Snapshot projectSnapshot) {
+ // TODO improvement : select only some columns
+ // TODO support measure on characteristics
+ String hql = "select m from " + MeasureModel.class.getSimpleName() + " m, " + Snapshot.class.getSimpleName() + " s " +
+ "where m.snapshotId=s.id and m.metricId in (:metricIds) and m.ruleId=null and m.rulePriority=null and m.characteristic=null "
+ + "and (s.rootId=:rootSnapshotId or s.id=:rootSnapshotId) and s.resourceId=:resourceId and s.status=:status";
+ return session.createQuery(hql)
+ .setParameter("metricIds", metricByIds.keySet())
+ .setParameter("rootSnapshotId", ObjectUtils.defaultIfNull(projectSnapshot.getRootId(), projectSnapshot.getId()))
+ .setParameter("resourceId", resourceId)
+ .setParameter("status", Snapshot.STATUS_PROCESSED)
+ .getResultList();
+ }
+}
--- /dev/null
+/*
+ * 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.components;
+
+import org.apache.commons.lang.builder.ReflectionToStringBuilder;
+import org.sonar.api.database.model.Snapshot;
+
+import java.util.Date;
+
+public class PastSnapshot {
+
+ private int index;
+ private String mode, modeParameter;
+ private Snapshot projectSnapshot;
+ private Date targetDate;
+
+ public PastSnapshot(String mode, Date targetDate, Snapshot projectSnapshot) {
+ this.mode = mode;
+ this.targetDate = targetDate;
+ this.projectSnapshot = projectSnapshot;
+ }
+
+ public PastSnapshot(String mode, Snapshot projectSnapshot) {
+ this.mode = mode;
+ this.projectSnapshot = projectSnapshot;
+ }
+
+ public PastSnapshot setIndex(int index) {
+ this.index = index;
+ return this;
+ }
+
+ public int getIndex() {
+ return index;
+ }
+
+ public Snapshot getProjectSnapshot() {
+ return projectSnapshot;
+ }
+
+ public Date getDate() {
+ return projectSnapshot.getCreatedAt();
+ }
+
+ public String getMode() {
+ return mode;
+ }
+
+ public String getModeParameter() {
+ return modeParameter;
+ }
+
+ public PastSnapshot setModeParameter(String s) {
+ this.modeParameter = s;
+ return this;
+ }
+
+ public Integer getProjectSnapshotId() {
+ return (projectSnapshot!=null ? projectSnapshot.getId() : null);
+ }
+
+ public Date getTargetDate() {
+ return targetDate;
+ }
+
+ public PastSnapshot setTargetDate(Date d) {
+ this.targetDate = d;
+ return this;
+ }
+
+ @Override
+ public String toString() {
+ return ReflectionToStringBuilder.toString(this);
+ }
+}
--- /dev/null
+/*
+ * 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.components;
+
+import org.apache.commons.configuration.Configuration;
+import org.apache.commons.lang.StringUtils;
+import org.sonar.api.BatchExtension;
+import org.sonar.api.CoreProperties;
+import org.sonar.api.database.model.Snapshot;
+import org.sonar.api.utils.Logs;
+
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+public class PastSnapshotFinder implements BatchExtension {
+
+ /**
+ * IMPORTANT : please update default values in the ruby side too. See app/helpers/FiltersHelper.rb, method period_names()
+ */
+ private PastSnapshotFinderByDays finderByDays;
+ private PastSnapshotFinderByVersion finderByVersion;
+ private PastSnapshotFinderByDate finderByDate;
+ private PastSnapshotFinderByPreviousAnalysis finderByPreviousAnalysis;
+
+ public PastSnapshotFinder(PastSnapshotFinderByDays finderByDays, PastSnapshotFinderByVersion finderByVersion,
+ PastSnapshotFinderByDate finderByDate, PastSnapshotFinderByPreviousAnalysis finderByPreviousAnalysis) {
+ this.finderByDays = finderByDays;
+ this.finderByVersion = finderByVersion;
+ this.finderByDate = finderByDate;
+ this.finderByPreviousAnalysis = finderByPreviousAnalysis;
+ }
+
+ public PastSnapshot find(Snapshot projectSnapshot, Configuration conf, int index) {
+ String propertyValue = getPropertyValue(conf, index);
+ PastSnapshot pastSnapshot = find(projectSnapshot, index, propertyValue);
+ if (pastSnapshot==null && StringUtils.isNotBlank(propertyValue)) {
+ Logs.INFO.warn("The property " + CoreProperties.TIMEMACHINE_PERIOD_PREFIX + index + " has an unvalid value: " + propertyValue);
+ }
+ return pastSnapshot;
+ }
+
+ static String getPropertyValue(Configuration conf, int index) {
+ String defaultValue = null;
+ switch (index) {
+ case 1: defaultValue = CoreProperties.TIMEMACHINE_DEFAULT_PERIOD_1; break;
+ case 2: defaultValue = CoreProperties.TIMEMACHINE_DEFAULT_PERIOD_2; break;
+ case 3: defaultValue = CoreProperties.TIMEMACHINE_DEFAULT_PERIOD_3; break;
+ case 4: defaultValue = CoreProperties.TIMEMACHINE_DEFAULT_PERIOD_4; break;
+ case 5: defaultValue = CoreProperties.TIMEMACHINE_DEFAULT_PERIOD_5; break;
+ }
+ return conf.getString(CoreProperties.TIMEMACHINE_PERIOD_PREFIX + index, defaultValue);
+ }
+
+ public PastSnapshot find(Snapshot projectSnapshot, int index, String property) {
+ if (StringUtils.isBlank(property)) {
+ return null;
+ }
+
+ PastSnapshot result = findByDays(projectSnapshot, property);
+ if (result == null) {
+ result = findByDate(projectSnapshot, property);
+ if (result == null) {
+ result = findByPreviousAnalysis(projectSnapshot, property);
+ if (result == null) {
+ result = findByVersion(projectSnapshot, property);
+ }
+ }
+ }
+
+ if (result != null) {
+ result.setIndex(index);
+ }
+
+ return result;
+ }
+
+ private PastSnapshot findByPreviousAnalysis(Snapshot projectSnapshot, String property) {
+ PastSnapshot pastSnapshot = null;
+ if (StringUtils.equals(CoreProperties.TIMEMACHINE_MODE_PREVIOUS_ANALYSIS, property)) {
+ pastSnapshot = finderByPreviousAnalysis.findByPreviousAnalysis(projectSnapshot);
+ }
+ return pastSnapshot;
+ }
+
+ private PastSnapshot findByDate(Snapshot projectSnapshot, String property) {
+ SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
+ try {
+ Date date = format.parse(property);
+ return finderByDate.findByDate(projectSnapshot, date);
+
+ } catch (ParseException e) {
+ return null;
+ }
+ }
+
+ private PastSnapshot findByVersion(Snapshot projectSnapshot, String property) {
+ return finderByVersion.findByVersion(projectSnapshot, property);
+ }
+
+ private PastSnapshot findByDays(Snapshot projectSnapshot, String property) {
+ try {
+ int days = Integer.parseInt(property);
+ return finderByDays.findFromDays(projectSnapshot, days);
+
+ } catch (NumberFormatException e) {
+ return null;
+ }
+ }
+
+}
--- /dev/null
+/*
+ * 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.components;
+
+import org.sonar.api.BatchExtension;
+import org.sonar.api.database.DatabaseSession;
+import org.sonar.api.database.model.Snapshot;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.List;
+
+public class PastSnapshotFinderByDate implements BatchExtension {
+
+ public static final String MODE = "date";
+
+ private DatabaseSession session;
+
+ public PastSnapshotFinderByDate(DatabaseSession session) {
+ this.session = session;
+ }
+
+ PastSnapshot findByDate(Snapshot projectSnapshot, Date date) {
+ String hql = "from " + Snapshot.class.getSimpleName() + " where createdAt>=:date AND resourceId=:resourceId AND status=:status order by createdAt asc";
+ List<Snapshot> snapshots = session.createQuery(hql)
+ .setParameter("date", date)
+ .setParameter("resourceId", projectSnapshot.getResourceId())
+ .setParameter("status", Snapshot.STATUS_PROCESSED)
+ .setMaxResults(1)
+ .getResultList();
+ if (snapshots.isEmpty()) {
+ return null;
+ }
+
+ SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
+ return new PastSnapshot(MODE, date, snapshots.get(0)).setModeParameter(format.format(date));
+ }
+
+}
--- /dev/null
+/*
+ * 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.components;
+
+import org.apache.commons.lang.time.DateUtils;
+import org.sonar.api.BatchExtension;
+import org.sonar.api.database.DatabaseSession;
+import org.sonar.api.database.model.Snapshot;
+
+import java.util.Date;
+import java.util.List;
+
+public class PastSnapshotFinderByDays implements BatchExtension {
+
+ public static final String MODE = "days";
+
+ private DatabaseSession session;
+
+ public PastSnapshotFinderByDays(DatabaseSession session) {
+ this.session = session;
+ }
+
+ PastSnapshot findFromDays(Snapshot projectSnapshot, int days) {
+ Date targetDate = DateUtils.addDays(projectSnapshot.getCreatedAt(), -days);
+ String hql = "from " + Snapshot.class.getSimpleName() + " where resourceId=:resourceId AND status=:status AND createdAt>=:from AND createdAt<:to order by createdAt asc";
+ List<Snapshot> snapshots = session.createQuery(hql)
+ .setParameter("from", targetDate)
+ .setParameter("to", projectSnapshot.getCreatedAt())
+ .setParameter("resourceId", projectSnapshot.getResourceId())
+ .setParameter("status", Snapshot.STATUS_PROCESSED)
+ .setMaxResults(1)
+ .getResultList();
+
+ if (snapshots.isEmpty()) {
+ return null;
+ }
+ return new PastSnapshot(MODE, targetDate, snapshots.get(0)).setModeParameter(String.valueOf(days));
+ }
+}
--- /dev/null
+/*
+ * 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.components;
+
+import org.sonar.api.BatchExtension;
+import org.sonar.api.CoreProperties;
+import org.sonar.api.database.DatabaseSession;
+import org.sonar.api.database.model.Snapshot;
+
+import java.text.SimpleDateFormat;
+import java.util.List;
+
+public class PastSnapshotFinderByPreviousAnalysis implements BatchExtension {
+
+ private DatabaseSession session;
+
+ public PastSnapshotFinderByPreviousAnalysis(DatabaseSession session) {
+ this.session = session;
+ }
+
+ PastSnapshot findByPreviousAnalysis(Snapshot projectSnapshot) {
+ String hql = "from " + Snapshot.class.getSimpleName() + " where createdAt<:date AND resourceId=:resourceId AND status=:status and last=true order by createdAt desc";
+ List<Snapshot> snapshots = session.createQuery(hql)
+ .setParameter("date", projectSnapshot.getCreatedAt())
+ .setParameter("resourceId", projectSnapshot.getResourceId())
+ .setParameter("status", Snapshot.STATUS_PROCESSED)
+ .setMaxResults(1)
+ .getResultList();
+
+ if (snapshots.isEmpty()) {
+ return null;
+ }
+ Snapshot snapshot = snapshots.get(0);
+ SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
+ return new PastSnapshot(CoreProperties.TIMEMACHINE_MODE_PREVIOUS_ANALYSIS, snapshot.getCreatedAt(), snapshot).setModeParameter(format.format(snapshot.getCreatedAt()));
+ }
+
+}
--- /dev/null
+/*
+ * 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.components;
+
+import org.sonar.api.BatchExtension;
+import org.sonar.api.database.DatabaseSession;
+import org.sonar.api.database.model.Snapshot;
+
+import java.util.List;
+
+public class PastSnapshotFinderByVersion implements BatchExtension {
+
+ public static final String MODE = "version";
+
+ private DatabaseSession session;
+
+ public PastSnapshotFinderByVersion(DatabaseSession session) {
+ this.session = session;
+ }
+
+ PastSnapshot findByVersion(Snapshot projectSnapshot, String version) {
+ String hql = "from " + Snapshot.class.getSimpleName() + " where version=:version AND resourceId=:resourceId AND status=:status order by createdAt desc";
+ List<Snapshot> snapshots = session.createQuery(hql)
+ .setParameter("version", version)
+ .setParameter("resourceId", projectSnapshot.getResourceId())
+ .setParameter("status", Snapshot.STATUS_PROCESSED)
+ .setMaxResults(1)
+ .getResultList();
+
+ if (snapshots.isEmpty()) {
+ return null;
+ }
+ Snapshot snapshot = snapshots.get(0);
+ return new PastSnapshot(MODE, snapshot.getCreatedAt(), snapshot).setModeParameter(snapshot.getVersion());
+ }
+
+}
--- /dev/null
+package org.sonar.batch.components;
+
+import org.sonar.api.BatchExtension;
+import org.sonar.api.database.DatabaseSession;
+import org.sonar.api.database.model.RuleFailureModel;
+import org.sonar.api.database.model.Snapshot;
+import org.sonar.api.database.model.SnapshotSource;
+import org.sonar.api.resources.Resource;
+import org.sonar.api.utils.SonarException;
+import org.sonar.batch.index.ResourcePersister;
+
+import java.util.Collections;
+import java.util.List;
+
+public class PastViolationsLoader implements BatchExtension {
+
+ private DatabaseSession session;
+ private ResourcePersister resourcePersister;
+
+ public PastViolationsLoader(DatabaseSession session, ResourcePersister resourcePersister) {
+ this.session = session;
+ this.resourcePersister = resourcePersister;
+ }
+
+ public List<RuleFailureModel> getPastViolations(Resource resource) {
+ if (resource == null) {
+ return Collections.emptyList();
+ }
+
+ Snapshot snapshot = resourcePersister.getSnapshot(resource);
+ if (snapshot == null) {
+ throw new SonarException("This resource has no snapshot ???" + resource);
+ }
+ Snapshot previousLastSnapshot = resourcePersister.getLastSnapshot(snapshot, true);
+ if (previousLastSnapshot == null) {
+ return Collections.emptyList();
+ }
+ return session.getResults(RuleFailureModel.class,
+ "snapshotId", previousLastSnapshot.getId());
+ }
+
+ public SnapshotSource getSource(Resource resource) {
+ Snapshot snapshot = resourcePersister.getSnapshot(resource);
+ return session.getSingleResult(SnapshotSource.class,
+ "snapshotId", snapshot.getId());
+ }
+
+}
--- /dev/null
+/*
+ * 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.components;
+
+import com.google.common.collect.Lists;
+import org.apache.commons.configuration.Configuration;
+import org.sonar.api.BatchExtension;
+import org.sonar.api.CoreProperties;
+import org.sonar.api.database.model.Snapshot;
+import org.sonar.api.utils.Logs;
+
+import java.util.Collections;
+import java.util.List;
+
+public class TimeMachineConfiguration implements BatchExtension {
+
+ private static final int NUMBER_OF_VARIATION_SNAPSHOTS = 5;
+
+ private final Configuration configuration;
+ private List<PastSnapshot> projectPastSnapshots;
+
+ public TimeMachineConfiguration(Configuration configuration, PastSnapshotFinder pastSnapshotFinder, Snapshot projectSnapshot) {
+ this.configuration = configuration;
+ initPastSnapshots(pastSnapshotFinder, projectSnapshot);
+ }
+
+ private void initPastSnapshots(PastSnapshotFinder pastSnapshotFinder, Snapshot projectSnapshot) {
+ projectPastSnapshots = Lists.newLinkedList();
+ for (int index = 1; index <= NUMBER_OF_VARIATION_SNAPSHOTS; index++) {
+ PastSnapshot variationSnapshot = pastSnapshotFinder.find(projectSnapshot, configuration, index);
+ if (variationSnapshot != null) {
+ Logs.INFO.info("Comparison date: " + variationSnapshot.getDate());
+ projectPastSnapshots.add(variationSnapshot);
+ }
+ }
+ }
+
+ public TimeMachineConfiguration(Configuration configuration) {
+ this.configuration = configuration;
+ this.projectPastSnapshots = Collections.emptyList();
+ }
+
+
+ public boolean skipTendencies() {
+ return configuration.getBoolean(CoreProperties.SKIP_TENDENCIES_PROPERTY, CoreProperties.SKIP_TENDENCIES_DEFAULT_VALUE);
+ }
+
+ public int getTendencyPeriodInDays() {
+ return configuration.getInt(CoreProperties.CORE_TENDENCY_DEPTH_PROPERTY, CoreProperties.CORE_TENDENCY_DEPTH_DEFAULT_VALUE);
+ }
+
+ public List<PastSnapshot> getProjectPastSnapshots() {
+ return projectPastSnapshots;
+ }
+}
import org.sonar.api.resources.Project;
import org.sonar.api.resources.ProjectLink;
import org.sonar.api.resources.Resource;
-import org.sonar.api.rules.Violation;
import java.util.List;
--- /dev/null
+/*
+ * 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.components;
+
+import org.junit.Test;
+import org.sonar.api.database.model.MeasureModel;
+import org.sonar.api.database.model.Snapshot;
+import org.sonar.api.measures.Metric;
+import org.sonar.batch.components.PastMeasuresLoader;
+import org.sonar.jpa.test.AbstractDbUnitTestCase;
+
+import java.util.Arrays;
+import java.util.List;
+
+import static org.hamcrest.CoreMatchers.anyOf;
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.internal.matchers.IsCollectionContaining.hasItems;
+
+public class PastMeasuresLoaderTest extends AbstractDbUnitTestCase {
+
+ private static final int PROJECT_SNAPSHOT_ID = 1000;
+ private static final int PROJECT_ID = 1;
+ private static final int FILE_ID = 3;
+
+ @Test
+ public void shouldGetPastResourceMeasures() {
+ setupData("shared");
+
+ List<Metric> metrics = selectMetrics();
+ Snapshot projectSnapshot = getSession().getSingleResult(Snapshot.class, "id", PROJECT_SNAPSHOT_ID);
+
+ PastMeasuresLoader loader = new PastMeasuresLoader(getSession(), metrics);
+ List<MeasureModel> measures = loader.getPastMeasures(FILE_ID, projectSnapshot);
+ assertThat(measures.size(), is(2));
+
+ for (MeasureModel measure : measures) {
+ assertThat(measure.getId(), anyOf(is(5L), is(6L)));
+ assertThat(measure.getValue(), anyOf(is(5.0), is(60.0)));
+ }
+ }
+
+ @Test
+ public void shouldGetPastProjectMeasures() {
+ setupData("shared");
+
+ List<Metric> metrics = selectMetrics();
+ Snapshot projectSnapshot = getSession().getSingleResult(Snapshot.class, "id", PROJECT_SNAPSHOT_ID);
+
+ PastMeasuresLoader loader = new PastMeasuresLoader(getSession(), metrics);
+ List<MeasureModel> measures = loader.getPastMeasures(PROJECT_ID, projectSnapshot);
+ assertThat(measures.size(), is(2));
+
+ for (MeasureModel measure : measures) {
+ assertThat(measure.getId(), anyOf(is(1L), is(2L)));
+ assertThat(measure.getValue(), anyOf(is(60.0), is(80.0)));
+ }
+ }
+
+ @Test
+ public void shouldKeepOnlyNumericalMetrics() {
+ Metric ncloc = new Metric("ncloc", Metric.ValueType.INT);
+ ncloc.setId(1);
+ Metric complexity = new Metric("complexity", Metric.ValueType.INT);
+ complexity.setId(2);
+ Metric data = new Metric("data", Metric.ValueType.DATA);
+ data.setId(3);
+ List<Metric> metrics = Arrays.asList(ncloc, complexity, data);
+
+ PastMeasuresLoader loader = new PastMeasuresLoader(getSession(), metrics);
+
+ assertThat(loader.getMetrics().size(), is(2));
+ assertThat(loader.getMetrics(), hasItems(ncloc, complexity));
+ }
+
+ private List<Metric> selectMetrics() {
+ return getSession().getResults(Metric.class);
+ }
+}
--- /dev/null
+/*
+ * 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.components;
+
+import org.junit.Test;
+import org.sonar.api.database.model.Snapshot;
+import org.sonar.jpa.test.AbstractDbUnitTestCase;
+
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertThat;
+
+public class PastSnapshotFinderByDateTest extends AbstractDbUnitTestCase {
+ public static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd");
+
+ @Test
+ public void shouldFindDate() throws ParseException {
+ setupData("shared");
+
+ Snapshot projectSnapshot = getSession().getSingleResult(Snapshot.class, "id", 1010);
+ PastSnapshotFinderByDate finder = new PastSnapshotFinderByDate(getSession());
+
+ Date date = DATE_FORMAT.parse("2008-11-22");
+
+ PastSnapshot pastSnapshot = finder.findByDate(projectSnapshot, date);
+ assertThat(pastSnapshot.getProjectSnapshotId(), is(1006));
+ }
+
+ @Test
+ public void shouldFindNearestLaterDate() throws ParseException {
+ setupData("shared");
+
+ Snapshot projectSnapshot = getSession().getSingleResult(Snapshot.class, "id", 1010);
+ PastSnapshotFinderByDate finder = new PastSnapshotFinderByDate(getSession());
+
+ Date date = DATE_FORMAT.parse("2008-11-24");
+
+ PastSnapshot pastSnapshot = finder.findByDate(projectSnapshot, date);
+ assertThat(pastSnapshot.getProjectSnapshotId(), is(1009));
+ }
+}
--- /dev/null
+/*
+ * 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.components;
+
+import org.junit.Test;
+import org.sonar.api.database.model.Snapshot;
+import org.sonar.jpa.test.AbstractDbUnitTestCase;
+
+import java.text.ParseException;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.Matchers.nullValue;
+import static org.junit.Assert.assertThat;
+
+public class PastSnapshotFinderByDaysTest extends AbstractDbUnitTestCase {
+
+ @Test
+ public void shouldGetNextSnapshot() throws ParseException {
+ setupData("shared");
+
+ Snapshot projectSnapshot = getSession().getSingleResult(Snapshot.class, "id", 1009); // 2008-11-16
+ PastSnapshotFinderByDays finder = new PastSnapshotFinderByDays(getSession());
+
+ assertThat(finder.findFromDays(projectSnapshot, 50).getProjectSnapshotId(), is(1000));
+ }
+
+ @Test
+ public void shouldIgnoreUnprocessedSnapshots() throws ParseException {
+ setupData("shared");
+
+ Snapshot projectSnapshot = getSession().getSingleResult(Snapshot.class, "id", 1009); // 2008-11-16
+ PastSnapshotFinderByDays finder = new PastSnapshotFinderByDays(getSession());
+
+ assertThat(finder.findFromDays(projectSnapshot, 7).getProjectSnapshotId(), is(1006));
+ }
+
+ @Test
+ public void shouldNotFindSelf() throws ParseException {
+ setupData("shared");
+
+ Snapshot projectSnapshot = getSession().getSingleResult(Snapshot.class, "id", 1009); // 2008-11-16
+ PastSnapshotFinderByDays finder = new PastSnapshotFinderByDays(getSession());
+
+ assertThat(finder.findFromDays(projectSnapshot, 1), nullValue());
+ }
+
+}
--- /dev/null
+/*
+ * 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.components;
+
+import org.junit.Test;
+import org.sonar.api.database.model.Snapshot;
+import org.sonar.jpa.test.AbstractDbUnitTestCase;
+
+import java.text.ParseException;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertThat;
+
+public class PastSnapshotFinderByPreviousAnalysisTest extends AbstractDbUnitTestCase {
+
+ @Test
+ public void shouldFindPreviousAnalysis() throws ParseException {
+ setupData("shouldFindPreviousAnalysis");
+
+ Snapshot projectSnapshot = getSession().getSingleResult(Snapshot.class, "id", 1010);
+ PastSnapshotFinderByPreviousAnalysis finder = new PastSnapshotFinderByPreviousAnalysis(getSession());
+
+ PastSnapshot pastSnapshot = finder.findByPreviousAnalysis(projectSnapshot);
+ assertThat(pastSnapshot.getProjectSnapshotId(), is(1009));
+ }
+
+ @Test
+ public void shouldNotFindPreviousAnalysis() throws ParseException {
+ setupData("shouldNotFindPreviousAnalysis");
+
+ Snapshot projectSnapshot = getSession().getSingleResult(Snapshot.class, "id", 1010);
+ PastSnapshotFinderByPreviousAnalysis finder = new PastSnapshotFinderByPreviousAnalysis(getSession());
+
+ assertNull(finder.findByPreviousAnalysis(projectSnapshot));
+ }
+}
--- /dev/null
+/*
+ * 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.components;
+
+import org.junit.Test;
+import org.sonar.api.database.model.Snapshot;
+import org.sonar.jpa.test.AbstractDbUnitTestCase;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.core.IsNull.nullValue;
+import static org.junit.Assert.assertThat;
+
+public class PastSnapshotFinderByVersionTest extends AbstractDbUnitTestCase {
+
+ @Test
+ public void shouldFindByVersion() {
+ setupData("shared");
+
+ Snapshot currentProjectSnapshot = getSession().getSingleResult(Snapshot.class, "id", 1010);
+ PastSnapshotFinderByVersion finder = new PastSnapshotFinderByVersion(getSession());
+
+ assertThat(finder.findByVersion(currentProjectSnapshot, "1.1").getProjectSnapshotId(), is(1009));
+ }
+
+ @Test
+ public void shouldNotFindVersion() {
+ setupData("shared");
+
+ Snapshot currentProjectSnapshot = getSession().getSingleResult(Snapshot.class, "id", 1010);
+ PastSnapshotFinderByVersion finder = new PastSnapshotFinderByVersion(getSession());
+
+ assertThat(finder.findByVersion(currentProjectSnapshot, "1.0"), nullValue());
+ }
+}
--- /dev/null
+/*
+ * 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.components;
+
+import org.apache.commons.configuration.PropertiesConfiguration;
+import org.hamcrest.BaseMatcher;
+import org.hamcrest.Description;
+import org.junit.Before;
+import org.junit.Test;
+import org.sonar.api.CoreProperties;
+import org.sonar.api.database.model.Snapshot;
+
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+import static junit.framework.Assert.assertNull;
+import static org.hamcrest.Matchers.nullValue;
+import static org.hamcrest.core.Is.is;
+import static org.hamcrest.core.IsNot.not;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertThat;
+import static org.mockito.Mockito.*;
+
+public class PastSnapshotFinderTest {
+
+ private PastSnapshotFinderByDays finderByDays;
+ private PastSnapshotFinderByDate finderByDate;
+ private PastSnapshotFinderByVersion finderByVersion;
+ private PastSnapshotFinderByPreviousAnalysis finderByPreviousAnalysis;
+ private PastSnapshotFinder finder;
+
+ @Before
+ public void initFinders() {
+ finderByDays = mock(PastSnapshotFinderByDays.class);
+ finderByDate = mock(PastSnapshotFinderByDate.class);
+ finderByVersion = mock(PastSnapshotFinderByVersion.class);
+ finderByPreviousAnalysis = mock(PastSnapshotFinderByPreviousAnalysis.class);
+ finder = new PastSnapshotFinder(finderByDays, finderByVersion, finderByDate, finderByPreviousAnalysis);
+ }
+
+ @Test
+ public void shouldFindByNumberOfDays() {
+ when(finderByDays.findFromDays(null, 30)).thenReturn(new PastSnapshot("days", null).setModeParameter("30"));
+
+ PastSnapshot variationSnapshot = finder.find(null, 1, "30");
+
+ verify(finderByDays).findFromDays(null, 30);
+ assertNotNull(variationSnapshot);
+ assertThat(variationSnapshot.getIndex(), is(1));
+ assertThat(variationSnapshot.getMode(), is("days"));
+ assertThat(variationSnapshot.getModeParameter(), is("30"));
+ }
+
+ @Test
+ public void shouldNotFindByNumberOfDays() {
+ PastSnapshot variationSnapshot = finder.find(null, 1, "30");
+
+ verify(finderByDays).findFromDays(null, 30);
+ assertNull(variationSnapshot);
+ }
+
+ @Test
+ public void shouldFindByDate() 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", new Snapshot()));
+
+ PastSnapshot variationSnapshot = finder.find(null, 2, "2010-05-18");
+
+ verify(finderByDate).findByDate((Snapshot) anyObject(), argThat(new BaseMatcher<Date>() {
+ public boolean matches(Object o) {
+ return o.equals(date);
+ }
+
+ public void describeTo(Description description) {
+
+ }
+ }));
+ assertThat(variationSnapshot.getIndex(), is(2));
+ assertThat(variationSnapshot.getMode(), is("date"));
+ assertThat(variationSnapshot.getProjectSnapshot(), not(nullValue()));
+ }
+
+ @Test
+ public void shouldNotFindByDate() throws ParseException {
+ when(finderByDate.findByDate((Snapshot) anyObject(), (Date) anyObject())).thenReturn(null);
+
+ PastSnapshot variationSnapshot = finder.find(null, 2, "2010-05-18");
+
+ verify(finderByDate).findByDate((Snapshot) anyObject(), (Date) anyObject());
+ assertNull(variationSnapshot);
+ }
+
+ @Test
+ public void shouldFindByPreviousAnalysis() throws ParseException {
+ final SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
+ final Date date = format.parse("2010-05-18");
+ Snapshot snapshot = new Snapshot();
+ snapshot.setCreatedAt(date);
+ when(finderByPreviousAnalysis.findByPreviousAnalysis(null)).thenReturn(new PastSnapshot(CoreProperties.TIMEMACHINE_MODE_PREVIOUS_ANALYSIS, snapshot));
+
+ PastSnapshot variationSnapshot = finder.find(null, 2, CoreProperties.TIMEMACHINE_MODE_PREVIOUS_ANALYSIS);
+
+ verify(finderByPreviousAnalysis).findByPreviousAnalysis(null);
+ assertThat(variationSnapshot.getIndex(), is(2));
+ assertThat(variationSnapshot.getMode(), is(CoreProperties.TIMEMACHINE_MODE_PREVIOUS_ANALYSIS));
+ assertThat(variationSnapshot.getProjectSnapshot(), not(nullValue()));
+ }
+
+ @Test
+ public void shouldNotFindPreviousAnalysis() {
+ when(finderByPreviousAnalysis.findByPreviousAnalysis(null)).thenReturn(null);
+
+ PastSnapshot variationSnapshot = finder.find(null, 2, CoreProperties.TIMEMACHINE_MODE_PREVIOUS_ANALYSIS);
+
+ verify(finderByPreviousAnalysis).findByPreviousAnalysis(null);
+
+ assertNull(variationSnapshot);
+ }
+
+ @Test
+ public void shouldFindByVersion() {
+ when(finderByVersion.findByVersion(null, "1.2")).thenReturn(new PastSnapshot("version", new Snapshot()));
+
+ PastSnapshot variationSnapshot = finder.find(null, 2, "1.2");
+
+ verify(finderByVersion).findByVersion(null, "1.2");
+ assertThat(variationSnapshot.getIndex(), is(2));
+ assertThat(variationSnapshot.getMode(), is("version"));
+ assertThat(variationSnapshot.getProjectSnapshot(), not(nullValue()));
+ }
+
+ @Test
+ public void shouldNotFindVersion() {
+ when(finderByVersion.findByVersion(null, "1.2")).thenReturn(null);
+
+ PastSnapshot variationSnapshot = finder.find(null, 2, "1.2");
+
+ verify(finderByVersion).findByVersion(null, "1.2");
+ assertNull(variationSnapshot);
+ }
+
+ @Test
+ public void shouldNotFailIfUnknownFormat() {
+ when(finderByPreviousAnalysis.findByPreviousAnalysis(null)).thenReturn(new PastSnapshot(CoreProperties.TIMEMACHINE_MODE_PREVIOUS_ANALYSIS, new Snapshot())); // should not be called
+ assertNull(finder.find(null, 2, "foooo"));
+ }
+
+ @Test
+ public void shouldGetPropertyValue() {
+ PropertiesConfiguration conf = new PropertiesConfiguration();
+ conf.setProperty("sonar.timemachine.period1", "5");
+
+ assertThat(PastSnapshotFinder.getPropertyValue(conf, 1), is("5"));
+ assertThat(PastSnapshotFinder.getPropertyValue(conf, 999), nullValue());
+ }
+
+ @Test
+ public void shouldGetDefaultPropertyValue() {
+ PropertiesConfiguration conf = new PropertiesConfiguration();
+ conf.setProperty("sonar.timemachine.period1", "5");
+
+ assertThat(PastSnapshotFinder.getPropertyValue(conf, 2), is(CoreProperties.TIMEMACHINE_DEFAULT_PERIOD_2));
+ }
+}
--- /dev/null
+package org.sonar.batch.components;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.sonar.api.database.model.RuleFailureModel;
+import org.sonar.api.database.model.Snapshot;
+import org.sonar.api.resources.JavaFile;
+import org.sonar.api.resources.Resource;
+import org.sonar.batch.index.ResourcePersister;
+import org.sonar.jpa.test.AbstractDbUnitTestCase;
+
+import java.util.List;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.notNullValue;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyBoolean;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+
+public class PastViolationsLoaderTest extends AbstractDbUnitTestCase {
+
+ private ResourcePersister resourcePersister;
+ private PastViolationsLoader loader;
+
+ @Before
+ public void setUp() {
+ setupData("shared");
+ resourcePersister = mock(ResourcePersister.class);
+ loader = new PastViolationsLoader(getSession(), resourcePersister);
+ }
+
+ @Test
+ public void shouldGetPastResourceViolations() {
+ Snapshot snapshot = getSession().getSingleResult(Snapshot.class, "id", 1000);
+ doReturn(snapshot).when(resourcePersister)
+ .getSnapshot(any(Resource.class));
+ doReturn(snapshot).when(resourcePersister)
+ .getLastSnapshot(any(Snapshot.class), anyBoolean());
+
+ List<RuleFailureModel> violations = loader.getPastViolations(new JavaFile("file"));
+
+ assertThat(violations.size(), is(2));
+ }
+
+ @Test
+ public void shouldReturnEmptyList() {
+ List<RuleFailureModel> violations = loader.getPastViolations(null);
+
+ assertThat(violations, notNullValue());
+ assertThat(violations.size(), is(0));
+ }
+
+}
Snapshot snapshot = getSession().getSingleResult(Snapshot.class, "id", 1000);
ResourcePersister resourcePersister = mock(ResourcePersister.class);
when(resourcePersister.saveResource((Project) anyObject(), eq(javaFile))).thenReturn(snapshot);
- when(resourcePersister.getLastSnapshot(snapshot, true)).thenReturn(snapshot);
when(resourcePersister.getSnapshot(javaFile)).thenReturn(snapshot);
violationPersister = new ViolationPersister(getSession(), resourcePersister, new DefaultRuleFinder(getSessionFactory()));
}
--- /dev/null
+<dataset>
+
+ <metrics id="1" name="ncloc" VAL_TYPE="INT" DESCRIPTION="[null]" domain="[null]" short_name=""
+ enabled="true" worst_value="[null]" optimized_best_value="[null]" best_value="[null]" direction="0" hidden="false"/>
+ <metrics id="2" name="coverage" VAL_TYPE="INT" DESCRIPTION="[null]" domain="[null]" short_name=""
+ enabled="true" worst_value="0" optimized_best_value="true" best_value="100" direction="1" hidden="false"/>
+
+
+ <rules_categories id="1" name="Efficiency" description="[null]"/>
+ <rules_categories id="6" name="Usability" description="[null]"/>
+
+ <rules id="30" name="Check Header" plugin_rule_key="com.puppycrawl.tools.checkstyle.checks.header.HeaderCheck"
+ plugin_config_key="Checker/Treewalker/HeaderCheck" plugin_name="checkstyle" description="[null]" priority="4" enabled="true"
+ cardinality="SINGLE" parent_id="[null]"/>
+
+ <rules id="31" name="Equals Avoid Null" plugin_rule_key="com.puppycrawl.tools.checkstyle.checks.coding.EqualsAvoidNullCheck"
+ plugin_config_key="Checker/TreeWalker/EqualsAvoidNull" plugin_name="checkstyle" description="[null]" priority="4" enabled="true"
+ cardinality="SINGLE" parent_id="[null]"/>
+
+ <!-- project -->
+ <projects long_name="[null]" id="1" scope="PRJ" qualifier="TRK" kee="project" name="project"
+ root_id="[null]"
+ description="[null]"
+ enabled="true" language="java" copy_resource_id="[null]"/>
+
+ <!-- package -->
+ <projects long_name="[null]" id="2" scope="DIR" qualifier="PAC" kee="project:org.foo" name="org.foo"
+ root_id="1"
+ description="[null]"
+ enabled="true" language="java" copy_resource_id="[null]"/>
+
+ <!-- file -->
+ <projects long_name="org.foo.Bar" id="3" scope="FIL" qualifier="CLA" kee="project:org.foo.Bar"
+ name="Bar" root_id="[null]"
+ description="[null]"
+ enabled="true" language="java" copy_resource_id="[null]"/>
+
+
+ <!-- snapshots -->
+ <snapshots period1_mode="[null]" period1_param="[null]" period1_date="[null]" period2_mode="[null]" period2_param="[null]" period2_date="[null]" period3_mode="[null]" period3_param="[null]" period3_date="[null]" period4_mode="[null]" period4_param="[null]" period4_date="[null]" period5_mode="[null]" period5_param="[null]" period5_date="[null]" id="1000" project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[null]"
+ scope="PRJ" qualifier="TRK" created_at="2008-11-01 13:58:00.00" version="[null]" path=""
+ status="P" islast="false" depth="0" />
+
+ <snapshots period1_mode="[null]" period1_param="[null]" period1_date="[null]" period2_mode="[null]" period2_param="[null]" period2_date="[null]" period3_mode="[null]" period3_param="[null]" period3_date="[null]" period4_mode="[null]" period4_param="[null]" period4_date="[null]" period5_mode="[null]" period5_param="[null]" period5_date="[null]" id="1001" project_id="2" parent_snapshot_id="1000" root_project_id="1" root_snapshot_id="1000"
+ scope="DIR" qualifier="PAC" created_at="2008-11-01 13:58:00.00" version="[null]" path="1000."
+ status="P" islast="false" depth="1" />
+
+ <snapshots period1_mode="[null]" period1_param="[null]" period1_date="[null]" period2_mode="[null]" period2_param="[null]" period2_date="[null]" period3_mode="[null]" period3_param="[null]" period3_date="[null]" period4_mode="[null]" period4_param="[null]" period4_date="[null]" period5_mode="[null]" period5_param="[null]" period5_date="[null]" id="1002" project_id="3" parent_snapshot_id="1001" root_project_id="1" root_snapshot_id="1000"
+ scope="FIL" qualifier="CLA" created_at="2008-11-01 13:58:00.00" version="[null]" path="1000.1001."
+ status="P" islast="false" depth="2" />
+
+
+ <!-- project measures -->
+ <project_measures id="1" VALUE="60" METRIC_ID="1" SNAPSHOT_ID="1000" alert_text="[null]" RULES_CATEGORY_ID="[null]"
+ RULE_ID="[null]" text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]"
+ alert_status="[null]" description="[null]" rule_priority="[null]" characteristic_id="[null]" url="[null]"
+ variation_value_1="[null]" variation_value_2="[null]" variation_value_3="[null]" variation_value_4="[null]" variation_value_5="[null]"/>
+
+ <project_measures id="2" VALUE="80" METRIC_ID="2" SNAPSHOT_ID="1000" alert_text="[null]" RULES_CATEGORY_ID="[null]"
+ RULE_ID="[null]" text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]"
+ alert_status="[null]" description="[null]" rule_priority="[null]" characteristic_id="[null]" url="[null]"
+ variation_value_1="[null]" variation_value_2="[null]" variation_value_3="[null]" variation_value_4="[null]" variation_value_5="[null]"/>
+
+ <!-- package measures -->
+ <project_measures id="3" VALUE="20" METRIC_ID="1" SNAPSHOT_ID="1001" alert_text="[null]" RULES_CATEGORY_ID="[null]"
+ RULE_ID="[null]" text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]"
+ alert_status="[null]" description="[null]" rule_priority="[null]" characteristic_id="[null]" url="[null]"
+ variation_value_1="[null]" variation_value_2="[null]" variation_value_3="[null]" variation_value_4="[null]" variation_value_5="[null]"/>
+
+ <project_measures id="4" VALUE="70" METRIC_ID="2" SNAPSHOT_ID="1001" alert_text="[null]" RULES_CATEGORY_ID="[null]"
+ RULE_ID="[null]" text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]"
+ alert_status="[null]" description="[null]" rule_priority="[null]" characteristic_id="[null]" url="[null]"
+ variation_value_1="[null]" variation_value_2="[null]" variation_value_3="[null]" variation_value_4="[null]" variation_value_5="[null]"/>
+
+ <!-- file measures -->
+ <project_measures id="5" VALUE="5" METRIC_ID="1" SNAPSHOT_ID="1002" alert_text="[null]" RULES_CATEGORY_ID="[null]"
+ RULE_ID="[null]" text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]"
+ alert_status="[null]" description="[null]" rule_priority="[null]" characteristic_id="[null]" url="[null]"
+ variation_value_1="[null]" variation_value_2="[null]" variation_value_3="[null]" variation_value_4="[null]" variation_value_5="[null]"/>
+
+ <project_measures id="6" VALUE="60" METRIC_ID="2" SNAPSHOT_ID="1002" alert_text="[null]" RULES_CATEGORY_ID="[null]"
+ RULE_ID="[null]" text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]"
+ alert_status="[null]" description="[null]" rule_priority="[null]" characteristic_id="[null]" url="[null]"
+ variation_value_1="[null]" variation_value_2="[null]" variation_value_3="[null]" variation_value_4="[null]" variation_value_5="[null]"/>
+</dataset>
\ No newline at end of file
--- /dev/null
+<dataset>
+
+ <projects long_name="[null]" id="1" scope="PRJ" qualifier="TRK" kee="project" name="project"
+ root_id="[null]"
+ description="[null]"
+ enabled="true" language="java" copy_resource_id="[null]"/>
+
+
+ <!-- 2008-11-01 -->
+ <snapshots period1_mode="[null]" period1_param="[null]" period1_date="[null]" period2_mode="[null]" period2_param="[null]" period2_date="[null]" period3_mode="[null]" period3_param="[null]" period3_date="[null]" period4_mode="[null]" period4_param="[null]" period4_date="[null]" period5_mode="[null]" period5_param="[null]" period5_date="[null]" id="1000"
+ project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[null]"
+ scope="PRJ" qualifier="TRK" created_at="2008-11-01 13:58:00.00" version="1.1-SNAPSHOT" path=""
+ status="P" islast="false" depth="0" />
+
+
+ <!-- 2008-11-12 -->
+ <snapshots period1_mode="[null]" period1_param="[null]" period1_date="[null]" period2_mode="[null]" period2_param="[null]" period2_date="[null]" period3_mode="[null]" period3_param="[null]" period3_date="[null]" period4_mode="[null]" period4_param="[null]" period4_date="[null]" period5_mode="[null]" period5_param="[null]" period5_date="[null]" id="1003"
+ project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[null]"
+ scope="PRJ" qualifier="TRK" created_at="2008-11-12 13:58:00.00" version="1.1-SNAPSHOT" path=""
+ status="P" islast="true" depth="0" />
+
+
+ <!-- 2008-11-22 -->
+ <snapshots period1_mode="[null]" period1_param="[null]" period1_date="[null]" period2_mode="[null]" period2_param="[null]" period2_date="[null]" period3_mode="[null]" period3_param="[null]" period3_date="[null]" period4_mode="[null]" period4_param="[null]" period4_date="[null]" period5_mode="[null]" period5_param="[null]" period5_date="[null]" id="1006"
+ project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[null]"
+ scope="PRJ" qualifier="TRK" created_at="2008-11-22 13:58:00.00" version="1.1" path=""
+ status="P" islast="false" depth="0" />
+
+
+ <!-- 2008-11-25-->
+ <snapshots period1_mode="[null]" period1_param="[null]" period1_date="[null]" period2_mode="[null]" period2_param="[null]" period2_date="[null]" period3_mode="[null]" period3_param="[null]" period3_date="[null]" period4_mode="[null]" period4_param="[null]" period4_date="[null]" period5_mode="[null]" period5_param="[null]" period5_date="[null]" id="1009"
+ project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[null]"
+ scope="PRJ" qualifier="TRK" created_at="2008-11-25 13:58:00.00" version="1.1" path=""
+ status="P" islast="false" depth="0" />
+
+ <!-- current analysis -->
+ <snapshots period1_mode="[null]" period1_param="[null]" period1_date="[null]" period2_mode="[null]" period2_param="[null]" period2_date="[null]" period3_mode="[null]" period3_param="[null]" period3_date="[null]" period4_mode="[null]" period4_param="[null]" period4_date="[null]" period5_mode="[null]" period5_param="[null]" period5_date="[null]" id="1010"
+ project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[null]"
+ scope="PRJ" qualifier="TRK" created_at="2008-11-27 13:58:00.00" version="1.2-SNAPSHOT" path=""
+ status="U" islast="false" depth="0" />
+
+</dataset>
\ No newline at end of file
--- /dev/null
+<dataset>
+
+ <!-- project -->
+ <projects long_name="[null]" id="1" scope="PRJ" qualifier="TRK" kee="project" name="project"
+ root_id="[null]"
+ description="[null]"
+ enabled="true" language="java" copy_resource_id="[null]"/>
+
+ <!-- package -->
+ <projects long_name="[null]" id="2" scope="DIR" qualifier="PAC" kee="project:org.foo" name="org.foo"
+ root_id="1"
+ description="[null]"
+ enabled="true" language="java" copy_resource_id="[null]"/>
+
+ <!-- file -->
+ <projects long_name="org.foo.Bar" id="3" scope="FIL" qualifier="CLA" kee="project:org.foo.Bar"
+ name="Bar" root_id="[null]"
+ description="[null]"
+ enabled="true" language="java" copy_resource_id="[null]"/>
+
+
+ <!-- first analysis : 2008-11-01-->
+ <snapshots period1_mode="[null]" period1_param="[null]" period1_date="[null]" period2_mode="[null]" period2_param="[null]" period2_date="[null]" period3_mode="[null]" period3_param="[null]" period3_date="[null]" period4_mode="[null]" period4_param="[null]" period4_date="[null]" period5_mode="[null]" period5_param="[null]" period5_date="[null]" id="1000" project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[null]"
+ scope="PRJ" qualifier="TRK" created_at="2008-11-01 13:58:00.00" version="[null]" path=""
+ status="P" islast="false" depth="0" />
+
+ <snapshots period1_mode="[null]" period1_param="[null]" period1_date="[null]" period2_mode="[null]" period2_param="[null]" period2_date="[null]" period3_mode="[null]" period3_param="[null]" period3_date="[null]" period4_mode="[null]" period4_param="[null]" period4_date="[null]" period5_mode="[null]" period5_param="[null]" period5_date="[null]" id="1001" project_id="2" parent_snapshot_id="1000" root_project_id="1" root_snapshot_id="1000"
+ scope="DIR" qualifier="PAC" created_at="2008-11-01 13:58:00.00" version="[null]" path="1000."
+ status="P" islast="false" depth="1" />
+
+ <snapshots period1_mode="[null]" period1_param="[null]" period1_date="[null]" period2_mode="[null]" period2_param="[null]" period2_date="[null]" period3_mode="[null]" period3_param="[null]" period3_date="[null]" period4_mode="[null]" period4_param="[null]" period4_date="[null]" period5_mode="[null]" period5_param="[null]" period5_date="[null]" id="1002" project_id="3" parent_snapshot_id="1001" root_project_id="1" root_snapshot_id="1000"
+ scope="FIL" qualifier="CLA" created_at="2008-11-01 13:58:00.00" version="[null]" path="1000.1001."
+ status="P" islast="false" depth="2" />
+
+
+ <!-- second unprocessed analysis - to ignore: 2008-11-12 -->
+ <snapshots period1_mode="[null]" period1_param="[null]" period1_date="[null]" period2_mode="[null]" period2_param="[null]" period2_date="[null]" period3_mode="[null]" period3_param="[null]" period3_date="[null]" period4_mode="[null]" period4_param="[null]" period4_date="[null]" period5_mode="[null]" period5_param="[null]" period5_date="[null]" id="1003" project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[null]"
+ scope="PRJ" qualifier="TRK" created_at="2008-11-12 13:58:00.00" version="[null]" path=""
+ status="U" islast="false" depth="0" />
+
+ <snapshots period1_mode="[null]" period1_param="[null]" period1_date="[null]" period2_mode="[null]" period2_param="[null]" period2_date="[null]" period3_mode="[null]" period3_param="[null]" period3_date="[null]" period4_mode="[null]" period4_param="[null]" period4_date="[null]" period5_mode="[null]" period5_param="[null]" period5_date="[null]" id="1004" project_id="2" parent_snapshot_id="1003" root_project_id="1" root_snapshot_id="1003"
+ scope="DIR" qualifier="PAC" created_at="2008-11-12 13:58:00.00" version="[null]" path="1003."
+ status="U" islast="false" depth="1" />
+
+ <snapshots period1_mode="[null]" period1_param="[null]" period1_date="[null]" period2_mode="[null]" period2_param="[null]" period2_date="[null]" period3_mode="[null]" period3_param="[null]" period3_date="[null]" period4_mode="[null]" period4_param="[null]" period4_date="[null]" period5_mode="[null]" period5_param="[null]" period5_date="[null]" id="1005" project_id="3" parent_snapshot_id="1004" root_project_id="1" root_snapshot_id="1003"
+ scope="FIL" qualifier="CLA" created_at="2008-11-12 13:58:00.00" version="[null]" path="1003.1004."
+ status="P" islast="false" depth="2" />
+
+
+ <!-- second analysis : 2008-11-13-->
+ <snapshots period1_mode="[null]" period1_param="[null]" period1_date="[null]" period2_mode="[null]" period2_param="[null]" period2_date="[null]" period3_mode="[null]" period3_param="[null]" period3_date="[null]" period4_mode="[null]" period4_param="[null]" period4_date="[null]" period5_mode="[null]" period5_param="[null]" period5_date="[null]" id="1006" project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[null]"
+ scope="PRJ" qualifier="TRK" created_at="2008-11-13 13:58:00.00" version="[null]" path=""
+ status="P" islast="true" depth="0" />
+
+ <snapshots period1_mode="[null]" period1_param="[null]" period1_date="[null]" period2_mode="[null]" period2_param="[null]" period2_date="[null]" period3_mode="[null]" period3_param="[null]" period3_date="[null]" period4_mode="[null]" period4_param="[null]" period4_date="[null]" period5_mode="[null]" period5_param="[null]" period5_date="[null]" id="1007" project_id="2" parent_snapshot_id="1006" root_project_id="1" root_snapshot_id="1006"
+ scope="DIR" qualifier="PAC" created_at="2008-11-13 13:58:00.00" version="[null]" path="1006."
+ status="P" islast="true" depth="1" />
+
+ <snapshots period1_mode="[null]" period1_param="[null]" period1_date="[null]" period2_mode="[null]" period2_param="[null]" period2_date="[null]" period3_mode="[null]" period3_param="[null]" period3_date="[null]" period4_mode="[null]" period4_param="[null]" period4_date="[null]" period5_mode="[null]" period5_param="[null]" period5_date="[null]" id="1008" project_id="3" parent_snapshot_id="1007" root_project_id="1" root_snapshot_id="1006"
+ scope="FIL" qualifier="CLA" created_at="2008-11-13 13:58:00.00" version="[null]" path="1006.1007."
+ status="P" islast="true" depth="2" />
+
+
+ <!-- current analysis : 2008-11-16 -->
+ <snapshots period1_mode="[null]" period1_param="[null]" period1_date="[null]" period2_mode="[null]" period2_param="[null]" period2_date="[null]" period3_mode="[null]" period3_param="[null]" period3_date="[null]" period4_mode="[null]" period4_param="[null]" period4_date="[null]" period5_mode="[null]" period5_param="[null]" period5_date="[null]" id="1009" project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[null]"
+ scope="PRJ" qualifier="TRK" created_at="2008-11-16 13:58:00.00" version="[null]" path=""
+ status="U" islast="false" depth="0" />
+
+ <snapshots period1_mode="[null]" period1_param="[null]" period1_date="[null]" period2_mode="[null]" period2_param="[null]" period2_date="[null]" period3_mode="[null]" period3_param="[null]" period3_date="[null]" period4_mode="[null]" period4_param="[null]" period4_date="[null]" period5_mode="[null]" period5_param="[null]" period5_date="[null]" id="1010" project_id="2" parent_snapshot_id="1009" root_project_id="1" root_snapshot_id="1009"
+ scope="DIR" qualifier="PAC" created_at="2008-11-16 13:58:00.00" version="[null]" path="1009."
+ status="U" islast="false" depth="1" />
+
+ <snapshots period1_mode="[null]" period1_param="[null]" period1_date="[null]" period2_mode="[null]" period2_param="[null]" period2_date="[null]" period3_mode="[null]" period3_param="[null]" period3_date="[null]" period4_mode="[null]" period4_param="[null]" period4_date="[null]" period5_mode="[null]" period5_param="[null]" period5_date="[null]" id="1011" project_id="3" parent_snapshot_id="1010" root_project_id="1" root_snapshot_id="1009"
+ scope="FIL" qualifier="CLA" created_at="2008-11-16 13:58:00.00" version="[null]" path="1009.1010."
+ status="U" islast="false" depth="2" />
+</dataset>
\ No newline at end of file
--- /dev/null
+<dataset>
+
+ <projects long_name="[null]" id="1" scope="PRJ" qualifier="TRK" kee="project" name="project"
+ root_id="[null]"
+ description="[null]"
+ enabled="true" language="java" copy_resource_id="[null]"/>
+
+ <snapshots period1_mode="[null]" period1_param="[null]" period1_date="[null]" period2_mode="[null]" period2_param="[null]" period2_date="[null]" period3_mode="[null]" period3_param="[null]" period3_date="[null]" period4_mode="[null]" period4_param="[null]" period4_date="[null]" period5_mode="[null]" period5_param="[null]" period5_date="[null]" id="1006"
+ project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[null]"
+ scope="PRJ" qualifier="TRK" created_at="2008-11-22 13:58:00.00" version="1.1" path=""
+ status="P" islast="false" depth="0" />
+
+
+ <!-- last analysis -->
+ <snapshots period1_mode="[null]" period1_param="[null]" period1_date="[null]" period2_mode="[null]" period2_param="[null]" period2_date="[null]" period3_mode="[null]" period3_param="[null]" period3_date="[null]" period4_mode="[null]" period4_param="[null]" period4_date="[null]" period5_mode="[null]" period5_param="[null]" period5_date="[null]" id="1009"
+ project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[null]"
+ scope="PRJ" qualifier="TRK" created_at="2008-11-25 13:58:00.00" version="1.1" path=""
+ status="P" islast="true" depth="0" />
+
+ <!-- current analysis -->
+ <snapshots period1_mode="[null]" period1_param="[null]" period1_date="[null]" period2_mode="[null]" period2_param="[null]" period2_date="[null]" period3_mode="[null]" period3_param="[null]" period3_date="[null]" period4_mode="[null]" period4_param="[null]" period4_date="[null]" period5_mode="[null]" period5_param="[null]" period5_date="[null]" id="1010"
+ project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[null]"
+ scope="PRJ" qualifier="TRK" created_at="2008-11-27 13:58:00.00" version="1.2-SNAPSHOT" path=""
+ status="U" islast="false" depth="0" />
+
+</dataset>
\ No newline at end of file
--- /dev/null
+<dataset>
+
+ <projects long_name="[null]" id="1" scope="PRJ" qualifier="TRK" kee="project" name="project"
+ root_id="[null]"
+ description="[null]"
+ enabled="true" language="java" copy_resource_id="[null]"/>
+
+
+ <!-- unprocessed analysis -->
+ <snapshots period1_mode="[null]" period1_param="[null]" period1_date="[null]" period2_mode="[null]" period2_param="[null]" period2_date="[null]" period3_mode="[null]" period3_param="[null]" period3_date="[null]" period4_mode="[null]" period4_param="[null]" period4_date="[null]" period5_mode="[null]" period5_param="[null]" period5_date="[null]" id="1009"
+ project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[null]"
+ scope="PRJ" qualifier="TRK" created_at="2008-11-25 13:58:00.00" version="1.1" path=""
+ status="U" islast="false" depth="0" />
+
+ <!-- current analysis -->
+ <snapshots period1_mode="[null]" period1_param="[null]" period1_date="[null]" period2_mode="[null]" period2_param="[null]" period2_date="[null]" period3_mode="[null]" period3_param="[null]" period3_date="[null]" period4_mode="[null]" period4_param="[null]" period4_date="[null]" period5_mode="[null]" period5_param="[null]" period5_date="[null]" id="1010"
+ project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[null]"
+ scope="PRJ" qualifier="TRK" created_at="2008-11-27 13:58:00.00" version="1.2-SNAPSHOT" path=""
+ status="U" islast="false" depth="0" />
+
+</dataset>
\ No newline at end of file
--- /dev/null
+<dataset>
+
+ <projects long_name="[null]" id="1" scope="PRJ" qualifier="TRK" kee="project" name="project"
+ root_id="[null]"
+ description="[null]"
+ enabled="true" language="java" copy_resource_id="[null]"/>
+
+
+ <!-- version 1.1-SNAPSHOT -->
+ <snapshots period1_mode="[null]" period1_param="[null]" period1_date="[null]" period2_mode="[null]" period2_param="[null]" period2_date="[null]" period3_mode="[null]" period3_param="[null]" period3_date="[null]" period4_mode="[null]" period4_param="[null]" period4_date="[null]" period5_mode="[null]" period5_param="[null]" period5_date="[null]" id="1000"
+ project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[null]"
+ scope="PRJ" qualifier="TRK" created_at="2008-11-01 13:58:00.00" version="1.1-SNAPSHOT" path=""
+ status="P" islast="false" depth="0" />
+
+
+ <!-- version 1.1-SNAPSHOT -->
+ <snapshots period1_mode="[null]" period1_param="[null]" period1_date="[null]" period2_mode="[null]" period2_param="[null]" period2_date="[null]" period3_mode="[null]" period3_param="[null]" period3_date="[null]" period4_mode="[null]" period4_param="[null]" period4_date="[null]" period5_mode="[null]" period5_param="[null]" period5_date="[null]" id="1003"
+ project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[null]"
+ scope="PRJ" qualifier="TRK" created_at="2008-11-02 13:58:00.00" version="1.1-SNAPSHOT" path=""
+ status="P" islast="true" depth="0" />
+
+
+ <!-- unprocessed version 1.1 (to ignore) -->
+ <snapshots period1_mode="[null]" period1_param="[null]" period1_date="[null]" period2_mode="[null]" period2_param="[null]" period2_date="[null]" period3_mode="[null]" period3_param="[null]" period3_date="[null]" period4_mode="[null]" period4_param="[null]" period4_date="[null]" period5_mode="[null]" period5_param="[null]" period5_date="[null]" id="1006"
+ project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[null]"
+ scope="PRJ" qualifier="TRK" created_at="2008-11-03 13:58:00.00" version="1.1" path=""
+ status="U" islast="false" depth="0" />
+
+
+ <!-- version 1.1 -->
+ <snapshots period1_mode="[null]" period1_param="[null]" period1_date="[null]" period2_mode="[null]" period2_param="[null]" period2_date="[null]" period3_mode="[null]" period3_param="[null]" period3_date="[null]" period4_mode="[null]" period4_param="[null]" period4_date="[null]" period5_mode="[null]" period5_param="[null]" period5_date="[null]" id="1009"
+ project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[null]"
+ scope="PRJ" qualifier="TRK" created_at="2008-11-04 13:58:00.00" version="1.1" path=""
+ status="P" islast="false" depth="0" />
+
+ <!-- current analysis -->
+ <snapshots period1_mode="[null]" period1_param="[null]" period1_date="[null]" period2_mode="[null]" period2_param="[null]" period2_date="[null]" period3_mode="[null]" period3_param="[null]" period3_date="[null]" period4_mode="[null]" period4_param="[null]" period4_date="[null]" period5_mode="[null]" period5_param="[null]" period5_date="[null]" id="1010"
+ project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[null]"
+ scope="PRJ" qualifier="TRK" created_at="2008-11-05 13:58:00.00" version="1.2-SNAPSHOT" path=""
+ status="U" islast="false" depth="0" />
+
+</dataset>
\ No newline at end of file
--- /dev/null
+<dataset>
+
+ <rules_categories id="1" name="Efficiency" description="[null]"/>
+ <rules_categories id="6" name="Usability" description="[null]"/>
+
+ <rules id="30" name="Check Header" plugin_rule_key="com.puppycrawl.tools.checkstyle.checks.header.HeaderCheck"
+ plugin_config_key="Checker/Treewalker/HeaderCheck" plugin_name="checkstyle" description="[null]" priority="4" enabled="true"
+ cardinality="SINGLE" parent_id="[null]"/>
+
+ <rules id="31" name="Equals Avoid Null" plugin_rule_key="com.puppycrawl.tools.checkstyle.checks.coding.EqualsAvoidNullCheck"
+ plugin_config_key="Checker/TreeWalker/EqualsAvoidNull" plugin_name="checkstyle" description="[null]" priority="4" enabled="true"
+ cardinality="SINGLE" parent_id="[null]"/>
+
+ <projects id="200" scope="FIL" qualifier="CLA" kee="project:org.foo.Bar" root_id="[null]"
+ name="Bar" long_name="org.foo.Bar" description="[null]"
+ enabled="true" language="java" copy_resource_id="[null]" profile_id="[null]"/>
+
+ <snapshots period1_mode="[null]" period1_param="[null]" period1_date="[null]" period2_mode="[null]" period2_param="[null]" period2_date="[null]" period3_mode="[null]" period3_param="[null]" period3_date="[null]" period4_mode="[null]" period4_param="[null]" period4_date="[null]" period5_mode="[null]" period5_param="[null]" period5_date="[null]" id="1000" project_id="200" parent_snapshot_id="[null]" root_project_id="100" root_snapshot_id="[null]"
+ scope="FIL" qualifier="CLA" created_at="2008-11-01 13:58:00.00" version="[null]" path=""
+ status="U" islast="false" depth="3" />
+
+ <RULE_FAILURES ID="1" SNAPSHOT_ID="1000" RULE_ID="30" FAILURE_LEVEL="3" MESSAGE="old message" LINE="10" COST="[null]" created_at="2008-11-01 13:58:00.00" />
+ <RULE_FAILURES ID="2" SNAPSHOT_ID="1000" RULE_ID="30" FAILURE_LEVEL="3" MESSAGE="old message" LINE="10" COST="[null]" created_at="2008-11-01 13:58:00.00" />
+</dataset>
/* Surefire */
String SUREFIRE_PLUGIN = "surefire";
String SUREFIRE_REPORTS_PATH_PROPERTY = "sonar.surefire.reportsPath";
+
+ /* Time machine periods */
+ String TIMEMACHINE_PERIOD_PREFIX = "sonar.timemachine.period";
+ String TIMEMACHINE_MODE_PREVIOUS_ANALYSIS = "previous_analysis";
+ String TIMEMACHINE_DEFAULT_PERIOD_1 = TIMEMACHINE_MODE_PREVIOUS_ANALYSIS;
+ String TIMEMACHINE_DEFAULT_PERIOD_2 = "5";
+ String TIMEMACHINE_DEFAULT_PERIOD_3 = "30";
+ String TIMEMACHINE_DEFAULT_PERIOD_4 = "";
+ String TIMEMACHINE_DEFAULT_PERIOD_5 = "";
}
}
private HttpURLConnection newHttpConnection(URI uri) throws IOException {
- LoggerFactory.getLogger(getClass()).info("Download: " + uri + " (" + getProxySynthesis(uri) + ")");
+ LoggerFactory.getLogger(getClass()).debug("Download: " + uri + " (" + getProxySynthesis(uri) + ")");
HttpURLConnection connection = (HttpURLConnection) uri.toURL().openConnection();
connection.setConnectTimeout(TIMEOUT_MILLISECONDS);
connection.setReadTimeout(TIMEOUT_MILLISECONDS);