瀏覽代碼

SONAR-6278 Stop relying on graph to store tests

tags/5.2-RC1
Julien HENRY 9 年之前
父節點
當前提交
921963613e
共有 100 個文件被更改,包括 533 次插入2513 次删除
  1. 4
    4
      plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/AbstractNewCoverageFileAnalyzer.java
  2. 3
    3
      plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/NewCoverageFileAnalyzer.java
  3. 2
    2
      plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/NewItCoverageFileAnalyzer.java
  4. 2
    2
      plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/NewOverallCoverageFileAnalyzer.java
  5. 3
    3
      plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/TimeMachineConfigurationPersister.java
  6. 2
    2
      plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/timemachine/NewCoverageFileAnalyzerTest.java
  7. 2
    2
      plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/timemachine/TimeMachineConfigurationPersisterTest.java
  8. 0
    5
      pom.xml
  9. 0
    6
      server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel4.java
  10. 3
    3
      sonar-batch/src/main/java/org/sonar/batch/cpd/index/DbDuplicationsIndex.java
  11. 4
    4
      sonar-batch/src/main/java/org/sonar/batch/cpd/index/IndexFactory.java
  12. 10
    22
      sonar-batch/src/main/java/org/sonar/batch/deprecated/perspectives/BatchPerspectives.java
  13. 4
    7
      sonar-batch/src/main/java/org/sonar/batch/deprecated/perspectives/PerspectiveBuilder.java
  14. 1
    1
      sonar-batch/src/main/java/org/sonar/batch/deprecated/perspectives/PerspectiveNotFoundException.java
  15. 8
    8
      sonar-batch/src/main/java/org/sonar/batch/index/BatchComponent.java
  16. 26
    40
      sonar-batch/src/main/java/org/sonar/batch/index/BatchComponentCache.java
  17. 2
    2
      sonar-batch/src/main/java/org/sonar/batch/index/DefaultIndex.java
  18. 9
    16
      sonar-batch/src/main/java/org/sonar/batch/index/ResourcePersister.java
  19. 6
    13
      sonar-batch/src/main/java/org/sonar/batch/issue/DefaultIssuable.java
  20. 4
    13
      sonar-batch/src/main/java/org/sonar/batch/issue/IssuableFactory.java
  21. 8
    8
      sonar-batch/src/main/java/org/sonar/batch/issue/tracking/LocalIssueTracking.java
  22. 6
    6
      sonar-batch/src/main/java/org/sonar/batch/issue/tracking/ServerIssueRepository.java
  23. 2
    2
      sonar-batch/src/main/java/org/sonar/batch/mediumtest/TaskResult.java
  24. 5
    5
      sonar-batch/src/main/java/org/sonar/batch/postjob/DefaultPostJobContext.java
  25. 3
    3
      sonar-batch/src/main/java/org/sonar/batch/qualitygate/QualityGateVerifier.java
  26. 9
    9
      sonar-batch/src/main/java/org/sonar/batch/report/ComponentsPublisher.java
  27. 5
    5
      sonar-batch/src/main/java/org/sonar/batch/report/CoveragePublisher.java
  28. 6
    6
      sonar-batch/src/main/java/org/sonar/batch/report/DuplicationsPublisher.java
  29. 3
    3
      sonar-batch/src/main/java/org/sonar/batch/report/EventCache.java
  30. 6
    6
      sonar-batch/src/main/java/org/sonar/batch/report/IssuesPublisher.java
  31. 5
    5
      sonar-batch/src/main/java/org/sonar/batch/report/MeasuresPublisher.java
  32. 5
    5
      sonar-batch/src/main/java/org/sonar/batch/report/SourcePublisher.java
  33. 17
    18
      sonar-batch/src/main/java/org/sonar/batch/report/TestExecutionAndCoveragePublisher.java
  34. 4
    10
      sonar-batch/src/main/java/org/sonar/batch/scan/ProjectScanContainer.java
  35. 4
    4
      sonar-batch/src/main/java/org/sonar/batch/scan/filesystem/ComponentIndexer.java
  36. 2
    2
      sonar-batch/src/main/java/org/sonar/batch/scan/filesystem/InputPathCache.java
  37. 7
    7
      sonar-batch/src/main/java/org/sonar/batch/scan/report/IssuesReport.java
  38. 6
    6
      sonar-batch/src/main/java/org/sonar/batch/scan/report/IssuesReportBuilder.java
  39. 4
    4
      sonar-batch/src/main/java/org/sonar/batch/scan/report/ResourceReport.java
  40. 2
    2
      sonar-batch/src/main/java/org/sonar/batch/scan/report/SourceProvider.java
  41. 5
    5
      sonar-batch/src/main/java/org/sonar/batch/scm/DefaultBlameOutput.java
  42. 3
    3
      sonar-batch/src/main/java/org/sonar/batch/scm/ScmSensor.java
  43. 5
    5
      sonar-batch/src/main/java/org/sonar/batch/sensor/DefaultSensorStorage.java
  44. 3
    3
      sonar-batch/src/main/java/org/sonar/batch/source/CodeColorizerSensor.java
  45. 0
    7
      sonar-batch/src/main/java/org/sonar/batch/source/DefaultHighlightable.java
  46. 0
    7
      sonar-batch/src/main/java/org/sonar/batch/source/DefaultSymbolizable.java
  47. 8
    25
      sonar-batch/src/main/java/org/sonar/batch/source/HighlightableBuilder.java
  48. 8
    25
      sonar-batch/src/main/java/org/sonar/batch/source/SymbolizableBuilder.java
  49. 16
    8
      sonar-batch/src/main/java/org/sonar/batch/test/DefaultCoverageBlock.java
  50. 51
    56
      sonar-batch/src/main/java/org/sonar/batch/test/DefaultTestCase.java
  51. 9
    21
      sonar-batch/src/main/java/org/sonar/batch/test/DefaultTestPlan.java
  52. 86
    0
      sonar-batch/src/main/java/org/sonar/batch/test/DefaultTestable.java
  53. 54
    0
      sonar-batch/src/main/java/org/sonar/batch/test/TestPlanBuilder.java
  54. 19
    10
      sonar-batch/src/main/java/org/sonar/batch/test/TestableBuilder.java
  55. 1
    1
      sonar-batch/src/main/java/org/sonar/batch/test/package-info.java
  56. 2
    2
      sonar-batch/src/test/java/org/sonar/batch/cpd/index/IndexFactoryTest.java
  57. 3
    3
      sonar-batch/src/test/java/org/sonar/batch/deprecated/perspectives/PerspectiveBuilderTest.java
  58. 3
    3
      sonar-batch/src/test/java/org/sonar/batch/index/BatchComponentCacheTest.java
  59. 1
    1
      sonar-batch/src/test/java/org/sonar/batch/index/DefaultIndexTest.java
  60. 7
    10
      sonar-batch/src/test/java/org/sonar/batch/index/ResourcePersisterTest.java
  61. 4
    5
      sonar-batch/src/test/java/org/sonar/batch/issue/DefaultIssuableTest.java
  62. 3
    6
      sonar-batch/src/test/java/org/sonar/batch/issue/IssuableFactoryTest.java
  63. 3
    3
      sonar-batch/src/test/java/org/sonar/batch/postjob/DefaultPostJobContextTest.java
  64. 3
    3
      sonar-batch/src/test/java/org/sonar/batch/qualitygate/QualityGateVerifierTest.java
  65. 3
    3
      sonar-batch/src/test/java/org/sonar/batch/report/ComponentsPublisherTest.java
  66. 2
    2
      sonar-batch/src/test/java/org/sonar/batch/report/CoveragePublisherTest.java
  67. 2
    2
      sonar-batch/src/test/java/org/sonar/batch/report/DuplicationsPublisherTest.java
  68. 2
    2
      sonar-batch/src/test/java/org/sonar/batch/report/IssuesPublisherTest.java
  69. 2
    2
      sonar-batch/src/test/java/org/sonar/batch/report/MeasuresPublisherTest.java
  70. 2
    2
      sonar-batch/src/test/java/org/sonar/batch/report/ReportPublisherTest.java
  71. 2
    2
      sonar-batch/src/test/java/org/sonar/batch/report/SourcePublisherTest.java
  72. 4
    4
      sonar-batch/src/test/java/org/sonar/batch/scan/filesystem/ComponentIndexerTest.java
  73. 3
    3
      sonar-batch/src/test/java/org/sonar/batch/sensor/DefaultSensorStorageTest.java
  74. 5
    13
      sonar-batch/src/test/java/org/sonar/batch/source/HighlightableBuilderTest.java
  75. 5
    14
      sonar-batch/src/test/java/org/sonar/batch/source/SymbolizableBuilderTest.java
  76. 0
    22
      sonar-core/pom.xml
  77. 0
    63
      sonar-core/src/main/java/org/sonar/core/component/ComponentQuery.java
  78. 0
    64
      sonar-core/src/main/java/org/sonar/core/component/ComponentVertex.java
  79. 0
    82
      sonar-core/src/main/java/org/sonar/core/component/GraphPerspectiveBuilder.java
  80. 0
    55
      sonar-core/src/main/java/org/sonar/core/component/GraphPerspectiveLoader.java
  81. 0
    79
      sonar-core/src/main/java/org/sonar/core/component/ResourceComponent.java
  82. 0
    82
      sonar-core/src/main/java/org/sonar/core/component/ScanGraph.java
  83. 0
    37
      sonar-core/src/main/java/org/sonar/core/component/SnapshotGraph.java
  84. 0
    31
      sonar-core/src/main/java/org/sonar/core/graph/BeanEdge.java
  85. 0
    68
      sonar-core/src/main/java/org/sonar/core/graph/BeanElement.java
  86. 0
    88
      sonar-core/src/main/java/org/sonar/core/graph/BeanElements.java
  87. 0
    63
      sonar-core/src/main/java/org/sonar/core/graph/BeanGraph.java
  88. 0
    59
      sonar-core/src/main/java/org/sonar/core/graph/BeanIterable.java
  89. 0
    34
      sonar-core/src/main/java/org/sonar/core/graph/BeanVertex.java
  90. 0
    55
      sonar-core/src/main/java/org/sonar/core/graph/EdgePath.java
  91. 0
    65
      sonar-core/src/main/java/org/sonar/core/graph/GraphUtil.java
  92. 0
    26
      sonar-core/src/main/java/org/sonar/core/graph/MultipleElementsException.java
  93. 0
    47
      sonar-core/src/main/java/org/sonar/core/graph/graphson/ElementFactory.java
  94. 0
    87
      sonar-core/src/main/java/org/sonar/core/graph/graphson/ElementPropertyConfig.java
  95. 0
    26
      sonar-core/src/main/java/org/sonar/core/graph/graphson/GraphsonException.java
  96. 0
    45
      sonar-core/src/main/java/org/sonar/core/graph/graphson/GraphsonMode.java
  97. 0
    75
      sonar-core/src/main/java/org/sonar/core/graph/graphson/GraphsonReader.java
  98. 0
    52
      sonar-core/src/main/java/org/sonar/core/graph/graphson/GraphsonTokens.java
  99. 0
    673
      sonar-core/src/main/java/org/sonar/core/graph/graphson/GraphsonUtil.java
  100. 0
    0
      sonar-core/src/main/java/org/sonar/core/graph/graphson/GraphsonWriter.java

+ 4
- 4
plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/AbstractNewCoverageFileAnalyzer.java 查看文件

@@ -37,7 +37,7 @@ import org.sonar.api.resources.Scopes;
import org.sonar.api.utils.KeyValueFormat;
import org.sonar.batch.components.Period;
import org.sonar.batch.components.TimeMachineConfiguration;
import org.sonar.batch.index.ResourceCache;
import org.sonar.batch.index.BatchComponentCache;
import org.sonar.batch.protocol.output.BatchReport;
import org.sonar.batch.protocol.output.BatchReport.Changesets.Changeset;
import org.sonar.batch.protocol.output.BatchReportReader;
@@ -59,16 +59,16 @@ public abstract class AbstractNewCoverageFileAnalyzer implements Decorator {

private final List<PeriodStruct> structs;
private final ReportPublisher publishReportJob;
private final ResourceCache resourceCache;
private final BatchComponentCache resourceCache;

public AbstractNewCoverageFileAnalyzer(TimeMachineConfiguration timeMachineConfiguration, ReportPublisher publishReportJob, ResourceCache resourceCache) {
public AbstractNewCoverageFileAnalyzer(TimeMachineConfiguration timeMachineConfiguration, ReportPublisher publishReportJob, BatchComponentCache resourceCache) {
this(Lists.<PeriodStruct>newArrayList(), publishReportJob, resourceCache);
for (Period period : timeMachineConfiguration.periods()) {
structs.add(new PeriodStruct(period.getIndex(), period.getDate()));
}
}

AbstractNewCoverageFileAnalyzer(List<PeriodStruct> structs, ReportPublisher publishReportJob, ResourceCache resourceCache) {
AbstractNewCoverageFileAnalyzer(List<PeriodStruct> structs, ReportPublisher publishReportJob, BatchComponentCache resourceCache) {
this.resourceCache = resourceCache;
this.publishReportJob = publishReportJob;
this.structs = structs;

+ 3
- 3
plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/NewCoverageFileAnalyzer.java 查看文件

@@ -22,18 +22,18 @@ package org.sonar.plugins.core.timemachine;
import org.sonar.api.measures.CoreMetrics;
import org.sonar.api.measures.Metric;
import org.sonar.batch.components.TimeMachineConfiguration;
import org.sonar.batch.index.ResourceCache;
import org.sonar.batch.index.BatchComponentCache;
import org.sonar.batch.report.ReportPublisher;

import java.util.List;

public class NewCoverageFileAnalyzer extends AbstractNewCoverageFileAnalyzer {

public NewCoverageFileAnalyzer(TimeMachineConfiguration timeMachineConfiguration, ReportPublisher publishReportJob, ResourceCache resourceCache) {
public NewCoverageFileAnalyzer(TimeMachineConfiguration timeMachineConfiguration, ReportPublisher publishReportJob, BatchComponentCache resourceCache) {
super(timeMachineConfiguration, publishReportJob, resourceCache);
}

NewCoverageFileAnalyzer(List<PeriodStruct> structs, ReportPublisher publishReportJob, ResourceCache resourceCache) {
NewCoverageFileAnalyzer(List<PeriodStruct> structs, ReportPublisher publishReportJob, BatchComponentCache resourceCache) {
super(structs, publishReportJob, resourceCache);
}


+ 2
- 2
plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/NewItCoverageFileAnalyzer.java 查看文件

@@ -22,12 +22,12 @@ package org.sonar.plugins.core.timemachine;
import org.sonar.api.measures.CoreMetrics;
import org.sonar.api.measures.Metric;
import org.sonar.batch.components.TimeMachineConfiguration;
import org.sonar.batch.index.ResourceCache;
import org.sonar.batch.index.BatchComponentCache;
import org.sonar.batch.report.ReportPublisher;

public class NewItCoverageFileAnalyzer extends AbstractNewCoverageFileAnalyzer {

public NewItCoverageFileAnalyzer(TimeMachineConfiguration timeMachineConfiguration, ReportPublisher publishReportJob, ResourceCache resourceCache) {
public NewItCoverageFileAnalyzer(TimeMachineConfiguration timeMachineConfiguration, ReportPublisher publishReportJob, BatchComponentCache resourceCache) {
super(timeMachineConfiguration, publishReportJob, resourceCache);
}


+ 2
- 2
plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/NewOverallCoverageFileAnalyzer.java 查看文件

@@ -22,12 +22,12 @@ package org.sonar.plugins.core.timemachine;
import org.sonar.api.measures.CoreMetrics;
import org.sonar.api.measures.Metric;
import org.sonar.batch.components.TimeMachineConfiguration;
import org.sonar.batch.index.ResourceCache;
import org.sonar.batch.index.BatchComponentCache;
import org.sonar.batch.report.ReportPublisher;

public class NewOverallCoverageFileAnalyzer extends AbstractNewCoverageFileAnalyzer {

public NewOverallCoverageFileAnalyzer(TimeMachineConfiguration timeMachineConfiguration, ReportPublisher publishReportJob, ResourceCache resourceCache) {
public NewOverallCoverageFileAnalyzer(TimeMachineConfiguration timeMachineConfiguration, ReportPublisher publishReportJob, BatchComponentCache resourceCache) {
super(timeMachineConfiguration, publishReportJob, resourceCache);
}


+ 3
- 3
plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/TimeMachineConfigurationPersister.java 查看文件

@@ -27,7 +27,7 @@ import org.sonar.api.resources.Resource;
import org.sonar.api.resources.ResourceUtils;
import org.sonar.batch.components.PastSnapshot;
import org.sonar.batch.components.TimeMachineConfiguration;
import org.sonar.batch.index.ResourceCache;
import org.sonar.batch.index.BatchComponentCache;

import java.util.List;

@@ -38,10 +38,10 @@ import static org.sonar.api.utils.DateUtils.dateToLong;
public final class TimeMachineConfigurationPersister implements Decorator {

private final TimeMachineConfiguration timeMachineConfiguration;
private ResourceCache resourceCache;
private BatchComponentCache resourceCache;
private DatabaseSession session;

public TimeMachineConfigurationPersister(TimeMachineConfiguration timeMachineConfiguration, ResourceCache resourceCache, DatabaseSession session) {
public TimeMachineConfigurationPersister(TimeMachineConfiguration timeMachineConfiguration, BatchComponentCache resourceCache, DatabaseSession session) {
this.timeMachineConfiguration = timeMachineConfiguration;
this.resourceCache = resourceCache;
this.session = session;

+ 2
- 2
plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/timemachine/NewCoverageFileAnalyzerTest.java 查看文件

@@ -31,7 +31,7 @@ import org.sonar.api.measures.Metric;
import org.sonar.api.resources.File;
import org.sonar.api.resources.Resource;
import org.sonar.api.utils.DateUtils;
import org.sonar.batch.index.ResourceCache;
import org.sonar.batch.index.BatchComponentCache;
import org.sonar.batch.protocol.output.BatchReport;
import org.sonar.batch.protocol.output.BatchReport.Changesets.Changeset;
import org.sonar.batch.protocol.output.BatchReportWriter;
@@ -64,7 +64,7 @@ public class NewCoverageFileAnalyzerTest {
context = mock(DecoratorContext.class);
Resource f = File.create("src/Foo.java").setEffectiveKey("foo:src/Foo.java");
when(context.getResource()).thenReturn(f);
ResourceCache cache = new ResourceCache();
BatchComponentCache cache = new BatchComponentCache();
cache.add(f, null);
List<AbstractNewCoverageFileAnalyzer.PeriodStruct> structs = Arrays.asList(
new AbstractNewCoverageFileAnalyzer.PeriodStruct(1, newDate("2009-12-25")),

+ 2
- 2
plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/timemachine/TimeMachineConfigurationPersisterTest.java 查看文件

@@ -26,7 +26,7 @@ import org.junit.Test;
import org.sonar.api.database.model.Snapshot;
import org.sonar.api.resources.Project;
import org.sonar.api.utils.DateUtils;
import org.sonar.batch.index.ResourceCache;
import org.sonar.batch.index.BatchComponentCache;
import org.sonar.jpa.test.AbstractDbUnitTestCase;

import java.util.Arrays;
@@ -48,7 +48,7 @@ public class TimeMachineConfigurationPersisterTest extends AbstractDbUnitTestCas
when(timeMachineConfiguration.getProjectPastSnapshots()).thenReturn(Arrays.asList(vs1, vs3));
Snapshot projectSnapshot = getSession().getSingleResult(Snapshot.class, "id", 1000);

ResourceCache resourceCache = new ResourceCache();
BatchComponentCache resourceCache = new BatchComponentCache();
Project project = new Project("foo");
resourceCache.add(project, null).setSnapshot(projectSnapshot);


+ 0
- 5
pom.xml 查看文件

@@ -694,11 +694,6 @@
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.tinkerpop.blueprints</groupId>
<artifactId>blueprints-core</artifactId>
<version>2.2.0</version>
</dependency>
<dependency>
<groupId>commons-collections</groupId>
<artifactId>commons-collections</artifactId>

+ 0
- 6
server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel4.java 查看文件

@@ -44,8 +44,6 @@ import org.sonar.core.qualitygate.db.ProjectQgateAssociationDao;
import org.sonar.core.qualitygate.db.QualityGateConditionDao;
import org.sonar.core.qualitygate.db.QualityGateDao;
import org.sonar.core.resource.DefaultResourcePermissions;
import org.sonar.core.test.TestPlanPerspectiveLoader;
import org.sonar.core.test.TestablePerspectiveLoader;
import org.sonar.core.timemachine.Periods;
import org.sonar.core.user.DefaultUserFinder;
import org.sonar.core.user.HibernateUserFinder;
@@ -631,10 +629,6 @@ public class PlatformLevel4 extends PlatformLevel {
// Properties
PropertiesWs.class,

// graphs and perspective related classes
TestablePerspectiveLoader.class,
TestPlanPerspectiveLoader.class,

// Type validation
TypeValidations.class,
IntegerTypeValidation.class,

+ 3
- 3
sonar-batch/src/main/java/org/sonar/batch/cpd/index/DbDuplicationsIndex.java 查看文件

@@ -26,7 +26,7 @@ import org.sonar.api.batch.fs.internal.DefaultInputFile;
import org.sonar.api.database.DatabaseSession;
import org.sonar.api.database.model.Snapshot;
import org.sonar.api.resources.Project;
import org.sonar.batch.index.ResourceCache;
import org.sonar.batch.index.BatchComponentCache;
import org.sonar.core.duplication.DuplicationDao;
import org.sonar.core.duplication.DuplicationUnitDto;
import org.sonar.duplications.block.Block;
@@ -51,10 +51,10 @@ public class DbDuplicationsIndex {
private final String languageKey;
private final DuplicationDao dao;
private final DatabaseSession session;
private final ResourceCache resourceCache;
private final BatchComponentCache resourceCache;

public DbDuplicationsIndex(Project currentProject, DuplicationDao dao,
String language, DatabaseSession session, ResourceCache resourceCache) {
String language, DatabaseSession session, BatchComponentCache resourceCache) {
this.dao = dao;
this.session = session;
this.resourceCache = resourceCache;

+ 4
- 4
sonar-batch/src/main/java/org/sonar/batch/cpd/index/IndexFactory.java 查看文件

@@ -29,7 +29,7 @@ import org.sonar.api.config.Settings;
import org.sonar.api.database.DatabaseSession;
import org.sonar.api.resources.Project;
import org.sonar.batch.bootstrap.DefaultAnalysisMode;
import org.sonar.batch.index.ResourceCache;
import org.sonar.batch.index.BatchComponentCache;
import org.sonar.core.duplication.DuplicationDao;

import javax.annotation.Nullable;
@@ -43,9 +43,9 @@ public class IndexFactory {
private final DuplicationDao dao;
private final DefaultAnalysisMode mode;
private final DatabaseSession session;
private final ResourceCache resourceCache;
private final BatchComponentCache resourceCache;

public IndexFactory(DefaultAnalysisMode mode, Settings settings, @Nullable DuplicationDao dao, @Nullable DatabaseSession session, ResourceCache resourceCache) {
public IndexFactory(DefaultAnalysisMode mode, Settings settings, @Nullable DuplicationDao dao, @Nullable DatabaseSession session, BatchComponentCache resourceCache) {
this.mode = mode;
this.settings = settings;
this.dao = dao;
@@ -56,7 +56,7 @@ public class IndexFactory {
/**
* Used by new sensor mode
*/
public IndexFactory(DefaultAnalysisMode mode, Settings settings, ResourceCache resourceCache) {
public IndexFactory(DefaultAnalysisMode mode, Settings settings, BatchComponentCache resourceCache) {
this(mode, settings, null, null, resourceCache);
}


+ 10
- 22
sonar-batch/src/main/java/org/sonar/batch/deprecated/perspectives/BatchPerspectives.java 查看文件

@@ -20,47 +20,33 @@
package org.sonar.batch.deprecated.perspectives;

import com.google.common.collect.Maps;
import java.util.Map;
import javax.annotation.CheckForNull;
import org.sonar.api.batch.SonarIndex;
import org.sonar.api.batch.fs.InputDir;
import org.sonar.api.batch.fs.InputFile;
import org.sonar.api.batch.fs.InputPath;
import org.sonar.api.component.Component;
import org.sonar.api.component.Perspective;
import org.sonar.api.component.ResourcePerspectives;
import org.sonar.api.resources.Directory;
import org.sonar.api.resources.File;
import org.sonar.api.resources.Resource;
import org.sonar.core.component.PerspectiveBuilder;
import org.sonar.core.component.PerspectiveNotFoundException;
import org.sonar.core.component.ResourceComponent;

import javax.annotation.CheckForNull;

import java.util.Map;
import org.sonar.batch.index.BatchComponentCache;

public class BatchPerspectives implements ResourcePerspectives {

private final Map<Class<?>, PerspectiveBuilder<?>> builders = Maps.newHashMap();
private final SonarIndex resourceIndex;
private final BatchComponentCache componentCache;

public BatchPerspectives(PerspectiveBuilder[] builders, SonarIndex resourceIndex) {
public BatchPerspectives(PerspectiveBuilder[] builders, SonarIndex resourceIndex, BatchComponentCache componentCache) {
this.resourceIndex = resourceIndex;
this.componentCache = componentCache;
for (PerspectiveBuilder builder : builders) {
// TODO check duplications
this.builders.put(builder.getPerspectiveClass(), builder);
}
}

@Override
@CheckForNull
public <P extends Perspective> P as(Class<P> perspectiveClass, Component component) {
if (component.key() == null) {
return null;
}
PerspectiveBuilder<P> builder = builderFor(perspectiveClass);
return builder.loadPerspective(perspectiveClass, component);
}

@Override
@CheckForNull
public <P extends Perspective> P as(Class<P> perspectiveClass, Resource resource) {
@@ -69,7 +55,8 @@ public class BatchPerspectives implements ResourcePerspectives {
indexedResource = resourceIndex.getResource(resource);
}
if (indexedResource != null) {
return as(perspectiveClass, new ResourceComponent(indexedResource));
PerspectiveBuilder<P> builder = builderFor(perspectiveClass);
return builder.loadPerspective(perspectiveClass, componentCache.get(indexedResource));
}
return null;
}
@@ -84,7 +71,8 @@ public class BatchPerspectives implements ResourcePerspectives {
} else {
throw new IllegalArgumentException("Unknow input path type: " + inputPath);
}
return as(perspectiveClass, r);
PerspectiveBuilder<P> builder = builderFor(perspectiveClass);
return builder.loadPerspective(perspectiveClass, componentCache.get(inputPath));
}

private <T extends Perspective> PerspectiveBuilder<T> builderFor(Class<T> clazz) {

sonar-core/src/main/java/org/sonar/core/component/PerspectiveBuilder.java → sonar-batch/src/main/java/org/sonar/batch/deprecated/perspectives/PerspectiveBuilder.java 查看文件

@@ -17,17 +17,14 @@
* 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.core.component;
package org.sonar.batch.deprecated.perspectives;

import javax.annotation.CheckForNull;
import org.sonar.api.batch.BatchSide;
import org.sonar.api.server.ServerSide;
import org.sonar.api.component.Component;
import org.sonar.api.component.Perspective;

import javax.annotation.CheckForNull;
import org.sonar.batch.index.BatchComponent;

@BatchSide
@ServerSide
public abstract class PerspectiveBuilder<T extends Perspective> {

private final Class<T> perspectiveClass;
@@ -41,5 +38,5 @@ public abstract class PerspectiveBuilder<T extends Perspective> {
}

@CheckForNull
public abstract T loadPerspective(Class<T> perspectiveClass, Component component);
public abstract T loadPerspective(Class<T> perspectiveClass, BatchComponent component);
}

sonar-core/src/main/java/org/sonar/core/component/PerspectiveNotFoundException.java → sonar-batch/src/main/java/org/sonar/batch/deprecated/perspectives/PerspectiveNotFoundException.java 查看文件

@@ -17,7 +17,7 @@
* 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.core.component;
package org.sonar.batch.deprecated.perspectives;

public class PerspectiveNotFoundException extends RuntimeException {
public PerspectiveNotFoundException(String message) {

sonar-batch/src/main/java/org/sonar/batch/index/BatchResource.java → sonar-batch/src/main/java/org/sonar/batch/index/BatchComponent.java 查看文件

@@ -31,16 +31,16 @@ import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.Collection;

public class BatchResource {
public class BatchComponent {

private final int batchId;
private final Resource r;
private Snapshot s;
private final BatchResource parent;
private final Collection<BatchResource> children = new ArrayList<>();
private final BatchComponent parent;
private final Collection<BatchComponent> children = new ArrayList<>();
private InputPath inputPath;

public BatchResource(int batchId, Resource r, @Nullable BatchResource parent) {
public BatchComponent(int batchId, Resource r, @Nullable BatchComponent parent) {
this.batchId = batchId;
this.r = r;
this.parent = parent;
@@ -61,7 +61,7 @@ public class BatchResource {
return r;
}

public BatchResource setSnapshot(Snapshot snapshot) {
public BatchComponent setSnapshot(Snapshot snapshot) {
this.s = snapshot;
return this;
}
@@ -79,11 +79,11 @@ public class BatchResource {
}

@CheckForNull
public BatchResource parent() {
public BatchComponent parent() {
return parent;
}

public Collection<BatchResource> children() {
public Collection<BatchComponent> children() {
return children;
}

@@ -95,7 +95,7 @@ public class BatchResource {
return Qualifiers.isDirectory(r);
}

public BatchResource setInputPath(InputPath inputPath) {
public BatchComponent setInputPath(InputPath inputPath) {
this.inputPath = inputPath;
return this;
}

sonar-batch/src/main/java/org/sonar/batch/index/ResourceCache.java → sonar-batch/src/main/java/org/sonar/batch/index/BatchComponentCache.java 查看文件

@@ -19,74 +19,60 @@
*/
package org.sonar.batch.index;

import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Preconditions;
import com.google.common.base.Strings;
import com.google.common.collect.Maps;
import java.util.Collection;
import java.util.Map;
import javax.annotation.CheckForNull;
import javax.annotation.Nullable;
import org.sonar.api.batch.BatchSide;
import org.sonar.api.batch.fs.InputFile;
import org.sonar.api.batch.fs.InputPath;
import org.sonar.api.batch.fs.internal.DefaultInputDir;
import org.sonar.api.batch.fs.internal.DefaultInputFile;
import org.sonar.api.resources.Resource;
import org.sonar.api.resources.ResourceUtils;
import org.sonar.core.component.ScanGraph;

import javax.annotation.CheckForNull;
import javax.annotation.Nullable;

import java.util.Collection;
import java.util.Map;

@BatchSide
public class ResourceCache {
// resource by component key
private final Map<String, BatchResource> resources = Maps.newLinkedHashMap();

private BatchResource root;
private final ScanGraph scanGraph;

public ResourceCache(ScanGraph scanGraph) {
this.scanGraph = scanGraph;
}
public class BatchComponentCache {
// components by key
private final Map<String, BatchComponent> components = Maps.newLinkedHashMap();

@VisibleForTesting
public ResourceCache() {
this.scanGraph = null;
}
private BatchComponent root;

@CheckForNull
public BatchResource get(String componentKey) {
return resources.get(componentKey);
public BatchComponent get(String componentKey) {
return components.get(componentKey);
}

public BatchResource get(Resource resource) {
return resources.get(resource.getEffectiveKey());
public BatchComponent get(Resource resource) {
return components.get(resource.getEffectiveKey());
}

public BatchResource get(InputFile inputFile) {
return resources.get(((DefaultInputFile) inputFile).key());
public BatchComponent get(InputPath inputPath) {
if (inputPath instanceof DefaultInputFile) {
return components.get(((DefaultInputFile) inputPath).key());
}
return components.get(((DefaultInputDir) inputPath).key());
}

public BatchResource add(Resource resource, @Nullable Resource parentResource) {
public BatchComponent add(Resource resource, @Nullable Resource parentResource) {
String componentKey = resource.getEffectiveKey();
Preconditions.checkState(!Strings.isNullOrEmpty(componentKey), "Missing resource effective key");
BatchResource parent = parentResource != null ? get(parentResource.getEffectiveKey()) : null;
BatchResource batchResource = new BatchResource(resources.size() + 1, resource, parent);
BatchComponent parent = parentResource != null ? get(parentResource.getEffectiveKey()) : null;
BatchComponent batchResource = new BatchComponent(components.size() + 1, resource, parent);
// Libraries can have the same effective key than a project so we can't cache by effectiveKey
resources.put(componentKey, batchResource);
components.put(componentKey, batchResource);
if (parent == null) {
root = batchResource;
}
if (scanGraph != null && ResourceUtils.isPersistable(batchResource.resource())) {
scanGraph.addComponent(batchResource.resource());
}
return batchResource;
}

public Collection<BatchResource> all() {
return resources.values();
public Collection<BatchComponent> all() {
return components.values();
}

public BatchResource getRoot() {
public BatchComponent getRoot() {
return root;
}
}

+ 2
- 2
sonar-batch/src/main/java/org/sonar/batch/index/DefaultIndex.java 查看文件

@@ -91,7 +91,7 @@ public class DefaultIndex extends SonarIndex {
CoreMetrics.DUPLICATIONS_DATA_KEY
);

private final ResourceCache resourceCache;
private final BatchComponentCache resourceCache;
private final MetricFinder metricFinder;
private final MeasureCache measureCache;
// caches
@@ -100,7 +100,7 @@ public class DefaultIndex extends SonarIndex {
private DefaultProjectTree projectTree;
private ModuleIssues moduleIssues;

public DefaultIndex(ResourceCache resourceCache, DefaultProjectTree projectTree, MetricFinder metricFinder, MeasureCache measureCache) {
public DefaultIndex(BatchComponentCache resourceCache, DefaultProjectTree projectTree, MetricFinder metricFinder, MeasureCache measureCache) {
this.resourceCache = resourceCache;
this.projectTree = projectTree;
this.metricFinder = metricFinder;

+ 9
- 16
sonar-batch/src/main/java/org/sonar/batch/index/ResourcePersister.java 查看文件

@@ -20,6 +20,8 @@
package org.sonar.batch.index;

import com.google.common.annotations.VisibleForTesting;
import javax.annotation.Nullable;
import javax.persistence.NonUniqueResultException;
import org.apache.commons.lang.ObjectUtils;
import org.apache.commons.lang.StringUtils;
import org.sonar.api.database.DatabaseSession;
@@ -34,10 +36,6 @@ import org.sonar.api.resources.Scopes;
import org.sonar.api.security.ResourcePermissions;
import org.sonar.api.utils.SonarException;
import org.sonar.api.utils.internal.Uuids;
import org.sonar.core.component.ScanGraph;

import javax.annotation.Nullable;
import javax.persistence.NonUniqueResultException;

import static org.sonar.api.utils.DateUtils.dateToLong;

@@ -48,29 +46,27 @@ public class ResourcePersister implements ScanPersister {

private final DatabaseSession session;
private final ResourcePermissions permissions;
private final ResourceCache resourceCache;
private final ScanGraph scanGraph;
private final BatchComponentCache resourceCache;

public ResourcePersister(DatabaseSession session, ResourcePermissions permissions, ResourceCache resourceCache, ScanGraph scanGraph) {
public ResourcePersister(DatabaseSession session, ResourcePermissions permissions, BatchComponentCache resourceCache) {
this.session = session;
this.permissions = permissions;
this.resourceCache = resourceCache;
this.scanGraph = scanGraph;
}

@Override
public void persist() {
for (BatchResource resource : resourceCache.all()) {
for (BatchComponent resource : resourceCache.all()) {
persist(resource);
}
}

private void persist(BatchResource batchResource) {
private void persist(BatchComponent batchResource) {
if (batchResource.snapshot() != null) {
// already persisted
return;
}
BatchResource parentBatchResource = batchResource.parent();
BatchComponent parentBatchResource = batchResource.parent();
Snapshot s;
if (parentBatchResource != null) {
persist(parentBatchResource);
@@ -80,12 +76,9 @@ public class ResourcePersister implements ScanPersister {
s = persistProject((Project) batchResource.resource(), null);
}
batchResource.setSnapshot(s);
if (ResourceUtils.isPersistable(batchResource.resource())) {
scanGraph.completeComponent(batchResource.key(), batchResource.resource().getId(), s.getId());
}
}

private Project findModule(BatchResource batchResource) {
private Project findModule(BatchComponent batchResource) {
if (batchResource.resource() instanceof Project) {
return (Project) batchResource.resource();
} else {
@@ -147,7 +140,7 @@ public class ResourcePersister implements ScanPersister {
* Everything except project and library
*/
private Snapshot persistFileOrDirectory(Project project, Resource resource, @Nullable Resource parentReference) {
BatchResource moduleResource = resourceCache.get(project);
BatchComponent moduleResource = resourceCache.get(project);
Integer moduleId = moduleResource.resource().getId();
ResourceModel model = findOrCreateModel(resource, parentReference != null ? parentReference : project);
model.setRootId(moduleId);

+ 6
- 13
sonar-batch/src/main/java/org/sonar/batch/issue/DefaultIssuable.java 查看文件

@@ -20,15 +20,14 @@
package org.sonar.batch.issue;

import com.google.common.collect.Lists;
import org.sonar.api.component.Component;
import java.util.List;
import org.sonar.api.issue.Issuable;
import org.sonar.api.issue.Issue;
import org.sonar.api.issue.internal.DefaultIssue;
import org.sonar.api.resources.Project;
import org.sonar.batch.index.BatchComponent;
import org.sonar.core.issue.DefaultIssueBuilder;

import java.util.List;

/**
* @since 3.6
*/
@@ -36,10 +35,10 @@ public class DefaultIssuable implements Issuable {

private final ModuleIssues moduleIssues;
private final IssueCache cache;
private final Component component;
private final BatchComponent component;
private final Project project;

DefaultIssuable(Component component, Project project, ModuleIssues moduleIssues, IssueCache cache) {
DefaultIssuable(BatchComponent component, Project project, ModuleIssues moduleIssues, IssueCache cache) {
this.component = component;
this.project = project;
this.moduleIssues = moduleIssues;
@@ -56,32 +55,26 @@ public class DefaultIssuable implements Issuable {
return moduleIssues.initAndAddIssue((DefaultIssue) issue);
}

@SuppressWarnings("unchecked")
@Override
public List<Issue> resolvedIssues() {
List<Issue> result = Lists.newArrayList();
for (DefaultIssue issue : cache.byComponent(component.key())) {
if (issue.resolution()!=null) {
if (issue.resolution() != null) {
result.add(issue);
}
}
return result;
}

@SuppressWarnings("unchecked")
@Override
public List<Issue> issues() {
List<Issue> result = Lists.newArrayList();
for (DefaultIssue issue : cache.byComponent(component.key())) {
if (issue.resolution()==null) {
if (issue.resolution() == null) {
result.add(issue);
}
}
return result;
}

@Override
public Component component() {
return component;
}
}

+ 4
- 13
sonar-batch/src/main/java/org/sonar/batch/issue/IssuableFactory.java 查看文件

@@ -19,14 +19,10 @@
*/
package org.sonar.batch.issue;

import org.sonar.api.component.Component;
import org.sonar.api.issue.Issuable;
import org.sonar.api.resources.Scopes;
import org.sonar.batch.DefaultProjectTree;
import org.sonar.core.component.PerspectiveBuilder;
import org.sonar.core.component.ResourceComponent;

import javax.annotation.CheckForNull;
import org.sonar.batch.deprecated.perspectives.PerspectiveBuilder;
import org.sonar.batch.index.BatchComponent;

/**
* Create the perspective {@link Issuable} on components.
@@ -45,13 +41,8 @@ public class IssuableFactory extends PerspectiveBuilder<Issuable> {
this.projectTree = projectTree;
}

@CheckForNull
@Override
public Issuable loadPerspective(Class<Issuable> perspectiveClass, Component component) {
boolean supported = true;
if (component instanceof ResourceComponent) {
supported = Scopes.isHigherThanOrEquals(((ResourceComponent) component).scope(), Scopes.FILE);
}
return supported ? new DefaultIssuable(component, projectTree.getRootProject(), moduleIssues, cache) : null;
public Issuable loadPerspective(Class<Issuable> perspectiveClass, BatchComponent component) {
return new DefaultIssuable(component, projectTree.getRootProject(), moduleIssues, cache);
}
}

+ 8
- 8
sonar-batch/src/main/java/org/sonar/batch/issue/tracking/LocalIssueTracking.java 查看文件

@@ -34,8 +34,8 @@ import org.sonar.api.issue.internal.IssueChangeContext;
import org.sonar.api.resources.Project;
import org.sonar.api.resources.ResourceUtils;
import org.sonar.api.rule.RuleKey;
import org.sonar.batch.index.BatchResource;
import org.sonar.batch.index.ResourceCache;
import org.sonar.batch.index.BatchComponent;
import org.sonar.batch.index.BatchComponentCache;
import org.sonar.batch.issue.IssueCache;
import org.sonar.batch.protocol.input.ProjectRepositories;
import org.sonar.batch.scan.filesystem.InputPathCache;
@@ -62,12 +62,12 @@ public class LocalIssueTracking {
private final IssueChangeContext changeContext;
private final ActiveRules activeRules;
private final InputPathCache inputPathCache;
private final ResourceCache resourceCache;
private final BatchComponentCache resourceCache;
private final ServerIssueRepository serverIssueRepository;
private final ProjectRepositories projectRepositories;
private final AnalysisMode analysisMode;

public LocalIssueTracking(ResourceCache resourceCache, IssueCache issueCache, IssueTracking tracking,
public LocalIssueTracking(BatchComponentCache resourceCache, IssueCache issueCache, IssueTracking tracking,
ServerLineHashesLoader lastLineHashes, IssueWorkflow workflow, IssueUpdater updater,
ActiveRules activeRules, InputPathCache inputPathCache, ServerIssueRepository serverIssueRepository,
ProjectRepositories projectRepositories, AnalysisMode analysisMode) {
@@ -93,12 +93,12 @@ public class LocalIssueTracking {

serverIssueRepository.load();

for (BatchResource component : resourceCache.all()) {
for (BatchComponent component : resourceCache.all()) {
trackIssues(component);
}
}

public void trackIssues(BatchResource component) {
public void trackIssues(BatchComponent component) {

Collection<DefaultIssue> issues = Lists.newArrayList();
for (Issue issue : issueCache.byComponent(component.resource().getEffectiveKey())) {
@@ -136,7 +136,7 @@ public class LocalIssueTracking {
}

@CheckForNull
private SourceHashHolder loadSourceHashes(BatchResource component) {
private SourceHashHolder loadSourceHashes(BatchComponent component) {
SourceHashHolder sourceHashHolder = null;
if (component.isFile()) {
DefaultInputFile file = (DefaultInputFile) inputPathCache.getInputPath(component);
@@ -148,7 +148,7 @@ public class LocalIssueTracking {
return sourceHashHolder;
}

private Collection<ServerIssue> loadServerIssues(BatchResource component) {
private Collection<ServerIssue> loadServerIssues(BatchComponent component) {
Collection<ServerIssue> serverIssues = new ArrayList<>();
for (org.sonar.batch.protocol.input.BatchInput.ServerIssue previousIssue : serverIssueRepository.byComponent(component)) {
serverIssues.add(new ServerIssueFromWs(previousIssue));

+ 6
- 6
sonar-batch/src/main/java/org/sonar/batch/issue/tracking/ServerIssueRepository.java 查看文件

@@ -29,10 +29,10 @@ import org.sonar.api.batch.fs.InputFile.Status;
import org.sonar.api.utils.log.Logger;
import org.sonar.api.utils.log.Loggers;
import org.sonar.api.utils.log.Profiler;
import org.sonar.batch.index.BatchResource;
import org.sonar.batch.index.BatchComponent;
import org.sonar.batch.index.Cache;
import org.sonar.batch.index.Caches;
import org.sonar.batch.index.ResourceCache;
import org.sonar.batch.index.BatchComponentCache;
import org.sonar.batch.protocol.input.BatchInput.ServerIssue;
import org.sonar.batch.repository.ServerIssuesLoader;
import org.sonar.batch.scan.filesystem.InputPathCache;
@@ -54,11 +54,11 @@ public class ServerIssueRepository {
private Cache<ServerIssue> issuesCache;
private final ServerIssuesLoader previousIssuesLoader;
private final ProjectReactor reactor;
private final ResourceCache resourceCache;
private final BatchComponentCache resourceCache;
private final AnalysisMode analysisMode;
private final InputPathCache inputPathCache;

public ServerIssueRepository(Caches caches, ServerIssuesLoader previousIssuesLoader, ProjectReactor reactor, ResourceCache resourceCache,
public ServerIssueRepository(Caches caches, ServerIssuesLoader previousIssuesLoader, ProjectReactor reactor, BatchComponentCache resourceCache,
AnalysisMode analysisMode, InputPathCache inputPathCache) {
this.caches = caches;
this.previousIssuesLoader = previousIssuesLoader;
@@ -83,7 +83,7 @@ public class ServerIssueRepository {
return null;
}
String componentKey = ComponentKeys.createEffectiveKey(issue.getModuleKey(), issue.hasPath() ? issue.getPath() : null);
BatchResource r = resourceCache.get(componentKey);
BatchComponent r = resourceCache.get(componentKey);
if (r == null) {
// Deleted resource
issuesCache.put(0, issue.getKey(), issue);
@@ -96,7 +96,7 @@ public class ServerIssueRepository {
profiler.stopDebug();
}

public Iterable<ServerIssue> byComponent(BatchResource component) {
public Iterable<ServerIssue> byComponent(BatchComponent component) {
if (analysisMode.isIncremental()) {
if (!component.isFile()) {
throw new UnsupportedOperationException("Incremental mode should only get issues on files");

+ 2
- 2
sonar-batch/src/main/java/org/sonar/batch/mediumtest/TaskResult.java 查看文件

@@ -41,7 +41,7 @@ import org.sonar.api.issue.internal.DefaultIssue;
import org.sonar.api.measures.Measure;
import org.sonar.batch.duplication.DuplicationCache;
import org.sonar.batch.index.Cache.Entry;
import org.sonar.batch.index.ResourceCache;
import org.sonar.batch.index.BatchComponentCache;
import org.sonar.batch.issue.IssueCache;
import org.sonar.batch.protocol.output.BatchReport;
import org.sonar.batch.protocol.output.BatchReport.Component;
@@ -120,7 +120,7 @@ public class TaskResult implements org.sonar.batch.mediumtest.ScanTaskObserver {
}

private void storeMeasures(ProjectScanContainer container) {
ResourceCache resourceCache = container.getComponentByType(ResourceCache.class);
BatchComponentCache resourceCache = container.getComponentByType(BatchComponentCache.class);
for (Entry<Measure> measureEntry : container.getComponentByType(MeasureCache.class).entries()) {
String componentKey = measureEntry.key()[0].toString();
InputPath path = resourceCache.get(componentKey).inputPath();

+ 5
- 5
sonar-batch/src/main/java/org/sonar/batch/postjob/DefaultPostJobContext.java 查看文件

@@ -30,8 +30,8 @@ import org.sonar.api.batch.rule.Severity;
import org.sonar.api.config.Settings;
import org.sonar.api.issue.internal.DefaultIssue;
import org.sonar.api.rule.RuleKey;
import org.sonar.batch.index.BatchResource;
import org.sonar.batch.index.ResourceCache;
import org.sonar.batch.index.BatchComponent;
import org.sonar.batch.index.BatchComponentCache;
import org.sonar.batch.issue.IssueCache;

import javax.annotation.Nullable;
@@ -41,9 +41,9 @@ public class DefaultPostJobContext implements PostJobContext {
private final Settings settings;
private final AnalysisMode analysisMode;
private final IssueCache cache;
private final ResourceCache resourceCache;
private final BatchComponentCache resourceCache;

public DefaultPostJobContext(Settings settings, AnalysisMode analysisMode, IssueCache cache, ResourceCache resourceCache) {
public DefaultPostJobContext(Settings settings, AnalysisMode analysisMode, IssueCache cache, BatchComponentCache resourceCache) {
this.settings = settings;
this.analysisMode = analysisMode;
this.cache = cache;
@@ -105,7 +105,7 @@ public class DefaultPostJobContext implements PostJobContext {

@Override
public InputPath inputPath() {
BatchResource component = resourceCache.get(wrapped.componentKey());
BatchComponent component = resourceCache.get(wrapped.componentKey());
return component != null ? component.inputPath() : null;
}


+ 3
- 3
sonar-batch/src/main/java/org/sonar/batch/qualitygate/QualityGateVerifier.java 查看文件

@@ -34,7 +34,7 @@ import org.sonar.api.resources.Resource;
import org.sonar.api.resources.ResourceUtils;
import org.sonar.api.utils.Duration;
import org.sonar.api.utils.Durations;
import org.sonar.batch.index.ResourceCache;
import org.sonar.batch.index.BatchComponentCache;
import org.sonar.core.qualitygate.db.QualityGateConditionDto;
import org.sonar.core.timemachine.Periods;

@@ -55,9 +55,9 @@ public class QualityGateVerifier implements Decorator {
private Periods periods;
private I18n i18n;
private Durations durations;
private ResourceCache resourceCache;
private BatchComponentCache resourceCache;

public QualityGateVerifier(QualityGate qualityGate, ResourceCache resourceCache, Periods periods, I18n i18n, Durations durations) {
public QualityGateVerifier(QualityGate qualityGate, BatchComponentCache resourceCache, Periods periods, I18n i18n, Durations durations) {
this.qualityGate = qualityGate;
this.resourceCache = resourceCache;
this.periods = periods;

+ 9
- 9
sonar-batch/src/main/java/org/sonar/batch/report/ComponentsPublisher.java 查看文件

@@ -27,8 +27,8 @@ import org.sonar.api.batch.fs.InputFile;
import org.sonar.api.resources.Language;
import org.sonar.api.resources.Resource;
import org.sonar.api.resources.ResourceUtils;
import org.sonar.batch.index.BatchResource;
import org.sonar.batch.index.ResourceCache;
import org.sonar.batch.index.BatchComponent;
import org.sonar.batch.index.BatchComponentCache;
import org.sonar.batch.protocol.Constants;
import org.sonar.batch.protocol.Constants.ComponentLinkType;
import org.sonar.batch.protocol.output.*;
@@ -43,11 +43,11 @@ import javax.annotation.CheckForNull;
*/
public class ComponentsPublisher implements ReportPublisherStep {

private final ResourceCache resourceCache;
private final BatchComponentCache resourceCache;
private final ProjectReactor reactor;
private final EventCache eventCache;

public ComponentsPublisher(ProjectReactor reactor, ResourceCache resourceCache, EventCache eventCache) {
public ComponentsPublisher(ProjectReactor reactor, BatchComponentCache resourceCache, EventCache eventCache) {
this.reactor = reactor;
this.resourceCache = resourceCache;
this.eventCache = eventCache;
@@ -55,11 +55,11 @@ public class ComponentsPublisher implements ReportPublisherStep {

@Override
public void publish(BatchReportWriter writer) {
BatchResource rootProject = resourceCache.get(reactor.getRoot().getKeyWithBranch());
BatchComponent rootProject = resourceCache.get(reactor.getRoot().getKeyWithBranch());
recursiveWriteComponent(rootProject, writer);
}

private void recursiveWriteComponent(BatchResource batchResource, BatchReportWriter writer) {
private void recursiveWriteComponent(BatchComponent batchResource, BatchReportWriter writer) {
Resource r = batchResource.resource();
BatchReport.Component.Builder builder = BatchReport.Component.newBuilder();

@@ -98,7 +98,7 @@ public class ComponentsPublisher implements ReportPublisherStep {
if (lang != null) {
builder.setLanguage(lang);
}
for (BatchResource child : batchResource.children()) {
for (BatchComponent child : batchResource.children()) {
builder.addChildRef(child.batchId());
}
writeLinks(r, builder);
@@ -106,12 +106,12 @@ public class ComponentsPublisher implements ReportPublisherStep {
writeEvents(batchResource, builder);
writer.writeComponent(builder.build());

for (BatchResource child : batchResource.children()) {
for (BatchComponent child : batchResource.children()) {
recursiveWriteComponent(child, writer);
}
}

private void writeEvents(BatchResource batchResource, Builder builder) {
private void writeEvents(BatchComponent batchResource, Builder builder) {
if (ResourceUtils.isProject(batchResource.resource())) {
for (Event event : eventCache.getEvents(batchResource.batchId())) {
builder.addEvent(event);

+ 5
- 5
sonar-batch/src/main/java/org/sonar/batch/report/CoveragePublisher.java 查看文件

@@ -26,8 +26,8 @@ import org.sonar.api.batch.fs.InputFile;
import org.sonar.api.measures.CoreMetrics;
import org.sonar.api.measures.Measure;
import org.sonar.api.utils.KeyValueFormat;
import org.sonar.batch.index.BatchResource;
import org.sonar.batch.index.ResourceCache;
import org.sonar.batch.index.BatchComponent;
import org.sonar.batch.index.BatchComponentCache;
import org.sonar.batch.protocol.output.BatchReport.Coverage;
import org.sonar.batch.protocol.output.BatchReport.Coverage.Builder;
import org.sonar.batch.protocol.output.BatchReportWriter;
@@ -38,17 +38,17 @@ import java.util.Map;

public class CoveragePublisher implements ReportPublisherStep {

private final ResourceCache resourceCache;
private final BatchComponentCache resourceCache;
private final MeasureCache measureCache;

public CoveragePublisher(ResourceCache resourceCache, MeasureCache measureCache) {
public CoveragePublisher(BatchComponentCache resourceCache, MeasureCache measureCache) {
this.resourceCache = resourceCache;
this.measureCache = measureCache;
}

@Override
public void publish(BatchReportWriter writer) {
for (final BatchResource resource : resourceCache.all()) {
for (final BatchComponent resource : resourceCache.all()) {
if (!resource.isFile()) {
continue;
}

+ 6
- 6
sonar-batch/src/main/java/org/sonar/batch/report/DuplicationsPublisher.java 查看文件

@@ -24,8 +24,8 @@ import com.google.common.collect.Iterables;
import org.sonar.api.batch.sensor.duplication.Duplication.Block;
import org.sonar.api.batch.sensor.duplication.internal.DefaultDuplication;
import org.sonar.batch.duplication.DuplicationCache;
import org.sonar.batch.index.BatchResource;
import org.sonar.batch.index.ResourceCache;
import org.sonar.batch.index.BatchComponent;
import org.sonar.batch.index.BatchComponentCache;
import org.sonar.batch.protocol.output.*;
import org.sonar.batch.protocol.output.BatchReport.Duplicate;
import org.sonar.batch.protocol.output.BatchReport.Duplication;
@@ -33,17 +33,17 @@ import org.sonar.batch.protocol.output.BatchReport.Range;

public class DuplicationsPublisher implements ReportPublisherStep {

private final ResourceCache resourceCache;
private final BatchComponentCache resourceCache;
private final DuplicationCache duplicationCache;

public DuplicationsPublisher(ResourceCache resourceCache, DuplicationCache duplicationCache) {
public DuplicationsPublisher(BatchComponentCache resourceCache, DuplicationCache duplicationCache) {
this.resourceCache = resourceCache;
this.duplicationCache = duplicationCache;
}

@Override
public void publish(BatchReportWriter writer) {
for (final BatchResource resource : resourceCache.all()) {
for (final BatchComponent resource : resourceCache.all()) {
if (!resource.isFile()) {
continue;
}
@@ -77,7 +77,7 @@ public class DuplicationsPublisher implements ReportPublisherStep {
blockBuilder.clear();
String componentKey = duplicate.resourceKey();
if (!currentComponentKey.equals(componentKey)) {
BatchResource sameProjectComponent = resourceCache.get(componentKey);
BatchComponent sameProjectComponent = resourceCache.get(componentKey);
if (sameProjectComponent != null) {
blockBuilder.setOtherFileRef(sameProjectComponent.batchId());
} else {

+ 3
- 3
sonar-batch/src/main/java/org/sonar/batch/report/EventCache.java 查看文件

@@ -21,7 +21,7 @@ package org.sonar.batch.report;

import org.sonar.api.batch.BatchSide;
import org.sonar.api.resources.Resource;
import org.sonar.batch.index.ResourceCache;
import org.sonar.batch.index.BatchComponentCache;
import org.sonar.batch.protocol.Constants.EventCategory;
import org.sonar.batch.protocol.output.BatchReport.Event;

@@ -37,9 +37,9 @@ import java.util.Map;
public class EventCache {

private final Map<Integer, List<Event>> eventsByComponentBatchId = new HashMap<>();
private final ResourceCache resourceCache;
private final BatchComponentCache resourceCache;

public EventCache(ResourceCache resourceCache) {
public EventCache(BatchComponentCache resourceCache) {
this.resourceCache = resourceCache;
}


+ 6
- 6
sonar-batch/src/main/java/org/sonar/batch/report/IssuesPublisher.java 查看文件

@@ -26,8 +26,8 @@ import org.sonar.api.issue.internal.DefaultIssue;
import org.sonar.api.issue.internal.FieldDiffs;
import org.sonar.api.resources.Project;
import org.sonar.api.utils.KeyValueFormat;
import org.sonar.batch.index.BatchResource;
import org.sonar.batch.index.ResourceCache;
import org.sonar.batch.index.BatchComponent;
import org.sonar.batch.index.BatchComponentCache;
import org.sonar.batch.issue.IssueCache;
import org.sonar.batch.protocol.Constants;
import org.sonar.batch.protocol.output.BatchReport;
@@ -41,11 +41,11 @@ import java.util.Iterator;

public class IssuesPublisher implements ReportPublisherStep {

private final ResourceCache resourceCache;
private final BatchComponentCache resourceCache;
private final IssueCache issueCache;
private final ProjectReactor reactor;

public IssuesPublisher(ProjectReactor reactor, ResourceCache resourceCache, IssueCache issueCache) {
public IssuesPublisher(ProjectReactor reactor, BatchComponentCache resourceCache, IssueCache issueCache) {
this.reactor = reactor;
this.resourceCache = resourceCache;
this.issueCache = issueCache;
@@ -54,7 +54,7 @@ public class IssuesPublisher implements ReportPublisherStep {
@Override
public void publish(BatchReportWriter writer) {
Collection<Object> deletedComponentKeys = issueCache.componentKeys();
for (BatchResource resource : resourceCache.all()) {
for (BatchComponent resource : resourceCache.all()) {
String componentKey = resource.resource().getEffectiveKey();
Iterable<DefaultIssue> issues = issueCache.byComponent(componentKey);
writer.writeComponentIssues(resource.batchId(), Iterables.transform(issues, new Function<DefaultIssue, BatchReport.Issue>() {
@@ -74,7 +74,7 @@ public class IssuesPublisher implements ReportPublisherStep {
}

private void exportMetadata(BatchReportWriter writer, int count) {
BatchResource rootProject = resourceCache.get(reactor.getRoot().getKeyWithBranch());
BatchComponent rootProject = resourceCache.get(reactor.getRoot().getKeyWithBranch());
BatchReport.Metadata.Builder builder = BatchReport.Metadata.newBuilder()
.setAnalysisDate(((Project) rootProject.resource()).getAnalysisDate().getTime())
.setProjectKey(((Project) rootProject.resource()).key())

+ 5
- 5
sonar-batch/src/main/java/org/sonar/batch/report/MeasuresPublisher.java 查看文件

@@ -31,8 +31,8 @@ import org.sonar.api.resources.ResourceUtils;
import org.sonar.api.rule.RuleKey;
import org.sonar.api.rules.RulePriority;
import org.sonar.api.technicaldebt.batch.Characteristic;
import org.sonar.batch.index.BatchResource;
import org.sonar.batch.index.ResourceCache;
import org.sonar.batch.index.BatchComponent;
import org.sonar.batch.index.BatchComponentCache;
import org.sonar.batch.protocol.Constants;
import org.sonar.batch.protocol.Constants.MeasureValueType;
import org.sonar.batch.protocol.output.BatchReport;
@@ -45,11 +45,11 @@ import java.io.Serializable;

public class MeasuresPublisher implements ReportPublisherStep {

private final ResourceCache resourceCache;
private final BatchComponentCache resourceCache;
private final MeasureCache measureCache;
private final MetricFinder metricFinder;

public MeasuresPublisher(ResourceCache resourceCache, MeasureCache measureCache, MetricFinder metricFinder) {
public MeasuresPublisher(BatchComponentCache resourceCache, MeasureCache measureCache, MetricFinder metricFinder) {
this.resourceCache = resourceCache;
this.measureCache = measureCache;
this.metricFinder = metricFinder;
@@ -57,7 +57,7 @@ public class MeasuresPublisher implements ReportPublisherStep {

@Override
public void publish(BatchReportWriter writer) {
for (final BatchResource resource : resourceCache.all()) {
for (final BatchComponent resource : resourceCache.all()) {
Iterable<Measure> batchMeasures = measureCache.byResource(resource.resource());
batchMeasures = Iterables.filter(batchMeasures, new Predicate<Measure>() {
@Override

+ 5
- 5
sonar-batch/src/main/java/org/sonar/batch/report/SourcePublisher.java 查看文件

@@ -23,8 +23,8 @@ import org.apache.commons.io.ByteOrderMark;
import org.apache.commons.io.IOUtils;
import org.apache.commons.io.input.BOMInputStream;
import org.sonar.api.batch.fs.internal.DefaultInputFile;
import org.sonar.batch.index.BatchResource;
import org.sonar.batch.index.ResourceCache;
import org.sonar.batch.index.BatchComponent;
import org.sonar.batch.index.BatchComponentCache;
import org.sonar.batch.protocol.output.BatchReportWriter;

import java.io.BufferedReader;
@@ -37,15 +37,15 @@ import java.nio.charset.StandardCharsets;

public class SourcePublisher implements ReportPublisherStep {

private final ResourceCache resourceCache;
private final BatchComponentCache resourceCache;

public SourcePublisher(ResourceCache resourceCache) {
public SourcePublisher(BatchComponentCache resourceCache) {
this.resourceCache = resourceCache;
}

@Override
public void publish(BatchReportWriter writer) {
for (final BatchResource resource : resourceCache.all()) {
for (final BatchComponent resource : resourceCache.all()) {
if (!resource.isFile()) {
continue;
}

+ 17
- 18
sonar-batch/src/main/java/org/sonar/batch/report/TestExecutionAndCoveragePublisher.java 查看文件

@@ -21,25 +21,24 @@ package org.sonar.batch.report;

import com.google.common.base.Function;
import com.google.common.collect.Iterables;
import java.util.HashSet;
import java.util.Set;
import javax.annotation.Nonnull;
import org.sonar.api.batch.fs.InputFile.Type;
import org.sonar.api.batch.fs.internal.DefaultInputFile;
import org.sonar.api.test.CoverageBlock;
import org.sonar.api.test.MutableTestCase;
import org.sonar.api.test.MutableTestPlan;
import org.sonar.api.test.TestCase;
import org.sonar.batch.index.BatchResource;
import org.sonar.batch.index.ResourceCache;
import org.sonar.batch.index.BatchComponent;
import org.sonar.batch.index.BatchComponentCache;
import org.sonar.batch.protocol.Constants.TestStatus;
import org.sonar.batch.protocol.output.BatchReport;
import org.sonar.batch.protocol.output.BatchReport.CoverageDetail;
import org.sonar.batch.protocol.output.BatchReport.Test;
import org.sonar.batch.protocol.output.BatchReportWriter;
import org.sonar.core.test.TestPlanBuilder;

import javax.annotation.Nonnull;

import java.util.HashSet;
import java.util.Set;
import org.sonar.batch.test.DefaultTestable;
import org.sonar.batch.test.TestPlanBuilder;

public class TestExecutionAndCoveragePublisher implements ReportPublisherStep {

@@ -95,7 +94,7 @@ public class TestExecutionAndCoveragePublisher implements ReportPublisherStep {
builder.setTestName(testName);
for (CoverageBlock block : testCase.coverageBlocks()) {
coveredBuilder.clear();
coveredBuilder.setFileRef(resourceCache.get(block.testable().component().key()).batchId());
coveredBuilder.setFileRef(componentCache.get(((DefaultTestable) block.testable()).inputFile().key()).batchId());
for (int line : block.lines()) {
coveredBuilder.addCoveredLine(line);
}
@@ -105,36 +104,36 @@ public class TestExecutionAndCoveragePublisher implements ReportPublisherStep {
}
}

private final ResourceCache resourceCache;
private final BatchComponentCache componentCache;
private final TestPlanBuilder testPlanBuilder;

public TestExecutionAndCoveragePublisher(ResourceCache resourceCache, TestPlanBuilder testPlanBuilder) {
this.resourceCache = resourceCache;
public TestExecutionAndCoveragePublisher(BatchComponentCache resourceCache, TestPlanBuilder testPlanBuilder) {
this.componentCache = resourceCache;
this.testPlanBuilder = testPlanBuilder;
}

@Override
public void publish(BatchReportWriter writer) {
for (final BatchResource resource : resourceCache.all()) {
if (!resource.isFile()) {
for (final BatchComponent component : componentCache.all()) {
if (!component.isFile()) {
continue;
}

DefaultInputFile inputFile = (DefaultInputFile) resource.inputPath();
DefaultInputFile inputFile = (DefaultInputFile) component.inputPath();
if (inputFile.type() != Type.TEST) {
continue;
}

final MutableTestPlan testPlan = testPlanBuilder.get(MutableTestPlan.class, inputFile.key());
final MutableTestPlan testPlan = testPlanBuilder.loadPerspective(MutableTestPlan.class, component);
if (testPlan == null || Iterables.isEmpty(testPlan.testCases())) {
continue;
}

final Set<String> testNamesWithCoverage = new HashSet<>();

writer.writeTests(resource.batchId(), Iterables.transform(testPlan.testCases(), new TestConverter(testNamesWithCoverage)));
writer.writeTests(component.batchId(), Iterables.transform(testPlan.testCases(), new TestConverter(testNamesWithCoverage)));

writer.writeCoverageDetails(resource.batchId(), Iterables.transform(testNamesWithCoverage, new TestCoverageConverter(testPlan)));
writer.writeCoverageDetails(component.batchId(), Iterables.transform(testNamesWithCoverage, new TestCoverageConverter(testPlan)));
}
}
}

+ 4
- 10
sonar-batch/src/main/java/org/sonar/batch/scan/ProjectScanContainer.java 查看文件

@@ -46,7 +46,7 @@ import org.sonar.batch.duplication.DuplicationCache;
import org.sonar.batch.events.EventBus;
import org.sonar.batch.index.Caches;
import org.sonar.batch.index.DefaultIndex;
import org.sonar.batch.index.ResourceCache;
import org.sonar.batch.index.BatchComponentCache;
import org.sonar.batch.index.ResourcePersister;
import org.sonar.batch.issue.DefaultProjectIssues;
import org.sonar.batch.issue.IssueCache;
@@ -75,7 +75,8 @@ import org.sonar.batch.scan.measure.DefaultMetricFinder;
import org.sonar.batch.scan.measure.DeprecatedMetricFinder;
import org.sonar.batch.scan.measure.MeasureCache;
import org.sonar.batch.source.CodeColorizers;
import org.sonar.core.component.ScanGraph;
import org.sonar.batch.test.TestPlanBuilder;
import org.sonar.batch.test.TestableBuilder;
import org.sonar.core.issue.IssueUpdater;
import org.sonar.core.issue.workflow.FunctionExecutor;
import org.sonar.core.issue.workflow.IssueWorkflow;
@@ -83,10 +84,6 @@ import org.sonar.core.permission.PermissionFacade;
import org.sonar.core.platform.ComponentContainer;
import org.sonar.core.resource.DefaultResourcePermissions;
import org.sonar.core.technicaldebt.DefaultTechnicalDebtModel;
import org.sonar.core.test.TestPlanBuilder;
import org.sonar.core.test.TestPlanPerspectiveLoader;
import org.sonar.core.test.TestableBuilder;
import org.sonar.core.test.TestablePerspectiveLoader;
import org.sonar.core.user.DefaultUserFinder;

public class ProjectScanContainer extends ComponentContainer {
@@ -154,7 +151,7 @@ public class ProjectScanContainer extends ComponentContainer {
DefaultIndex.class,
DefaultFileLinesContextFactory.class,
Caches.class,
ResourceCache.class,
BatchComponentCache.class,

// file system
InputPathCache.class,
@@ -177,11 +174,8 @@ public class ProjectScanContainer extends ComponentContainer {
DeprecatedMetricFinder.class,

// tests
TestPlanPerspectiveLoader.class,
TestablePerspectiveLoader.class,
TestPlanBuilder.class,
TestableBuilder.class,
ScanGraph.create(),

// lang
Languages.class,

+ 4
- 4
sonar-batch/src/main/java/org/sonar/batch/scan/filesystem/ComponentIndexer.java 查看文件

@@ -26,7 +26,7 @@ import org.sonar.api.resources.File;
import org.sonar.api.resources.Languages;
import org.sonar.api.resources.Project;
import org.sonar.api.resources.Resource;
import org.sonar.batch.index.ResourceCache;
import org.sonar.batch.index.BatchComponentCache;
import org.sonar.batch.index.ResourcePersister;

import javax.annotation.Nullable;
@@ -43,9 +43,9 @@ public class ComponentIndexer {
private final SonarIndex sonarIndex;
private final Project module;
private final ResourcePersister resourcePersister;
private final ResourceCache resourceCache;
private final BatchComponentCache resourceCache;

public ComponentIndexer(Project module, Languages languages, SonarIndex sonarIndex, ResourceCache resourceCache, @Nullable ResourcePersister resourcePersister) {
public ComponentIndexer(Project module, Languages languages, SonarIndex sonarIndex, BatchComponentCache resourceCache, @Nullable ResourcePersister resourcePersister) {
this.module = module;
this.languages = languages;
this.sonarIndex = sonarIndex;
@@ -53,7 +53,7 @@ public class ComponentIndexer {
this.resourcePersister = resourcePersister;
}

public ComponentIndexer(Project module, Languages languages, SonarIndex sonarIndex, ResourceCache resourceCache) {
public ComponentIndexer(Project module, Languages languages, SonarIndex sonarIndex, BatchComponentCache resourceCache) {
this(module, languages, sonarIndex, resourceCache, null);
}


+ 2
- 2
sonar-batch/src/main/java/org/sonar/batch/scan/filesystem/InputPathCache.java 查看文件

@@ -25,7 +25,7 @@ import org.sonar.api.batch.BatchSide;
import org.sonar.api.batch.fs.InputDir;
import org.sonar.api.batch.fs.InputFile;
import org.sonar.api.batch.fs.InputPath;
import org.sonar.batch.index.BatchResource;
import org.sonar.batch.index.BatchComponent;

import javax.annotation.CheckForNull;

@@ -131,7 +131,7 @@ public class InputPathCache {
}

@CheckForNull
public InputPath getInputPath(BatchResource component) {
public InputPath getInputPath(BatchComponent component) {
if (component.isFile()) {
return getFile(component.parent().parent().resource().getEffectiveKey(), component.resource().getPath());
} else if (component.isDir()) {

+ 7
- 7
sonar-batch/src/main/java/org/sonar/batch/scan/report/IssuesReport.java 查看文件

@@ -23,7 +23,7 @@ import com.google.common.collect.Maps;
import org.sonar.api.issue.Issue;
import org.sonar.api.rules.Rule;
import org.sonar.api.rules.RulePriority;
import org.sonar.batch.index.BatchResource;
import org.sonar.batch.index.BatchComponent;

import java.util.ArrayList;
import java.util.Date;
@@ -37,7 +37,7 @@ public class IssuesReport {
private Date date;
private boolean noFile;
private final ReportSummary summary = new ReportSummary();
private final Map<BatchResource, ResourceReport> resourceReportsByResource = Maps.newLinkedHashMap();
private final Map<BatchComponent, ResourceReport> resourceReportsByResource = Maps.newLinkedHashMap();

public IssuesReport() {
}
@@ -70,7 +70,7 @@ public class IssuesReport {
this.noFile = noFile;
}

public Map<BatchResource, ResourceReport> getResourceReportsByResource() {
public Map<BatchComponent, ResourceReport> getResourceReportsByResource() {
return resourceReportsByResource;
}

@@ -78,23 +78,23 @@ public class IssuesReport {
return new ArrayList<>(resourceReportsByResource.values());
}

public List<BatchResource> getResourcesWithReport() {
public List<BatchComponent> getResourcesWithReport() {
return new ArrayList<>(resourceReportsByResource.keySet());
}

public void addIssueOnResource(BatchResource resource, Issue issue, Rule rule, RulePriority severity) {
public void addIssueOnResource(BatchComponent resource, Issue issue, Rule rule, RulePriority severity) {
addResource(resource);
getSummary().addIssue(issue, rule, severity);
resourceReportsByResource.get(resource).addIssue(issue, rule, RulePriority.valueOf(issue.severity()));
}

public void addResolvedIssueOnResource(BatchResource resource, Issue issue, Rule rule, RulePriority severity) {
public void addResolvedIssueOnResource(BatchComponent resource, Issue issue, Rule rule, RulePriority severity) {
addResource(resource);
getSummary().addResolvedIssue(issue, rule, severity);
resourceReportsByResource.get(resource).addResolvedIssue(issue, rule, RulePriority.valueOf(issue.severity()));
}

private void addResource(BatchResource resource) {
private void addResource(BatchComponent resource) {
if (!resourceReportsByResource.containsKey(resource)) {
resourceReportsByResource.put(resource, new ResourceReport(resource));
}

+ 6
- 6
sonar-batch/src/main/java/org/sonar/batch/scan/report/IssuesReportBuilder.java 查看文件

@@ -30,8 +30,8 @@ import org.sonar.api.rules.Rule;
import org.sonar.api.rules.RuleFinder;
import org.sonar.api.rules.RulePriority;
import org.sonar.batch.DefaultProjectTree;
import org.sonar.batch.index.BatchResource;
import org.sonar.batch.index.ResourceCache;
import org.sonar.batch.index.BatchComponent;
import org.sonar.batch.index.BatchComponentCache;
import org.sonar.batch.issue.IssueCache;
import org.sonar.batch.scan.filesystem.InputPathCache;

@@ -44,11 +44,11 @@ public class IssuesReportBuilder {

private final IssueCache issueCache;
private final RuleFinder ruleFinder;
private final ResourceCache resourceCache;
private final BatchComponentCache resourceCache;
private final DefaultProjectTree projectTree;
private final InputPathCache inputPathCache;

public IssuesReportBuilder(IssueCache issueCache, RuleFinder ruleFinder, ResourceCache resourceCache, DefaultProjectTree projectTree, InputPathCache inputPathCache) {
public IssuesReportBuilder(IssueCache issueCache, RuleFinder ruleFinder, BatchComponentCache resourceCache, DefaultProjectTree projectTree, InputPathCache inputPathCache) {
this.issueCache = issueCache;
this.ruleFinder = ruleFinder;
this.resourceCache = resourceCache;
@@ -72,7 +72,7 @@ public class IssuesReportBuilder {
for (Issue issue : issues) {
Rule rule = findRule(issue);
RulePriority severity = RulePriority.valueOf(issue.severity());
BatchResource resource = resourceCache.get(issue.componentKey());
BatchComponent resource = resourceCache.get(issue.componentKey());
if (!validate(issue, rule, resource)) {
continue;
}
@@ -84,7 +84,7 @@ public class IssuesReportBuilder {
}
}

private boolean validate(Issue issue, Rule rule, BatchResource resource) {
private boolean validate(Issue issue, Rule rule, BatchComponent resource) {
if (rule == null) {
LOG.warn("Unknow rule for issue {}", issue);
return false;

+ 4
- 4
sonar-batch/src/main/java/org/sonar/batch/scan/report/ResourceReport.java 查看文件

@@ -23,7 +23,7 @@ import com.google.common.collect.Maps;
import org.sonar.api.issue.Issue;
import org.sonar.api.rules.Rule;
import org.sonar.api.rules.RulePriority;
import org.sonar.batch.index.BatchResource;
import org.sonar.batch.index.BatchComponent;

import java.util.ArrayList;
import java.util.Collections;
@@ -32,7 +32,7 @@ import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;

public final class ResourceReport {
private final BatchResource resource;
private final BatchComponent resource;
private final IssueVariation total = new IssueVariation();
private final Map<ReportRuleKey, RuleReport> ruleReportByRuleKey = Maps.newHashMap();

@@ -42,11 +42,11 @@ public final class ResourceReport {
private Map<Rule, AtomicInteger> issuesByRule = Maps.newHashMap();
private Map<RulePriority, AtomicInteger> issuesBySeverity = Maps.newHashMap();

public ResourceReport(BatchResource resource) {
public ResourceReport(BatchComponent resource) {
this.resource = resource;
}

public BatchResource getResourceNode() {
public BatchComponent getResourceNode() {
return resource;
}


+ 2
- 2
sonar-batch/src/main/java/org/sonar/batch/scan/report/SourceProvider.java 查看文件

@@ -26,7 +26,7 @@ import org.slf4j.LoggerFactory;
import org.sonar.api.batch.BatchSide;
import org.sonar.api.batch.fs.FileSystem;
import org.sonar.api.batch.fs.InputFile;
import org.sonar.batch.index.BatchResource;
import org.sonar.batch.index.BatchComponent;
import org.sonar.batch.scan.filesystem.InputPathCache;

import java.io.IOException;
@@ -46,7 +46,7 @@ public class SourceProvider {
this.fs = fs;
}

public List<String> getEscapedSource(BatchResource component) {
public List<String> getEscapedSource(BatchComponent component) {
if (!component.isFile()) {
// Folder
return Collections.emptyList();

+ 5
- 5
sonar-batch/src/main/java/org/sonar/batch/scm/DefaultBlameOutput.java 查看文件

@@ -26,8 +26,8 @@ import org.slf4j.LoggerFactory;
import org.sonar.api.batch.fs.InputFile;
import org.sonar.api.batch.scm.BlameCommand.BlameOutput;
import org.sonar.api.batch.scm.BlameLine;
import org.sonar.batch.index.BatchResource;
import org.sonar.batch.index.ResourceCache;
import org.sonar.batch.index.BatchComponent;
import org.sonar.batch.index.BatchComponentCache;
import org.sonar.batch.protocol.output.BatchReport;
import org.sonar.batch.protocol.output.BatchReport.Changesets.Builder;
import org.sonar.batch.protocol.output.BatchReportWriter;
@@ -48,13 +48,13 @@ class DefaultBlameOutput implements BlameOutput {
private static final Pattern ACCENT_CODES = Pattern.compile("\\p{InCombiningDiacriticalMarks}+");

private final BatchReportWriter writer;
private final ResourceCache componentCache;
private final BatchComponentCache componentCache;
private final Set<InputFile> allFilesToBlame = new HashSet<>();
private ProgressReport progressReport;
private int count;
private int total;

DefaultBlameOutput(BatchReportWriter writer, ResourceCache componentCache, List<InputFile> filesToBlame) {
DefaultBlameOutput(BatchReportWriter writer, BatchComponentCache componentCache, List<InputFile> filesToBlame) {
this.writer = writer;
this.componentCache = componentCache;
this.allFilesToBlame.addAll(filesToBlame);
@@ -75,7 +75,7 @@ class DefaultBlameOutput implements BlameOutput {
return;
}

BatchResource batchComponent = componentCache.get(file);
BatchComponent batchComponent = componentCache.get(file);
Builder scmBuilder = BatchReport.Changesets.newBuilder();
scmBuilder.setComponentRef(batchComponent.batchId());
Map<String, Integer> changesetsIdByRevision = new HashMap<>();

+ 3
- 3
sonar-batch/src/main/java/org/sonar/batch/scm/ScmSensor.java 查看文件

@@ -29,7 +29,7 @@ import org.sonar.api.batch.fs.InputFile.Status;
import org.sonar.api.batch.sensor.Sensor;
import org.sonar.api.batch.sensor.SensorContext;
import org.sonar.api.batch.sensor.SensorDescriptor;
import org.sonar.batch.index.ResourceCache;
import org.sonar.batch.index.BatchComponentCache;
import org.sonar.batch.protocol.input.FileData;
import org.sonar.batch.protocol.input.ProjectRepositories;
import org.sonar.batch.report.ReportPublisher;
@@ -46,11 +46,11 @@ public final class ScmSensor implements Sensor {
private final ScmConfiguration configuration;
private final FileSystem fs;
private final ProjectRepositories projectReferentials;
private final ResourceCache resourceCache;
private final BatchComponentCache resourceCache;
private final ReportPublisher publishReportJob;

public ScmSensor(ProjectDefinition projectDefinition, ScmConfiguration configuration,
ProjectRepositories projectReferentials, FileSystem fs, InputPathCache inputPathCache, ResourceCache resourceCache,
ProjectRepositories projectReferentials, FileSystem fs, InputPathCache inputPathCache, BatchComponentCache resourceCache,
ReportPublisher publishReportJob) {
this.projectDefinition = projectDefinition;
this.configuration = configuration;

+ 5
- 5
sonar-batch/src/main/java/org/sonar/batch/sensor/DefaultSensorStorage.java 查看文件

@@ -52,9 +52,9 @@ import org.sonar.api.rule.RuleKey;
import org.sonar.api.source.Symbol;
import org.sonar.api.utils.KeyValueFormat;
import org.sonar.batch.duplication.DuplicationCache;
import org.sonar.batch.index.BatchResource;
import org.sonar.batch.index.BatchComponent;
import org.sonar.batch.index.DefaultIndex;
import org.sonar.batch.index.ResourceCache;
import org.sonar.batch.index.BatchComponentCache;
import org.sonar.batch.issue.ModuleIssues;
import org.sonar.batch.protocol.output.BatchReport;
import org.sonar.batch.protocol.output.BatchReport.Range;
@@ -76,12 +76,12 @@ public class DefaultSensorStorage implements SensorStorage {
private final DefaultIndex sonarIndex;
private final CoverageExclusions coverageExclusions;
private final DuplicationCache duplicationCache;
private final ResourceCache resourceCache;
private final BatchComponentCache resourceCache;
private final ReportPublisher reportPublisher;

public DefaultSensorStorage(MetricFinder metricFinder, Project project, ModuleIssues moduleIssues,
Settings settings, FileSystem fs, ActiveRules activeRules, DuplicationCache duplicationCache, DefaultIndex sonarIndex,
CoverageExclusions coverageExclusions, ResourceCache resourceCache, ReportPublisher reportPublisher) {
CoverageExclusions coverageExclusions, BatchComponentCache resourceCache, ReportPublisher reportPublisher) {
this.metricFinder = metricFinder;
this.project = project;
this.moduleIssues = moduleIssues;
@@ -178,7 +178,7 @@ public class DefaultSensorStorage implements SensorStorage {
}

private File getFile(InputFile file) {
BatchResource r = resourceCache.get(file);
BatchComponent r = resourceCache.get(file);
if (r == null) {
throw new IllegalStateException("Provided input file is not indexed");
}

+ 3
- 3
sonar-batch/src/main/java/org/sonar/batch/source/CodeColorizerSensor.java 查看文件

@@ -25,7 +25,7 @@ import org.sonar.api.batch.fs.InputFile;
import org.sonar.api.batch.sensor.Sensor;
import org.sonar.api.batch.sensor.SensorContext;
import org.sonar.api.batch.sensor.SensorDescriptor;
import org.sonar.batch.index.ResourceCache;
import org.sonar.batch.index.BatchComponentCache;
import org.sonar.batch.protocol.output.BatchReportReader;
import org.sonar.batch.report.ReportPublisher;
import org.sonar.colorizer.CodeColorizer;
@@ -37,10 +37,10 @@ import org.sonar.colorizer.CodeColorizer;
public final class CodeColorizerSensor implements Sensor {

private final ReportPublisher reportPublisher;
private final ResourceCache resourceCache;
private final BatchComponentCache resourceCache;
private final CodeColorizers codeColorizers;

public CodeColorizerSensor(ReportPublisher reportPublisher, ResourceCache resourceCache, CodeColorizers codeColorizers) {
public CodeColorizerSensor(ReportPublisher reportPublisher, BatchComponentCache resourceCache, CodeColorizers codeColorizers) {
this.reportPublisher = reportPublisher;
this.resourceCache = resourceCache;
this.codeColorizers = codeColorizers;

+ 0
- 7
sonar-batch/src/main/java/org/sonar/batch/source/DefaultHighlightable.java 查看文件

@@ -23,9 +23,7 @@ import org.sonar.api.batch.fs.internal.DefaultInputFile;
import org.sonar.api.batch.sensor.highlighting.TypeOfText;
import org.sonar.api.batch.sensor.highlighting.internal.DefaultHighlighting;
import org.sonar.api.batch.sensor.internal.SensorStorage;
import org.sonar.api.component.Component;
import org.sonar.api.source.Highlightable;
import org.sonar.batch.deprecated.InputFileComponent;

/**
* @since 3.6
@@ -47,11 +45,6 @@ public class DefaultHighlightable implements Highlightable {
return new DefaultHighlightingBuilder(defaultHighlighting);
}

@Override
public Component component() {
return new InputFileComponent(inputFile);
}

private static class DefaultHighlightingBuilder implements HighlightingBuilder {

private final DefaultHighlighting defaultHighlighting;

+ 0
- 7
sonar-batch/src/main/java/org/sonar/batch/source/DefaultSymbolizable.java 查看文件

@@ -21,9 +21,7 @@
package org.sonar.batch.source;

import org.sonar.api.batch.fs.internal.DefaultInputFile;
import org.sonar.api.component.Component;
import org.sonar.api.source.Symbolizable;
import org.sonar.batch.deprecated.InputFileComponent;
import org.sonar.batch.sensor.DefaultSensorStorage;

public class DefaultSymbolizable implements Symbolizable {
@@ -36,11 +34,6 @@ public class DefaultSymbolizable implements Symbolizable {
this.sensorStorage = sensorStorage;
}

@Override
public Component component() {
return new InputFileComponent(inputFile);
}

@Override
public SymbolTableBuilder newSymbolTableBuilder() {
return new DefaultSymbolTable.Builder(inputFile);

+ 8
- 25
sonar-batch/src/main/java/org/sonar/batch/source/HighlightableBuilder.java 查看文件

@@ -19,46 +19,29 @@
*/
package org.sonar.batch.source;

import com.google.common.collect.ImmutableSet;
import javax.annotation.CheckForNull;
import org.sonar.api.batch.fs.InputFile;
import org.sonar.api.batch.fs.internal.DefaultInputFile;
import org.sonar.api.batch.sensor.internal.SensorStorage;
import org.sonar.api.component.Component;
import org.sonar.api.resources.Qualifiers;
import org.sonar.api.source.Highlightable;
import org.sonar.batch.index.BatchResource;
import org.sonar.batch.index.ResourceCache;
import org.sonar.core.component.PerspectiveBuilder;
import org.sonar.core.component.ResourceComponent;

import javax.annotation.CheckForNull;

import java.util.Set;
import org.sonar.batch.deprecated.perspectives.PerspectiveBuilder;
import org.sonar.batch.index.BatchComponent;

public class HighlightableBuilder extends PerspectiveBuilder<Highlightable> {

private static final Set<String> SUPPORTED_QUALIFIERS = ImmutableSet.of(Qualifiers.FILE, Qualifiers.UNIT_TEST_FILE);
private final ResourceCache cache;
private final SensorStorage sensorStorage;

public HighlightableBuilder(ResourceCache cache, SensorStorage sensorStorage) {
public HighlightableBuilder(SensorStorage sensorStorage) {
super(Highlightable.class);
this.cache = cache;
this.sensorStorage = sensorStorage;
}

@CheckForNull
@Override
public Highlightable loadPerspective(Class<Highlightable> perspectiveClass, Component component) {
boolean supported = SUPPORTED_QUALIFIERS.contains(component.qualifier());
if (supported && component instanceof ResourceComponent) {
BatchResource batchComponent = cache.get(component.key());
if (batchComponent != null) {
InputFile path = (InputFile) batchComponent.inputPath();
if (path != null) {
return new DefaultHighlightable((DefaultInputFile) path, sensorStorage);
}
}
public Highlightable loadPerspective(Class<Highlightable> perspectiveClass, BatchComponent component) {
if (component.isFile()) {
InputFile path = (InputFile) component.inputPath();
return new DefaultHighlightable((DefaultInputFile) path, sensorStorage);
}
return null;
}

+ 8
- 25
sonar-batch/src/main/java/org/sonar/batch/source/SymbolizableBuilder.java 查看文件

@@ -20,46 +20,29 @@

package org.sonar.batch.source;

import com.google.common.collect.ImmutableSet;
import javax.annotation.CheckForNull;
import org.sonar.api.batch.fs.InputFile;
import org.sonar.api.batch.fs.internal.DefaultInputFile;
import org.sonar.api.component.Component;
import org.sonar.api.resources.Qualifiers;
import org.sonar.api.source.Symbolizable;
import org.sonar.batch.index.BatchResource;
import org.sonar.batch.index.ResourceCache;
import org.sonar.batch.deprecated.perspectives.PerspectiveBuilder;
import org.sonar.batch.index.BatchComponent;
import org.sonar.batch.sensor.DefaultSensorStorage;
import org.sonar.core.component.PerspectiveBuilder;
import org.sonar.core.component.ResourceComponent;

import javax.annotation.CheckForNull;

import java.util.Set;

public class SymbolizableBuilder extends PerspectiveBuilder<Symbolizable> {

private static final Set<String> SUPPORTED_QUALIFIERS = ImmutableSet.of(Qualifiers.FILE, Qualifiers.UNIT_TEST_FILE);
private final ResourceCache cache;
private final DefaultSensorStorage sensorStorage;

public SymbolizableBuilder(ResourceCache cache, DefaultSensorStorage sensorStorage) {
public SymbolizableBuilder(DefaultSensorStorage sensorStorage) {
super(Symbolizable.class);
this.cache = cache;
this.sensorStorage = sensorStorage;
}

@CheckForNull
@Override
public Symbolizable loadPerspective(Class<Symbolizable> perspectiveClass, Component component) {
boolean supported = SUPPORTED_QUALIFIERS.contains(component.qualifier());
if (supported && component instanceof ResourceComponent) {
BatchResource batchComponent = cache.get(component.key());
if (batchComponent != null) {
InputFile path = (InputFile) batchComponent.inputPath();
if (path != null) {
return new DefaultSymbolizable((DefaultInputFile) path, sensorStorage);
}
}
public Symbolizable loadPerspective(Class<Symbolizable> perspectiveClass, BatchComponent component) {
if (component.isFile()) {
InputFile path = (InputFile) component.inputPath();
return new DefaultSymbolizable((DefaultInputFile) path, sensorStorage);
}
return null;
}

sonar-core/src/main/java/org/sonar/core/test/DefaultCoverageBlock.java → sonar-batch/src/main/java/org/sonar/batch/test/DefaultCoverageBlock.java 查看文件

@@ -17,30 +17,38 @@
* 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.core.test;
package org.sonar.batch.test;

import com.tinkerpop.blueprints.Direction;
import java.util.List;
import org.sonar.api.batch.fs.internal.DefaultInputFile;
import org.sonar.api.test.CoverageBlock;
import org.sonar.api.test.TestCase;
import org.sonar.api.test.Testable;
import org.sonar.core.graph.BeanEdge;

import java.util.List;
public class DefaultCoverageBlock implements CoverageBlock {

public class DefaultCoverageBlock extends BeanEdge implements CoverageBlock {
private final TestCase testCase;
private final DefaultInputFile testable;
private final List<Integer> lines;

public DefaultCoverageBlock(TestCase testCase, DefaultInputFile testable, List<Integer> lines) {
this.testCase = testCase;
this.testable = testable;
this.lines = lines;
}

@Override
public TestCase testCase() {
return getVertex(DefaultTestCase.class, Direction.OUT);
return testCase;
}

@Override
public Testable testable() {
return getVertex(DefaultTestable.class, Direction.IN);
return new DefaultTestable(testable);
}

@Override
public List<Integer> lines() {
return (List<Integer>) getProperty("lines");
return lines;
}
}

sonar-core/src/main/java/org/sonar/core/test/DefaultTestCase.java → sonar-batch/src/main/java/org/sonar/batch/test/DefaultTestCase.java 查看文件

@@ -17,52 +17,52 @@
* 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.core.test;
package org.sonar.batch.test;

import com.google.common.base.Predicate;
import com.google.common.collect.Iterables;
import com.tinkerpop.blueprints.Direction;
import com.tinkerpop.blueprints.Edge;
import com.tinkerpop.blueprints.Vertex;
import com.google.common.base.Preconditions;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import javax.annotation.Nullable;
import org.sonar.api.batch.fs.InputFile;
import org.sonar.api.batch.fs.InputFile.Type;
import org.sonar.api.batch.fs.internal.DefaultInputFile;
import org.sonar.api.test.CoverageBlock;
import org.sonar.api.test.MutableTestCase;
import org.sonar.api.test.TestPlan;
import org.sonar.api.test.Testable;
import org.sonar.api.test.exception.CoverageAlreadyExistsException;
import org.sonar.api.test.exception.IllegalDurationException;
import org.sonar.core.graph.BeanVertex;
import org.sonar.core.graph.GraphUtil;

import javax.annotation.Nullable;

import java.util.List;
public class DefaultTestCase implements MutableTestCase {

public class DefaultTestCase extends BeanVertex implements MutableTestCase {
private final DefaultTestPlan testPlan;
private String type;
private Long durationInMs;
private Status status;
private String name;
private String message;
private String stackTrace;
private Map<DefaultInputFile, CoverageBlock> coverageBlocksByTestedFile = new LinkedHashMap<>();

private static final String DURATION = "duration";
private static final String TYPE = "type";
private static final String STATUS = "status";
private static final String NAME = "name";
private static final String MESSAGE = "message";
private static final String STACK_TRACE = "stackTrace";
private static final String COVERS = "covers";
private static final String LINES = "lines";
private static final String TESTCASE = "testcase";
public DefaultTestCase(DefaultTestPlan testPlan) {
this.testPlan = testPlan;
}

@Override
public String type() {
return (String) getProperty(TYPE);
return type;
}

@Override
public MutableTestCase setType(@Nullable String s) {
setProperty(TYPE, s);
this.type = s;
return this;
}

@Override
public Long durationInMs() {
return (Long) getProperty(DURATION);
return durationInMs;
}

@Override
@@ -70,100 +70,95 @@ public class DefaultTestCase extends BeanVertex implements MutableTestCase {
if (l != null && l < 0) {
throw new IllegalDurationException("Test duration must be positive (got: " + l + ")");
}
setProperty(DURATION, l);
this.durationInMs = l;
return this;
}

@Override
public Status status() {
return Status.of((String) getProperty(STATUS));
return status;
}

@Override
public MutableTestCase setStatus(@Nullable Status s) {
setProperty(STATUS, s == null ? null : s.name());
this.status = s;
;
return this;
}

@Override
public String name() {
return (String) getProperty(NAME);
return name;
}

public MutableTestCase setName(String s) {
setProperty(NAME, s);
this.name = s;
return this;
}

@Override
public String message() {
return (String) getProperty(MESSAGE);
return message;
}

@Override
public MutableTestCase setMessage(String s) {
setProperty(MESSAGE, s);
this.message = s;
return this;
}

@Override
public String stackTrace() {
return (String) getProperty(STACK_TRACE);
return stackTrace;
}

@Override
public MutableTestCase setStackTrace(String s) {
setProperty(STACK_TRACE, s);
this.stackTrace = s;
return this;
}

@Override
public MutableTestCase setCoverageBlock(Testable testable, List<Integer> lines) {
if (coverageBlock(testable) != null) {
throw new CoverageAlreadyExistsException("The link between " + name() + " and " + testable.component().key() + " already exists");
DefaultInputFile coveredFile = ((DefaultTestable) testable).inputFile();
return setCoverageBlock(coveredFile, lines);
}

@Override
public MutableTestCase setCoverageBlock(InputFile mainFile, List<Integer> lines) {
Preconditions.checkArgument(mainFile.type() == Type.MAIN, "Test file can only cover a main file");
DefaultInputFile coveredFile = (DefaultInputFile) mainFile;
if (coverageBlocksByTestedFile.containsKey(coveredFile)) {
throw new CoverageAlreadyExistsException("The link between " + name() + " and " + coveredFile.key() + " already exists");
}
beanGraph().getUnderlyingGraph().addEdge(null, element(), ((BeanVertex) testable).element(), COVERS).setProperty(LINES, lines);
coverageBlocksByTestedFile.put(coveredFile, new DefaultCoverageBlock(this, coveredFile, lines));
return this;
}

@Override
public TestPlan testPlan() {
Vertex plan = GraphUtil.singleAdjacent(element(), Direction.IN, TESTCASE);
return beanGraph().wrap(plan, DefaultTestPlan.class);
return testPlan;
}

@Override
public boolean doesCover() {
return edgeCovers().iterator().hasNext();
return !coverageBlocksByTestedFile.isEmpty();
}

@Override
public int countCoveredLines() {
int result = 0;
for (Edge edge : edgeCovers()) {
List<Integer> lines = (List<Integer>) edge.getProperty(LINES);
result = result + lines.size();
}
return result;
throw new UnsupportedOperationException("Not supported since SQ 5.2");
}

@Override
public Iterable<CoverageBlock> coverageBlocks() {
return (Iterable) getEdges(DefaultCoverageBlock.class, Direction.OUT, COVERS);
return coverageBlocksByTestedFile.values();
}

@Override
public CoverageBlock coverageBlock(final Testable testable) {
return Iterables.find(getEdges(DefaultCoverageBlock.class, Direction.OUT, COVERS), new Predicate<CoverageBlock>() {
@Override
public boolean apply(CoverageBlock input) {
return input.testable().component().key().equals(testable.component().key());
}
}, null);
}

private Iterable<Edge> edgeCovers() {
return element().query().labels(COVERS).direction(Direction.OUT).edges();
DefaultInputFile coveredFile = ((DefaultTestable) testable).inputFile();
return coverageBlocksByTestedFile.get(coveredFile);
}

}

sonar-core/src/main/java/org/sonar/core/test/DefaultTestPlan.java → sonar-batch/src/main/java/org/sonar/batch/test/DefaultTestPlan.java 查看文件

@@ -17,30 +17,17 @@
* 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.core.test;
package org.sonar.batch.test;

import com.google.common.collect.Lists;
import com.tinkerpop.blueprints.Direction;
import com.tinkerpop.blueprints.Vertex;
import org.sonar.api.component.Component;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.CheckForNull;
import org.sonar.api.test.MutableTestCase;
import org.sonar.api.test.MutableTestPlan;
import org.sonar.core.component.ComponentVertex;
import org.sonar.core.graph.BeanVertex;
import org.sonar.core.graph.GraphUtil;

import javax.annotation.CheckForNull;

import java.util.List;

public class DefaultTestPlan extends BeanVertex implements MutableTestPlan {
private static final String TESTCASE = "testcase";

@Override
public Component component() {
Vertex component = GraphUtil.singleAdjacent(element(), Direction.IN, "testplan");
return beanGraph().wrap(component, ComponentVertex.class);
}
public class DefaultTestPlan implements MutableTestPlan {
private List<MutableTestCase> testCases = new ArrayList<>();

@Override
@CheckForNull
@@ -56,14 +43,15 @@ public class DefaultTestPlan extends BeanVertex implements MutableTestPlan {

@Override
public MutableTestCase addTestCase(String name) {
DefaultTestCase testCase = beanGraph().createAdjacentVertex(this, DefaultTestCase.class, TESTCASE);
DefaultTestCase testCase = new DefaultTestCase(this);
testCase.setName(name);
testCases.add(testCase);
return testCase;
}

@Override
public Iterable<MutableTestCase> testCases() {
return (Iterable) getVertices(DefaultTestCase.class, Direction.OUT, TESTCASE);
return testCases;
}

}

+ 86
- 0
sonar-batch/src/main/java/org/sonar/batch/test/DefaultTestable.java 查看文件

@@ -0,0 +1,86 @@
/*
* 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.batch.test;

import java.util.List;
import java.util.Map;
import java.util.SortedSet;
import org.sonar.api.batch.fs.internal.DefaultInputFile;
import org.sonar.api.test.CoverageBlock;
import org.sonar.api.test.MutableTestable;
import org.sonar.api.test.TestCase;

public class DefaultTestable implements MutableTestable {

private final DefaultInputFile inputFile;

public DefaultTestable(DefaultInputFile inputFile) {
this.inputFile = inputFile;
}

public DefaultInputFile inputFile() {
return inputFile;
}

@Override
public List<TestCase> testCases() {
throw unsupported();
}

@Override
public TestCase testCaseByName(final String name) {
throw unsupported();
}

@Override
public int countTestCasesOfLine(Integer line) {
throw unsupported();
}

@Override
public Map<Integer, Integer> testCasesByLines() {
throw unsupported();
}

@Override
public List<TestCase> testCasesOfLine(int line) {
throw unsupported();
}

@Override
public SortedSet<Integer> testedLines() {
throw unsupported();
}

@Override
public CoverageBlock coverageBlock(final TestCase testCase) {
throw unsupported();
}

@Override
public Iterable<CoverageBlock> coverageBlocks() {
throw unsupported();
}

private UnsupportedOperationException unsupported() {
return new UnsupportedOperationException("No more available since SQ 5.2");
}

}

+ 54
- 0
sonar-batch/src/main/java/org/sonar/batch/test/TestPlanBuilder.java 查看文件

@@ -0,0 +1,54 @@
/*
* 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.batch.test;

import java.util.HashMap;
import java.util.Map;
import javax.annotation.CheckForNull;
import org.sonar.api.batch.fs.InputFile;
import org.sonar.api.batch.fs.InputFile.Type;
import org.sonar.api.test.MutableTestPlan;
import org.sonar.batch.deprecated.perspectives.PerspectiveBuilder;
import org.sonar.batch.index.BatchComponent;

public class TestPlanBuilder extends PerspectiveBuilder<MutableTestPlan> {

private Map<InputFile, DefaultTestPlan> testPlanByFile = new HashMap<>();

public TestPlanBuilder() {
super(MutableTestPlan.class);
}

@CheckForNull
@Override
public MutableTestPlan loadPerspective(Class<MutableTestPlan> perspectiveClass, BatchComponent component) {
if (component.isFile()) {
InputFile inputFile = (InputFile) component.inputPath();
if (inputFile.type() == Type.TEST) {
if (!testPlanByFile.containsKey(inputFile)) {
testPlanByFile.put(inputFile, new DefaultTestPlan());
}
return testPlanByFile.get(inputFile);
}
}
return null;
}

}

sonar-core/src/main/java/org/sonar/core/test/TestablePerspectiveLoader.java → sonar-batch/src/main/java/org/sonar/batch/test/TestableBuilder.java 查看文件

@@ -17,22 +17,31 @@
* 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.core.test;
package org.sonar.batch.test;

import javax.annotation.CheckForNull;
import org.sonar.api.batch.fs.InputFile;
import org.sonar.api.batch.fs.InputFile.Type;
import org.sonar.api.batch.fs.internal.DefaultInputFile;
import org.sonar.api.test.MutableTestable;
import org.sonar.core.component.GraphPerspectiveLoader;
import org.sonar.core.graph.BeanVertex;
import org.sonar.batch.deprecated.perspectives.PerspectiveBuilder;
import org.sonar.batch.index.BatchComponent;

public class TestablePerspectiveLoader extends GraphPerspectiveLoader<MutableTestable> {
public class TestableBuilder extends PerspectiveBuilder<MutableTestable> {

static final String PERSPECTIVE_KEY = "testable";

public TestablePerspectiveLoader() {
super(PERSPECTIVE_KEY, MutableTestable.class);
public TestableBuilder() {
super(MutableTestable.class);
}

@CheckForNull
@Override
protected Class<? extends BeanVertex> getBeanClass() {
return DefaultTestable.class;
public MutableTestable loadPerspective(Class<MutableTestable> perspectiveClass, BatchComponent component) {
if (component.isFile()) {
InputFile inputFile = (InputFile) component.inputPath();
if (inputFile.type() == Type.MAIN) {
return new DefaultTestable((DefaultInputFile) inputFile);
}
}
return null;
}
}

sonar-core/src/main/java/org/sonar/core/test/package-info.java → sonar-batch/src/main/java/org/sonar/batch/test/package-info.java 查看文件

@@ -19,6 +19,6 @@
*/

@ParametersAreNonnullByDefault
package org.sonar.core.test;
package org.sonar.batch.test;

import javax.annotation.ParametersAreNonnullByDefault;

+ 2
- 2
sonar-batch/src/test/java/org/sonar/batch/cpd/index/IndexFactoryTest.java 查看文件

@@ -27,7 +27,7 @@ import org.sonar.api.config.Settings;
import org.sonar.api.database.DatabaseSession;
import org.sonar.api.resources.Project;
import org.sonar.batch.bootstrap.DefaultAnalysisMode;
import org.sonar.batch.index.ResourceCache;
import org.sonar.batch.index.BatchComponentCache;
import org.sonar.core.duplication.DuplicationDao;

import static org.assertj.core.api.Assertions.assertThat;
@@ -48,7 +48,7 @@ public class IndexFactoryTest {
project = new Project("foo");
settings = new Settings();
analysisMode = mock(DefaultAnalysisMode.class);
factory = new IndexFactory(analysisMode, settings, mock(DuplicationDao.class), mock(DatabaseSession.class), new ResourceCache());
factory = new IndexFactory(analysisMode, settings, mock(DuplicationDao.class), mock(DatabaseSession.class), new BatchComponentCache());
logger = mock(Logger.class);
}


sonar-core/src/test/java/org/sonar/core/component/PerspectiveBuilderTest.java → sonar-batch/src/test/java/org/sonar/batch/deprecated/perspectives/PerspectiveBuilderTest.java 查看文件

@@ -17,11 +17,11 @@
* 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.core.component;
package org.sonar.batch.deprecated.perspectives;

import org.junit.Test;
import org.sonar.api.component.Component;
import org.sonar.api.component.Perspective;
import org.sonar.batch.index.BatchComponent;

import static org.assertj.core.api.Assertions.assertThat;

@@ -30,7 +30,7 @@ public class PerspectiveBuilderTest {
public void testGetPerspectiveClass() throws Exception {
PerspectiveBuilder<FakePerspective> builder = new PerspectiveBuilder<FakePerspective>(FakePerspective.class) {
@Override
public FakePerspective loadPerspective(Class<FakePerspective> perspectiveClass, Component component) {
public FakePerspective loadPerspective(Class<FakePerspective> perspectiveClass, BatchComponent component) {
return null;
}
};

sonar-batch/src/test/java/org/sonar/batch/index/ResourceCacheTest.java → sonar-batch/src/test/java/org/sonar/batch/index/BatchComponentCacheTest.java 查看文件

@@ -26,10 +26,10 @@ import org.sonar.api.resources.Resource;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.Assert.fail;

public class ResourceCacheTest {
public class BatchComponentCacheTest {
@Test
public void should_cache_resource() {
ResourceCache cache = new ResourceCache();
BatchComponentCache cache = new BatchComponentCache();
String componentKey = "struts:src/org/struts/Action.java";
Resource resource = File.create("org/struts/Action.java").setEffectiveKey(componentKey);
cache.add(resource, null);
@@ -40,7 +40,7 @@ public class ResourceCacheTest {

@Test
public void should_fail_if_missing_component_key() {
ResourceCache cache = new ResourceCache();
BatchComponentCache cache = new BatchComponentCache();
Resource resource = File.create("org/struts/Action.java").setEffectiveKey(null);
try {
cache.add(resource, null);

+ 1
- 1
sonar-batch/src/test/java/org/sonar/batch/index/DefaultIndexTest.java 查看文件

@@ -68,7 +68,7 @@ public class DefaultIndexTest {
ruleFinder = mock(RuleFinder.class);

DefaultProjectTree projectTree = mock(DefaultProjectTree.class);
ResourceCache resourceCache = new ResourceCache();
BatchComponentCache resourceCache = new BatchComponentCache();
index = new DefaultIndex(resourceCache, projectTree, metricFinder, mock(MeasureCache.class));

baseDir = temp.newFolder();

+ 7
- 10
sonar-batch/src/test/java/org/sonar/batch/index/ResourcePersisterTest.java 查看文件

@@ -19,6 +19,10 @@
*/
package org.sonar.batch.index;

import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import javax.persistence.Query;
import org.apache.ibatis.session.SqlSession;
import org.junit.Before;
import org.junit.Rule;
@@ -38,16 +42,9 @@ import org.sonar.api.security.ResourcePermissions;
import org.sonar.batch.DefaultProjectTree;
import org.sonar.batch.scan.measure.MeasureCache;
import org.sonar.core.component.ComponentDto;
import org.sonar.core.component.ScanGraph;
import org.sonar.core.component.db.ComponentMapper;
import org.sonar.jpa.test.AbstractDbUnitTestCase;

import javax.persistence.Query;

import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;

import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
@@ -64,7 +61,7 @@ public class ResourcePersisterTest extends AbstractDbUnitTestCase {
public TemporaryFolder temp = new TemporaryFolder();

private Project singleProject, singleCopyProject, multiModuleProject, moduleA, moduleB, moduleB1, existingProject;
private ResourceCache resourceCache;
private BatchComponentCache resourceCache;

private ResourcePersister persister;

@@ -74,7 +71,7 @@ public class ResourcePersisterTest extends AbstractDbUnitTestCase {

@Before
public void before() throws ParseException {
resourceCache = new ResourceCache();
resourceCache = new BatchComponentCache();

SimpleDateFormat format = new SimpleDateFormat("dd/MM/yyyy");
singleProject = newProject("foo", "java");
@@ -106,7 +103,7 @@ public class ResourcePersisterTest extends AbstractDbUnitTestCase {

projectTree = mock(DefaultProjectTree.class);
permissions = mock(ResourcePermissions.class);
persister = new ResourcePersister(getSession(), permissions, resourceCache, mock(ScanGraph.class));
persister = new ResourcePersister(getSession(), permissions, resourceCache);
}

@Test

+ 4
- 5
sonar-batch/src/test/java/org/sonar/batch/issue/DefaultIssuableTest.java 查看文件

@@ -19,14 +19,13 @@
*/
package org.sonar.batch.issue;

import java.util.Arrays;
import java.util.List;
import org.junit.Test;
import org.sonar.api.component.Component;
import org.sonar.api.issue.Issue;
import org.sonar.api.issue.internal.DefaultIssue;
import org.sonar.api.resources.Project;

import java.util.Arrays;
import java.util.List;
import org.sonar.batch.index.BatchComponent;

import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
@@ -37,7 +36,7 @@ public class DefaultIssuableTest {
ModuleIssues moduleIssues = mock(ModuleIssues.class);
IssueCache cache = mock(IssueCache.class);
Project project = mock(Project.class);
Component component = mock(Component.class);
BatchComponent component = mock(BatchComponent.class);

@Test
public void test_unresolved_issues() throws Exception {

+ 3
- 6
sonar-batch/src/test/java/org/sonar/batch/issue/IssuableFactoryTest.java 查看文件

@@ -21,12 +21,11 @@ package org.sonar.batch.issue;

import org.junit.Test;
import org.mockito.Mockito;
import org.sonar.api.component.Component;
import org.sonar.api.issue.Issuable;
import org.sonar.api.resources.File;
import org.sonar.api.resources.Project;
import org.sonar.batch.DefaultProjectTree;
import org.sonar.core.component.ResourceComponent;
import org.sonar.batch.index.BatchComponent;

import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
@@ -40,22 +39,20 @@ public class IssuableFactoryTest {
@Test
public void file_should_be_issuable() {
IssuableFactory factory = new IssuableFactory(moduleIssues, cache, projectTree);
Component component = new ResourceComponent(File.create("foo/bar.c").setEffectiveKey("foo/bar.c"));
BatchComponent component = new BatchComponent(1, File.create("foo/bar.c").setEffectiveKey("foo/bar.c"), null);
Issuable issuable = factory.loadPerspective(Issuable.class, component);

assertThat(issuable).isNotNull();
assertThat(issuable.component()).isSameAs(component);
assertThat(issuable.issues()).isEmpty();
}

@Test
public void project_should_be_issuable() {
IssuableFactory factory = new IssuableFactory(moduleIssues, cache, projectTree);
Component component = new ResourceComponent(new Project("Foo").setEffectiveKey("foo"));
BatchComponent component = new BatchComponent(1, new Project("Foo").setEffectiveKey("foo"), null);
Issuable issuable = factory.loadPerspective(Issuable.class, component);

assertThat(issuable).isNotNull();
assertThat(issuable.component()).isSameAs(component);
assertThat(issuable.issues()).isEmpty();
}
}

+ 3
- 3
sonar-batch/src/test/java/org/sonar/batch/postjob/DefaultPostJobContextTest.java 查看文件

@@ -28,7 +28,7 @@ import org.sonar.api.batch.rule.Severity;
import org.sonar.api.config.Settings;
import org.sonar.api.issue.internal.DefaultIssue;
import org.sonar.api.resources.File;
import org.sonar.batch.index.ResourceCache;
import org.sonar.batch.index.BatchComponentCache;
import org.sonar.batch.issue.IssueCache;

import java.util.Arrays;
@@ -40,7 +40,7 @@ import static org.mockito.Mockito.when;
public class DefaultPostJobContextTest {

private IssueCache issueCache;
private ResourceCache resourceCache;
private BatchComponentCache resourceCache;
private AnalysisMode analysisMode;
private DefaultPostJobContext context;
private Settings settings;
@@ -48,7 +48,7 @@ public class DefaultPostJobContextTest {
@Before
public void prepare() {
issueCache = mock(IssueCache.class);
resourceCache = new ResourceCache();
resourceCache = new BatchComponentCache();
analysisMode = mock(AnalysisMode.class);
settings = new Settings();
context = new DefaultPostJobContext(settings, analysisMode, issueCache, resourceCache);

+ 3
- 3
sonar-batch/src/test/java/org/sonar/batch/qualitygate/QualityGateVerifierTest.java 查看文件

@@ -39,7 +39,7 @@ import org.sonar.api.resources.Resource;
import org.sonar.api.test.IsMeasure;
import org.sonar.api.utils.Duration;
import org.sonar.api.utils.Durations;
import org.sonar.batch.index.ResourceCache;
import org.sonar.batch.index.BatchComponentCache;
import org.sonar.core.qualitygate.db.QualityGateConditionDto;
import org.sonar.core.timemachine.Periods;

@@ -70,7 +70,7 @@ public class QualityGateVerifierTest {
Periods periods;
I18n i18n;
Durations durations;
private ResourceCache resourceCache;
private BatchComponentCache resourceCache;

@Before
public void before() {
@@ -94,7 +94,7 @@ public class QualityGateVerifierTest {

project = new Project("foo");

resourceCache = new ResourceCache();
resourceCache = new BatchComponentCache();
resourceCache.add(project, null).setSnapshot(snapshot);

verifier = new QualityGateVerifier(qualityGate, resourceCache, periods, i18n, durations);

+ 3
- 3
sonar-batch/src/test/java/org/sonar/batch/report/ComponentsPublisherTest.java 查看文件

@@ -32,7 +32,7 @@ import org.sonar.api.resources.Directory;
import org.sonar.api.resources.Java;
import org.sonar.api.resources.Project;
import org.sonar.api.utils.DateUtils;
import org.sonar.batch.index.ResourceCache;
import org.sonar.batch.index.BatchComponentCache;
import org.sonar.batch.protocol.Constants.ComponentLinkType;
import org.sonar.batch.protocol.Constants.EventCategory;
import org.sonar.batch.protocol.output.BatchReport.Component;
@@ -54,7 +54,7 @@ public class ComponentsPublisherTest {
public TemporaryFolder temp = new TemporaryFolder();

private ProjectReactor reactor;
private ResourceCache resourceCache;
private BatchComponentCache resourceCache;
private ComponentsPublisher publisher;
private EventCache eventCache;

@@ -62,7 +62,7 @@ public class ComponentsPublisherTest {
public void prepare() {
reactor = new ProjectReactor(ProjectDefinition.create().setKey("foo"));
reactor.getRoot().properties().put(CoreProperties.PROJECT_VERSION_PROPERTY, "1.0");
resourceCache = new ResourceCache();
resourceCache = new BatchComponentCache();
eventCache = mock(EventCache.class);
publisher = new ComponentsPublisher(reactor, resourceCache, eventCache);
}

+ 2
- 2
sonar-batch/src/test/java/org/sonar/batch/report/CoveragePublisherTest.java 查看文件

@@ -29,7 +29,7 @@ import org.sonar.api.database.model.Snapshot;
import org.sonar.api.measures.CoreMetrics;
import org.sonar.api.measures.Measure;
import org.sonar.api.resources.Project;
import org.sonar.batch.index.ResourceCache;
import org.sonar.batch.index.BatchComponentCache;
import org.sonar.batch.protocol.output.BatchReport;
import org.sonar.batch.protocol.output.BatchReport.Coverage;
import org.sonar.batch.protocol.output.BatchReportReader;
@@ -60,7 +60,7 @@ public class CoveragePublisherTest {
@Before
public void prepare() {
Project p = new Project("foo").setAnalysisDate(new Date(1234567L));
ResourceCache resourceCache = new ResourceCache();
BatchComponentCache resourceCache = new BatchComponentCache();
sampleFile = org.sonar.api.resources.File.create("src/Foo.php").setEffectiveKey("foo:src/Foo.php");
resourceCache.add(p, null).setSnapshot(new Snapshot().setId(2));
resourceCache.add(sampleFile, null).setInputPath(new DefaultInputFile("foo", "src/Foo.php").setLines(5));

+ 2
- 2
sonar-batch/src/test/java/org/sonar/batch/report/DuplicationsPublisherTest.java 查看文件

@@ -27,7 +27,7 @@ import org.sonar.api.batch.sensor.duplication.Duplication;
import org.sonar.api.batch.sensor.duplication.internal.DefaultDuplication;
import org.sonar.api.resources.Project;
import org.sonar.batch.duplication.DuplicationCache;
import org.sonar.batch.index.ResourceCache;
import org.sonar.batch.index.BatchComponentCache;
import org.sonar.batch.protocol.output.BatchReportReader;
import org.sonar.batch.protocol.output.BatchReportWriter;

@@ -51,7 +51,7 @@ public class DuplicationsPublisherTest {

@Before
public void prepare() {
ResourceCache resourceCache = new ResourceCache();
BatchComponentCache resourceCache = new BatchComponentCache();
Project p = new Project("foo");
resourceCache.add(p, null);
org.sonar.api.resources.Resource sampleFile = org.sonar.api.resources.File.create("src/Foo.php").setEffectiveKey("foo:src/Foo.php");

+ 2
- 2
sonar-batch/src/test/java/org/sonar/batch/report/IssuesPublisherTest.java 查看文件

@@ -31,7 +31,7 @@ import org.sonar.api.issue.internal.FieldDiffs;
import org.sonar.api.resources.Project;
import org.sonar.api.rule.RuleKey;
import org.sonar.api.utils.Duration;
import org.sonar.batch.index.ResourceCache;
import org.sonar.batch.index.BatchComponentCache;
import org.sonar.batch.issue.IssueCache;
import org.sonar.batch.protocol.output.BatchReport.Metadata;
import org.sonar.batch.protocol.output.BatchReportReader;
@@ -59,7 +59,7 @@ public class IssuesPublisherTest {
public void prepare() {
ProjectDefinition root = ProjectDefinition.create().setKey("foo");
Project p = new Project("foo").setAnalysisDate(new Date(1234567L));
ResourceCache resourceCache = new ResourceCache();
BatchComponentCache resourceCache = new BatchComponentCache();
org.sonar.api.resources.Resource sampleFile = org.sonar.api.resources.File.create("src/Foo.php").setEffectiveKey("foo:src/Foo.php");
resourceCache.add(p, null).setSnapshot(new Snapshot().setId(2));
resourceCache.add(sampleFile, null);

+ 2
- 2
sonar-batch/src/test/java/org/sonar/batch/report/MeasuresPublisherTest.java 查看文件

@@ -36,7 +36,7 @@ import org.sonar.api.resources.Resource;
import org.sonar.api.rule.RuleKey;
import org.sonar.api.rules.RulePriority;
import org.sonar.api.technicaldebt.batch.Characteristic;
import org.sonar.batch.index.ResourceCache;
import org.sonar.batch.index.BatchComponentCache;
import org.sonar.batch.protocol.output.BatchReportReader;
import org.sonar.batch.protocol.output.BatchReportWriter;
import org.sonar.batch.scan.measure.MeasureCache;
@@ -66,7 +66,7 @@ public class MeasuresPublisherTest {
@Before
public void prepare() {
Project p = new Project("foo").setAnalysisDate(new Date(1234567L));
ResourceCache resourceCache = new ResourceCache();
BatchComponentCache resourceCache = new BatchComponentCache();
sampleFile = org.sonar.api.resources.File.create("src/Foo.php").setEffectiveKey("foo:src/Foo.php");
resourceCache.add(p, null).setSnapshot(new Snapshot().setId(2));
resourceCache.add(sampleFile, null);

+ 2
- 2
sonar-batch/src/test/java/org/sonar/batch/report/ReportPublisherTest.java 查看文件

@@ -30,7 +30,7 @@ import org.sonar.api.platform.Server;
import org.sonar.api.utils.TempFolder;
import org.sonar.batch.bootstrap.DefaultAnalysisMode;
import org.sonar.batch.bootstrap.ServerClient;
import org.sonar.batch.index.ResourceCache;
import org.sonar.batch.index.BatchComponentCache;
import org.sonar.jpa.test.AbstractDbUnitTestCase;

import static org.mockito.Mockito.mock;
@@ -41,7 +41,7 @@ public class ReportPublisherTest extends AbstractDbUnitTestCase {

private DefaultAnalysisMode mode;

ResourceCache resourceCache = mock(ResourceCache.class);
BatchComponentCache resourceCache = mock(BatchComponentCache.class);

private ProjectReactor reactor;


+ 2
- 2
sonar-batch/src/test/java/org/sonar/batch/report/SourcePublisherTest.java 查看文件

@@ -28,7 +28,7 @@ import org.sonar.api.batch.fs.internal.DefaultInputFile;
import org.sonar.api.database.model.Snapshot;
import org.sonar.api.resources.Project;
import org.sonar.api.resources.Qualifiers;
import org.sonar.batch.index.ResourceCache;
import org.sonar.batch.index.BatchComponentCache;
import org.sonar.batch.protocol.output.BatchReportWriter;

import java.io.File;
@@ -54,7 +54,7 @@ public class SourcePublisherTest {
@Before
public void prepare() throws IOException {
Project p = new Project("foo").setAnalysisDate(new Date(1234567L));
ResourceCache resourceCache = new ResourceCache();
BatchComponentCache resourceCache = new BatchComponentCache();
sampleFile = org.sonar.api.resources.File.create("src/Foo.php");
sampleFile.setEffectiveKey("foo:src/Foo.php");
resourceCache.add(p, null).setSnapshot(new Snapshot().setId(2));

+ 4
- 4
sonar-batch/src/test/java/org/sonar/batch/scan/filesystem/ComponentIndexerTest.java 查看文件

@@ -35,8 +35,8 @@ import org.sonar.api.resources.Languages;
import org.sonar.api.resources.Project;
import org.sonar.api.resources.Qualifiers;
import org.sonar.api.resources.Resource;
import org.sonar.batch.index.BatchResource;
import org.sonar.batch.index.ResourceCache;
import org.sonar.batch.index.BatchComponent;
import org.sonar.batch.index.BatchComponentCache;

import java.io.File;
import java.io.IOException;
@@ -100,8 +100,8 @@ public class ComponentIndexerTest {
}

private ComponentIndexer createIndexer(Languages languages) {
ResourceCache resourceCache = mock(ResourceCache.class);
when(resourceCache.get(any(Resource.class))).thenReturn(new BatchResource(1, org.sonar.api.resources.File.create("foo.php"), null));
BatchComponentCache resourceCache = mock(BatchComponentCache.class);
when(resourceCache.get(any(Resource.class))).thenReturn(new BatchComponent(1, org.sonar.api.resources.File.create("foo.php"), null));
return new ComponentIndexer(project, languages, sonarIndex, resourceCache);
}


+ 3
- 3
sonar-batch/src/test/java/org/sonar/batch/sensor/DefaultSensorStorageTest.java 查看文件

@@ -46,7 +46,7 @@ import org.sonar.api.resources.Resource;
import org.sonar.api.rule.RuleKey;
import org.sonar.batch.duplication.DuplicationCache;
import org.sonar.batch.index.DefaultIndex;
import org.sonar.batch.index.ResourceCache;
import org.sonar.batch.index.BatchComponentCache;
import org.sonar.batch.issue.ModuleIssues;
import org.sonar.batch.report.ReportPublisher;
import org.sonar.batch.sensor.coverage.CoverageExclusions;
@@ -74,7 +74,7 @@ public class DefaultSensorStorageTest {
private Project project;
private DefaultIndex sonarIndex;

private ResourceCache resourceCache;
private BatchComponentCache resourceCache;

@Before
public void prepare() throws Exception {
@@ -89,7 +89,7 @@ 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();
resourceCache = new BatchComponentCache();
sensorStorage = new DefaultSensorStorage(metricFinder, project,
moduleIssues, settings, fs, activeRules, mock(DuplicationCache.class), sonarIndex, coverageExclusions, resourceCache, mock(ReportPublisher.class));
}

+ 5
- 13
sonar-batch/src/test/java/org/sonar/batch/source/HighlightableBuilderTest.java 查看文件

@@ -20,42 +20,34 @@
package org.sonar.batch.source;

import org.junit.Test;
import org.sonar.api.batch.fs.internal.DefaultInputFile;
import org.sonar.api.batch.sensor.internal.SensorStorage;
import org.sonar.api.component.Component;
import org.sonar.api.resources.File;
import org.sonar.api.resources.Project;
import org.sonar.api.resources.Resource;
import org.sonar.api.source.Highlightable;
import org.sonar.batch.index.BatchResource;
import org.sonar.batch.index.ResourceCache;
import org.sonar.core.component.ResourceComponent;
import org.sonar.batch.index.BatchComponent;

import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

public class HighlightableBuilderTest {

@Test
public void should_load_default_perspective() {
Resource file = File.create("foo.c").setEffectiveKey("myproject:path/to/foo.c");
Component component = new ResourceComponent(file);
BatchComponent component = new BatchComponent(1, file, null);

ResourceCache resourceCache = mock(ResourceCache.class);
when(resourceCache.get(file.getEffectiveKey())).thenReturn(new BatchResource(1, file, null).setInputPath(new DefaultInputFile("myproject", "path/to/foo.c")));
HighlightableBuilder builder = new HighlightableBuilder(resourceCache, mock(SensorStorage.class));
HighlightableBuilder builder = new HighlightableBuilder(mock(SensorStorage.class));
Highlightable perspective = builder.loadPerspective(Highlightable.class, component);

assertThat(perspective).isNotNull().isInstanceOf(DefaultHighlightable.class);
assertThat(perspective.component().key()).isEqualTo(component.key());
}

@Test
public void project_should_not_be_highlightable() {
Component component = new ResourceComponent(new Project("struts").setEffectiveKey("org.struts"));
BatchComponent component = new BatchComponent(1, new Project("struts").setEffectiveKey("org.struts"), null);

HighlightableBuilder builder = new HighlightableBuilder(mock(ResourceCache.class), mock(SensorStorage.class));
HighlightableBuilder builder = new HighlightableBuilder(mock(SensorStorage.class));
Highlightable perspective = builder.loadPerspective(Highlightable.class, component);

assertThat(perspective).isNull();

+ 5
- 14
sonar-batch/src/test/java/org/sonar/batch/source/SymbolizableBuilderTest.java 查看文件

@@ -21,44 +21,35 @@
package org.sonar.batch.source;

import org.junit.Test;
import org.sonar.api.batch.fs.internal.DefaultInputFile;
import org.sonar.api.component.Component;
import org.sonar.api.component.Perspective;
import org.sonar.api.resources.File;
import org.sonar.api.resources.Project;
import org.sonar.api.resources.Resource;
import org.sonar.api.source.Symbolizable;
import org.sonar.batch.index.BatchResource;
import org.sonar.batch.index.ResourceCache;
import org.sonar.batch.index.BatchComponent;
import org.sonar.batch.sensor.DefaultSensorStorage;
import org.sonar.core.component.ResourceComponent;

import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

public class SymbolizableBuilderTest {

@Test
public void should_load_perspective() {
Resource file = File.create("foo.c").setEffectiveKey("myproject:path/to/foo.c");
Component component = new ResourceComponent(file);
BatchComponent component = new BatchComponent(1, file, null);

ResourceCache resourceCache = mock(ResourceCache.class);
when(resourceCache.get(file.getEffectiveKey())).thenReturn(new BatchResource(1, file, null).setInputPath(new DefaultInputFile("myproject", "path/to/foo.c")));

SymbolizableBuilder perspectiveBuilder = new SymbolizableBuilder(resourceCache, mock(DefaultSensorStorage.class));
SymbolizableBuilder perspectiveBuilder = new SymbolizableBuilder(mock(DefaultSensorStorage.class));
Perspective perspective = perspectiveBuilder.loadPerspective(Symbolizable.class, component);

assertThat(perspective).isInstanceOf(Symbolizable.class);
assertThat(perspective.component().key()).isEqualTo(component.key());
}

@Test
public void project_should_not_be_highlightable() {
Component component = new ResourceComponent(new Project("struts").setEffectiveKey("org.struts"));
BatchComponent component = new BatchComponent(1, new Project("struts").setEffectiveKey("org.struts"), null);

SymbolizableBuilder builder = new SymbolizableBuilder(mock(ResourceCache.class), mock(DefaultSensorStorage.class));
SymbolizableBuilder builder = new SymbolizableBuilder(mock(DefaultSensorStorage.class));
Perspective perspective = builder.loadPerspective(Symbolizable.class, component);

assertThat(perspective).isNull();

+ 0
- 22
sonar-core/pom.xml 查看文件

@@ -86,28 +86,6 @@
<groupId>com.googlecode.json-simple</groupId>
<artifactId>json-simple</artifactId>
</dependency>
<dependency>
<groupId>com.tinkerpop.blueprints</groupId>
<artifactId>blueprints-core</artifactId>
<exclusions>
<exclusion>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-core-asl</artifactId>
</exclusion>
<exclusion>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
</exclusion>
<exclusion>
<groupId>org.codehaus.jettison</groupId>
<artifactId>jettison</artifactId>
</exclusion>
<exclusion>
<groupId>colt</groupId>
<artifactId>colt</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.codehaus.sonar</groupId>
<artifactId>sonar-graph</artifactId>

+ 0
- 63
sonar-core/src/main/java/org/sonar/core/component/ComponentQuery.java 查看文件

@@ -1,63 +0,0 @@
/*
* 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.core.component;

import com.google.common.collect.Sets;

import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;

/**
* @since 4.3
*/
public class ComponentQuery {

private Collection<Long> ids;

private Collection<String> qualifiers;

private ComponentQuery() {
this.ids = Sets.newHashSet();
this.qualifiers = Sets.newHashSet();
}

public static ComponentQuery create() {
return new ComponentQuery();
}

public Collection<Long> ids() {
return Collections.unmodifiableCollection(ids);
}

public ComponentQuery addIds(Long... ids) {
this.ids.addAll(Arrays.asList(ids));
return this;
}

public Collection<String> qualifiers() {
return Collections.unmodifiableCollection(qualifiers);
}

public ComponentQuery addQualifiers(String... qualifiers) {
this.qualifiers.addAll(Arrays.asList(qualifiers));
return this;
}
}

+ 0
- 64
sonar-core/src/main/java/org/sonar/core/component/ComponentVertex.java 查看文件

@@ -1,64 +0,0 @@
/*
* 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.core.component;

import org.sonar.api.component.Component;
import org.sonar.core.graph.BeanVertex;

public class ComponentVertex extends BeanVertex implements Component {

@Override
public String key() {
return (String) getProperty("key");
}

@Override
public String path() {
return (String) getProperty("path");
}

@Override
public String name() {
return (String) getProperty("name");
}

@Override
public String longName() {
return (String) getProperty("longName");
}

@Override
public String qualifier() {
return (String) getProperty("qualifier");
}

void copyFrom(Component component) {
setProperty("key", component.key());
setProperty("path", component.path());
setProperty("name", component.name());
setProperty("longName", component.longName());
setProperty("qualifier", component.qualifier());
}

@Override
public String toString() {
return key();
}
}

+ 0
- 82
sonar-core/src/main/java/org/sonar/core/component/GraphPerspectiveBuilder.java 查看文件

@@ -1,82 +0,0 @@
/*
* 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.core.component;

import org.sonar.api.component.Component;
import org.sonar.api.component.Perspective;
import org.sonar.core.graph.EdgePath;

public abstract class GraphPerspectiveBuilder<T extends Perspective> extends PerspectiveBuilder<T> {

protected final ScanGraph graph;
protected final EdgePath path;
protected final GraphPerspectiveLoader<T> perspectiveLoader;

protected GraphPerspectiveBuilder(ScanGraph graph, Class<T> perspectiveClass, EdgePath path,
GraphPerspectiveLoader<T> perspectiveLoader) {
super(perspectiveClass);
this.graph = graph;
this.path = path;
this.perspectiveLoader = perspectiveLoader;
}

public T create(ComponentVertex component) {
return (T) component.beanGraph().createAdjacentVertex(component, perspectiveLoader.getBeanClass(),
perspectiveLoader.getPerspectiveKey());
}

public EdgePath path() {
return path;
}

public GraphPerspectiveLoader<T> getPerspectiveLoader() {
return perspectiveLoader;
}

@Override
public T loadPerspective(Class<T> perspectiveClass, Component component) {
ComponentVertex vertex;
if (component instanceof ComponentVertex) {
vertex = (ComponentVertex) component;
} else {
vertex = graph.getComponent(component.key());
}

if (vertex != null) {
T perspective = perspectiveLoader.load(vertex);
if (perspective == null) {
perspective = create(vertex);
}
return perspective;
}
return null;
}

public T get(Class<T> perspectiveClass, String componentKey) {
ComponentVertex vertex = graph.getComponent(componentKey);
if (vertex != null) {
T perspective = perspectiveLoader.load(vertex);
if (perspective != null) {
return perspective;
}
}
return null;
}
}

+ 0
- 55
sonar-core/src/main/java/org/sonar/core/component/GraphPerspectiveLoader.java 查看文件

@@ -1,55 +0,0 @@
/*
* 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.core.component;

import com.tinkerpop.blueprints.Direction;
import com.tinkerpop.blueprints.Vertex;
import org.sonar.api.component.Perspective;
import org.sonar.core.graph.BeanVertex;
import org.sonar.core.graph.GraphUtil;

public abstract class GraphPerspectiveLoader<T extends Perspective> {

protected final String perspectiveKey;
protected final Class<T> perspectiveClass;

protected GraphPerspectiveLoader(String perspectiveKey, Class<T> perspectiveClass) {
this.perspectiveKey = perspectiveKey;
this.perspectiveClass = perspectiveClass;
}

public T load(ComponentVertex component) {
Vertex perspectiveVertex = GraphUtil.singleAdjacent(component.element(), Direction.OUT, getPerspectiveKey());
if (perspectiveVertex != null) {
return (T) component.beanGraph().wrap(perspectiveVertex, getBeanClass());
}
return null;
}

public String getPerspectiveKey() {
return perspectiveKey;
}

protected Class<T> getPerspectiveClass() {
return perspectiveClass;
}

protected abstract Class<? extends BeanVertex> getBeanClass();
}

+ 0
- 79
sonar-core/src/main/java/org/sonar/core/component/ResourceComponent.java 查看文件

@@ -1,79 +0,0 @@
/*
* 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.core.component;

import com.google.common.base.Strings;
import org.sonar.api.component.Component;
import org.sonar.api.resources.Resource;

public class ResourceComponent implements Component {
private String key;
private String path;
private String name;
private String longName;
private String qualifier;
private String scope;

public ResourceComponent(Resource resource) {
this.key = resource.getEffectiveKey();
this.path = resource.getPath();
if (Strings.isNullOrEmpty(key)) {
throw new IllegalArgumentException("Missing component key");
}
this.name = resource.getName();
this.longName = resource.getLongName();
this.qualifier = resource.getQualifier();
this.scope = resource.getScope();
}

@Override
public String key() {
return key;
}

@Override
public String path() {
return path;
}

@Override
public String name() {
return name;
}

@Override
public String longName() {
return longName;
}

@Override
public String qualifier() {
return qualifier;
}

public String scope() {
return scope;
}

@Override
public String toString() {
return key;
}
}

+ 0
- 82
sonar-core/src/main/java/org/sonar/core/component/ScanGraph.java 查看文件

@@ -1,82 +0,0 @@
/*
* 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.core.component;

import com.tinkerpop.blueprints.Direction;
import com.tinkerpop.blueprints.Graph;
import com.tinkerpop.blueprints.Vertex;
import com.tinkerpop.blueprints.impls.tg.TinkerGraph;
import org.sonar.api.batch.BatchSide;
import org.sonar.api.component.Component;
import org.sonar.api.resources.Resource;
import org.sonar.core.graph.BeanGraph;
import org.sonar.core.graph.BeanIterable;
import org.sonar.core.graph.GraphUtil;

@BatchSide
public class ScanGraph extends BeanGraph {

private static final String COMPONENT = "component";
private final Vertex componentsRoot;

private ScanGraph(Graph graph) {
super(graph);
componentsRoot = graph.addVertex(null);
componentsRoot.setProperty("root", "components");
}

public static ScanGraph create() {
TinkerGraph graph = new TinkerGraph();
graph.createKeyIndex("key", Vertex.class);
return new ScanGraph(graph);
}

public ComponentVertex wrapComponent(Vertex vertex) {
return wrap(vertex, ComponentVertex.class);
}

public ComponentVertex getComponent(String key) {
Vertex vertex = GraphUtil.single(getUnderlyingGraph().getVertices("key", key));
return vertex != null ? wrapComponent(vertex) : null;
}

public ComponentVertex addComponent(Resource resource) {
return addComponent(new ResourceComponent(resource));
}

public void completeComponent(String key, long resourceId, long snapshotId) {
ComponentVertex component = getComponent(key);
component.setProperty("sid", snapshotId);
component.setProperty("rid", resourceId);
}

public Iterable<ComponentVertex> getComponents() {
Iterable<Vertex> componentVertices = componentsRoot.getVertices(Direction.OUT, COMPONENT);
return new BeanIterable<>(this, ComponentVertex.class, componentVertices);
}

public ComponentVertex addComponent(Component component) {
Vertex vertex = getUnderlyingGraph().addVertex(null);
getUnderlyingGraph().addEdge(null, componentsRoot, vertex, COMPONENT);
ComponentVertex wrapper = wrap(vertex, ComponentVertex.class);
wrapper.copyFrom(component);
return wrapper;
}
}

+ 0
- 37
sonar-core/src/main/java/org/sonar/core/component/SnapshotGraph.java 查看文件

@@ -1,37 +0,0 @@
/*
* 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.core.component;

import com.tinkerpop.blueprints.Graph;
import com.tinkerpop.blueprints.Vertex;
import org.sonar.core.graph.BeanGraph;

class SnapshotGraph extends BeanGraph {
private final Vertex componentRoot;

SnapshotGraph(Graph graph, String rootVertexId) {
super(graph);
componentRoot = graph.getVertex(rootVertexId);
}

Vertex getComponentRoot() {
return componentRoot;
}
}

+ 0
- 31
sonar-core/src/main/java/org/sonar/core/graph/BeanEdge.java 查看文件

@@ -1,31 +0,0 @@
/*
* 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.core.graph;

import com.tinkerpop.blueprints.Direction;
import com.tinkerpop.blueprints.Edge;

public abstract class BeanEdge extends BeanElement<Edge, BeanEdge> {

protected final <T extends BeanVertex> T getVertex(Class<T> vertexClass, Direction direction) {
return beanGraph().wrap(element().getVertex(direction), vertexClass);
}

}

+ 0
- 68
sonar-core/src/main/java/org/sonar/core/graph/BeanElement.java 查看文件

@@ -1,68 +0,0 @@
/*
* 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.core.graph;

import com.tinkerpop.blueprints.Element;

import javax.annotation.Nullable;

import java.util.Set;

public abstract class BeanElement<T extends Element, C extends BeanElement<T, C>> {
private T element;
private BeanGraph graph;

public T element() {
return element;
}

void setElement(T element) {
this.element = element;
}

public BeanGraph beanGraph() {
return graph;
}

void setBeanGraph(BeanGraph graph) {
this.graph = graph;
}

protected final Object getProperty(String key) {
return element.getProperty(key);
}

protected final Set<String> getPropertyKeys() {
return element.getPropertyKeys();
}

public final C setProperty(String key, @Nullable Object value) {
if (value != null) {
element.setProperty(key, value);
} else {
element.removeProperty(key);
}
return (C) this;
}

protected final Object removeProperty(String key) {
return element.removeProperty(key);
}
}

+ 0
- 88
sonar-core/src/main/java/org/sonar/core/graph/BeanElements.java 查看文件

@@ -1,88 +0,0 @@
/*
* 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.core.graph;

import com.google.common.collect.MapMaker;
import com.tinkerpop.blueprints.Element;

import java.util.Map;

class BeanElements {

private final Map<ElementKey, BeanElement> cache;

BeanElements() {
cache = new MapMaker().weakValues().makeMap();
}

<T extends BeanElement> T wrap(Element element, Class<T> beanClass, BeanGraph graph) {
ElementKey key = new ElementKey(element, beanClass);
T bean = (T) cache.get(key);
if (bean == null) {
try {
bean = (T) key.beanClass.newInstance();
bean.setElement(key.element);
bean.setBeanGraph(graph);
cache.put(key, bean);
} catch (InstantiationException e) {
throw new IllegalStateException("Class has no default constructor: " + beanClass.getName(), e);
} catch (IllegalAccessException e) {
throw new IllegalStateException("Can not access to default constructor: " + beanClass.getName(), e);
}
}
return bean;
}

void clear() {
cache.clear();
}

private static class ElementKey {
Element element;
Class<? extends BeanElement> beanClass;

ElementKey(Element element, Class<? extends BeanElement> beanClass) {
this.element = element;
this.beanClass = beanClass;
}

@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null) {
return false;
}
ElementKey that = (ElementKey) o;
if (!element.equals(that.element)) {
return false;
}
return beanClass.equals(that.beanClass);
}

@Override
public int hashCode() {
int result = element.hashCode();
result = 31 * result + beanClass.hashCode();
return result;
}
}
}

+ 0
- 63
sonar-core/src/main/java/org/sonar/core/graph/BeanGraph.java 查看文件

@@ -1,63 +0,0 @@
/*
* 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.core.graph;

import com.tinkerpop.blueprints.Edge;
import com.tinkerpop.blueprints.Element;
import com.tinkerpop.blueprints.Graph;
import com.tinkerpop.blueprints.Vertex;
import com.tinkerpop.blueprints.impls.tg.TinkerGraph;
import com.tinkerpop.blueprints.util.ElementHelper;

import javax.annotation.Nullable;

public class BeanGraph {
private final Graph graph;
private final BeanElements beans;

public BeanGraph(Graph graph) {
this.graph = graph;
this.beans = new BeanElements();
}

public static BeanGraph createInMemory() {
return new BeanGraph(new TinkerGraph());
}

public final <T extends BeanElement> T wrap(@Nullable Element element, Class<T> beanClass) {
return element != null ? beans.wrap(element, beanClass, this) : null;
}

public final <T extends BeanVertex> T createAdjacentVertex(BeanVertex from, Class<T> beanClass, String edgeLabel, String... edgeProperties) {
T to = createVertex(beanClass);
Edge edge = graph.addEdge(null, from.element(), to.element(), edgeLabel);
ElementHelper.setProperties(edge, edgeProperties);
return to;
}

public final <T extends BeanVertex> T createVertex(Class<T> beanClass) {
Vertex vertex = graph.addVertex(null);
return beans.wrap(vertex, beanClass, this);
}

public final Graph getUnderlyingGraph() {
return graph;
}
}

+ 0
- 59
sonar-core/src/main/java/org/sonar/core/graph/BeanIterable.java 查看文件

@@ -1,59 +0,0 @@
/*
* 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.core.graph;

import com.tinkerpop.blueprints.Element;

import java.util.Iterator;

public class BeanIterable<T extends BeanElement> implements Iterable<T> {

private final Iterable<? extends Element> iterable;
private final BeanGraph graph;
private final Class<T> beanClass;

public BeanIterable(BeanGraph graph, Class<T> beanClass, Iterable<? extends Element> iterable) {
this.iterable = iterable;
this.graph = graph;
this.beanClass = beanClass;
}

@Override
public Iterator<T> iterator() {
return new Iterator<T>() {
private final Iterator<? extends Element> iterator = iterable.iterator();

@Override
public void remove() {
throw new UnsupportedOperationException();
}

@Override
public boolean hasNext() {
return this.iterator.hasNext();
}

@Override
public T next() {
return graph.wrap(this.iterator.next(), beanClass);
}
};
}
}

+ 0
- 34
sonar-core/src/main/java/org/sonar/core/graph/BeanVertex.java 查看文件

@@ -1,34 +0,0 @@
/*
* 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.core.graph;

import com.tinkerpop.blueprints.Direction;
import com.tinkerpop.blueprints.Vertex;

public abstract class BeanVertex extends BeanElement<Vertex, BeanVertex> {

protected final <T extends BeanEdge> Iterable<T> getEdges(Class<T> edgeClass, Direction direction, String... labels) {
return new BeanIterable<>(beanGraph(), edgeClass, element().getEdges(direction, labels));
}

protected final <T extends BeanVertex> Iterable<T> getVertices(Class<T> vertexClass, Direction direction, String... labels) {
return new BeanIterable<>(beanGraph(), vertexClass, element().getVertices(direction, labels));
}
}

+ 0
- 55
sonar-core/src/main/java/org/sonar/core/graph/EdgePath.java 查看文件

@@ -1,55 +0,0 @@
/*
* 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.core.graph;

import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import com.tinkerpop.blueprints.Direction;

import java.util.List;

public class EdgePath {
private List<Object> elements;

private EdgePath(Object[] elements) {
Preconditions.checkArgument(elements != null && elements.length > 0, "Elements can't be null or empty");
Preconditions.checkArgument(elements.length % 2 == 0, "Odd number of elements (" + elements.length + ")");

for (int i = 0; i < elements.length; i++) {
if (i % 2 == 0) {
Preconditions.checkArgument(elements[i] instanceof Direction,
"Element " + i + " must be a " + Direction.class.getName() + " (got " + elements[i].getClass().getName() + ")");
} else {
Preconditions.checkArgument(elements[i] instanceof String,
"Element " + i + " must be a String" + " (got " + elements[i].getClass().getName() + ")");
}
}

this.elements = ImmutableList.copyOf(elements);
}

public List<Object> getElements() {
return elements;
}

public static EdgePath create(Object... elements) {
return new EdgePath(elements);
}
}

+ 0
- 65
sonar-core/src/main/java/org/sonar/core/graph/GraphUtil.java 查看文件

@@ -1,65 +0,0 @@
/*
* 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.core.graph;

import com.google.common.base.Joiner;
import com.tinkerpop.blueprints.Direction;
import com.tinkerpop.blueprints.Element;
import com.tinkerpop.blueprints.Vertex;

import javax.annotation.CheckForNull;

import java.util.Iterator;

public class GraphUtil {

private GraphUtil() {
}

/**
* Get adjacent vertex. It assumes that there are only 0 or 1 results.
*
* @throws MultipleElementsException if there are more than 1 adjacent vertices with the given criteria.
*/
@CheckForNull
public static Vertex singleAdjacent(Vertex from, Direction direction, String... labels) {
Iterator<Vertex> vertices = from.getVertices(direction, labels).iterator();
Vertex result = null;
if (vertices.hasNext()) {
result = vertices.next();
if (vertices.hasNext()) {
throw new MultipleElementsException(String.format("More than one vertex is adjacent to: %s, direction: %s, labels: %s", from, direction, Joiner.on(",").join(labels)));
}
}
return result;
}

public static <T extends Element> T single(Iterable<T> iterable) {
Iterator<T> iterator = iterable.iterator();
T result = null;
if (iterator.hasNext()) {
result = iterator.next();
if (iterator.hasNext()) {
throw new MultipleElementsException("More than one element");
}
}
return result;
}
}

+ 0
- 26
sonar-core/src/main/java/org/sonar/core/graph/MultipleElementsException.java 查看文件

@@ -1,26 +0,0 @@
/*
* 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.core.graph;

public class MultipleElementsException extends RuntimeException {
public MultipleElementsException(String message) {
super(message);
}
}

+ 0
- 47
sonar-core/src/main/java/org/sonar/core/graph/graphson/ElementFactory.java 查看文件

@@ -1,47 +0,0 @@
/*
* 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.core.graph.graphson;

import com.tinkerpop.blueprints.Edge;
import com.tinkerpop.blueprints.Graph;
import com.tinkerpop.blueprints.Vertex;

/**
* The standard factory used for most graph element creation. It uses an actual
* Graph implementation to construct vertices and edges
*
* @author Stephen Mallette (http://stephen.genoprime.com)
*/
class ElementFactory {

private final Graph graph;

ElementFactory(Graph g) {
this.graph = g;
}

Edge createEdge(Object id, Vertex out, Vertex in, String label) {
return this.graph.addEdge(id, out, in, label);
}

Vertex createVertex(Object id) {
return this.graph.addVertex(id);
}
}

+ 0
- 87
sonar-core/src/main/java/org/sonar/core/graph/graphson/ElementPropertyConfig.java 查看文件

@@ -1,87 +0,0 @@
/*
* 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.core.graph.graphson;

import java.util.Set;

/**
* Configure how the GraphSON utility treats edge and vertex properties.
*
* @author Stephen Mallette (http://stephen.genoprime.com)
*/
class ElementPropertyConfig {

enum ElementPropertiesRule {
INCLUDE, EXCLUDE
}

private final Set<String> vertexPropertyKeys;
private final Set<String> edgePropertyKeys;
private final ElementPropertiesRule vertexPropertiesRule;
private final ElementPropertiesRule edgePropertiesRule;

/**
* A configuration that includes all properties of vertices and edges.
*/
static ElementPropertyConfig AllProperties = new ElementPropertyConfig(null, null,
ElementPropertiesRule.INCLUDE, ElementPropertiesRule.INCLUDE);

ElementPropertyConfig(Set<String> vertexPropertyKeys, Set<String> edgePropertyKeys,
ElementPropertiesRule vertexPropertiesRule, ElementPropertiesRule edgePropertiesRule) {
this.vertexPropertiesRule = vertexPropertiesRule;
this.vertexPropertyKeys = vertexPropertyKeys;
this.edgePropertiesRule = edgePropertiesRule;
this.edgePropertyKeys = edgePropertyKeys;
}

/**
* Construct a configuration that includes the specified properties from both vertices and edges.
*/
static ElementPropertyConfig includeProperties(Set<String> vertexPropertyKeys,
Set<String> edgePropertyKeys) {
return new ElementPropertyConfig(vertexPropertyKeys, edgePropertyKeys, ElementPropertiesRule.INCLUDE,
ElementPropertiesRule.INCLUDE);
}

/**
* Construct a configuration that excludes the specified properties from both vertices and edges.
*/
static ElementPropertyConfig excludeProperties(Set<String> vertexPropertyKeys,
Set<String> edgePropertyKeys) {
return new ElementPropertyConfig(vertexPropertyKeys, edgePropertyKeys, ElementPropertiesRule.EXCLUDE,
ElementPropertiesRule.EXCLUDE);
}

Set<String> getVertexPropertyKeys() {
return vertexPropertyKeys;
}

Set<String> getEdgePropertyKeys() {
return edgePropertyKeys;
}

ElementPropertiesRule getVertexPropertiesRule() {
return vertexPropertiesRule;
}

ElementPropertiesRule getEdgePropertiesRule() {
return edgePropertiesRule;
}
}

+ 0
- 26
sonar-core/src/main/java/org/sonar/core/graph/graphson/GraphsonException.java 查看文件

@@ -1,26 +0,0 @@
/*
* 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.core.graph.graphson;

public class GraphsonException extends RuntimeException {
public GraphsonException(String message, Throwable cause) {
super(message, cause);
}
}

+ 0
- 45
sonar-core/src/main/java/org/sonar/core/graph/graphson/GraphsonMode.java 查看文件

@@ -1,45 +0,0 @@
/*
* 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.core.graph.graphson;

/**
* Modes of operation of the GraphSONUtility.
*
* @author Stephen Mallette
*/
public enum GraphsonMode {
/**
* COMPACT constructs GraphSON on the assumption that all property keys
* are fair game for exclusion including _type, _inV, _outV, _label and _id.
* It is possible to write GraphSON that cannot be read back into Graph,
* if some or all of these keys are excluded.
*/
COMPACT,

/**
* NORMAL includes the _type field and JSON data typing.
*/
NORMAL,

/**
* EXTENDED includes the _type field and explicit data typing.
*/
EXTENDED
}

+ 0
- 75
sonar-core/src/main/java/org/sonar/core/graph/graphson/GraphsonReader.java 查看文件

@@ -1,75 +0,0 @@
/*
* 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.core.graph.graphson;

import com.tinkerpop.blueprints.Graph;
import com.tinkerpop.blueprints.Vertex;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;

import java.io.Reader;
import java.util.Set;

/**
* Greatly inspired by the Blueprints implementation based on Jettison/Jackson
*/
public class GraphsonReader {

public Graph read(Reader jsonInput, Graph toGraph) {
return read(jsonInput, toGraph, null, null);
}

/**
* Input the JSON stream data into the graph.
* More control over how data is streamed is provided by this method.
*
* @param toGraph the graph to populate with the JSON data
* @param input an InputStream of JSON data
* @param bufferSize the amount of elements to hold in memory before committing a transactions (only valid for TransactionalGraphs)
*/
public Graph read(Reader input, Graph toGraph, Set<String> edgePropertyKeys, Set<String> vertexPropertyKeys) {
try {
JSONParser parser = new JSONParser();
JSONObject json = (JSONObject) parser.parse(input);

ElementFactory elementFactory = new ElementFactory(toGraph);
GraphsonMode mode = GraphsonMode.valueOf(json.get(GraphsonTokens.MODE).toString());
GraphsonUtil graphson = new GraphsonUtil(mode, elementFactory, vertexPropertyKeys, edgePropertyKeys);

JSONArray vertices = (JSONArray) json.get(GraphsonTokens.VERTICES);
for (Object vertice : vertices) {
graphson.vertexFromJson((JSONObject) vertice);
}

JSONArray edges = (JSONArray) json.get(GraphsonTokens.EDGES);
for (Object edgeObject : edges) {
JSONObject edge = (JSONObject) edgeObject;
Vertex inV = toGraph.getVertex(edge.get(GraphsonTokens._IN_V));
Vertex outV = toGraph.getVertex(edge.get(GraphsonTokens._OUT_V));
graphson.edgeFromJson(edge, outV, inV);
}
toGraph.shutdown();
return toGraph;
} catch (Exception e) {
throw new GraphsonException("Unable to parse GraphSON", e);
}
}
}

+ 0
- 52
sonar-core/src/main/java/org/sonar/core/graph/graphson/GraphsonTokens.java 查看文件

@@ -1,52 +0,0 @@
/*
* 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.core.graph.graphson;

/**
* @author Marko A. Rodriguez (http://markorodriguez.com)
* @author Stephen Mallette
*/
class GraphsonTokens {
private GraphsonTokens() {
}

static final String VERTEX = "vertex";
static final String EDGE = "edge";
static final String _ID = "_id";
static final String _LABEL = "_label";
static final String _TYPE = "_type";
static final String _OUT_V = "_outV";
static final String _IN_V = "_inV";
static final String VALUE = "value";
static final String TYPE = "type";
static final String TYPE_LIST = "list";
static final String TYPE_STRING = "string";
static final String TYPE_DOUBLE = "double";
static final String TYPE_INTEGER = "integer";
static final String TYPE_FLOAT = "float";
static final String TYPE_MAP = "map";
static final String TYPE_BOOLEAN = "boolean";
static final String TYPE_LONG = "long";
static final String TYPE_UNKNOWN = "unknown";

static final String VERTICES = "vertices";
static final String EDGES = "edges";
static final String MODE = "mode";
}

+ 0
- 673
sonar-core/src/main/java/org/sonar/core/graph/graphson/GraphsonUtil.java 查看文件

@@ -1,673 +0,0 @@
/*
* 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.core.graph.graphson;

import com.tinkerpop.blueprints.Direction;
import com.tinkerpop.blueprints.Edge;
import com.tinkerpop.blueprints.Element;
import com.tinkerpop.blueprints.Vertex;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;

import javax.annotation.Nullable;

import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import static org.sonar.core.graph.graphson.ElementPropertyConfig.ElementPropertiesRule;

/**
* Helps write individual graph elements to TinkerPop JSON format known as GraphSON.
*
* @author Stephen Mallette (http://stephen.genoprime.com)
*/
class GraphsonUtil {

private final GraphsonMode mode;
private final Set<String> vertexPropertyKeys;
private final Set<String> edgePropertyKeys;
private final ElementFactory factory;
private final boolean hasEmbeddedTypes;
private final ElementPropertiesRule vertexPropertiesRule;
private final ElementPropertiesRule edgePropertiesRule;
private final boolean includeReservedVertexId;
private final boolean includeReservedEdgeId;
private final boolean includeReservedVertexType;
private final boolean includeReservedEdgeType;
private final boolean includeReservedEdgeLabel;
private final boolean includeReservedEdgeOutV;
private final boolean includeReservedEdgeInV;
private JSONParser parser = new JSONParser();

/**
* A GraphSONUtiltiy that includes all properties of vertices and edges.
*/
GraphsonUtil(GraphsonMode mode, ElementFactory factory) {
this(mode, factory, ElementPropertyConfig.AllProperties);
}

/**
* A GraphSONUtility that includes the specified properties.
*/
GraphsonUtil(GraphsonMode mode, ElementFactory factory,
Set<String> vertexPropertyKeys, Set<String> edgePropertyKeys) {
this(mode, factory, ElementPropertyConfig.includeProperties(vertexPropertyKeys, edgePropertyKeys));
}

GraphsonUtil(GraphsonMode mode, ElementFactory factory,
ElementPropertyConfig config) {
this.vertexPropertyKeys = config.getVertexPropertyKeys();
this.edgePropertyKeys = config.getEdgePropertyKeys();
this.vertexPropertiesRule = config.getVertexPropertiesRule();
this.edgePropertiesRule = config.getEdgePropertiesRule();

this.mode = mode;
this.factory = factory;
this.hasEmbeddedTypes = mode == GraphsonMode.EXTENDED;

this.includeReservedVertexId = includeReservedKey(mode, GraphsonTokens._ID, vertexPropertyKeys, this.vertexPropertiesRule);
this.includeReservedEdgeId = includeReservedKey(mode, GraphsonTokens._ID, edgePropertyKeys, this.edgePropertiesRule);
this.includeReservedVertexType = includeReservedKey(mode, GraphsonTokens._TYPE, vertexPropertyKeys, this.vertexPropertiesRule);
this.includeReservedEdgeType = includeReservedKey(mode, GraphsonTokens._TYPE, edgePropertyKeys, this.edgePropertiesRule);
this.includeReservedEdgeLabel = includeReservedKey(mode, GraphsonTokens._LABEL, edgePropertyKeys, this.edgePropertiesRule);
this.includeReservedEdgeOutV = includeReservedKey(mode, GraphsonTokens._OUT_V, edgePropertyKeys, this.edgePropertiesRule);
this.includeReservedEdgeInV = includeReservedKey(mode, GraphsonTokens._IN_V, edgePropertyKeys, this.edgePropertiesRule);
}

/**
* Creates a JSONObject from a graph element.
*
* @param element the graph element to convert to JSON.
* @param propertyKeys The property keys at the root of the element to serialize. If null, then all keys are serialized.
* @param mode the type of GraphSON to be generated.
*/
static JSONObject jsonFromElement(Element element, @Nullable Set<String> propertyKeys, GraphsonMode mode) {
GraphsonUtil graphson = element instanceof Edge ? new GraphsonUtil(mode, null, null, propertyKeys)
: new GraphsonUtil(mode, null, propertyKeys, null);
return graphson.jsonFromElement(element);
}

/**
* Reads an individual Vertex from JSON. The vertex must match the accepted GraphSON format.
*
* @param json a single vertex in GraphSON format as JSONObject
* @param factory the factory responsible for constructing graph elements
* @param mode the mode of the GraphSON
* @param propertyKeys a list of keys to include on reading of element properties
*/
static Vertex vertexFromJson(JSONObject json, ElementFactory factory, GraphsonMode mode,
Set<String> propertyKeys) throws IOException {
GraphsonUtil graphson = new GraphsonUtil(mode, factory, propertyKeys, null);
return graphson.vertexFromJson(json);
}

/**
* Reads an individual Vertex from JSON. The vertex must match the accepted GraphSON format.
*
* @param json a single vertex in GraphSON format as a String.
* @param factory the factory responsible for constructing graph elements
* @param mode the mode of the GraphSON
* @param propertyKeys a list of keys to include on reading of element properties
*/
static Vertex vertexFromJson(String json, ElementFactory factory, GraphsonMode mode,
Set<String> propertyKeys) throws ParseException {
GraphsonUtil graphson = new GraphsonUtil(mode, factory, propertyKeys, null);
return graphson.vertexFromJson(json);
}

/**
* Reads an individual Vertex from JSON. The vertex must match the accepted GraphSON format.
*
* @param json a single vertex in GraphSON format as an InputStream.
* @param factory the factory responsible for constructing graph elements
* @param mode the mode of the GraphSON
* @param propertyKeys a list of keys to include on reading of element properties
*/
static Vertex vertexFromJson(InputStream json, ElementFactory factory, GraphsonMode mode,
Set<String> propertyKeys) throws IOException, ParseException {
GraphsonUtil graphson = new GraphsonUtil(mode, factory, propertyKeys, null);
return graphson.vertexFromJson(json);
}

private static boolean includeReservedKey(GraphsonMode mode, String key,
Set<String> propertyKeys,
ElementPropertiesRule rule) {
// the key is always included in modes other than compact. if it is compact, then validate that the
// key is in the property key list
return mode != GraphsonMode.COMPACT || includeKey(key, propertyKeys, rule);
}

private static boolean includeKey(String key, Set<String> propertyKeys,
ElementPropertiesRule rule) {
if (propertyKeys == null) {
// when null always include the key and shortcut this piece
return true;
}

// default the key situation. if it's included then it should be explicitly defined in the
// property keys list to be included or the reverse otherwise
boolean keySituation = rule == ElementPropertiesRule.INCLUDE;

if (rule == ElementPropertiesRule.INCLUDE) {
keySituation = propertyKeys.contains(key);
} else if (rule == ElementPropertiesRule.EXCLUDE) {
keySituation = !propertyKeys.contains(key);
}
return keySituation;
}

/**
* Reads an individual Edge from JSON. The edge must match the accepted GraphSON format.
*
* @param json a single edge in GraphSON format as a String
* @param factory the factory responsible for constructing graph elements
* @param mode the mode of the GraphSON
* @param propertyKeys a list of keys to include when reading of element properties
*/
static Edge edgeFromJson(String json, Vertex out, Vertex in,
ElementFactory factory, GraphsonMode mode,
Set<String> propertyKeys) throws IOException, ParseException {
GraphsonUtil graphson = new GraphsonUtil(mode, factory, null, propertyKeys);
return graphson.edgeFromJson(json, out, in);
}

/**
* Reads an individual Edge from JSON. The edge must match the accepted GraphSON format.
*
* @param json a single edge in GraphSON format as an InputStream
* @param factory the factory responsible for constructing graph elements
* @param mode the mode of the GraphSON
* @param propertyKeys a list of keys to include when reading of element properties
*/
static Edge edgeFromJson(InputStream json, Vertex out, Vertex in,
ElementFactory factory, GraphsonMode mode,
Set<String> propertyKeys) throws IOException, ParseException {
GraphsonUtil graphson = new GraphsonUtil(mode, factory, null, propertyKeys);
return graphson.edgeFromJson(json, out, in);
}

/**
* Reads an individual Edge from JSON. The edge must match the accepted GraphSON format.
*
* @param json a single edge in GraphSON format as a JSONObject
* @param factory the factory responsible for constructing graph elements
* @param mode the mode of the GraphSON
* @param propertyKeys a list of keys to include when reading of element properties
*/
static Edge edgeFromJson(JSONObject json, Vertex out, Vertex in,
ElementFactory factory, GraphsonMode mode,
Set<String> propertyKeys) throws IOException {
GraphsonUtil graphson = new GraphsonUtil(mode, factory, null, propertyKeys);
return graphson.edgeFromJson(json, out, in);
}

static Map<String, Object> readProperties(JSONObject node, boolean ignoreReservedKeys, boolean hasEmbeddedTypes) {
Map<String, Object> map = new HashMap<>();

for (Object objKey : node.keySet()) {
String key = (String) objKey;
Object value = node.get(key);

if (!ignoreReservedKeys || !isReservedKey(key)) {
map.put(key, readProperty(value, hasEmbeddedTypes));
}
}

return map;
}

private static boolean isReservedKey(String key) {
return key.equals(GraphsonTokens._ID) || key.equals(GraphsonTokens._TYPE) || key.equals(GraphsonTokens._LABEL)
|| key.equals(GraphsonTokens._OUT_V) || key.equals(GraphsonTokens._IN_V);
}

private static JSONArray createJSONList(List list, Set<String> propertyKeys, boolean showTypes) {
JSONArray jsonList = new JSONArray();
for (Object item : list) {
if (item instanceof Element) {
jsonList.add(jsonFromElement((Element) item, propertyKeys,
showTypes ? GraphsonMode.EXTENDED : GraphsonMode.NORMAL));
} else if (item instanceof List) {
jsonList.add(createJSONList((List) item, propertyKeys, showTypes));
} else if (item instanceof Map) {
jsonList.add(createJSONMap((Map) item, propertyKeys, showTypes));
} else if (item != null && item.getClass().isArray()) {
jsonList.add(createJSONList(convertArrayToList(item), propertyKeys, showTypes));
} else if (item instanceof Set) {
throw new UnsupportedOperationException("Set property is not supported");
} else {
addObject(jsonList, item);
}
}
return jsonList;
}

//
private static JSONObject createJSONMap(Map<Object, Object> map, Set<String> propertyKeys, boolean showTypes) {
JSONObject jsonMap = new JSONObject();
for (Map.Entry<Object, Object> entry : map.entrySet()) {
Object value = entry.getValue();
if (value != null) {
if (value instanceof List) {
value = createJSONList((List) value, propertyKeys, showTypes);
} else if (value instanceof Map) {
value = createJSONMap((Map) value, propertyKeys, showTypes);
} else if (value instanceof Element) {
value = jsonFromElement((Element) value, propertyKeys,
showTypes ? GraphsonMode.EXTENDED : GraphsonMode.NORMAL);
} else if (value.getClass().isArray()) {
value = createJSONList(convertArrayToList(value), propertyKeys, showTypes);
}
}

putObject(jsonMap, entry.getKey().toString(), getValue(value, showTypes));
}
return jsonMap;

}

private static Object readProperty(Object node, boolean hasEmbeddedTypes) {
Object propertyValue;

if (hasEmbeddedTypes) {
JSONObject json = (JSONObject) node;
if (json.get(GraphsonTokens.TYPE).equals(GraphsonTokens.TYPE_UNKNOWN)) {
propertyValue = null;
} else if (json.get(GraphsonTokens.TYPE).equals(GraphsonTokens.TYPE_BOOLEAN)) {
propertyValue = json.get(GraphsonTokens.VALUE);
} else if (json.get(GraphsonTokens.TYPE).equals(GraphsonTokens.TYPE_FLOAT)) {
propertyValue = ((Double) json.get(GraphsonTokens.VALUE)).floatValue();
} else if (json.get(GraphsonTokens.TYPE).equals(GraphsonTokens.TYPE_DOUBLE)) {
propertyValue = json.get(GraphsonTokens.VALUE);
} else if (json.get(GraphsonTokens.TYPE).equals(GraphsonTokens.TYPE_INTEGER)) {
propertyValue = ((Long) json.get(GraphsonTokens.VALUE)).intValue();
} else if (json.get(GraphsonTokens.TYPE).equals(GraphsonTokens.TYPE_LONG)) {
propertyValue = json.get(GraphsonTokens.VALUE);
} else if (json.get(GraphsonTokens.TYPE).equals(GraphsonTokens.TYPE_STRING)) {
propertyValue = json.get(GraphsonTokens.VALUE);
} else if (json.get(GraphsonTokens.TYPE).equals(GraphsonTokens.TYPE_LIST)) {
propertyValue = readProperties(((JSONArray) json.get(GraphsonTokens.VALUE)).iterator(), hasEmbeddedTypes);
} else if (json.get(GraphsonTokens.TYPE).equals(GraphsonTokens.TYPE_MAP)) {
propertyValue = readProperties((JSONObject) json.get(GraphsonTokens.VALUE), false, hasEmbeddedTypes);
} else {
propertyValue = node.toString();
}
} else {
if (node == null) {
propertyValue = null;
} else if (node instanceof Boolean) {
propertyValue = node;
} else if (node instanceof Double) {
propertyValue = node;
} else if (node instanceof Integer) {
propertyValue = node;
} else if (node instanceof Long) {
propertyValue = node;
} else if (node instanceof String) {
propertyValue = node;
} else if (node instanceof JSONArray) {
propertyValue = readProperties(((JSONArray) node).iterator(), hasEmbeddedTypes);
} else if (node instanceof JSONObject) {
propertyValue = readProperties((JSONObject) node, false, hasEmbeddedTypes);
} else {
propertyValue = node;
}
}

return propertyValue;
}

private static void putObject(JSONObject jsonMap, String key, Object value) {
if (value == null) {
jsonMap.put(key, null);
} else if (value instanceof Boolean) {
jsonMap.put(key, value);
} else if (value instanceof Long) {
jsonMap.put(key, value);
} else if (value instanceof Integer) {
jsonMap.put(key, value);
} else if (value instanceof Float) {
jsonMap.put(key, value);
} else if (value instanceof Double) {
jsonMap.put(key, value);
} else if (value instanceof String) {
jsonMap.put(key, value);
} else if (value instanceof JSONObject) {
jsonMap.put(key, value);
} else if (value instanceof JSONArray) {
jsonMap.put(key, value);
} else {
jsonMap.put(key, value.toString());
}
}

private static List readProperties(Iterator<JSONObject> listOfNodes, boolean hasEmbeddedTypes) {
List array = new ArrayList();

while (listOfNodes.hasNext()) {
array.add(readProperty(listOfNodes.next(), hasEmbeddedTypes));
}

return array;
}

private static void addObject(JSONArray jsonList, Object value) {
if (value == null) {
jsonList.add(null);
} else if (value instanceof Boolean) {
jsonList.add(value);
} else if (value instanceof Long) {
jsonList.add(value);
} else if (value instanceof Integer) {
jsonList.add(value);
} else if (value instanceof Float) {
jsonList.add(value);
} else if (value instanceof Double) {
jsonList.add(value);
} else if (value instanceof String) {
jsonList.add(value);
} else if (value instanceof JSONObject) {
jsonList.add(value);
} else if (value instanceof JSONArray) {
jsonList.add(value);
} else {
jsonList.add(value.toString());
}
}

private static Map createPropertyMap(Element element, Set<String> propertyKeys, ElementPropertiesRule rule) {
Map map = new HashMap<>();

if (propertyKeys == null) {
for (String key : element.getPropertyKeys()) {
map.put(key, element.getProperty(key));
}
} else {
if (rule == ElementPropertiesRule.INCLUDE) {
for (String key : propertyKeys) {
Object valToPutInMap = element.getProperty(key);
if (valToPutInMap != null) {
map.put(key, valToPutInMap);
}
}
} else {
for (String key : element.getPropertyKeys()) {
if (!propertyKeys.contains(key)) {
map.put(key, element.getProperty(key));
}
}
}
}

return map;
}

private static Object getValue(Object value, boolean includeType) {

Object returnValue = value;

// if the includeType is set to true then show the data types of the properties
if (includeType) {

// type will be one of: map, list, string, long, int, double, float.
// in the event of a complex object it will call a toString and store as a
// string
String type = determineType(value);

JSONObject valueAndType = new JSONObject();
valueAndType.put(GraphsonTokens.TYPE, type);

if (type.equals(GraphsonTokens.TYPE_LIST)) {

// values of lists must be accumulated as ObjectNode objects under the value key.
// will return as a ArrayNode. called recursively to traverse the entire
// object graph of each item in the array.
JSONArray list = (JSONArray) value;

// there is a set of values that must be accumulated as an array under a key
JSONArray valueArray = new JSONArray();
valueAndType.put(GraphsonTokens.VALUE, valueArray);
for (int ix = 0; ix < list.size(); ix++) {
// the value of each item in the array is a node object from an ArrayNode...must
// get the value of it.
addObject(valueArray, getValue(list.get(ix), includeType));
}

} else if (type.equals(GraphsonTokens.TYPE_MAP)) {

// maps are converted to a ObjectNode. called recursively to traverse
// the entire object graph within the map.
JSONObject convertedMap = new JSONObject();
JSONObject jsonObject = (JSONObject) value;

Map<Object, Object> jsonObjectMap = jsonObject;
for (Map.Entry<Object, Object> entry : jsonObjectMap.entrySet()) {

// no need to getValue() here as this is already a ObjectNode and should have type info
convertedMap.put(entry.getKey(), entry.getValue());
}

valueAndType.put(GraphsonTokens.VALUE, convertedMap);

} else {

// this must be a primitive value or a complex object. if a complex
// object it will be handled by a call to toString and stored as a
// string value
putObject(valueAndType, GraphsonTokens.VALUE, value);
}

// this goes back as a JSONObject with data type and value
returnValue = valueAndType;
}

return returnValue;
}

private static List convertArrayToList(Object value) {

// is there seriously no better way to do this...bah!
List list = new ArrayList();
if (value instanceof int[]) {
int[] arr = (int[]) value;
for (int ix = 0; ix < arr.length; ix++) {
list.add(arr[ix]);
}
} else if (value instanceof double[]) {
double[] arr = (double[]) value;
for (int ix = 0; ix < arr.length; ix++) {
list.add(arr[ix]);
}
} else if (value instanceof float[]) {
float[] arr = (float[]) value;
for (int ix = 0; ix < arr.length; ix++) {
list.add(arr[ix]);
}
} else if (value instanceof long[]) {
long[] arr = (long[]) value;
for (int ix = 0; ix < arr.length; ix++) {
list.add(arr[ix]);
}
} else if (value instanceof boolean[]) {
boolean[] arr = (boolean[]) value;
for (int ix = 0; ix < arr.length; ix++) {
list.add(arr[ix]);
}
} else {
list = Arrays.asList((Object[]) value);
}

return list;
}

private static String determineType(Object value) {
String type = GraphsonTokens.TYPE_STRING;
if (value == null) {
type = "unknown";
} else if (value instanceof Double) {
type = GraphsonTokens.TYPE_DOUBLE;
} else if (value instanceof Float) {
type = GraphsonTokens.TYPE_FLOAT;
} else if (value instanceof Integer) {
type = GraphsonTokens.TYPE_INTEGER;
} else if (value instanceof Long) {
type = GraphsonTokens.TYPE_LONG;
} else if (value instanceof Boolean) {
type = GraphsonTokens.TYPE_BOOLEAN;
} else if (value instanceof JSONArray) {
type = GraphsonTokens.TYPE_LIST;
} else if (value instanceof JSONObject) {
type = GraphsonTokens.TYPE_MAP;
}

return type;
}

/**
* Creates a vertex from GraphSON using settings supplied in the constructor.
*/
Vertex vertexFromJson(InputStream json) throws ParseException, IOException {
return this.vertexFromJson((JSONObject) parser.parse(new InputStreamReader(json, StandardCharsets.UTF_8)));
}

/**
* Creates an edge from GraphSON using settings supplied in the constructor.
*/
Edge edgeFromJson(String json, Vertex out, Vertex in) throws IOException, ParseException {
return this.edgeFromJson((JSONObject) parser.parse(json), out, in);
}

/**
* Creates an edge from GraphSON using settings supplied in the constructor.
*/
Edge edgeFromJson(InputStream json, Vertex out, Vertex in) throws IOException, ParseException {
return this.edgeFromJson((JSONObject) parser.parse(new InputStreamReader(json, StandardCharsets.UTF_8)), out, in);
}

/**
* Creates an edge from GraphSON using settings supplied in the constructor.
*/
Edge edgeFromJson(JSONObject json, Vertex out, Vertex in) throws IOException {
Map<String, Object> props = GraphsonUtil.readProperties(json, true, this.hasEmbeddedTypes);

Object edgeId = json.get(GraphsonTokens._ID);

Object nodeLabel = json.get(GraphsonTokens._LABEL);
String label = nodeLabel == null ? null : nodeLabel.toString();

Edge e = factory.createEdge(edgeId, out, in, label);

for (Map.Entry<String, Object> entry : props.entrySet()) {
if (includeKey(entry.getKey(), edgePropertyKeys, this.edgePropertiesRule)) {
e.setProperty(entry.getKey(), entry.getValue());
}
}

return e;
}

/**
* Creates a vertex from GraphSON using settings supplied in the constructor.
*/
Vertex vertexFromJson(String json) throws ParseException {
return this.vertexFromJson((JSONObject) parser.parse(json));
}

/**
* Creates a vertex from GraphSON using settings supplied in the constructor.
*/
Vertex vertexFromJson(JSONObject json) {
Map<String, Object> props = readProperties(json, true, this.hasEmbeddedTypes);

Object vertexId = json.get(GraphsonTokens._ID);
Vertex v = factory.createVertex(vertexId);

for (Map.Entry<String, Object> entry : props.entrySet()) {
if (includeKey(entry.getKey(), vertexPropertyKeys, this.vertexPropertiesRule)) {
v.setProperty(entry.getKey(), entry.getValue());
}
}

return v;
}

/**
* Creates GraphSON for a single graph element.
*/
JSONObject jsonFromElement(Element element) {
boolean isEdge = element instanceof Edge;
boolean showTypes = mode == GraphsonMode.EXTENDED;
Set<String> propertyKeys = isEdge ? this.edgePropertyKeys : this.vertexPropertyKeys;
ElementPropertiesRule elementPropertyConfig = isEdge ? this.edgePropertiesRule : this.vertexPropertiesRule;

JSONObject jsonElement = createJSONMap(createPropertyMap(element, propertyKeys, elementPropertyConfig), propertyKeys, showTypes);

if ((isEdge && this.includeReservedEdgeId) || (!isEdge && this.includeReservedVertexId)) {
putObject(jsonElement, GraphsonTokens._ID, element.getId());
}

// it's important to keep the order of these straight. check Edge first and then Vertex because there
// are graph implementations that have Edge extend from Vertex
if (element instanceof Edge) {
Edge edge = (Edge) element;

if (this.includeReservedEdgeId) {
putObject(jsonElement, GraphsonTokens._ID, element.getId());
}

if (this.includeReservedEdgeType) {
jsonElement.put(GraphsonTokens._TYPE, GraphsonTokens.EDGE);
}

if (this.includeReservedEdgeOutV) {
putObject(jsonElement, GraphsonTokens._OUT_V, edge.getVertex(Direction.OUT).getId());
}

if (this.includeReservedEdgeInV) {
putObject(jsonElement, GraphsonTokens._IN_V, edge.getVertex(Direction.IN).getId());
}

if (this.includeReservedEdgeLabel) {
jsonElement.put(GraphsonTokens._LABEL, edge.getLabel());
}
} else if (element instanceof Vertex) {
if (this.includeReservedVertexId) {
putObject(jsonElement, GraphsonTokens._ID, element.getId());
}

if (this.includeReservedVertexType) {
jsonElement.put(GraphsonTokens._TYPE, GraphsonTokens.VERTEX);
}
}

return jsonElement;
}
}

+ 0
- 0
sonar-core/src/main/java/org/sonar/core/graph/graphson/GraphsonWriter.java 查看文件


部分文件因文件數量過多而無法顯示

Loading…
取消
儲存