@@ -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; |
@@ -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); | |||
} | |||
@@ -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); | |||
} | |||
@@ -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); | |||
} | |||
@@ -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; |
@@ -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")), |
@@ -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); | |||
@@ -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> |
@@ -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, |
@@ -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; |
@@ -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); | |||
} | |||
@@ -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) { |
@@ -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); | |||
} |
@@ -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) { |
@@ -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; | |||
} |
@@ -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; | |||
} | |||
} |
@@ -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; |
@@ -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); |
@@ -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; | |||
} | |||
} |
@@ -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); | |||
} | |||
} |
@@ -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)); |
@@ -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"); |
@@ -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(); |
@@ -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; | |||
} | |||
@@ -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; |
@@ -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); |
@@ -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; | |||
} |
@@ -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 { |
@@ -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; | |||
} | |||
@@ -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()) |
@@ -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 |
@@ -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; | |||
} |
@@ -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))); | |||
} | |||
} | |||
} |
@@ -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, |
@@ -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); | |||
} | |||
@@ -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()) { |
@@ -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)); | |||
} |
@@ -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; |
@@ -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; | |||
} | |||
@@ -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(); |
@@ -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<>(); |
@@ -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; |
@@ -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"); | |||
} |
@@ -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; |
@@ -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; |
@@ -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); |
@@ -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; | |||
} |
@@ -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; | |||
} |
@@ -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; | |||
} | |||
} |
@@ -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); | |||
} | |||
} |
@@ -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; | |||
} | |||
} |
@@ -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"); | |||
} | |||
} |
@@ -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; | |||
} | |||
} |
@@ -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; | |||
} | |||
} |
@@ -19,6 +19,6 @@ | |||
*/ | |||
@ParametersAreNonnullByDefault | |||
package org.sonar.core.test; | |||
package org.sonar.batch.test; | |||
import javax.annotation.ParametersAreNonnullByDefault; |
@@ -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); | |||
} | |||
@@ -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; | |||
} | |||
}; |
@@ -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); |
@@ -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(); |
@@ -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 |
@@ -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 { |
@@ -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(); | |||
} | |||
} |
@@ -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); |
@@ -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); |
@@ -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); | |||
} |
@@ -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)); |
@@ -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"); |
@@ -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); |
@@ -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); |
@@ -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; | |||
@@ -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)); |
@@ -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); | |||
} | |||
@@ -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)); | |||
} |
@@ -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(); |
@@ -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(); |
@@ -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> |
@@ -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; | |||
} | |||
} |
@@ -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(); | |||
} | |||
} |
@@ -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; | |||
} | |||
} |
@@ -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(); | |||
} |
@@ -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; | |||
} | |||
} |
@@ -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; | |||
} | |||
} |
@@ -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; | |||
} | |||
} |
@@ -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); | |||
} | |||
} |
@@ -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); | |||
} | |||
} |
@@ -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; | |||
} | |||
} | |||
} |
@@ -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; | |||
} | |||
} |
@@ -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); | |||
} | |||
}; | |||
} | |||
} |
@@ -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)); | |||
} | |||
} |
@@ -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); | |||
} | |||
} |
@@ -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; | |||
} | |||
} |
@@ -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); | |||
} | |||
} |
@@ -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); | |||
} | |||
} |
@@ -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; | |||
} | |||
} |
@@ -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); | |||
} | |||
} |
@@ -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 | |||
} |
@@ -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); | |||
} | |||
} | |||
} |
@@ -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"; | |||
} |
@@ -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; | |||
} | |||
} |