diff options
Diffstat (limited to 'sonar-scanner-engine/src/main/java/org')
12 files changed, 135 insertions, 495 deletions
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/tracking/LocalIssueTracking.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/tracking/LocalIssueTracking.java index bf026425205..7e496fd478b 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/tracking/LocalIssueTracking.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/tracking/LocalIssueTracking.java @@ -31,14 +31,12 @@ import java.util.Map; import java.util.stream.Stream; import javax.annotation.CheckForNull; import javax.annotation.Nullable; -import org.sonar.api.batch.ScannerSide; import org.sonar.api.batch.fs.InputComponent; import org.sonar.api.batch.fs.InputFile; import org.sonar.api.batch.fs.InputFile.Status; import org.sonar.api.batch.fs.InputModule; import org.sonar.api.batch.fs.internal.DefaultInputFile; -import org.sonar.api.batch.fs.internal.AbstractProjectOrModule; -import org.sonar.api.batch.fs.internal.InputComponentTree; +import org.sonar.api.batch.fs.internal.DefaultInputProject; import org.sonar.api.batch.rule.ActiveRule; import org.sonar.api.batch.rule.ActiveRules; import org.sonar.core.issue.tracking.Input; @@ -49,22 +47,21 @@ import org.sonar.scanner.issue.IssueTransformer; import org.sonar.scanner.protocol.output.ScannerReport; import org.sonar.scanner.repository.ProjectRepositories; -@ScannerSide public class LocalIssueTracking { + private final DefaultInputProject project; private final Tracker<TrackedIssue, ServerIssueFromWs> tracker; private final ServerLineHashesLoader lastLineHashes; private final ActiveRules activeRules; private final ServerIssueRepository serverIssueRepository; private final DefaultAnalysisMode mode; - private final InputComponentTree componentTree; private boolean hasServerAnalysis; - public LocalIssueTracking(Tracker<TrackedIssue, ServerIssueFromWs> tracker, ServerLineHashesLoader lastLineHashes, InputComponentTree componentTree, - ActiveRules activeRules, ServerIssueRepository serverIssueRepository, ProjectRepositories projectRepositories, DefaultAnalysisMode mode) { + public LocalIssueTracking(DefaultInputProject project, Tracker<TrackedIssue, ServerIssueFromWs> tracker, ServerLineHashesLoader lastLineHashes, + ActiveRules activeRules, ServerIssueRepository serverIssueRepository, ProjectRepositories projectRepositories, DefaultAnalysisMode mode) { + this.project = project; this.tracker = tracker; this.lastLineHashes = lastLineHashes; - this.componentTree = componentTree; this.serverIssueRepository = serverIssueRepository; this.mode = mode; this.activeRules = activeRules; @@ -102,7 +99,7 @@ public class LocalIssueTracking { } } - if (hasServerAnalysis && componentTree.getParent(component) == null) { + if (hasServerAnalysis && !component.isFile()) { Preconditions.checkState(component instanceof InputModule, "Object without parent is of type: " + component.getClass()); // issues that relate to deleted components addIssuesOnDeletedComponents(trackedIssues, component.key()); @@ -165,9 +162,8 @@ public class LocalIssueTracking { private SourceHashHolder loadSourceHashes(InputComponent component) { SourceHashHolder sourceHashHolder = null; if (component.isFile()) { - AbstractProjectOrModule module = (AbstractProjectOrModule) componentTree.getParent(componentTree.getParent(component)); DefaultInputFile file = (DefaultInputFile) component; - sourceHashHolder = new SourceHashHolder(module, file, lastLineHashes); + sourceHashHolder = new SourceHashHolder(project, file, lastLineHashes); } return sourceHashHolder; } diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/tracking/SourceHashHolder.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/tracking/SourceHashHolder.java index b1b56be89a8..48721f3cbdd 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/tracking/SourceHashHolder.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/tracking/SourceHashHolder.java @@ -19,25 +19,23 @@ */ package org.sonar.scanner.issue.tracking; -import java.util.Collection; -import java.util.Collections; import javax.annotation.CheckForNull; import org.sonar.api.batch.fs.InputFile.Status; import org.sonar.api.batch.fs.internal.DefaultInputFile; -import org.sonar.api.batch.fs.internal.AbstractProjectOrModule; +import org.sonar.api.batch.fs.internal.DefaultInputProject; import org.sonar.core.component.ComponentKeys; public class SourceHashHolder { - private final AbstractProjectOrModule module; + private final DefaultInputProject project; private final DefaultInputFile inputFile; private final ServerLineHashesLoader lastSnapshots; private FileHashes hashedReference; private FileHashes hashedSource; - public SourceHashHolder(AbstractProjectOrModule module, DefaultInputFile inputFile, ServerLineHashesLoader lastSnapshots) { - this.module = module; + public SourceHashHolder(DefaultInputProject project, DefaultInputFile inputFile, ServerLineHashesLoader lastSnapshots) { + this.project = project; this.inputFile = inputFile; this.lastSnapshots = lastSnapshots; } @@ -52,7 +50,7 @@ public class SourceHashHolder { hashedReference = hashedSource; } else { // Need key with branch - String serverSideKey = ComponentKeys.createEffectiveKey(module.definition().getKeyWithBranch(), inputFile); + String serverSideKey = ComponentKeys.createEffectiveKey(project.getKeyWithBranch(), inputFile); String[] lineHashes = lastSnapshots.getLineHashes(serverSideKey); hashedReference = lineHashes != null ? FileHashes.create(lineHashes) : null; } @@ -69,13 +67,4 @@ public class SourceHashHolder { initHashes(); return hashedSource; } - - public Collection<Integer> getNewLinesMatching(Integer originLine) { - FileHashes reference = getHashedReference(); - if (reference == null) { - return Collections.emptySet(); - } else { - return getHashedSource().getLinesForHash(reference.getHash(originLine)); - } - } } diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/mediumtest/AnalysisResult.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/mediumtest/AnalysisResult.java index 4c2cff60a32..db4f0787172 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/mediumtest/AnalysisResult.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/mediumtest/AnalysisResult.java @@ -32,12 +32,11 @@ import javax.annotation.CheckForNull; import org.apache.commons.io.FileUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.sonar.api.batch.AnalysisMode; import org.sonar.api.batch.fs.InputComponent; -import org.sonar.api.batch.fs.InputDir; import org.sonar.api.batch.fs.InputFile; import org.sonar.api.batch.fs.TextPointer; import org.sonar.api.batch.fs.TextRange; +import org.sonar.api.batch.fs.internal.DefaultInputComponent; import org.sonar.api.batch.fs.internal.DefaultInputFile; import org.sonar.api.batch.sensor.highlighting.TypeOfText; import org.sonar.api.scanner.fs.InputProject; @@ -46,7 +45,6 @@ import org.sonar.scanner.issue.IssueCache; import org.sonar.scanner.issue.tracking.TrackedIssue; import org.sonar.scanner.protocol.output.ScannerReport; import org.sonar.scanner.protocol.output.ScannerReport.Component; -import org.sonar.scanner.protocol.output.ScannerReport.Metadata; import org.sonar.scanner.protocol.output.ScannerReport.Symbol; import org.sonar.scanner.protocol.output.ScannerReportReader; import org.sonar.scanner.report.ReportPublisher; @@ -54,16 +52,12 @@ import org.sonar.scanner.report.ScannerReportUtils; import org.sonar.scanner.scan.ProjectScanContainer; import org.sonar.scanner.scan.filesystem.InputComponentStore; -import static org.apache.commons.lang.StringUtils.isNotEmpty; - public class AnalysisResult implements AnalysisObserver { private static final Logger LOG = LoggerFactory.getLogger(AnalysisResult.class); private List<TrackedIssue> issues = new ArrayList<>(); - private Map<String, InputFile> inputFiles = new HashMap<>(); - private Map<String, Component> reportComponents = new HashMap<>(); - private Map<String, InputDir> inputDirs = new HashMap<>(); + private Map<String, InputFile> inputFilesByKeys = new HashMap<>(); private InputProject project; private ScannerReportReader reader; @@ -76,30 +70,12 @@ public class AnalysisResult implements AnalysisObserver { ReportPublisher reportPublisher = container.getComponentByType(ReportPublisher.class); reader = new ScannerReportReader(reportPublisher.getReportDir().toFile()); - if (!container.getComponentByType(AnalysisMode.class).isIssues()) { - Metadata readMetadata = getReportReader().readMetadata(); - int rootComponentRef = readMetadata.getRootComponentRef(); - storeReportComponents(rootComponentRef, null); - project = container.getComponentByType(InputProject.class); - } + project = container.getComponentByType(InputProject.class); storeFs(container); } - private void storeReportComponents(int componentRef, String parentModuleKey) { - Component component = getReportReader().readComponent(componentRef); - if (isNotEmpty(component.getKey())) { - reportComponents.put(component.getKey(), component); - } else { - reportComponents.put(parentModuleKey + ":" + component.getPath(), component); - } - for (int childId : component.getChildRefList()) { - storeReportComponents(childId, isNotEmpty(component.getKey()) ? component.getKey() : parentModuleKey); - } - - } - public ScannerReportReader getReportReader() { return reader; } @@ -107,10 +83,7 @@ public class AnalysisResult implements AnalysisObserver { private void storeFs(ProjectScanContainer container) { InputComponentStore inputFileCache = container.getComponentByType(InputComponentStore.class); for (InputFile inputPath : inputFileCache.allFiles()) { - inputFiles.put(((DefaultInputFile) inputPath).getProjectRelativePath(), inputPath); - } - for (InputDir inputPath : inputFileCache.allDirs()) { - inputDirs.put(inputPath.relativePath(), inputPath); + inputFilesByKeys.put(((DefaultInputFile) inputPath).getProjectRelativePath(), inputPath); } } @@ -118,18 +91,20 @@ public class AnalysisResult implements AnalysisObserver { return issues; } - public Component getReportComponent(String key) { - return reportComponents.get(key); + public Component getReportComponent(InputComponent inputComponent) { + return getReportReader().readComponent(((DefaultInputComponent) inputComponent).scannerId()); + } + + public Component getReportComponent(int scannerId) { + return getReportReader().readComponent(scannerId); } public List<ScannerReport.Issue> issuesFor(InputComponent inputComponent) { - int ref = reportComponents.get(inputComponent.key()).getRef(); - return issuesFor(ref); + return issuesFor(((DefaultInputComponent) inputComponent).scannerId()); } - + public List<ScannerReport.ExternalIssue> externalIssuesFor(InputComponent inputComponent) { - int ref = reportComponents.get(inputComponent.key()).getRef(); - return externalIssuesFor(ref); + return externalIssuesFor(((DefaultInputComponent) inputComponent).scannerId()); } public List<ScannerReport.Issue> issuesFor(Component reportComponent) { @@ -146,7 +121,7 @@ public class AnalysisResult implements AnalysisObserver { } return result; } - + private List<ScannerReport.ExternalIssue> externalIssuesFor(int ref) { List<ScannerReport.ExternalIssue> result = Lists.newArrayList(); try (CloseableIterator<ScannerReport.ExternalIssue> it = reader.readComponentExternalIssues(ref)) { @@ -162,41 +137,38 @@ public class AnalysisResult implements AnalysisObserver { } public Collection<InputFile> inputFiles() { - return inputFiles.values(); + return inputFilesByKeys.values(); } @CheckForNull public InputFile inputFile(String relativePath) { - return inputFiles.get(relativePath); - } - - public Collection<InputDir> inputDirs() { - return inputDirs.values(); - } - - @CheckForNull - public InputDir inputDir(String relativePath) { - return inputDirs.get(relativePath); + return inputFilesByKeys.get(relativePath); } public Map<String, List<ScannerReport.Measure>> allMeasures() { Map<String, List<ScannerReport.Measure>> result = new HashMap<>(); - for (Map.Entry<String, Component> component : reportComponents.entrySet()) { + List<ScannerReport.Measure> projectMeasures = new ArrayList<>(); + try (CloseableIterator<ScannerReport.Measure> it = reader.readComponentMeasures(((DefaultInputComponent) project).scannerId())) { + Iterators.addAll(projectMeasures, it); + } + result.put(project.key(), projectMeasures); + for (InputFile inputFile : inputFilesByKeys.values()) { List<ScannerReport.Measure> measures = new ArrayList<>(); - try (CloseableIterator<ScannerReport.Measure> it = reader.readComponentMeasures(component.getValue().getRef())) { + try (CloseableIterator<ScannerReport.Measure> it = reader.readComponentMeasures(((DefaultInputComponent) inputFile).scannerId())) { Iterators.addAll(measures, it); } - result.put(component.getKey(), measures); + result.put(inputFile.key(), measures); } return result; } /** * Get highlighting types at a given position in an inputfile + * * @param lineOffset 0-based offset in file */ public List<TypeOfText> highlightingTypeFor(InputFile file, int line, int lineOffset) { - int ref = reportComponents.get(file.key()).getRef(); + int ref = ((DefaultInputComponent) file).scannerId(); if (!reader.hasSyntaxHighlighting(ref)) { return Collections.emptyList(); } @@ -222,12 +194,13 @@ public class AnalysisResult implements AnalysisObserver { /** * Get list of all start positions of a symbol in an inputfile - * @param symbolStartLine 0-based start offset for the symbol in file + * + * @param symbolStartLine 0-based start offset for the symbol in file * @param symbolStartLineOffset 0-based end offset for the symbol in file */ @CheckForNull public List<ScannerReport.TextRange> symbolReferencesFor(InputFile file, int symbolStartLine, int symbolStartLineOffset) { - int ref = reportComponents.get(file.key()).getRef(); + int ref = ((DefaultInputComponent) file).scannerId(); try (CloseableIterator<Symbol> symbols = getReportReader().readComponentSymbols(ref)) { while (symbols.hasNext()) { Symbol symbol = symbols.next(); @@ -241,7 +214,7 @@ public class AnalysisResult implements AnalysisObserver { public List<ScannerReport.Duplication> duplicationsFor(InputFile file) { List<ScannerReport.Duplication> result = new ArrayList<>(); - int ref = reportComponents.get(file.key()).getRef(); + int ref = ((DefaultInputComponent) file).scannerId(); try (CloseableIterator<ScannerReport.Duplication> it = getReportReader().readComponentDuplications(ref)) { while (it.hasNext()) { result.add(it.next()); @@ -254,7 +227,7 @@ public class AnalysisResult implements AnalysisObserver { public List<ScannerReport.CpdTextBlock> duplicationBlocksFor(InputFile file) { List<ScannerReport.CpdTextBlock> result = new ArrayList<>(); - int ref = reportComponents.get(file.key()).getRef(); + int ref = ((DefaultInputComponent) file).scannerId(); try (CloseableIterator<ScannerReport.CpdTextBlock> it = getReportReader().readCpdTextBlocks(ref)) { while (it.hasNext()) { result.add(it.next()); @@ -267,7 +240,7 @@ public class AnalysisResult implements AnalysisObserver { @CheckForNull public ScannerReport.LineCoverage coverageFor(InputFile file, int line) { - int ref = reportComponents.get(file.key()).getRef(); + int ref = ((DefaultInputComponent) file).scannerId(); try (CloseableIterator<ScannerReport.LineCoverage> it = getReportReader().readComponentCoverage(ref)) { while (it.hasNext()) { ScannerReport.LineCoverage coverage = it.next(); @@ -282,7 +255,7 @@ public class AnalysisResult implements AnalysisObserver { } public ScannerReport.Test firstTestExecutionForName(InputFile testFile, String testName) { - int ref = reportComponents.get(testFile.key()).getRef(); + int ref = ((DefaultInputComponent) testFile).scannerId(); try (InputStream inputStream = FileUtils.openInputStream(getReportReader().readTests(ref))) { ScannerReport.Test test = ScannerReport.Test.parser().parseDelimitedFrom(inputStream); while (test != null) { @@ -298,7 +271,7 @@ public class AnalysisResult implements AnalysisObserver { } public ScannerReport.CoverageDetail coveragePerTestFor(InputFile testFile, String testName) { - int ref = reportComponents.get(testFile.key()).getRef(); + int ref = ((DefaultInputComponent) testFile).scannerId(); try (InputStream inputStream = FileUtils.openInputStream(getReportReader().readCoverageDetails(ref))) { ScannerReport.CoverageDetail details = ScannerReport.CoverageDetail.parser().parseDelimitedFrom(inputStream); while (details != null) { diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/report/ComponentsPublisher.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/report/ComponentsPublisher.java index 7902bcde706..a9d042489b9 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/report/ComponentsPublisher.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/report/ComponentsPublisher.java @@ -19,129 +19,93 @@ */ package org.sonar.scanner.report; -import java.nio.file.Path; -import java.util.Collection; -import java.util.stream.Collectors; +import java.util.Map; import javax.annotation.CheckForNull; import org.apache.commons.lang.StringUtils; import org.sonar.api.CoreProperties; -import org.sonar.api.batch.bootstrap.ProjectDefinition; -import org.sonar.api.batch.fs.InputComponent; -import org.sonar.api.batch.fs.InputDir; import org.sonar.api.batch.fs.InputFile; import org.sonar.api.batch.fs.InputFile.Status; -import org.sonar.api.batch.fs.InputModule; -import org.sonar.api.batch.fs.internal.DefaultInputComponent; -import org.sonar.api.batch.fs.internal.DefaultInputFile; import org.sonar.api.batch.fs.internal.AbstractProjectOrModule; -import org.sonar.api.batch.fs.internal.DefaultInputModule; -import org.sonar.api.batch.fs.internal.InputComponentTree; -import org.sonar.api.batch.fs.internal.InputModuleHierarchy; -import org.sonar.api.utils.PathUtils; -import org.sonar.core.util.CloseableIterator; +import org.sonar.api.batch.fs.internal.DefaultInputFile; +import org.sonar.api.batch.fs.internal.DefaultInputProject; import org.sonar.scanner.protocol.output.ScannerReport; import org.sonar.scanner.protocol.output.ScannerReport.Component.ComponentType; import org.sonar.scanner.protocol.output.ScannerReport.Component.FileStatus; import org.sonar.scanner.protocol.output.ScannerReport.ComponentLink; import org.sonar.scanner.protocol.output.ScannerReport.ComponentLink.ComponentLinkType; -import org.sonar.scanner.protocol.output.ScannerReport.Issue; -import org.sonar.scanner.protocol.output.ScannerReportReader; import org.sonar.scanner.protocol.output.ScannerReportWriter; -import org.sonar.scanner.scan.branch.BranchConfiguration; +import org.sonar.scanner.scan.filesystem.InputComponentStore; /** * Adds components and analysis metadata to output report */ public class ComponentsPublisher implements ReportPublisherStep { - private final InputComponentTree componentTree; - private final InputModuleHierarchy moduleHierarchy; - private final BranchConfiguration branchConfiguration; + private final InputComponentStore inputComponentStore; + private final DefaultInputProject project; - private ScannerReportReader reader; - private ScannerReportWriter writer; - public ComponentsPublisher(InputModuleHierarchy moduleHierarchy, InputComponentTree inputComponentTree, BranchConfiguration branchConfiguration) { - this.moduleHierarchy = moduleHierarchy; - this.componentTree = inputComponentTree; - this.branchConfiguration = branchConfiguration; + public ComponentsPublisher(DefaultInputProject project, InputComponentStore inputComponentStore) { + this.project = project; + this.inputComponentStore = inputComponentStore; } @Override public void publish(ScannerReportWriter writer) { - this.reader = new ScannerReportReader(writer.getFileStructure().root()); - this.writer = writer; - recursiveWriteComponent(moduleHierarchy.root()); - } - - /** - * Writes the tree of components recursively, deep-first. - * - * @return true if component was written (not skipped) - */ - private boolean recursiveWriteComponent(DefaultInputComponent component) { - Collection<InputComponent> children = componentTree.getChildren(component).stream() - .filter(c -> recursiveWriteComponent((DefaultInputComponent) c)) - .collect(Collectors.toList()); - - if (shouldSkipComponent(component, children)) { - return false; - } + ScannerReport.Component.Builder projectBuilder = prepareProjectBuilder(); - ScannerReport.Component.Builder builder = ScannerReport.Component.newBuilder(); + ScannerReport.Component.Builder fileBuilder = ScannerReport.Component.newBuilder(); + for (DefaultInputFile file : inputComponentStore.allFilesToPublish()) { + projectBuilder.addChildRef(file.scannerId()); - // non-null fields - builder.setRef(component.scannerId()); - builder.setType(getType(component)); + fileBuilder.clear(); - // Don't set key on directories and files to save space since it can be deduced from path - if (component instanceof InputModule) { - DefaultInputModule inputModule = (DefaultInputModule) component; - // Here we want key without branch - builder.setKey(inputModule.key()); + // non-null fields + fileBuilder.setRef(file.scannerId()); + fileBuilder.setType(ComponentType.FILE); - // protocol buffers does not accept null values - String name = getName(inputModule); - if (name != null) { - builder.setName(name); - } - String description = getDescription(inputModule); - if (description != null) { - builder.setDescription(description); - } - - writeVersion(inputModule, builder); - } else if (component.isFile()) { - DefaultInputFile file = (DefaultInputFile) component; - builder.setIsTest(file.type() == InputFile.Type.TEST); - builder.setLines(file.lines()); - builder.setStatus(convert(file.status())); + fileBuilder.setIsTest(file.type() == InputFile.Type.TEST); + fileBuilder.setLines(file.lines()); + fileBuilder.setStatus(convert(file.status())); String lang = getLanguageKey(file); if (lang != null) { - builder.setLanguage(lang); + fileBuilder.setLanguage(lang); } + fileBuilder.setProjectRelativePath(file.getProjectRelativePath()); + writer.writeComponent(fileBuilder.build()); } - String path = getPath(component); - if (path != null) { - builder.setPath(path); - } + writer.writeComponent(projectBuilder.build()); + } + + private ScannerReport.Component.Builder prepareProjectBuilder() { + ScannerReport.Component.Builder projectBuilder = ScannerReport.Component.newBuilder(); + projectBuilder.setRef(project.scannerId()); + projectBuilder.setType(ComponentType.PROJECT); + // Here we want key without branch + projectBuilder.setKey(project.key()); - String projectRelativePath = getProjectRelativePath(component); - if (projectRelativePath != null) { - builder.setProjectRelativePath(projectRelativePath); + // protocol buffers does not accept null values + String name = getName(project); + if (name != null) { + projectBuilder.setName(name); + } + String description = getDescription(project); + if (description != null) { + projectBuilder.setDescription(description); } - for (InputComponent child : children) { - builder.addChildRef(((DefaultInputComponent) child).scannerId()); + String version = project.getOriginalVersion(); + if (version != null) { + projectBuilder.setVersion(version); } - writeLinks(component, builder); - writer.writeComponent(builder.build()); - return true; + + writeLinks(project, projectBuilder); + return projectBuilder; } - private FileStatus convert(Status status) { + private static FileStatus convert(Status status) { switch (status) { case ADDED: return FileStatus.ADDED; @@ -154,97 +118,18 @@ public class ComponentsPublisher implements ReportPublisherStep { } } - private boolean shouldSkipComponent(DefaultInputComponent component, Collection<InputComponent> children) { - if (component instanceof InputModule && children.isEmpty() && (branchConfiguration.isShortOrPullRequest())) { - // no children on a module in short branch analysis -> skip it (except root) - return !moduleHierarchy.isRoot((DefaultInputModule) component); - } else if (component instanceof InputDir && children.isEmpty()) { - try (CloseableIterator<Issue> componentIssuesIt = reader.readComponentIssues(component.scannerId())) { - if (!componentIssuesIt.hasNext()) { - // no files to publish on a directory without issues -> skip it - return true; - } - } - } else if (component instanceof DefaultInputFile) { - // skip files not marked for publishing - DefaultInputFile inputFile = (DefaultInputFile) component; - return !inputFile.isPublished(); - } - return false; - } + private static void writeLinks(DefaultInputProject project, ScannerReport.Component.Builder builder) { + ComponentLink.Builder linkBuilder = ComponentLink.newBuilder(); - private void writeVersion(DefaultInputModule module, ScannerReport.Component.Builder builder) { - String version = getVersion(module); - if (version != null) { - builder.setVersion(version); - } + writeProjectLink(builder, project.properties(), linkBuilder, CoreProperties.LINKS_HOME_PAGE, ComponentLinkType.HOME); + writeProjectLink(builder, project.properties(), linkBuilder, CoreProperties.LINKS_CI, ComponentLinkType.CI); + writeProjectLink(builder, project.properties(), linkBuilder, CoreProperties.LINKS_ISSUE_TRACKER, ComponentLinkType.ISSUE); + writeProjectLink(builder, project.properties(), linkBuilder, CoreProperties.LINKS_SOURCES, ComponentLinkType.SCM); } - @CheckForNull - private String getPath(InputComponent component) { - if (component instanceof InputFile) { - DefaultInputFile inputPath = (DefaultInputFile) component; - return inputPath.getModuleRelativePath(); - } else if (component instanceof InputDir) { - InputDir inputPath = (InputDir) component; - if (StringUtils.isEmpty(inputPath.relativePath())) { - return "/"; - } else { - return inputPath.relativePath(); - } - } else if (component instanceof InputModule) { - DefaultInputModule module = (DefaultInputModule) component; - return moduleHierarchy.relativePath(module); - } - throw new IllegalStateException("Unknown component: " + component.getClass()); - } - - @CheckForNull - private String getProjectRelativePath(DefaultInputComponent component) { - if (component instanceof InputFile) { - DefaultInputFile inputFile = (DefaultInputFile) component; - return inputFile.getProjectRelativePath(); - } - - Path projectBaseDir = moduleHierarchy.root().getBaseDir(); - if (component instanceof InputDir) { - InputDir inputDir = (InputDir) component; - return PathUtils.sanitize(projectBaseDir.relativize(inputDir.path()).toString()); - } - if (component instanceof InputModule) { - AbstractProjectOrModule module = (AbstractProjectOrModule) component; - return PathUtils.sanitize(projectBaseDir.relativize(module.getBaseDir()).toString()); - } - throw new IllegalStateException("Unknown component: " + component.getClass()); - } - - private String getVersion(DefaultInputModule module) { - String version = module.getOriginalVersion(); - if (StringUtils.isNotBlank(version)) { - return version; - } - - DefaultInputModule parent = moduleHierarchy.parent(module); - - return parent != null ? getVersion(parent) : null; - } - - private static void writeLinks(InputComponent c, ScannerReport.Component.Builder builder) { - if (c instanceof InputModule) { - AbstractProjectOrModule inputModule = (AbstractProjectOrModule) c; - ProjectDefinition def = inputModule.definition(); - ComponentLink.Builder linkBuilder = ComponentLink.newBuilder(); - - writeProjectLink(builder, def, linkBuilder, CoreProperties.LINKS_HOME_PAGE, ComponentLinkType.HOME); - writeProjectLink(builder, def, linkBuilder, CoreProperties.LINKS_CI, ComponentLinkType.CI); - writeProjectLink(builder, def, linkBuilder, CoreProperties.LINKS_ISSUE_TRACKER, ComponentLinkType.ISSUE); - writeProjectLink(builder, def, linkBuilder, CoreProperties.LINKS_SOURCES, ComponentLinkType.SCM); - } - } - - private static void writeProjectLink(ScannerReport.Component.Builder componentBuilder, ProjectDefinition def, ComponentLink.Builder linkBuilder, String linkProp, - ComponentLinkType linkType) { - String link = def.properties().get(linkProp); + private static void writeProjectLink(ScannerReport.Component.Builder componentBuilder, Map<String, String> properties, ComponentLink.Builder linkBuilder, String linkProp, + ComponentLinkType linkType) { + String link = properties.get(linkProp); if (StringUtils.isNotBlank(link)) { linkBuilder.setType(linkType); linkBuilder.setHref(link); @@ -272,18 +157,4 @@ public class ComponentsPublisher implements ReportPublisherStep { return module.definition().getDescription(); } - private ComponentType getType(InputComponent r) { - if (r instanceof InputFile) { - return ComponentType.FILE; - } else if (r instanceof InputDir) { - return ComponentType.DIRECTORY; - } else if ((r instanceof InputModule) && moduleHierarchy.isRoot((DefaultInputModule) r)) { - return ComponentType.PROJECT; - } else if (r instanceof InputModule) { - return ComponentType.MODULE; - } - - throw new IllegalArgumentException("Unknown resource type: " + r); - } - } diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/DefaultComponentTree.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/DefaultComponentTree.java deleted file mode 100644 index 7da8990ded6..00000000000 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/DefaultComponentTree.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2019 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program 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. - * - * This program 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.scanner.scan; - -import com.google.common.base.Preconditions; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.LinkedHashSet; -import java.util.Map; -import java.util.Set; -import javax.annotation.CheckForNull; -import org.sonar.api.batch.fs.InputComponent; -import org.sonar.api.batch.fs.internal.InputComponentTree; - -public class DefaultComponentTree implements InputComponentTree { - private Map<InputComponent, InputComponent> parents = new HashMap<>(); - private Map<InputComponent, Set<InputComponent>> children = new HashMap<>(); - - public void index(InputComponent component, InputComponent parent) { - Preconditions.checkNotNull(component); - Preconditions.checkNotNull(parent); - parents.put(component, parent); - children.computeIfAbsent(parent, k -> new LinkedHashSet<>()).add(component); - } - - @Override - public Collection<InputComponent> getChildren(InputComponent component) { - return children.getOrDefault(component, Collections.emptySet()); - } - - @CheckForNull - @Override - public InputComponent getParent(InputComponent component) { - return parents.get(component); - } -} diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ModuleIndexer.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ModuleIndexer.java index 60baccdfa5a..4b85e732f66 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ModuleIndexer.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ModuleIndexer.java @@ -30,12 +30,10 @@ import org.sonar.scanner.scan.filesystem.InputComponentStore; * project definitions provided by the {@link ImmutableProjectReactor}. */ public class ModuleIndexer implements Startable { - private final DefaultComponentTree componentTree; private final InputModuleHierarchy moduleHierarchy; private final InputComponentStore componentStore; - public ModuleIndexer(DefaultComponentTree componentTree, InputComponentStore componentStore, InputModuleHierarchy moduleHierarchy) { - this.componentTree = componentTree; + public ModuleIndexer(InputComponentStore componentStore, InputModuleHierarchy moduleHierarchy) { this.componentStore = componentStore; this.moduleHierarchy = moduleHierarchy; } @@ -49,7 +47,6 @@ public class ModuleIndexer implements Startable { private void indexChildren(DefaultInputModule parent) { for (DefaultInputModule module : moduleHierarchy.children(parent)) { - componentTree.index(module, parent); componentStore.put(module); indexChildren(module); } diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ProjectScanContainer.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ProjectScanContainer.java index eb33fe12f42..7e595179de1 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ProjectScanContainer.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ProjectScanContainer.java @@ -160,7 +160,6 @@ public class ProjectScanContainer extends ComponentContainer { PathResolver.class, new InputProjectProvider(), new InputModuleHierarchyProvider(), - DefaultComponentTree.class, ScannerComponentIdGenerator.class, new ScmChangedFilesProvider(), StatusDetection.class, diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/FileIndexer.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/FileIndexer.java index 5294797c67c..20a1d803688 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/FileIndexer.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/FileIndexer.java @@ -44,12 +44,9 @@ import org.sonar.api.batch.ScannerSide; import org.sonar.api.batch.fs.InputFile; import org.sonar.api.batch.fs.InputFile.Type; import org.sonar.api.batch.fs.InputFileFilter; -import org.sonar.api.batch.fs.internal.DefaultInputDir; import org.sonar.api.batch.fs.internal.DefaultInputFile; import org.sonar.api.batch.fs.internal.DefaultInputModule; -import org.sonar.api.scan.filesystem.PathResolver; import org.sonar.api.utils.MessageException; -import org.sonar.scanner.scan.DefaultComponentTree; import org.sonar.scanner.util.ProgressReport; /** @@ -62,7 +59,6 @@ public class FileIndexer { private final InputFileFilter[] filters; private final ExclusionFilters exclusionFilters; private final InputFileBuilder inputFileBuilder; - private final DefaultComponentTree componentTree; private final DefaultInputModule module; private final ScannerComponentIdGenerator scannerComponentIdGenerator; private final InputComponentStore componentStore; @@ -74,13 +70,12 @@ public class FileIndexer { private ProgressReport progressReport; public FileIndexer(ScannerComponentIdGenerator scannerComponentIdGenerator, InputComponentStore componentStore, DefaultInputModule module, ExclusionFilters exclusionFilters, - DefaultComponentTree componentTree, InputFileBuilder inputFileBuilder, DefaultModuleFileSystem defaultModuleFileSystem, + InputFileBuilder inputFileBuilder, DefaultModuleFileSystem defaultModuleFileSystem, LanguageDetection languageDetection, InputFileFilter[] filters) { this.scannerComponentIdGenerator = scannerComponentIdGenerator; this.componentStore = componentStore; this.module = module; - this.componentTree = componentTree; this.inputFileBuilder = inputFileBuilder; this.defaultModuleFileSystem = defaultModuleFileSystem; this.langDetection = languageDetection; @@ -90,9 +85,9 @@ public class FileIndexer { } public FileIndexer(ScannerComponentIdGenerator scannerComponentIdGenerator, InputComponentStore componentStore, DefaultInputModule module, ExclusionFilters exclusionFilters, - DefaultComponentTree componentTree, InputFileBuilder inputFileBuilder, DefaultModuleFileSystem defaultModuleFileSystem, + InputFileBuilder inputFileBuilder, DefaultModuleFileSystem defaultModuleFileSystem, LanguageDetection languageDetection) { - this(scannerComponentIdGenerator, componentStore, module, exclusionFilters, componentTree, inputFileBuilder, defaultModuleFileSystem, languageDetection, + this(scannerComponentIdGenerator, componentStore, module, exclusionFilters, inputFileBuilder, defaultModuleFileSystem, languageDetection, new InputFileFilter[0]); } @@ -192,34 +187,15 @@ public class FileIndexer { progress.increaseExcludedByPatternsCount(); return null; } - String parentRelativePath = getParentRelativePath(realAbsoluteFile); synchronized (this) { progress.markAsIndexed(inputFile); - indexFileAndParentDir(inputFile, parentRelativePath); + defaultModuleFileSystem.add(inputFile); } LOG.debug("'{}' indexed {}with language '{}'", relativePath, type == Type.TEST ? "as test " : "", inputFile.language()); inputFileBuilder.checkMetadata(inputFile); return null; } - private String getParentRelativePath(Path filePath) { - Path parentDir = filePath.getParent(); - return PathResolver.relativize(module.getBaseDir(), parentDir) - .orElseThrow(() -> new IllegalStateException("Failed to compute relative path of file: " + parentDir)); - } - - private void indexFileAndParentDir(InputFile inputFile, String parentRelativePath) { - DefaultInputDir inputDir = (DefaultInputDir) componentStore.getDir(module.key(), parentRelativePath); - if (inputDir == null) { - inputDir = new DefaultInputDir(module.key(), parentRelativePath, scannerComponentIdGenerator.getAsInt()); - inputDir.setModuleBaseDir(module.getBaseDir()); - componentTree.index(inputDir, module); - defaultModuleFileSystem.add(inputDir); - } - componentTree.index(inputFile, inputDir); - defaultModuleFileSystem.add(inputFile); - } - private boolean accept(InputFile indexedFile) { // InputFileFilter extensions. Might trigger generation of metadata for (InputFileFilter filter : filters) { diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/InputComponentStore.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/InputComponentStore.java index 15eb4f6b0a0..8d1071b172c 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/InputComponentStore.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/InputComponentStore.java @@ -24,7 +24,6 @@ import com.google.common.collect.LinkedHashMultimap; import com.google.common.collect.SetMultimap; import com.google.common.collect.Table; import com.google.common.collect.TreeBasedTable; -import java.nio.file.Path; import java.util.Collection; import java.util.Collections; import java.util.HashMap; @@ -34,13 +33,10 @@ import java.util.TreeSet; import java.util.stream.Stream; import javax.annotation.CheckForNull; import org.sonar.api.batch.fs.InputComponent; -import org.sonar.api.batch.fs.InputDir; import org.sonar.api.batch.fs.InputFile; import org.sonar.api.batch.fs.internal.AbstractProjectOrModule; -import org.sonar.api.batch.fs.internal.DefaultInputDir; import org.sonar.api.batch.fs.internal.DefaultInputFile; import org.sonar.api.batch.fs.internal.FileExtensionPredicate; -import org.sonar.api.scan.filesystem.PathResolver; import org.sonar.api.scanner.fs.InputProject; import org.sonar.scanner.scan.branch.BranchConfiguration; @@ -53,9 +49,7 @@ public class InputComponentStore { private final SortedSet<String> globalLanguagesCache = new TreeSet<>(); private final Map<String, SortedSet<String>> languagesCache = new HashMap<>(); private final Map<String, InputFile> globalInputFileCache = new HashMap<>(); - private final Table<String, String, InputFile> inputFileCache = TreeBasedTable.create(); - private final Map<String, InputDir> globalInputDirCache = new HashMap<>(); - private final Table<String, String, InputDir> inputDirCache = TreeBasedTable.create(); + private final Table<String, String, InputFile> inputFileByModuleCache = TreeBasedTable.create(); // indexed by key with branch private final Map<String, AbstractProjectOrModule> inputModuleCache = new HashMap<>(); private final Map<String, InputComponent> inputComponents = new HashMap<>(); @@ -74,7 +68,7 @@ public class InputComponentStore { } private Stream<DefaultInputFile> allFilesToPublishStream() { - return inputFileCache.values().stream() + return inputFileByModuleCache.values().stream() .map(f -> (DefaultInputFile) f) .filter(DefaultInputFile::isPublished); } @@ -90,11 +84,7 @@ public class InputComponentStore { } public Iterable<InputFile> allFiles() { - return inputFileCache.values(); - } - - public Iterable<InputDir> allDirs() { - return inputDirCache.values(); + return globalInputFileCache.values(); } public InputComponent getByKey(String key) { @@ -102,35 +92,13 @@ public class InputComponentStore { } public Iterable<InputFile> filesByModule(String moduleKey) { - return inputFileCache.row(moduleKey).values(); - } - - public Iterable<InputDir> dirsByModule(String moduleKey) { - return inputDirCache.row(moduleKey).values(); - } - - public InputComponentStore removeModule(String moduleKey) { - inputFileCache.row(moduleKey).clear(); - inputDirCache.row(moduleKey).clear(); - return this; - } - - public InputComponentStore remove(InputFile inputFile) { - DefaultInputFile file = (DefaultInputFile) inputFile; - inputFileCache.remove(file.moduleKey(), file.getModuleRelativePath()); - return this; - } - - public InputComponentStore remove(InputDir inputDir) { - DefaultInputDir dir = (DefaultInputDir) inputDir; - inputDirCache.remove(dir.moduleKey(), inputDir.relativePath()); - return this; + return inputFileByModuleCache.row(moduleKey).values(); } - public InputComponentStore put(InputFile inputFile) { + public InputComponentStore put(String moduleKey, InputFile inputFile) { DefaultInputFile file = (DefaultInputFile) inputFile; - addToLanguageCache(file); - inputFileCache.put(file.moduleKey(), file.getModuleRelativePath(), inputFile); + addToLanguageCache(moduleKey, file); + inputFileByModuleCache.put(moduleKey, file.getModuleRelativePath(), inputFile); globalInputFileCache.put(file.getProjectRelativePath(), inputFile); inputComponents.put(inputFile.key(), inputFile); filesByNameCache.put(inputFile.filename(), inputFile); @@ -138,34 +106,17 @@ public class InputComponentStore { return this; } - private void addToLanguageCache(DefaultInputFile inputFile) { + private void addToLanguageCache(String moduleKey, DefaultInputFile inputFile) { String language = inputFile.language(); if (language != null) { globalLanguagesCache.add(language); - languagesCache.computeIfAbsent(inputFile.moduleKey(), k -> new TreeSet<>()).add(language); + languagesCache.computeIfAbsent(moduleKey, k -> new TreeSet<>()).add(language); } } - public InputComponentStore put(InputDir inputDir) { - DefaultInputDir dir = (DefaultInputDir) inputDir; - inputDirCache.put(dir.moduleKey(), inputDir.relativePath(), inputDir); - // FIXME an InputDir can be already indexed by another module - globalInputDirCache.put(getProjectRelativePath(dir), inputDir); - inputComponents.put(inputDir.key(), inputDir); - return this; - } - - private String getProjectRelativePath(DefaultInputDir dir) { - return PathResolver.relativize(getProjectBaseDir(), dir.path()).orElseThrow(() -> new IllegalStateException("Dir " + dir.path() + " should be relative to project baseDir")); - } - - private Path getProjectBaseDir() { - return ((AbstractProjectOrModule) project).getBaseDir(); - } - @CheckForNull public InputFile getFile(String moduleKey, String relativePath) { - return inputFileCache.get(moduleKey, relativePath); + return inputFileByModuleCache.get(moduleKey, relativePath); } @CheckForNull @@ -174,16 +125,6 @@ public class InputComponentStore { } @CheckForNull - public InputDir getDir(String moduleKey, String relativePath) { - return inputDirCache.get(moduleKey, relativePath); - } - - @CheckForNull - public InputDir getDir(String relativePath) { - return globalInputDirCache.get(relativePath); - } - - @CheckForNull public AbstractProjectOrModule getModule(String moduleKeyWithBranch) { return inputModuleCache.get(moduleKeyWithBranch); } diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/InputFileBuilder.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/InputFileBuilder.java index 4de7d1bf07e..438a0edd44b 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/InputFileBuilder.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/InputFileBuilder.java @@ -30,6 +30,7 @@ import org.sonar.api.batch.fs.internal.SensorStrategy; import org.sonar.scanner.scan.ScanProperties; public class InputFileBuilder { + private final DefaultInputProject project; private final DefaultInputModule module; private final ScannerComponentIdGenerator idGenerator; private final MetadataGenerator metadataGenerator; @@ -42,6 +43,7 @@ public class InputFileBuilder { SensorStrategy sensorStrategy) { this.sensorStrategy = sensorStrategy; this.projectBaseDir = project.getBaseDir(); + this.project = project; this.module = module; this.metadataGenerator = metadataGenerator; this.idGenerator = idGenerator; @@ -49,7 +51,7 @@ public class InputFileBuilder { } DefaultInputFile create(InputFile.Type type, Path absolutePath, @Nullable String language) { - DefaultIndexedFile indexedFile = new DefaultIndexedFile(absolutePath, module.key(), + DefaultIndexedFile indexedFile = new DefaultIndexedFile(absolutePath, project.key(), projectBaseDir.relativize(absolutePath).toString(), module.getBaseDir().relativize(absolutePath).toString(), type, language, idGenerator.getAsInt(), sensorStrategy); diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/ModuleInputComponentStore.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/ModuleInputComponentStore.java index 8d694756fb9..6bb17759043 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/ModuleInputComponentStore.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/ModuleInputComponentStore.java @@ -21,7 +21,6 @@ package org.sonar.scanner.scan.filesystem; import java.util.SortedSet; import org.sonar.api.batch.ScannerSide; -import org.sonar.api.batch.fs.InputDir; import org.sonar.api.batch.fs.InputFile; import org.sonar.api.batch.fs.InputModule; import org.sonar.api.batch.fs.internal.DefaultFileSystem; @@ -59,15 +58,6 @@ public class ModuleInputComponentStore extends DefaultFileSystem.Cache { } @Override - public InputDir inputDir(String relativePath) { - if (strategy.isGlobal()) { - return inputComponentStore.getDir(relativePath); - } else { - return inputComponentStore.getDir(moduleKey, relativePath); - } - } - - @Override public SortedSet<String> languages() { if (strategy.isGlobal()) { return inputComponentStore.getLanguages(); @@ -78,12 +68,7 @@ public class ModuleInputComponentStore extends DefaultFileSystem.Cache { @Override protected void doAdd(InputFile inputFile) { - inputComponentStore.put(inputFile); - } - - @Override - protected void doAdd(InputDir inputDir) { - inputComponentStore.put(inputDir); + inputComponentStore.put(moduleKey, inputFile); } @Override diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/report/JSONReport.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/report/JSONReport.java index b302742bf7b..d965bb3e908 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/report/JSONReport.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/report/JSONReport.java @@ -38,13 +38,8 @@ import org.sonar.api.Property; import org.sonar.api.PropertyType; import org.sonar.api.batch.fs.FileSystem; import org.sonar.api.batch.fs.InputComponent; -import org.sonar.api.batch.fs.InputDir; -import org.sonar.api.batch.fs.InputPath; import org.sonar.api.batch.fs.internal.DefaultInputFile; -import org.sonar.api.batch.fs.internal.AbstractProjectOrModule; -import org.sonar.api.batch.fs.internal.DefaultInputModule; -import org.sonar.api.batch.fs.internal.InputComponentTree; -import org.sonar.api.batch.fs.internal.InputModuleHierarchy; +import org.sonar.api.batch.fs.internal.DefaultInputProject; import org.sonar.api.batch.rule.Rule; import org.sonar.api.batch.rule.Rules; import org.sonar.api.config.Configuration; @@ -72,21 +67,17 @@ public class JSONReport implements Reporter { private final Rules rules; private final IssueCache issueCache; private final InputComponentStore componentStore; - private final DefaultInputModule rootModule; - private final InputModuleHierarchy moduleHierarchy; - private final InputComponentTree inputComponentTree; + private final DefaultInputProject project; - public JSONReport(InputModuleHierarchy moduleHierarchy, Configuration settings, FileSystem fileSystem, Server server, Rules rules, IssueCache issueCache, - DefaultInputModule rootModule, InputComponentStore componentStore, InputComponentTree inputComponentTree) { - this.moduleHierarchy = moduleHierarchy; + public JSONReport(Configuration settings, FileSystem fileSystem, Server server, Rules rules, IssueCache issueCache, + DefaultInputProject project, InputComponentStore componentStore) { this.settings = settings; this.fileSystem = fileSystem; this.server = server; this.rules = rules; this.issueCache = issueCache; - this.rootModule = rootModule; + this.project = project; this.componentStore = componentStore; - this.inputComponentTree = inputComponentTree; } @Override @@ -126,14 +117,14 @@ public class JSONReport implements Reporter { for (TrackedIssue issue : getIssues()) { if (issue.resolution() == null) { InputComponent component = componentStore.getByKey(issue.componentKey()); - String componentKey = getModule(component).definition().getKeyWithBranch(); - if (component instanceof InputPath) { - componentKey = ComponentKeys.createEffectiveKey(componentKey, (InputPath) component); + String componentKeyWithBranch = project.getKeyWithBranch(); + if (component.isFile()) { + componentKeyWithBranch = ComponentKeys.createEffectiveKey(componentKeyWithBranch, (DefaultInputFile) component); } json .beginObject() .prop("key", issue.key()) - .prop("component", componentKey) + .prop("component", componentKeyWithBranch) .prop("line", issue.startLine()) .prop("startLine", issue.startLine()) .prop("startOffset", issue.startLineOffset()) @@ -158,54 +149,28 @@ public class JSONReport implements Reporter { json.endArray(); } - private AbstractProjectOrModule getModule(InputComponent component) { - if (component.isFile()) { - return (AbstractProjectOrModule) inputComponentTree.getParent(inputComponentTree.getParent(component)); - } - if (component instanceof InputDir) { - return (AbstractProjectOrModule) inputComponentTree.getParent(component); - } - return (AbstractProjectOrModule) component; - } - private void writeJsonComponents(JsonWriter json) { json.name("components").beginArray(); // Dump modules - writeJsonModuleComponents(json, rootModule); + writeJsonProject(json); for (DefaultInputFile inputFile : componentStore.allFilesToPublish()) { - String moduleKey = getModule(inputFile).definition().getKeyWithBranch(); - String key = ComponentKeys.createEffectiveKey(moduleKey, inputFile); + String projectKey = project.getKeyWithBranch(); + String key = ComponentKeys.createEffectiveKey(projectKey, inputFile); json .beginObject() .prop("key", key) .prop("path", inputFile.relativePath()) - .prop("moduleKey", moduleKey) .prop("status", inputFile.status().name()) .endObject(); } - for (InputDir inputDir : componentStore.allDirs()) { - String moduleKey = getModule(inputDir).definition().getKeyWithBranch(); - String key = ComponentKeys.createEffectiveKey(moduleKey, inputDir); - json - .beginObject() - .prop("key", key) - .prop("path", inputDir.relativePath()) - .prop("moduleKey", moduleKey) - .endObject(); - - } json.endArray(); } - private void writeJsonModuleComponents(JsonWriter json, DefaultInputModule moduleOrProject) { + private void writeJsonProject(JsonWriter json) { json .beginObject() - .prop("key", moduleOrProject.definition().getKeyWithBranch()) - .prop("path", moduleHierarchy.relativePath(moduleOrProject)) + .prop("key", project.definition().getKeyWithBranch()) .endObject(); - for (DefaultInputModule subModule : moduleHierarchy.children(moduleOrProject)) { - writeJsonModuleComponents(json, subModule); - } } private void writeJsonRules(JsonWriter json, Set<RuleKey> ruleKeys) { |