defaultValue = CoreProperties.TIMEMACHINE_DEFAULT_PERIOD_3,
category = CoreProperties.CATEGORY_DIFFERENTIAL_VIEWS),
@Property(
- key = "sonar.timemachine.period4",
+ key = "sonar.timemachine.TRK.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, " +
project = true,
global = false,
defaultValue = CoreProperties.TIMEMACHINE_DEFAULT_PERIOD_4,
- category = CoreProperties.CATEGORY_DIFFERENTIAL_VIEWS),
+ category = CoreProperties.CATEGORY_DIFFERENTIAL_VIEWS,
+ deprecatedKey = "sonar.timemachine.period4"),
@Property(
- key = "sonar.timemachine.period5",
+ key = "sonar.timemachine.TRK.period5",
name = "Period 5",
description = "See the property 'Period 4'",
project = true,
global = false,
defaultValue = CoreProperties.TIMEMACHINE_DEFAULT_PERIOD_5,
- category = CoreProperties.CATEGORY_DIFFERENTIAL_VIEWS),
+ category = CoreProperties.CATEGORY_DIFFERENTIAL_VIEWS,
+ deprecatedKey = "sonar.timemachine.period5"),
@Property(
key = CoreProperties.DRY_RUN,
defaultValue = "false",
defaultValue = "false",
project = false,
global = false,
- type = PropertyType.BOOLEAN)
+ type = PropertyType.BOOLEAN),
+ @Property(
+ key = "sonar.enableFileVariation",
+ name = "Enable file variation",
+ global = false,
+ defaultValue = "false",
+ category = CoreProperties.CATEGORY_GENERAL),
})
public final class CorePlugin extends SonarPlugin {
*/
package org.sonar.batch.components;
-import org.apache.commons.configuration.Configuration;
import org.apache.commons.lang.StringUtils;
+import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.sonar.api.BatchExtension;
import org.sonar.api.CoreProperties;
+import org.sonar.api.config.Settings;
import org.sonar.api.database.model.Snapshot;
import java.text.ParseException;
public class PastSnapshotFinder implements BatchExtension {
- /**
- * IMPORTANT : please update default values in the ruby side too. See app/helpers/FiltersHelper.rb, method period_names()
- */
+ private static final Logger LOG = LoggerFactory.getLogger(PastSnapshotFinder.class);
+
private PastSnapshotFinderByDays finderByDays;
private PastSnapshotFinderByVersion finderByVersion;
private PastSnapshotFinderByDate finderByDate;
this.finderByPreviousVersion = finderByPreviousVersion;
}
- public PastSnapshot find(Snapshot projectSnapshot, Configuration conf, int index) {
- String propertyValue = getPropertyValue(conf, index);
+ public PastSnapshot find(Snapshot projectSnapshot, String rootQualifier, Settings settings, int index) {
+ String propertyValue = getPropertyValue(rootQualifier, settings, index);
PastSnapshot pastSnapshot = find(projectSnapshot, index, propertyValue);
if (pastSnapshot == null && StringUtils.isNotBlank(propertyValue)) {
- LoggerFactory.getLogger(PastSnapshotFinder.class).debug("Property " + CoreProperties.TIMEMACHINE_PERIOD_PREFIX + index + " is not valid: " + propertyValue);
+ LOG.debug("Property " + getProperty(rootQualifier, index) + " is not valid: " + 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; // NOSONAR false-positive: constant 4 is the same than 5 (empty string)
- case 5:
- defaultValue = CoreProperties.TIMEMACHINE_DEFAULT_PERIOD_5;
- break; // NOSONAR false-positive: constant 5 is the same than 4 (empty string)
+ static String getPropertyValue(String rootQualifier, Settings settings, int index) {
+ return settings.getString(getProperty(rootQualifier, index));
+ }
+
+ static private String getProperty(String rootQualifier, int index) {
+ if (index <= 3) {
+ return CoreProperties.TIMEMACHINE_PERIOD_PREFIX + index;
+ } else {
+ return CoreProperties.TIMEMACHINE_PREFIX + "." + rootQualifier + "." + CoreProperties.TIMEMACHINE_PERIOD_SUFFIX + index;
}
- return conf.getString(CoreProperties.TIMEMACHINE_PERIOD_PREFIX + index, defaultValue);
}
public PastSnapshot findPreviousAnalysis(Snapshot projectSnapshot) {
package org.sonar.batch.components;
import com.google.common.collect.Lists;
-import org.apache.commons.configuration.Configuration;
import org.apache.commons.lang.StringUtils;
+import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.sonar.api.BatchExtension;
+import org.sonar.api.config.Settings;
import org.sonar.api.database.DatabaseSession;
import org.sonar.api.database.model.Snapshot;
import org.sonar.api.resources.Project;
import org.sonar.api.resources.Qualifiers;
-import org.sonar.api.utils.Logs;
import javax.persistence.Query;
public class TimeMachineConfiguration implements BatchExtension {
+ private static final Logger LOG = LoggerFactory.getLogger(TimeMachineConfiguration.class);
+
private static final int NUMBER_OF_VARIATION_SNAPSHOTS = 5;
private static final int CORE_TENDENCY_DEPTH_DEFAULT_VALUE = 30;
private Project project;
- private final Configuration configuration;
+ private final Settings settings;
private List<PastSnapshot> projectPastSnapshots;
private DatabaseSession session;
- public TimeMachineConfiguration(DatabaseSession session, Project project, Configuration configuration,
+ public TimeMachineConfiguration(DatabaseSession session, Project project, Settings settings,
PastSnapshotFinder pastSnapshotFinder) {
this.session = session;
this.project = project;
- this.configuration = configuration;
- initPastSnapshots(pastSnapshotFinder);
+ this.settings = settings;
+ initPastSnapshots(pastSnapshotFinder, getRootProject(project).getQualifier());
+ }
+
+ private Project getRootProject(Project project){
+ if (!project.isRoot()) {
+ return getRootProject(project.getRoot());
+ }
+ return project;
}
- private void initPastSnapshots(PastSnapshotFinder pastSnapshotFinder) {
+ private void initPastSnapshots(PastSnapshotFinder pastSnapshotFinder, String rootQualifier) {
Snapshot projectSnapshot = buildProjectSnapshot();
projectPastSnapshots = Lists.newLinkedList();
if (projectSnapshot != null) {
for (int index = 1; index <= NUMBER_OF_VARIATION_SNAPSHOTS; index++) {
- PastSnapshot pastSnapshot = pastSnapshotFinder.find(projectSnapshot, configuration, index);
+ PastSnapshot pastSnapshot = pastSnapshotFinder.find(projectSnapshot, rootQualifier, settings, index);
if (pastSnapshot != null) {
log(pastSnapshot);
projectPastSnapshots.add(pastSnapshot);
String qualifier = pastSnapshot.getQualifier();
// hack to avoid too many logs when the views plugin is installed
if (StringUtils.equals(Qualifiers.VIEW, qualifier) || StringUtils.equals(Qualifiers.SUBVIEW, qualifier)) {
- LoggerFactory.getLogger(getClass()).debug(pastSnapshot.toString());
+ LOG.debug(pastSnapshot.toString());
} else {
- Logs.INFO.info(pastSnapshot.toString());
+ LOG.info(pastSnapshot.toString());
}
}
}
public boolean isFileVariationEnabled() {
- return configuration.getBoolean("sonar.enableFileVariation", Boolean.FALSE);
+ return settings.getBoolean("sonar.enableFileVariation");
}
}
*/
package org.sonar.batch.components;
-import org.apache.commons.configuration.BaseConfiguration;
-import org.apache.commons.configuration.Configuration;
-import org.apache.commons.configuration.PropertiesConfiguration;
import org.junit.Before;
import org.junit.Test;
import org.mockito.ArgumentMatcher;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.sonar.api.CoreProperties;
+import org.sonar.api.config.Settings;
import org.sonar.api.database.model.Snapshot;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
-import static org.mockito.Matchers.any;
import static junit.framework.Assert.assertNull;
import static org.hamcrest.Matchers.nullValue;
import static org.hamcrest.core.IsNot.not;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertThat;
+import static org.mockito.Matchers.any;
import static org.mockito.Matchers.argThat;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@Test
public void shouldFind() {
- Configuration conf = new BaseConfiguration();
- conf.addProperty("sonar.timemachine.period5", "1.2");
+ Settings settings = new Settings().setProperty("sonar.timemachine.TRK.period5", "1.2");
when(finderByVersion.findByVersion(null, "1.2")).thenReturn(new PastSnapshot("version", new Date(), new Snapshot()));
- PastSnapshot variationSnapshot = finder.find(null, conf, 5);
+ PastSnapshot variationSnapshot = finder.find(null, "TRK", settings, 5);
verify(finderByVersion).findByVersion(null, "1.2");
assertThat(variationSnapshot.getIndex(), is(5));
@Test
public void shouldNotFailIfUnknownFormat() {
- when(finderByPreviousAnalysis.findByPreviousAnalysis(null)).thenReturn(new PastSnapshot(CoreProperties.TIMEMACHINE_MODE_PREVIOUS_ANALYSIS, new Date(), new Snapshot())); // should
- // not
- // be
- // called
+ // should not be called
+ when(finderByPreviousAnalysis.findByPreviousAnalysis(null)).thenReturn(new PastSnapshot(CoreProperties.TIMEMACHINE_MODE_PREVIOUS_ANALYSIS, new Date(), new Snapshot()));
+
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");
+ Settings settings = new Settings().setProperty("sonar.timemachine.period1", "5");
- assertThat(PastSnapshotFinder.getPropertyValue(conf, 2), is(CoreProperties.TIMEMACHINE_DEFAULT_PERIOD_2));
+ assertThat(PastSnapshotFinder.getPropertyValue("FIL", settings, 1), is("5"));
+ assertThat(PastSnapshotFinder.getPropertyValue("FIL",settings, 999), nullValue());
}
}
*/
package org.sonar.batch.components;
-import org.apache.commons.configuration.PropertiesConfiguration;
+import org.junit.Before;
import org.junit.Test;
import org.mockito.ArgumentMatcher;
+import org.sonar.api.config.Settings;
import org.sonar.api.database.model.Snapshot;
import org.sonar.api.resources.Project;
import org.sonar.jpa.test.AbstractDbUnitTestCase;
+import static org.mockito.Matchers.anyString;
import static org.mockito.Matchers.argThat;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.mock;
public class TimeMachineConfigurationTest extends AbstractDbUnitTestCase {
- @Test
- public void should_init_past_snapshots() {
+ private Settings settings;
+ private PastSnapshotFinder pastSnapshotFinder;
+
+ @Before
+ public void before() {
setupData("shared");
- PropertiesConfiguration conf = new PropertiesConfiguration();
- PastSnapshotFinder pastSnapshotFinder = mock(PastSnapshotFinder.class);
+ settings = new Settings();
+ pastSnapshotFinder = mock(PastSnapshotFinder.class);
+ }
- new TimeMachineConfiguration(getSession(), new Project("my:project"), conf, pastSnapshotFinder);
+ @Test
+ public void should_init_past_snapshots() {
+ new TimeMachineConfiguration(getSession(), new Project("my:project"), settings, pastSnapshotFinder);
verify(pastSnapshotFinder).find(argThat(new ArgumentMatcher<Snapshot>() {
@Override
public boolean matches(Object o) {
return ((Snapshot) o).getResourceId() == 2 /* see database in shared.xml */;
}
- }), eq(conf), eq(1));
+ }), anyString(), eq(settings), eq(1));
}
@Test
public void should_not_init_past_snapshots_if_first_analysis() {
- setupData("shared");
- PropertiesConfiguration conf = new PropertiesConfiguration();
- PastSnapshotFinder pastSnapshotFinder = mock(PastSnapshotFinder.class);
-
- new TimeMachineConfiguration(getSession(), new Project("new:project"), conf, pastSnapshotFinder);
+ new TimeMachineConfiguration(getSession(), new Project("new:project"), settings, pastSnapshotFinder);
verifyZeroInteractions(pastSnapshotFinder);
}
String GOOGLE_ANALYTICS_ACCOUNT_PROPERTY = "sonar.google-analytics.account";
/* Time machine periods */
- String TIMEMACHINE_PERIOD_PREFIX = "sonar.timemachine.period";
+ String TIMEMACHINE_PREFIX = "sonar.timemachine";
+ String TIMEMACHINE_PERIOD_SUFFIX = "period";
+ String TIMEMACHINE_PERIOD_PREFIX = TIMEMACHINE_PREFIX + "." + TIMEMACHINE_PERIOD_SUFFIX;
String TIMEMACHINE_MODE_PREVIOUS_ANALYSIS = "previous_analysis";
String TIMEMACHINE_MODE_DATE = "date";
String TIMEMACHINE_MODE_VERSION = "version";
*/
@Beta
@Immutable
-public final class ResourceType {
+public class ResourceType {
/**
* Builder used to create {@link ResourceType} objects.
import com.google.common.collect.ImmutableListMultimap;
import com.google.common.collect.ListMultimap;
import com.google.common.collect.Lists;
-import org.sonar.api.BatchExtension;
import org.sonar.api.ServerExtension;
-import org.sonar.api.batch.InstantiationStrategy;
import org.sonar.api.task.TaskExtension;
import javax.annotation.concurrent.Immutable;
*/
@Beta
@Immutable
-public final class ResourceTypeTree implements TaskExtension, ServerExtension {
+public class ResourceTypeTree implements TaskExtension, ServerExtension {
private List<ResourceType> types;
private ListMultimap<String, String> relations;
* @since 2.14
*/
@Beta
-public final class ResourceTypes implements TaskComponent, ServerComponent {
+public class ResourceTypes implements TaskComponent, ServerComponent {
public static final Predicate<ResourceType> AVAILABLE_FOR_FILTERS = new Predicate<ResourceType>() {
public boolean apply(@Nullable ResourceType input) {
return treeByQualifier.get(qualifier);
}
+ public ResourceType getRoot(String qualifier){
+ return getTree(qualifier).getRootType();
+ }
+
}
}
@Test
- public void getAll() {
+ public void get_all() {
assertThat(qualifiers(types.getAll())).containsOnly(Qualifiers.PROJECT, Qualifiers.DIRECTORY, Qualifiers.FILE, Qualifiers.VIEW, Qualifiers.SUBVIEW);
}
@Test
- public void getRoots() {
+ public void get_roots() {
assertThat(qualifiers(types.getRoots())).containsOnly(Qualifiers.PROJECT, Qualifiers.VIEW);
}
@Test
- public void getAll_predicate() {
+ public void get_all_predicate() {
Collection<ResourceType> forFilters = types.getAll(ResourceTypes.AVAILABLE_FOR_FILTERS);
assertThat(qualifiers(forFilters)).containsOnly(Qualifiers.PROJECT, Qualifiers.VIEW).doesNotHaveDuplicates();
}
@Test
- public void getAllWithPropertyKey() {
+ public void get_all_with_property_key() {
assertThat(qualifiers(types.getAllWithPropertyKey("supportsMeasureFilters"))).containsOnly(Qualifiers.VIEW, Qualifiers.PROJECT);
}
@Test
- public void getAllWithPropertyValue() {
+ public void get_all_with_property_value() {
assertThat(qualifiers(types.getAllWithPropertyValue("supportsMeasureFilters", "true"))).containsOnly(Qualifiers.VIEW, Qualifiers.PROJECT);
assertThat(qualifiers(types.getAllWithPropertyValue("supportsMeasureFilters", true))).containsOnly(Qualifiers.VIEW, Qualifiers.PROJECT);
assertThat(qualifiers(types.getAllWithPropertyValue("supportsMeasureFilters", false))).containsOnly(Qualifiers.SUBVIEW, Qualifiers.DIRECTORY, Qualifiers.FILE);
}
@Test
- public void getChildrenQualifiers() {
+ public void get_children_qualifiers() {
assertThat(types.getChildrenQualifiers(Qualifiers.PROJECT)).containsExactly(Qualifiers.DIRECTORY);
assertThat(types.getChildrenQualifiers(Qualifiers.SUBVIEW)).containsExactly(Qualifiers.PROJECT);
assertThat(types.getChildrenQualifiers("xxx")).isEmpty();
}
@Test
- public void getChildren() {
+ public void get_children() {
assertThat(qualifiers(types.getChildren(Qualifiers.PROJECT))).contains(Qualifiers.DIRECTORY);
assertThat(qualifiers(types.getChildren(Qualifiers.SUBVIEW))).contains(Qualifiers.PROJECT);
}
@Test
- public void getLeavesQualifiers() {
+ public void get_leaves_qualifiers() {
assertThat(types.getLeavesQualifiers(Qualifiers.PROJECT)).containsExactly(Qualifiers.FILE);
assertThat(types.getLeavesQualifiers(Qualifiers.DIRECTORY)).containsExactly(Qualifiers.FILE);
}
@Test
- public void getTree() {
+ public void get_tree() {
assertThat(qualifiers(types.getTree(Qualifiers.VIEW).getTypes())).containsOnly(Qualifiers.VIEW, Qualifiers.SUBVIEW).doesNotHaveDuplicates();
assertThat(types.getTree("xxx")).isNull();
}
+ @Test
+ public void get_root() {
+ assertThat(types.getRoot(Qualifiers.FILE).getQualifier()).isEqualTo(Qualifiers.PROJECT);
+ }
+
@Test(expected = IllegalStateException.class)
- public void failOnDuplicatedQualifier() {
+ public void fail_on_duplicated_qualifier() {
ResourceTypeTree tree1 = ResourceTypeTree.builder()
.addType(ResourceType.builder("foo").build())
.build();