diff options
author | Julien HENRY <julien.henry@sonarsource.com> | 2015-02-17 18:47:59 +0100 |
---|---|---|
committer | Julien HENRY <julien.henry@sonarsource.com> | 2015-02-17 18:56:29 +0100 |
commit | 27962d4b5f724cf0b3016ffef2e43fefeb1c2d0d (patch) | |
tree | c5b4dae3b3f8e9637b704babc98918fa5d41bf6a | |
parent | 40c0a83d32c1d27b3a9cfe64bff9c24597684035 (diff) | |
download | sonarqube-27962d4b5f724cf0b3016ffef2e43fefeb1c2d0d.tar.gz sonarqube-27962d4b5f724cf0b3016ffef2e43fefeb1c2d0d.zip |
SONAR-5931 Cleanup dependency API
19 files changed, 237 insertions, 158 deletions
diff --git a/sonar-batch/src/main/java/org/sonar/batch/dependency/DefaultDependencyValueCoder.java b/sonar-batch/src/main/java/org/sonar/batch/dependency/DefaultDependencyValueCoder.java index 8f01f2c233b..6dd1202dc42 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/dependency/DefaultDependencyValueCoder.java +++ b/sonar-batch/src/main/java/org/sonar/batch/dependency/DefaultDependencyValueCoder.java @@ -22,47 +22,26 @@ package org.sonar.batch.dependency; import com.persistit.Value; import com.persistit.encoding.CoderContext; import com.persistit.encoding.ValueCoder; -import org.sonar.api.batch.fs.InputFile; -import org.sonar.api.batch.fs.internal.DefaultInputFile; import org.sonar.api.batch.sensor.dependency.internal.DefaultDependency; -import org.sonar.batch.scan.filesystem.InputPathCache; class DefaultDependencyValueCoder implements ValueCoder { - private InputPathCache inputPathCache; - - public DefaultDependencyValueCoder(InputPathCache inputPathCache) { - this.inputPathCache = inputPathCache; - } - @Override public void put(Value value, Object object, CoderContext context) { DefaultDependency dep = (DefaultDependency) object; - value.putUTF(((DefaultInputFile) dep.from()).moduleKey()); - value.putUTF(((DefaultInputFile) dep.from()).relativePath()); - value.putUTF(((DefaultInputFile) dep.to()).moduleKey()); - value.putUTF(((DefaultInputFile) dep.to()).relativePath()); + value.putUTF(dep.fromKey()); + value.putUTF(dep.toKey()); value.put(dep.weight()); } @Override public Object get(Value value, Class clazz, CoderContext context) { - String fromModuleKey = value.getString(); - String fromRelativePath = value.getString(); - InputFile from = inputPathCache.getFile(fromModuleKey, fromRelativePath); - if (from == null) { - throw new IllegalStateException("Unable to load InputFile " + fromModuleKey + ":" + fromRelativePath); - } - String toModuleKey = value.getString(); - String toRelativePath = value.getString(); - InputFile to = inputPathCache.getFile(toModuleKey, toRelativePath); - if (to == null) { - throw new IllegalStateException("Unable to load InputFile " + toModuleKey + ":" + toRelativePath); - } + String fromKey = value.getString(); + String toKey = value.getString(); int weight = value.getInt(); return new DefaultDependency() - .from(from) - .to(to) - .weight(weight); + .setFromKey(fromKey) + .setToKey(toKey) + .setWeight(weight); } } diff --git a/sonar-batch/src/main/java/org/sonar/batch/dependency/DependencyCache.java b/sonar-batch/src/main/java/org/sonar/batch/dependency/DependencyCache.java index 9e3709a5532..50ce7577c7b 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/dependency/DependencyCache.java +++ b/sonar-batch/src/main/java/org/sonar/batch/dependency/DependencyCache.java @@ -21,14 +21,10 @@ package org.sonar.batch.dependency; import com.google.common.base.Preconditions; import org.sonar.api.BatchComponent; -import org.sonar.api.batch.fs.InputFile; -import org.sonar.api.batch.fs.internal.DefaultInputFile; -import org.sonar.api.batch.sensor.dependency.Dependency; import org.sonar.api.batch.sensor.dependency.internal.DefaultDependency; import org.sonar.batch.index.Cache; import org.sonar.batch.index.Cache.Entry; import org.sonar.batch.index.Caches; -import org.sonar.batch.scan.filesystem.InputPathCache; import javax.annotation.CheckForNull; @@ -38,29 +34,29 @@ import javax.annotation.CheckForNull; */ public class DependencyCache implements BatchComponent { - private final Cache<Dependency> cache; + private final Cache<DefaultDependency> cache; - public DependencyCache(Caches caches, InputPathCache inputPathCache) { - caches.registerValueCoder(DefaultDependency.class, new DefaultDependencyValueCoder(inputPathCache)); + public DependencyCache(Caches caches) { + caches.registerValueCoder(DefaultDependency.class, new DefaultDependencyValueCoder()); cache = caches.createCache("dependencies"); } - public Iterable<Entry<Dependency>> entries() { + public Iterable<Entry<DefaultDependency>> entries() { return cache.entries(); } @CheckForNull - public Dependency get(String moduleKey, InputFile from, InputFile to) { + public DefaultDependency get(String moduleKey, String fromKey, String toKey) { Preconditions.checkNotNull(moduleKey); - Preconditions.checkNotNull(from); - Preconditions.checkNotNull(to); - return cache.get(moduleKey, ((DefaultInputFile) from).key(), ((DefaultInputFile) to).key()); + Preconditions.checkNotNull(fromKey); + Preconditions.checkNotNull(toKey); + return cache.get(moduleKey, fromKey, toKey); } - public DependencyCache put(String moduleKey, Dependency dependency) { + public DependencyCache put(String moduleKey, DefaultDependency dependency) { Preconditions.checkNotNull(moduleKey); Preconditions.checkNotNull(dependency); - cache.put(moduleKey, ((DefaultInputFile) dependency.from()).key(), ((DefaultInputFile) dependency.to()).key(), dependency); + cache.put(moduleKey, dependency.fromKey(), dependency.toKey(), dependency); return this; } diff --git a/sonar-batch/src/main/java/org/sonar/batch/deprecated/DeprecatedSensorContext.java b/sonar-batch/src/main/java/org/sonar/batch/deprecated/DeprecatedSensorContext.java index 6c7146c6e61..a8d96036863 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/deprecated/DeprecatedSensorContext.java +++ b/sonar-batch/src/main/java/org/sonar/batch/deprecated/DeprecatedSensorContext.java @@ -40,7 +40,6 @@ import org.sonar.api.measures.Metric; import org.sonar.api.resources.*; import org.sonar.api.rules.Violation; import org.sonar.api.utils.SonarException; -import org.sonar.batch.duplication.DuplicationCache; import org.sonar.batch.index.ComponentDataCache; import org.sonar.batch.sensor.DefaultSensorContext; import org.sonar.batch.sensor.coverage.CoverageExclusions; @@ -63,8 +62,8 @@ public class DeprecatedSensorContext extends DefaultSensorContext implements Sen public DeprecatedSensorContext(SonarIndex index, Project project, Settings settings, FileSystem fs, ActiveRules activeRules, AnalysisMode analysisMode, ComponentDataCache componentDataCache, CoverageExclusions coverageFilter, - DuplicationCache duplicationCache, SensorStorage sensorStorage) { - super(settings, fs, activeRules, analysisMode, componentDataCache, duplicationCache, sensorStorage); + SensorStorage sensorStorage) { + super(settings, fs, activeRules, analysisMode, componentDataCache, sensorStorage); this.index = index; this.project = project; this.coverageFilter = coverageFilter; diff --git a/sonar-batch/src/main/java/org/sonar/batch/index/BatchResource.java b/sonar-batch/src/main/java/org/sonar/batch/index/BatchResource.java index 10d4b9d543e..a07eded789c 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/index/BatchResource.java +++ b/sonar-batch/src/main/java/org/sonar/batch/index/BatchResource.java @@ -46,6 +46,10 @@ public class BatchResource { } } + public String key() { + return r.getEffectiveKey(); + } + public int batchId() { return batchId; } diff --git a/sonar-batch/src/main/java/org/sonar/batch/index/DefaultIndex.java b/sonar-batch/src/main/java/org/sonar/batch/index/DefaultIndex.java index e551d462507..0e2c128b185 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/index/DefaultIndex.java +++ b/sonar-batch/src/main/java/org/sonar/batch/index/DefaultIndex.java @@ -114,9 +114,9 @@ public class DefaultIndex extends SonarIndex { this.measureCache = measureCache; } - public DefaultIndex(ResourceCache resourceCache, ProjectTree projectTree, MetricFinder metricFinder, MeasureCache measureCache) { + public DefaultIndex(ResourceCache resourceCache, DependencyPersister dependencyPersister, ProjectTree projectTree, MetricFinder metricFinder, MeasureCache measureCache) { this.resourceCache = resourceCache; - this.dependencyPersister = null; + this.dependencyPersister = dependencyPersister; this.linkPersister = null; this.eventPersister = null; this.projectTree = projectTree; @@ -188,6 +188,12 @@ public class DefaultIndex extends SonarIndex { } } + // store dependencies + for (Dependency dep : dependencies) { + dependencyPersister.saveDependency(currentProject, dep); + } + + // Keep only inter module dependencies Set<Dependency> projectDependencies = getDependenciesBetweenProjects(); dependencies.clear(); incomingDependenciesByResource.clear(); @@ -268,8 +274,10 @@ public class DefaultIndex extends SonarIndex { // Reload resources Resource from = getResource(dependency.getFrom()); Preconditions.checkArgument(from != null, dependency.getFrom() + " is not indexed"); + dependency.setFrom(from); Resource to = getResource(dependency.getTo()); Preconditions.checkArgument(to != null, dependency.getTo() + " is not indexed"); + dependency.setTo(to); Dependency existingDep = getEdge(from, to); if (existingDep != null) { @@ -280,10 +288,7 @@ public class DefaultIndex extends SonarIndex { if (parentDependency != null) { addDependency(parentDependency); } - - if (registerDependency(dependency) && dependencyPersister != null) { - dependencyPersister.saveDependency(currentProject, from, to, dependency, parentDependency); - } + registerDependency(dependency); return dependency; } diff --git a/sonar-batch/src/main/java/org/sonar/batch/index/DependencyPersister.java b/sonar-batch/src/main/java/org/sonar/batch/index/DependencyPersister.java index 15886b6b4ac..13c73e278f5 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/index/DependencyPersister.java +++ b/sonar-batch/src/main/java/org/sonar/batch/index/DependencyPersister.java @@ -19,27 +19,46 @@ */ package org.sonar.batch.index; +import org.sonar.api.batch.sensor.dependency.internal.DefaultDependency; import org.sonar.api.database.DatabaseSession; import org.sonar.api.design.Dependency; import org.sonar.api.design.DependencyDto; import org.sonar.api.resources.Project; -import org.sonar.api.resources.Resource; +import org.sonar.batch.dependency.DependencyCache; + +import javax.annotation.Nullable; public final class DependencyPersister { - private ResourceCache resourceCache; - private DatabaseSession session; + private final ResourceCache resourceCache; + private final DatabaseSession session; + private final DependencyCache dependencyCache; - public DependencyPersister(ResourceCache resourceCache, DatabaseSession session) { + public DependencyPersister(ResourceCache resourceCache, DependencyCache dependencyCache, @Nullable DatabaseSession session) { this.resourceCache = resourceCache; + this.dependencyCache = dependencyCache; this.session = session; } - public void saveDependency(Project project, Resource from, Resource to, Dependency dependency, Dependency parentDependency) { - BatchResource fromResource = resourceCache.get(from); - BatchResource toResource = resourceCache.get(to); + public DependencyPersister(ResourceCache resourceCache, DependencyCache dependencyCache) { + this(resourceCache, dependencyCache, null); + } + + public void saveDependency(Project project, Dependency dependency) { + BatchResource fromResource = resourceCache.get(dependency.getFrom()); + BatchResource toResource = resourceCache.get(dependency.getTo()); BatchResource projectResource = resourceCache.get(project); + if (fromResource.isFile() && toResource.isFile()) { + dependencyCache.put(project.getEffectiveKey(), new DefaultDependency().setFromKey(fromResource.key()).setToKey(toResource.key()).setWeight(dependency.getWeight())); + } + + if (session != null) { + saveInDB(project, dependency, fromResource, toResource, projectResource); + } + } + + private void saveInDB(Project project, Dependency dependency, BatchResource fromResource, BatchResource toResource, BatchResource projectResource) { DependencyDto model = new DependencyDto(); model.setProjectSnapshotId(projectResource.snapshotId()); model.setUsage(dependency.getUsage()); @@ -53,8 +72,11 @@ public final class DependencyPersister { model.setToScope(toResource.resource().getScope()); model.setToSnapshotId(toResource.snapshotId()); + Dependency parentDependency = dependency.getParent(); if (parentDependency != null) { - // assume that it has been previously saved + if (parentDependency.getId() == null) { + saveDependency(project, parentDependency); + } model.setParentDependencyId(parentDependency.getId()); } session.save(model); diff --git a/sonar-batch/src/main/java/org/sonar/batch/mediumtest/TaskResult.java b/sonar-batch/src/main/java/org/sonar/batch/mediumtest/TaskResult.java index 8013dd54d9d..245f85bd38d 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/mediumtest/TaskResult.java +++ b/sonar-batch/src/main/java/org/sonar/batch/mediumtest/TaskResult.java @@ -26,7 +26,7 @@ import org.slf4j.LoggerFactory; import org.sonar.api.batch.fs.InputDir; import org.sonar.api.batch.fs.InputFile; import org.sonar.api.batch.fs.internal.DefaultInputFile; -import org.sonar.api.batch.sensor.dependency.Dependency; +import org.sonar.api.batch.sensor.dependency.internal.DefaultDependency; import org.sonar.api.batch.sensor.duplication.Duplication; import org.sonar.api.batch.sensor.highlighting.TypeOfText; import org.sonar.api.batch.sensor.measure.internal.DefaultMeasure; @@ -92,7 +92,7 @@ public class TaskResult implements org.sonar.batch.mediumtest.ScanTaskObserver { storeDuplication(container); // storeTestCases(container); // storeCoveragePerTest(container); - // storeDependencies(container); + storeDependencies(container); } @@ -174,7 +174,7 @@ public class TaskResult implements org.sonar.batch.mediumtest.ScanTaskObserver { private void storeDependencies(ProjectScanContainer container) { DependencyCache dependencyCache = container.getComponentByType(DependencyCache.class); - for (Entry<Dependency> entry : dependencyCache.entries()) { + for (Entry<DefaultDependency> entry : dependencyCache.entries()) { String fromKey = entry.key()[1].toString(); String toKey = entry.key()[2].toString(); if (!dependencies.containsKey(fromKey)) { diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan/ProjectScanContainer.java b/sonar-batch/src/main/java/org/sonar/batch/scan/ProjectScanContainer.java index 850b6e984bf..a2f46a03fe4 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/scan/ProjectScanContainer.java +++ b/sonar-batch/src/main/java/org/sonar/batch/scan/ProjectScanContainer.java @@ -41,6 +41,7 @@ import org.sonar.batch.bootstrap.ExtensionUtils; import org.sonar.batch.bootstrap.MetricProvider; import org.sonar.batch.debt.DebtModelProvider; import org.sonar.batch.debt.IssueChangelogDebtCalculator; +import org.sonar.batch.dependency.DependencyCache; import org.sonar.batch.deprecated.components.DefaultResourceCreationLock; import org.sonar.batch.deprecated.components.PeriodsDefinition; import org.sonar.batch.duplication.DuplicationCache; @@ -189,6 +190,10 @@ public class ProjectScanContainer extends ComponentContainer { // Duplications DuplicationCache.class, + // Dependencies + DependencyPersister.class, + DependencyCache.class, + ProjectSettings.class, ScanTaskObservers.class); @@ -196,7 +201,6 @@ public class ProjectScanContainer extends ComponentContainer { private void addDataBaseComponents() { add( - DependencyPersister.class, EventPersister.class, LinkPersister.class, MeasurePersister.class, diff --git a/sonar-batch/src/main/java/org/sonar/batch/sensor/DefaultSensorContext.java b/sonar-batch/src/main/java/org/sonar/batch/sensor/DefaultSensorContext.java index 654134b0519..7dd0c1eab1c 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/sensor/DefaultSensorContext.java +++ b/sonar-batch/src/main/java/org/sonar/batch/sensor/DefaultSensorContext.java @@ -26,7 +26,7 @@ import org.sonar.api.batch.fs.internal.DefaultInputFile; import org.sonar.api.batch.rule.ActiveRules; import org.sonar.api.batch.sensor.SensorContext; import org.sonar.api.batch.sensor.SensorStorage; -import org.sonar.api.batch.sensor.dependency.Dependency; +import org.sonar.api.batch.sensor.dependency.NewDependency; import org.sonar.api.batch.sensor.dependency.internal.DefaultDependency; import org.sonar.api.batch.sensor.duplication.NewDuplication; import org.sonar.api.batch.sensor.duplication.internal.DefaultDuplication; @@ -43,7 +43,6 @@ import org.sonar.api.batch.sensor.test.internal.DefaultCoverage; import org.sonar.api.batch.sensor.test.internal.DefaultTestCaseCoverage; import org.sonar.api.batch.sensor.test.internal.DefaultTestCaseExecution; import org.sonar.api.config.Settings; -import org.sonar.batch.duplication.DuplicationCache; import org.sonar.batch.highlighting.DefaultHighlightingBuilder; import org.sonar.batch.index.ComponentDataCache; import org.sonar.batch.symbol.DefaultSymbolTableBuilder; @@ -56,18 +55,16 @@ public class DefaultSensorContext implements SensorContext { private final FileSystem fs; private final ActiveRules activeRules; private final ComponentDataCache componentDataCache; - private final DuplicationCache duplicationCache; private final SensorStorage sensorStorage; private final AnalysisMode analysisMode; public DefaultSensorContext(Settings settings, FileSystem fs, ActiveRules activeRules, AnalysisMode analysisMode, ComponentDataCache componentDataCache, - DuplicationCache duplicationCache, SensorStorage sensorStorage) { + SensorStorage sensorStorage) { this.settings = settings; this.fs = fs; this.activeRules = activeRules; this.analysisMode = analysisMode; this.componentDataCache = componentDataCache; - this.duplicationCache = duplicationCache; this.sensorStorage = sensorStorage; } @@ -132,7 +129,7 @@ public class DefaultSensorContext implements SensorContext { } @Override - public Dependency newDependency() { + public NewDependency newDependency() { return new DefaultDependency(sensorStorage); } diff --git a/sonar-batch/src/main/java/org/sonar/batch/sensor/DefaultSensorStorage.java b/sonar-batch/src/main/java/org/sonar/batch/sensor/DefaultSensorStorage.java index 300fe651380..d512c02ca96 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/sensor/DefaultSensorStorage.java +++ b/sonar-batch/src/main/java/org/sonar/batch/sensor/DefaultSensorStorage.java @@ -58,6 +58,7 @@ import org.sonar.api.test.Testable; import org.sonar.batch.duplication.DuplicationCache; import org.sonar.batch.index.ComponentDataCache; import org.sonar.batch.index.DefaultIndex; +import org.sonar.batch.index.ResourceCache; import org.sonar.batch.sensor.coverage.CoverageExclusions; import org.sonar.core.component.ComponentKeys; @@ -70,17 +71,20 @@ public class DefaultSensorStorage implements SensorStorage { private final DefaultIndex sonarIndex; private final CoverageExclusions coverageExclusions; private final DuplicationCache duplicationCache; + private final ResourceCache resourceCache; public DefaultSensorStorage(MetricFinder metricFinder, Project project, ResourcePerspectives perspectives, Settings settings, FileSystem fs, ActiveRules activeRules, ComponentDataCache componentDataCache, - DuplicationCache duplicationCache, DefaultIndex sonarIndex, CoverageExclusions coverageExclusions) { + DuplicationCache duplicationCache, DefaultIndex sonarIndex, CoverageExclusions coverageExclusions, + ResourceCache resourceCache) { this.metricFinder = metricFinder; this.project = project; this.perspectives = perspectives; this.sonarIndex = sonarIndex; this.coverageExclusions = coverageExclusions; this.duplicationCache = duplicationCache; + this.resourceCache = resourceCache; } private Metric findMetricOrFail(String metricKey) { @@ -241,10 +245,10 @@ public class DefaultSensorStorage implements SensorStorage { @Override public void store(org.sonar.api.batch.sensor.dependency.Dependency dep) { - File fromResource = getFile(dep.from()); - File toResource = getFile(dep.to()); + File fromResource = (File) resourceCache.get(dep.fromKey()).resource(); + File toResource = (File) resourceCache.get(dep.toKey()).resource(); if (sonarIndex.getEdge(fromResource, toResource) != null) { - throw new IllegalStateException("Dependency between " + dep.from() + " and " + dep.to() + " was already saved."); + throw new IllegalStateException("Dependency between " + dep.fromKey() + " and " + dep.toKey() + " was already saved."); } Directory fromParent = fromResource.getParent(); Directory toParent = toResource.getParent(); diff --git a/sonar-batch/src/test/java/org/sonar/batch/mediumtest/dependency/DependencyMediumTest.java b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/dependency/DependencyMediumTest.java index 4d562d4de87..e7a08a4a37c 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/mediumtest/dependency/DependencyMediumTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/dependency/DependencyMediumTest.java @@ -34,6 +34,8 @@ import org.sonar.xoo.XooPlugin; import java.io.File; import java.io.IOException; +import static org.assertj.core.api.Assertions.assertThat; + public class DependencyMediumTest { @Rule @@ -85,8 +87,8 @@ public class DependencyMediumTest { .build()) .start(); - // assertThat(result.dependencyWeight(result.inputFile("src/sample.xoo"), result.inputFile("src/sample2.xoo"))).isEqualTo(3); - // assertThat(result.dependencyWeight(result.inputFile("src/sample.xoo"), result.inputFile("src/foo/sample3.xoo"))).isEqualTo(6); + assertThat(result.dependencyWeight(result.inputFile("src/sample.xoo"), result.inputFile("src/sample2.xoo"))).isEqualTo(3); + assertThat(result.dependencyWeight(result.inputFile("src/sample.xoo"), result.inputFile("src/foo/sample3.xoo"))).isEqualTo(6); } } diff --git a/sonar-batch/src/test/java/org/sonar/batch/sensor/DefaultSensorContextTest.java b/sonar-batch/src/test/java/org/sonar/batch/sensor/DefaultSensorContextTest.java index 4f7fa7507ac..19b12f7b972 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/sensor/DefaultSensorContextTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/sensor/DefaultSensorContextTest.java @@ -32,7 +32,6 @@ import org.sonar.api.batch.rule.internal.ActiveRulesBuilder; import org.sonar.api.batch.sensor.SensorStorage; import org.sonar.api.config.Settings; import org.sonar.api.measures.CoreMetrics; -import org.sonar.batch.duplication.DuplicationCache; import org.sonar.batch.index.ComponentDataCache; import static org.assertj.core.api.Assertions.assertThat; @@ -65,7 +64,7 @@ public class DefaultSensorContextTest { ComponentDataCache componentDataCache = mock(ComponentDataCache.class); sensorStorage = mock(SensorStorage.class); analysisMode = mock(AnalysisMode.class); - adaptor = new DefaultSensorContext(settings, fs, activeRules, analysisMode, componentDataCache, mock(DuplicationCache.class), sensorStorage); + adaptor = new DefaultSensorContext(settings, fs, activeRules, analysisMode, componentDataCache, sensorStorage); } @Test diff --git a/sonar-batch/src/test/java/org/sonar/batch/sensor/DefaultSensorStorageTest.java b/sonar-batch/src/test/java/org/sonar/batch/sensor/DefaultSensorStorageTest.java index a4ed0b08571..02b526f0375 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/sensor/DefaultSensorStorageTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/sensor/DefaultSensorStorageTest.java @@ -54,6 +54,7 @@ import org.sonar.api.rule.RuleKey; import org.sonar.batch.duplication.DuplicationCache; import org.sonar.batch.index.ComponentDataCache; import org.sonar.batch.index.DefaultIndex; +import org.sonar.batch.index.ResourceCache; import org.sonar.batch.sensor.coverage.CoverageExclusions; import static org.assertj.core.api.Assertions.assertThat; @@ -80,6 +81,8 @@ public class DefaultSensorStorageTest { private Project project; private DefaultIndex sonarIndex; + private ResourceCache resourceCache; + @Before public void prepare() throws Exception { activeRules = new ActiveRulesBuilder().build(); @@ -94,8 +97,9 @@ public class DefaultSensorStorageTest { sonarIndex = mock(DefaultIndex.class); CoverageExclusions coverageExclusions = mock(CoverageExclusions.class); when(coverageExclusions.accept(any(Resource.class), any(Measure.class))).thenReturn(true); + resourceCache = new ResourceCache(); sensorStorage = new DefaultSensorStorage(metricFinder, project, - resourcePerspectives, settings, fs, activeRules, componentDataCache, mock(DuplicationCache.class), sonarIndex, coverageExclusions); + resourcePerspectives, settings, fs, activeRules, componentDataCache, mock(DuplicationCache.class), sonarIndex, coverageExclusions, resourceCache); } @Test @@ -248,10 +252,10 @@ public class DefaultSensorStorageTest { @Test public void shouldStoreDependencyInSameFolder() { - File foo = File.create("src/Foo.java"); - File bar = File.create("src/Bar.java"); - when(sonarIndex.getResource(foo)).thenReturn(foo); - when(sonarIndex.getResource(bar)).thenReturn(bar); + Resource foo = File.create("src/Foo.java").setEffectiveKey("foo:src/Foo.java"); + Resource bar = File.create("src/Bar.java").setEffectiveKey("foo:src/Bar.java"); + resourceCache.add(foo, null); + resourceCache.add(bar, null); sensorStorage.store(new DefaultDependency() .from(new DefaultInputFile("foo", "src/Foo.java").setType(Type.MAIN)) @@ -270,14 +274,15 @@ public class DefaultSensorStorageTest { @Test public void throw_if_attempt_to_save_same_dep_twice() { - File foo = File.create("src/Foo.java"); - File bar = File.create("src/Bar.java"); - when(sonarIndex.getResource(foo)).thenReturn(foo); - when(sonarIndex.getResource(bar)).thenReturn(bar); + Resource foo = File.create("src/Foo.java").setEffectiveKey("foo:src/Foo.java"); + Resource bar = File.create("src/Bar.java").setEffectiveKey("foo:src/Bar.java"); + resourceCache.add(foo, null); + resourceCache.add(bar, null); + when(sonarIndex.getEdge(foo, bar)).thenReturn(new Dependency(foo, bar)); thrown.expect(IllegalStateException.class); - thrown.expectMessage("Dependency between [moduleKey=foo, relative=src/Foo.java, basedir=null] and [moduleKey=foo, relative=src/Bar.java, basedir=null] was already saved."); + thrown.expectMessage("Dependency between foo:src/Foo.java and foo:src/Bar.java was already saved."); sensorStorage.store(new DefaultDependency() .from(new DefaultInputFile("foo", "src/Foo.java").setType(Type.MAIN)) @@ -288,10 +293,10 @@ public class DefaultSensorStorageTest { @Test public void shouldStoreDependencyInDifferentFolder() { - File foo = File.create("src1/Foo.java"); - File bar = File.create("src2/Bar.java"); - when(sonarIndex.getResource(foo)).thenReturn(foo); - when(sonarIndex.getResource(bar)).thenReturn(bar); + Resource foo = File.create("src1/Foo.java").setEffectiveKey("foo:src1/Foo.java"); + Resource bar = File.create("src2/Bar.java").setEffectiveKey("foo:src2/Bar.java"); + resourceCache.add(foo, null); + resourceCache.add(bar, null); sensorStorage.store(new DefaultDependency() .from(new DefaultInputFile("foo", "src1/Foo.java").setType(Type.MAIN)) @@ -318,12 +323,14 @@ public class DefaultSensorStorageTest { @Test public void shouldIncrementParentWeight() { - File foo = File.create("src1/Foo.java"); - File bar = File.create("src2/Bar.java"); - Directory src1 = Directory.create("src1"); - Directory src2 = Directory.create("src2"); - when(sonarIndex.getResource(foo)).thenReturn(foo); - when(sonarIndex.getResource(bar)).thenReturn(bar); + Resource src1 = Directory.create("src1").setEffectiveKey("foo:src1"); + Resource src2 = Directory.create("src2").setEffectiveKey("foo:src2"); + Resource foo = File.create("src1/Foo.java").setEffectiveKey("foo:src1/Foo.java"); + Resource bar = File.create("src2/Bar.java").setEffectiveKey("foo:src2/Bar.java"); + resourceCache.add(src1, null); + resourceCache.add(src2, null); + resourceCache.add(foo, src1); + resourceCache.add(bar, src2); Dependency parentDep = new Dependency(src1, src2).setWeight(4); when(sonarIndex.getEdge(src1, src2)).thenReturn(parentDep); diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/SensorContext.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/SensorContext.java index 00fd00d8314..6a5463e67f9 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/SensorContext.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/SensorContext.java @@ -192,14 +192,23 @@ public interface SensorContext extends org.sonar.api.batch.sensor.SensorContext // ----------- DEPENDENCIES BETWEEN RESOURCES -------------- /** - * Build a new dependency : from depends upon to. The dependency is NOT saved. The method saveDependency() must still be executed. + * @deprecated since 5.1 use {@link #newDependency()} */ Dependency saveDependency(Dependency dependency); + /** + * @deprecated since 5.1 Sensors should not read but only save data + */ Set<Dependency> getDependencies(); + /** + * @deprecated since 5.1 Sensors should not read but only save data + */ Collection<Dependency> getIncomingDependencies(Resource to); + /** + * @deprecated since 5.1 Sensors should not read but only save data + */ Collection<Dependency> getOutgoingDependencies(Resource from); // ----------- FILE SOURCES -------------- diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/SensorContext.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/SensorContext.java index b36786c2333..a1de94d8b3f 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/SensorContext.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/SensorContext.java @@ -24,7 +24,7 @@ import org.sonar.api.batch.CpdMapping; import org.sonar.api.batch.fs.FileSystem; import org.sonar.api.batch.fs.InputFile; import org.sonar.api.batch.rule.ActiveRules; -import org.sonar.api.batch.sensor.dependency.Dependency; +import org.sonar.api.batch.sensor.dependency.NewDependency; import org.sonar.api.batch.sensor.duplication.NewDuplication; import org.sonar.api.batch.sensor.highlighting.HighlightingBuilder; import org.sonar.api.batch.sensor.issue.Issue; @@ -82,7 +82,6 @@ public interface SensorContext { /** * Builder to define highlighting of a file. - * @since 4.5 */ HighlightingBuilder highlightingBuilder(InputFile inputFile); @@ -90,7 +89,6 @@ public interface SensorContext { /** * Builder to define symbol references in a file. - * @since 4.5 */ SymbolTableBuilder symbolTableBuilder(InputFile inputFile); @@ -99,7 +97,6 @@ public interface SensorContext { /** * Builder to manually register duplication in a file. This can be used in addition to {@link CpdMapping} extension point. * Don't forget to call {@link NewDuplication#save()}. - * @since 5.1 */ NewDuplication newDuplication(); @@ -108,21 +105,18 @@ public interface SensorContext { /** * Create a new coverage report. * Don't forget to call {@link Coverage#save()} once all parameters are provided. - * @since 5.0 */ Coverage newCoverage(); /** * Create a new test case execution report. * Don't forget to call {@link TestCaseExecution#save()} once all parameters are provided. - * @since 5.0 */ TestCaseExecution newTestCaseExecution(); /** * Create a new test case coverage report. * Don't forget to call {@link TestCaseCoverage#save()} once all parameters are provided. - * @since 5.0 */ TestCaseCoverage newTestCaseCoverage(); @@ -130,9 +124,8 @@ public interface SensorContext { /** * Create a new dependency. - * Don't forget to call {@link Dependency#save()} once all parameters are provided. - * @since 5.0 + * Don't forget to call {@link NewDependency#save()} once all parameters are provided. */ - Dependency newDependency(); + NewDependency newDependency(); } diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/dependency/Dependency.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/dependency/Dependency.java index 87bd3029fbd..56185acaf3a 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/dependency/Dependency.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/dependency/Dependency.java @@ -19,36 +19,19 @@ */ package org.sonar.api.batch.sensor.dependency; -import com.google.common.annotations.Beta; -import org.sonar.api.batch.fs.InputFile; /** - * @since 5.0 + * @since 5.1 */ -@Beta public interface Dependency { - InputFile from(); + String fromKey(); - Dependency from(InputFile from); - - InputFile to(); - - Dependency to(InputFile to); + String toKey(); /** * Default weight value is 1. */ int weight(); - /** - * Set the weight of the dependency. - */ - Dependency weight(int weight); - - /** - * Save the dependency. - */ - void save(); - } diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/dependency/NewDependency.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/dependency/NewDependency.java new file mode 100644 index 00000000000..8d62a2f6516 --- /dev/null +++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/dependency/NewDependency.java @@ -0,0 +1,45 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * SonarQube is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonar.api.batch.sensor.dependency; + +import org.sonar.api.batch.fs.InputFile; + +/** + * Builder to create new Dependency. + * Should not be implemented by client. + * @since 5.1 + */ +public interface NewDependency { + + NewDependency from(InputFile from); + + NewDependency to(InputFile to); + + /** + * Set the weight of the dependency. If not set default weight is 1. + */ + NewDependency weight(int weight); + + /** + * Save the dependency. It is not permitted so save several time a dependency between two same files. + */ + void save(); + +} diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/dependency/internal/DefaultDependency.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/dependency/internal/DefaultDependency.java index c7ab2fcc997..9dcb3d34ece 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/dependency/internal/DefaultDependency.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/dependency/internal/DefaultDependency.java @@ -23,16 +23,18 @@ import com.google.common.base.Preconditions; import org.apache.commons.lang.builder.EqualsBuilder; import org.apache.commons.lang.builder.HashCodeBuilder; import org.sonar.api.batch.fs.InputFile; +import org.sonar.api.batch.fs.internal.DefaultInputFile; import org.sonar.api.batch.sensor.SensorStorage; import org.sonar.api.batch.sensor.dependency.Dependency; +import org.sonar.api.batch.sensor.dependency.NewDependency; import org.sonar.api.batch.sensor.internal.DefaultStorable; import javax.annotation.Nullable; -public class DefaultDependency extends DefaultStorable implements Dependency { +public class DefaultDependency extends DefaultStorable implements Dependency, NewDependency { - private InputFile from; - private InputFile to; + private String fromKey; + private String toKey; private int weight = 1; public DefaultDependency() { @@ -44,21 +46,21 @@ public class DefaultDependency extends DefaultStorable implements Dependency { } @Override - public Dependency from(InputFile from) { + public DefaultDependency from(InputFile from) { Preconditions.checkNotNull(from, "InputFile should be non null"); - this.from = from; + this.fromKey = ((DefaultInputFile) from).key(); return this; } @Override - public Dependency to(InputFile to) { + public DefaultDependency to(InputFile to) { Preconditions.checkNotNull(to, "InputFile should be non null"); - this.to = to; + this.toKey = ((DefaultInputFile) to).key(); return this; } @Override - public Dependency weight(int weight) { + public DefaultDependency weight(int weight) { Preconditions.checkArgument(weight > 1, "weight should be greater than 1"); this.weight = weight; return this; @@ -66,20 +68,30 @@ public class DefaultDependency extends DefaultStorable implements Dependency { @Override public void doSave() { - Preconditions.checkState(!this.from.equals(this.to), "From and To can't be the same inputFile"); - Preconditions.checkNotNull(this.from, "From inputFile can't be null"); - Preconditions.checkNotNull(this.to, "To inputFile can't be null"); + Preconditions.checkState(!this.fromKey.equals(this.toKey), "From and To can't be the same inputFile"); + Preconditions.checkNotNull(this.fromKey, "From inputFile can't be null"); + Preconditions.checkNotNull(this.toKey, "To inputFile can't be null"); storage.store((Dependency) this); } @Override - public InputFile from() { - return this.from; + public String fromKey() { + return this.fromKey; + } + + public DefaultDependency setFromKey(String fromKey) { + this.fromKey = fromKey; + return this; } @Override - public InputFile to() { - return this.to; + public String toKey() { + return this.toKey; + } + + public DefaultDependency setToKey(String toKey) { + this.toKey = toKey; + return this; } @Override @@ -87,6 +99,11 @@ public class DefaultDependency extends DefaultStorable implements Dependency { return this.weight; } + public DefaultDependency setWeight(int weight) { + this.weight = weight; + return this; + } + // For testing purpose @Override @@ -102,8 +119,8 @@ public class DefaultDependency extends DefaultStorable implements Dependency { } DefaultDependency rhs = (DefaultDependency) obj; return new EqualsBuilder() - .append(from, rhs.from) - .append(to, rhs.to) + .append(fromKey, rhs.fromKey) + .append(toKey, rhs.toKey) .append(weight, rhs.weight) .isEquals(); } @@ -111,8 +128,8 @@ public class DefaultDependency extends DefaultStorable implements Dependency { @Override public int hashCode() { return new HashCodeBuilder(27, 45). - append(from). - append(to). + append(fromKey). + append(toKey). append(weight). toHashCode(); } diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/design/Dependency.java b/sonar-plugin-api/src/main/java/org/sonar/api/design/Dependency.java index 5b7537f20da..bc965583881 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/design/Dependency.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/design/Dependency.java @@ -50,11 +50,25 @@ public class Dependency implements Edge<Resource> { return from; } + /** + * For internal use only + */ + public void setFrom(Resource from) { + this.from = from; + } + @Override public Resource getTo() { return to; } + /** + * For internal use only + */ + public void setTo(Resource to) { + this.to = to; + } + public String getUsage() { return usage; } @@ -105,26 +119,26 @@ public class Dependency implements Edge<Resource> { } Dependency other = (Dependency) obj; return new EqualsBuilder() - .append(from, other.from) - .append(to, other.to) - .isEquals(); + .append(from, other.from) + .append(to, other.to) + .isEquals(); } @Override public int hashCode() { return new HashCodeBuilder(17, 37) - .append(from) - .append(to) - .toHashCode(); + .append(from) + .append(to) + .toHashCode(); } @Override public String toString() { return new ToStringBuilder(this) - .append("from", from) - .append("to", to) - .append("weight", weight) - .append("usage", usage) - .toString(); + .append("from", from) + .append("to", to) + .append("weight", weight) + .append("usage", usage) + .toString(); } } |