From 37de8c365c2c6174c532e1a4d0986e7be348968f Mon Sep 17 00:00:00 2001 From: Arshan Dabirsiaghi Date: Thu, 9 Jan 2025 09:15:32 -0500 Subject: [PATCH] Honor new combined Sonar flag (#489) https://github.com/pixee/codemodder-specs/pull/43 --- .../codemods/AddMissingI18nCodemodTest.java | 1 - .../codemods/JSPScriptletXSSCodemodTest.java | 1 - .../codemods/VerbTamperingCodemodTest.java | 1 - .../sonar/AddMissingOverrideCodemodTest.java | 2 +- .../{sonar-issues.json => sonar.json} | 0 .../src/main/java/io/codemodder/CLI.java | 19 ++--- .../java/io/codemodder/CodemodLoader.java | 6 +- .../java/io/codemodder/CodemodProvider.java | 9 +- .../java/io/codemodder/CodemodLoaderTest.java | 5 -- .../testutils/CodemodTestMixin.java | 31 ++++--- .../io/codemodder/testutils/Metadata.java | 5 +- .../testutils/RawFileCodemodTest.java | 1 - .../sarif/appscan/AppScanProvider.java | 3 +- .../codemodder/plugins/aws/AwsProvider.java | 3 +- .../sarif/codeql/CodeQLProvider.java | 3 +- .../sarif/codeql/ConflictingSarifTest.java | 1 - .../defectdojo/DefectDojoProvider.java | 3 +- .../codemodder/plugins/llm/LLMProvider.java | 3 +- .../providers/sarif/pmd/PmdProvider.java | 3 +- .../sarif/semgrep/SemgrepProvider.java | 3 +- .../providers/sonar/SonarProvider.java | 83 ++++++------------- ...CombinedSearchIssueAndHotspotResponse.java | 29 +++++++ 22 files changed, 89 insertions(+), 126 deletions(-) rename core-codemods/src/test/resources/avoid-implicit-public-constructor-s1118/{sonar-issues.json => sonar.json} (100%) create mode 100644 sonar-api-model/src/main/java/io/codemodder/sonar/model/CombinedSearchIssueAndHotspotResponse.java diff --git a/core-codemods/src/test/java/io/codemodder/codemods/AddMissingI18nCodemodTest.java b/core-codemods/src/test/java/io/codemodder/codemods/AddMissingI18nCodemodTest.java index ae20efad3..639ae2f98 100644 --- a/core-codemods/src/test/java/io/codemodder/codemods/AddMissingI18nCodemodTest.java +++ b/core-codemods/src/test/java/io/codemodder/codemods/AddMissingI18nCodemodTest.java @@ -254,7 +254,6 @@ private CodemodLoader createLoader(final Class codemodTyp Files.list(dir).toList(), Map.of(), List.of(), - List.of(), null, null, null); diff --git a/core-codemods/src/test/java/io/codemodder/codemods/JSPScriptletXSSCodemodTest.java b/core-codemods/src/test/java/io/codemodder/codemods/JSPScriptletXSSCodemodTest.java index 2674b6bc4..797265310 100644 --- a/core-codemods/src/test/java/io/codemodder/codemods/JSPScriptletXSSCodemodTest.java +++ b/core-codemods/src/test/java/io/codemodder/codemods/JSPScriptletXSSCodemodTest.java @@ -50,7 +50,6 @@ void it_fixes_jsp( List.of(jsp), Map.of(), List.of(), - List.of(), null, null, null); diff --git a/core-codemods/src/test/java/io/codemodder/codemods/VerbTamperingCodemodTest.java b/core-codemods/src/test/java/io/codemodder/codemods/VerbTamperingCodemodTest.java index 6afa4b5b5..9dbc9b269 100644 --- a/core-codemods/src/test/java/io/codemodder/codemods/VerbTamperingCodemodTest.java +++ b/core-codemods/src/test/java/io/codemodder/codemods/VerbTamperingCodemodTest.java @@ -60,7 +60,6 @@ void it_removes_verb_tampering( List.of(webxml), Map.of(), List.of(), - List.of(), null, null, null); diff --git a/core-codemods/src/test/java/io/codemodder/codemods/sonar/AddMissingOverrideCodemodTest.java b/core-codemods/src/test/java/io/codemodder/codemods/sonar/AddMissingOverrideCodemodTest.java index 484bf6ba7..b4010daf1 100644 --- a/core-codemods/src/test/java/io/codemodder/codemods/sonar/AddMissingOverrideCodemodTest.java +++ b/core-codemods/src/test/java/io/codemodder/codemods/sonar/AddMissingOverrideCodemodTest.java @@ -8,5 +8,5 @@ testResourceDir = "add-missing-override-s1161", renameTestFile = "src/main/java/SqlInjectionLesson10b.java", dependencies = {}, - sonarIssuesJsonFiles = {"sonar-issues_1.json", "sonar-issues_2.json"}) + sonarJsonFiles = {"sonar-issues_1.json", "sonar-issues_2.json"}) final class AddMissingOverrideCodemodTest implements CodemodTestMixin {} diff --git a/core-codemods/src/test/resources/avoid-implicit-public-constructor-s1118/sonar-issues.json b/core-codemods/src/test/resources/avoid-implicit-public-constructor-s1118/sonar.json similarity index 100% rename from core-codemods/src/test/resources/avoid-implicit-public-constructor-s1118/sonar-issues.json rename to core-codemods/src/test/resources/avoid-implicit-public-constructor-s1118/sonar.json diff --git a/framework/codemodder-base/src/main/java/io/codemodder/CLI.java b/framework/codemodder-base/src/main/java/io/codemodder/CLI.java index 2811e794a..559134a37 100644 --- a/framework/codemodder-base/src/main/java/io/codemodder/CLI.java +++ b/framework/codemodder-base/src/main/java/io/codemodder/CLI.java @@ -116,11 +116,11 @@ final class CLI implements Callable { private String projectName; @CommandLine.Option( - names = {"--sonar-issues-json"}, + names = {"--sonar-json"}, description = - "comma-separated set of path(s) to file(s) containing the result of a call to the Sonar Web API Issues endpoint", + "comma-separated set of path(s) to file(s) containing the result of a call to the Sonar Web API Issues or Hotspots endpoint (or both such files merged together)", split = ",") - private List sonarIssuesJsonFilePaths; + private List sonarJsons; @CommandLine.Option( names = {"--defectdojo-findings-json"}, @@ -128,13 +128,6 @@ final class CLI implements Callable { "a path to a file containing the result of a call to the DefectDojo v2 Findings API endpoint") private Path defectDojoFindingsJsonFilePath; - @CommandLine.Option( - names = {"--sonar-hotspots-json"}, - description = - "comma-separated set of path(s) to file(s) containing the result of a call to the Sonar Web API Hotspots endpoint", - split = ",") - private List sonarHotspotsJsonFilePaths; - @CommandLine.Option( names = {"--contrast-vulnerabilities-xml"}, description = @@ -394,8 +387,7 @@ public Integer call() throws IOException { log.debug("Loading input files"); CodeDirectory codeDirectory = new DefaultCodeDirectory(projectPath); List sarifFiles = convertToPaths(sarifs); - List sonarIssuesJsonFiles = convertToPaths(sonarIssuesJsonFilePaths); - List sonarHotspotJsonFiles = convertToPaths(sonarHotspotsJsonFilePaths); + List sonarJsonFiles = convertToPaths(sonarJsons); log.debug("Parsing SARIFs"); Map> pathSarifMap = @@ -412,8 +404,7 @@ public Integer call() throws IOException { filePaths, pathSarifMap, codemodParameters, - sonarIssuesJsonFiles, - sonarHotspotJsonFiles, + sonarJsonFiles, defectDojoFindingsJsonFilePath, contrastVulnerabilitiesXmlFilePath); List codemods = loader.getCodemods(); diff --git a/framework/codemodder-base/src/main/java/io/codemodder/CodemodLoader.java b/framework/codemodder-base/src/main/java/io/codemodder/CodemodLoader.java index 77d45611c..3158610f3 100644 --- a/framework/codemodder-base/src/main/java/io/codemodder/CodemodLoader.java +++ b/framework/codemodder-base/src/main/java/io/codemodder/CodemodLoader.java @@ -30,8 +30,7 @@ public CodemodLoader( final List includedFiles, final Map> ruleSarifByTool, final List codemodParameters, - final List sonarIssuesJsonFiles, - final List sonarHotspotsJsonFiles, + final List sonarJsonFiles, final Path defectDojoFindingsJsonFile, final Path contrastVulnerabilitiesXmlFilePath) { @@ -119,8 +118,7 @@ public CodemodLoader( pathExcludes, orderedCodemodTypes, allWantedSarifs, - sonarIssuesJsonFiles, - sonarHotspotsJsonFiles, + sonarJsonFiles, defectDojoFindingsJsonFile, contrastVulnerabilitiesXmlFilePath); allModules.addAll(modules); diff --git a/framework/codemodder-base/src/main/java/io/codemodder/CodemodProvider.java b/framework/codemodder-base/src/main/java/io/codemodder/CodemodProvider.java index dd472cc61..853e33e5d 100644 --- a/framework/codemodder-base/src/main/java/io/codemodder/CodemodProvider.java +++ b/framework/codemodder-base/src/main/java/io/codemodder/CodemodProvider.java @@ -22,8 +22,8 @@ public interface CodemodProvider { * their own analysis) * @param codemodTypes the codemod types that are being run * @param sarifs the SARIF output of tools that are being run - * @param sonarIssuesJsonPaths the path to a Sonar issues JSON file retrieved from their web API - * -- may be null + * @param sonarJsonPaths the path to a Sonar issues/hotspots or combined JSON file retrieved from + * their web API -- may be null * @param contrastFindingsJsonPath the path to a Contrast findings JSON file retrieved from their * web API -- may be null * @return a set of modules that perform dependency injection @@ -35,15 +35,14 @@ Set getModules( List pathExcludes, List> codemodTypes, List sarifs, - List sonarIssuesJsonPaths, - List sonarHotspotsJsonPaths, + List sonarJsonPaths, Path defectDojoFindingsJsonPath, Path contrastFindingsJsonPath); /** * Tools this provider is interested in processing the SARIF output of. Codemodder CLI will look * for the SARIF outputted by tools in this list in the repository root and then provide the - * results to {@link #getModules(Path, List, List, List, List, List, List, List, Path, Path)} as a + * results to {@link #getModules(Path, List, List, List, List, List, List, Path, Path)} as a * {@link List} of {@link RuleSarif}s. * *

By default, this returns an empty list. diff --git a/framework/codemodder-base/src/test/java/io/codemodder/CodemodLoaderTest.java b/framework/codemodder-base/src/test/java/io/codemodder/CodemodLoaderTest.java index 5ee1ed817..e165cc8f1 100644 --- a/framework/codemodder-base/src/test/java/io/codemodder/CodemodLoaderTest.java +++ b/framework/codemodder-base/src/test/java/io/codemodder/CodemodLoaderTest.java @@ -257,7 +257,6 @@ void it_handles_codemod_orders(final @TempDir Path tmpDir) throws IOException { Files.list(tmpDir).toList(), Map.of(), List.of(), - List.of(), null, null, null); @@ -282,7 +281,6 @@ void it_handles_codemod_orders(final @TempDir Path tmpDir) throws IOException { Files.list(tmpDir).toList(), Map.of(), List.of(), - List.of(), null, null, null); @@ -510,7 +508,6 @@ private CodemodLoader createLoader(final Class codemodTyp Files.list(dir).toList(), Map.of(), List.of(), - List.of(), null, null, null); @@ -527,7 +524,6 @@ private CodemodLoader createLoader( Files.list(dir).toList(), Map.of(), List.of(), - List.of(), null, null, null); @@ -549,7 +545,6 @@ private CodemodLoader createLoader( params, null, null, - null, null); } } diff --git a/framework/codemodder-testutils/src/main/java/io/codemodder/testutils/CodemodTestMixin.java b/framework/codemodder-testutils/src/main/java/io/codemodder/testutils/CodemodTestMixin.java index 064c8de28..880ea44dd 100644 --- a/framework/codemodder-testutils/src/main/java/io/codemodder/testutils/CodemodTestMixin.java +++ b/framework/codemodder-testutils/src/main/java/io/codemodder/testutils/CodemodTestMixin.java @@ -83,8 +83,7 @@ default Stream generateTestCases(@TempDir final Path tmpDir) throws metadata.doRetransformTest(), metadata.expectingFixesAtLines(), metadata.expectingFailedFixesAtLines(), - metadata.sonarIssuesJsonFiles(), - metadata.sonarHotspotsJsonFiles()); + metadata.sonarJsonFiles()); }; final Predicate displayNameFilter = @@ -104,8 +103,7 @@ private void verifyCodemod( final boolean doRetransformTest, final int[] expectedFixLines, final int[] expectingFailedFixesAtLines, - final String[] sonarIssuesJsonFiles, - final String[] sonarHotspotsJsonFiles) + final String[] sonarJsonFiles) throws IOException { // create a copy of the test file in the temp directory to serve as our "repository" @@ -125,10 +123,11 @@ private void verifyCodemod( pathToJavaFile = newPathToJavaFile; } - final List sonarIssuesJsonsPaths = - buildSonarJsonPaths(testResourceDir, sonarIssuesJsonFiles, "sonar-issues.json"); - final List sonarHotspotsJsonPaths = - buildSonarJsonPaths(testResourceDir, sonarHotspotsJsonFiles, "sonar-hotspots.json"); + final List sonarJsonsPaths = + buildSonarJsonPaths( + testResourceDir, + sonarJsonFiles, + List.of("sonar.json", "sonar-issues.json", "sonar-hotspots.json")); // Check for any sarif files and build the RuleSarif map CodeDirectory codeDir = CodeDirectory.from(tmpDir); @@ -155,8 +154,7 @@ private void verifyCodemod( List.of(pathToJavaFile), map, List.of(), - sonarIssuesJsonsPaths, - sonarHotspotsJsonPaths, + sonarJsonsPaths, Files.exists(defectDojo) ? defectDojo : null, Files.exists(contrastXml) ? contrastXml : null); @@ -242,8 +240,7 @@ private void verifyCodemod( List.of(pathToJavaFile), map, List.of(), - null, - null, + List.of(), null, null); CodemodIdPair codemod2 = loader2.getCodemods().get(0); @@ -275,7 +272,7 @@ private void verifyCodemod( private List buildSonarJsonPaths( final Path testResourceDir, final String[] sonarJsonFiles, - final String defaultSonarFilename) { + final List defaultSonarFilenames) { final List sonarJsons = sonarJsonFiles != null ? Arrays.asList(sonarJsonFiles) : new ArrayList<>(); @@ -286,9 +283,11 @@ private List buildSonarJsonPaths( .collect(Collectors.toList()); if (sonarIssuesJsonsPaths.isEmpty()) { - Path defaultPath = testResourceDir.resolve(defaultSonarFilename); - if (Files.exists(defaultPath)) { - sonarIssuesJsonsPaths.add(defaultPath); + for (String defaultSonarFilename : defaultSonarFilenames) { + Path defaultPath = testResourceDir.resolve(defaultSonarFilename); + if (Files.exists(defaultPath)) { + sonarIssuesJsonsPaths.add(defaultPath); + } } } diff --git a/framework/codemodder-testutils/src/main/java/io/codemodder/testutils/Metadata.java b/framework/codemodder-testutils/src/main/java/io/codemodder/testutils/Metadata.java index 440773dc5..fbd77a896 100644 --- a/framework/codemodder-testutils/src/main/java/io/codemodder/testutils/Metadata.java +++ b/framework/codemodder-testutils/src/main/java/io/codemodder/testutils/Metadata.java @@ -50,10 +50,7 @@ int[] expectingFailedFixesAtLines() default {}; /** Sonar issues file names for testing multiple json files */ - String[] sonarIssuesJsonFiles() default {}; - - /** Sonar hotspots file names for testing multiple json files */ - String[] sonarHotspotsJsonFiles() default {}; + String[] sonarJsonFiles() default {}; /** * Used to filter test execution to only the tests with a display name that matches the given diff --git a/framework/codemodder-testutils/src/main/java/io/codemodder/testutils/RawFileCodemodTest.java b/framework/codemodder-testutils/src/main/java/io/codemodder/testutils/RawFileCodemodTest.java index 4782216b1..333bb52fb 100644 --- a/framework/codemodder-testutils/src/main/java/io/codemodder/testutils/RawFileCodemodTest.java +++ b/framework/codemodder-testutils/src/main/java/io/codemodder/testutils/RawFileCodemodTest.java @@ -71,7 +71,6 @@ private void verifySingleCase( List.of(), null, null, - null, null); List codemods = loader.getCodemods(); assertThat("Only expecting 1 codemod per test", codemods.size(), equalTo(1)); diff --git a/plugins/codemodder-plugin-appscan/src/main/java/io/codemodder/providers/sarif/appscan/AppScanProvider.java b/plugins/codemodder-plugin-appscan/src/main/java/io/codemodder/providers/sarif/appscan/AppScanProvider.java index 42d983285..d83408017 100644 --- a/plugins/codemodder-plugin-appscan/src/main/java/io/codemodder/providers/sarif/appscan/AppScanProvider.java +++ b/plugins/codemodder-plugin-appscan/src/main/java/io/codemodder/providers/sarif/appscan/AppScanProvider.java @@ -19,8 +19,7 @@ public Set getModules( final List excludePaths, final List> codemodTypes, final List sarifs, - final List sonarIssuesJsonPaths, - final List sonarHotspotsJsonPaths, + final List sonarJsonPaths, final Path defectDojoFindingsJsonFile, final Path contrastFindingsJsonPath) { return Set.of(new AppScanModule(codemodTypes, sarifs)); diff --git a/plugins/codemodder-plugin-aws/src/main/java/io/codemodder/plugins/aws/AwsProvider.java b/plugins/codemodder-plugin-aws/src/main/java/io/codemodder/plugins/aws/AwsProvider.java index 844a1afa0..509a858c4 100644 --- a/plugins/codemodder-plugin-aws/src/main/java/io/codemodder/plugins/aws/AwsProvider.java +++ b/plugins/codemodder-plugin-aws/src/main/java/io/codemodder/plugins/aws/AwsProvider.java @@ -19,8 +19,7 @@ public Set getModules( final List excludePaths, final List> codemodTypes, final List sarifs, - final List sonarIssuesJsonPaths, - final List sonarHotspotsJsonPaths, + final List sonarJsonPaths, final Path defectDojoFindingsJsonFile, final Path contrastFindingsJsonPath) { return Set.of(new AwsClientModule()); diff --git a/plugins/codemodder-plugin-codeql/src/main/java/io/codemodder/providers/sarif/codeql/CodeQLProvider.java b/plugins/codemodder-plugin-codeql/src/main/java/io/codemodder/providers/sarif/codeql/CodeQLProvider.java index d21fe2c61..207cf91a2 100644 --- a/plugins/codemodder-plugin-codeql/src/main/java/io/codemodder/providers/sarif/codeql/CodeQLProvider.java +++ b/plugins/codemodder-plugin-codeql/src/main/java/io/codemodder/providers/sarif/codeql/CodeQLProvider.java @@ -19,8 +19,7 @@ public Set getModules( final List excludePaths, final List> codemodTypes, final List sarifs, - final List sonarIssuesJsonPaths, - final List sonarHotspotsJsonPaths, + final List sonarJsonPaths, final Path defectDojoFindingsJsonFile, final Path contrastFindingsJsonPath) { return Set.of(new CodeQLModule(codemodTypes, sarifs)); diff --git a/plugins/codemodder-plugin-codeql/src/test/java/io/codemodder/providers/sarif/codeql/ConflictingSarifTest.java b/plugins/codemodder-plugin-codeql/src/test/java/io/codemodder/providers/sarif/codeql/ConflictingSarifTest.java index 0eac2d336..4cf403d67 100644 --- a/plugins/codemodder-plugin-codeql/src/test/java/io/codemodder/providers/sarif/codeql/ConflictingSarifTest.java +++ b/plugins/codemodder-plugin-codeql/src/test/java/io/codemodder/providers/sarif/codeql/ConflictingSarifTest.java @@ -37,7 +37,6 @@ void it_combines_sarifs_with_overlapping_keys(@TempDir Path tempDir) { pathSarifMap, List.of(), List.of(), - List.of(), null, null); } diff --git a/plugins/codemodder-plugin-defectdojo/src/main/java/io/codemodder/providers/defectdojo/DefectDojoProvider.java b/plugins/codemodder-plugin-defectdojo/src/main/java/io/codemodder/providers/defectdojo/DefectDojoProvider.java index 5b1a12aad..42df2e68f 100644 --- a/plugins/codemodder-plugin-defectdojo/src/main/java/io/codemodder/providers/defectdojo/DefectDojoProvider.java +++ b/plugins/codemodder-plugin-defectdojo/src/main/java/io/codemodder/providers/defectdojo/DefectDojoProvider.java @@ -19,8 +19,7 @@ public Set getModules( final List pathExcludes, final List> codemodTypes, final List sarifs, - final List sonarIssuesJsonPaths, - final List sonarHotspotsJsonPaths, + final List sonarJsonPaths, final Path defectDojoFindingsJsonFile, final Path contrastFindingsJsonPath) { return Set.of(new DefectDojoModule(codemodTypes, repository, defectDojoFindingsJsonFile)); diff --git a/plugins/codemodder-plugin-llm/src/main/java/io/codemodder/plugins/llm/LLMProvider.java b/plugins/codemodder-plugin-llm/src/main/java/io/codemodder/plugins/llm/LLMProvider.java index 4a1dfde19..f5cfe5ab0 100644 --- a/plugins/codemodder-plugin-llm/src/main/java/io/codemodder/plugins/llm/LLMProvider.java +++ b/plugins/codemodder-plugin-llm/src/main/java/io/codemodder/plugins/llm/LLMProvider.java @@ -19,8 +19,7 @@ public Set getModules( final List excludePaths, final List> codemodTypes, final List sarifs, - final List sonarIssuesJsonPaths, - final List sonarHotspotsJsonPaths, + final List sonarJsonPaths, final Path defectDojoFindingsJsonFile, final Path contrastFindingsJsonPath) { return Set.of(new LLMServiceModule()); diff --git a/plugins/codemodder-plugin-pmd/src/main/java/io/codemodder/providers/sarif/pmd/PmdProvider.java b/plugins/codemodder-plugin-pmd/src/main/java/io/codemodder/providers/sarif/pmd/PmdProvider.java index e9a6cf88e..669ebf31b 100644 --- a/plugins/codemodder-plugin-pmd/src/main/java/io/codemodder/providers/sarif/pmd/PmdProvider.java +++ b/plugins/codemodder-plugin-pmd/src/main/java/io/codemodder/providers/sarif/pmd/PmdProvider.java @@ -19,8 +19,7 @@ public Set getModules( final List excludePaths, final List> codemodTypes, final List sarifs, - final List sonarIssuesJsonPaths, - final List sonarHotspotsJsonPaths, + final List sonarJsonPaths, final Path defectDojoFindingsJsonFile, final Path contrastFindingsJsonPath) { return Set.of(new PmdModule(codeDirectory, includedFiles, codemodTypes)); diff --git a/plugins/codemodder-plugin-semgrep/src/main/java/io/codemodder/providers/sarif/semgrep/SemgrepProvider.java b/plugins/codemodder-plugin-semgrep/src/main/java/io/codemodder/providers/sarif/semgrep/SemgrepProvider.java index 3d31db0aa..09505d39c 100644 --- a/plugins/codemodder-plugin-semgrep/src/main/java/io/codemodder/providers/sarif/semgrep/SemgrepProvider.java +++ b/plugins/codemodder-plugin-semgrep/src/main/java/io/codemodder/providers/sarif/semgrep/SemgrepProvider.java @@ -19,8 +19,7 @@ public Set getModules( final List excludePaths, final List> codemodTypes, final List sarifs, - final List sonarIssuesJsonPaths, - final List sonarHotspotsJsonPaths, + final List sonarJsonPaths, final Path defectDojoFindingsJsonFile, final Path contrastFindingsJsonPath) { return Set.of( diff --git a/plugins/codemodder-plugin-sonar/src/main/java/io/codemodder/providers/sonar/SonarProvider.java b/plugins/codemodder-plugin-sonar/src/main/java/io/codemodder/providers/sonar/SonarProvider.java index 55adc0407..089c452ee 100644 --- a/plugins/codemodder-plugin-sonar/src/main/java/io/codemodder/providers/sonar/SonarProvider.java +++ b/plugins/codemodder-plugin-sonar/src/main/java/io/codemodder/providers/sonar/SonarProvider.java @@ -6,10 +6,7 @@ import io.codemodder.CodeChanger; import io.codemodder.CodemodProvider; import io.codemodder.RuleSarif; -import io.codemodder.sonar.model.Hotspot; -import io.codemodder.sonar.model.Issue; -import io.codemodder.sonar.model.SearchHotspotsResponse; -import io.codemodder.sonar.model.SearchIssueResponse; +import io.codemodder.sonar.model.*; import java.io.IOException; import java.io.UncheckedIOException; import java.nio.file.Path; @@ -28,64 +25,34 @@ public Set getModules( final List pathExcludes, final List> codemodTypes, final List sarifs, - final List sonarIssuesJsonPaths, - final List sonarHotspotsJsonPaths, + final List sonarJsonPaths, final Path defectDojoFindingsJsonFile, final Path contrastFindingsJsonPath) { - final List issues = getIssues(sonarIssuesJsonPaths); - final List hotspots = getHotspots(sonarHotspotsJsonPaths); - return Set.of( - new SonarModule<>(codemodTypes, repository, issues, RuleIssue.class), - new SonarModule<>(codemodTypes, repository, hotspots, RuleHotspot.class)); - } - - private List getIssues(List sonarIssuesJsonPaths) { - List allIssues = List.of(); - if (sonarIssuesJsonPaths != null) { - List issueResponses = new ArrayList<>(); - sonarIssuesJsonPaths.forEach( - issuesFile -> { - try { - SearchIssueResponse issueResponse = - new ObjectMapper() - .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false) - .readValue(issuesFile.toFile(), SearchIssueResponse.class); - issueResponses.add(issueResponse); - } catch (IOException e) { - throw new UncheckedIOException("Problem reading Sonar issues JSON file", e); - } - }); - - allIssues = - issueResponses.stream().flatMap(response -> response.getIssues().stream()).toList(); + List issues = new ArrayList<>(); + List hotspots = new ArrayList<>(); + if (sonarJsonPaths != null) { + for (Path path : sonarJsonPaths) { + try { + CombinedSearchIssueAndHotspotResponse response = + new ObjectMapper() + .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false) + .readValue(path.toFile(), CombinedSearchIssueAndHotspotResponse.class); + + if (response.getIssues() != null) { + issues.addAll(response.getIssues()); + } + if (response.getHotspots() != null) { + hotspots.addAll(response.getHotspots()); + } + } catch (IOException e) { + throw new UncheckedIOException("Problem reading Sonar JSON file", e); + } + } } - return allIssues; - } - - private List getHotspots(final List sonarHotspotsJsonPaths) { - List allHotspots = List.of(); - if (sonarHotspotsJsonPaths != null) { - List hotspotsResponses = new ArrayList<>(); - - sonarHotspotsJsonPaths.forEach( - hotspotsFile -> { - try { - SearchHotspotsResponse hotspotResponse = - new ObjectMapper() - .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false) - .readValue(hotspotsFile.toFile(), SearchHotspotsResponse.class); - hotspotsResponses.add(hotspotResponse); - } catch (IOException e) { - throw new UncheckedIOException("Problem reading Sonar hotspot JSON file", e); - } - }); - - allHotspots = - hotspotsResponses.stream().flatMap(response -> response.getHotspots().stream()).toList(); - } - - return allHotspots; + return Set.of( + new SonarModule<>(codemodTypes, repository, List.copyOf(issues), RuleIssue.class), + new SonarModule<>(codemodTypes, repository, List.copyOf(hotspots), RuleHotspot.class)); } } diff --git a/sonar-api-model/src/main/java/io/codemodder/sonar/model/CombinedSearchIssueAndHotspotResponse.java b/sonar-api-model/src/main/java/io/codemodder/sonar/model/CombinedSearchIssueAndHotspotResponse.java new file mode 100644 index 000000000..5520cedd3 --- /dev/null +++ b/sonar-api-model/src/main/java/io/codemodder/sonar/model/CombinedSearchIssueAndHotspotResponse.java @@ -0,0 +1,29 @@ +package io.codemodder.sonar.model; + +import com.fasterxml.jackson.annotation.JsonProperty; +import java.util.List; + +/** + * The response when searching for issues, combined with hotspots. The metadata fields are ignored. + */ +public final class CombinedSearchIssueAndHotspotResponse extends SearchFindingResponse { + + @JsonProperty("issues") + private List issues; + + @JsonProperty("hotspots") + private List hotspots; + + public List getHotspots() { + return hotspots; + } + + public List getIssues() { + return issues; + } + + @Override + public int findingCount() { + throw new UnsupportedOperationException("Not implemented"); + } +}