Skip to content

Commit 33aef9a

Browse files
Avoid accessing SonarComponents at injection time to prevent NPE
1 parent 59c0140 commit 33aef9a

File tree

2 files changed

+35
-23
lines changed

2 files changed

+35
-23
lines changed

java-frontend/src/main/java/org/sonar/java/DefaultModuleMetadata.java

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,21 +16,25 @@
1616
*/
1717
package org.sonar.java;
1818

19+
import javax.annotation.CheckForNull;
20+
import org.sonar.api.batch.bootstrap.ProjectDefinition;
1921
import org.sonar.api.config.Configuration;
2022
import org.sonar.java.model.JavaVersionImpl;
2123
import org.sonar.plugins.java.api.JavaVersion;
2224
import org.sonar.plugins.java.api.internal.ModuleMetadata;
2325

26+
import static org.sonar.java.SonarComponents.SONAR_IGNORE_UNNAMED_MODULE_FOR_SPLIT_PACKAGE;
27+
2428
public class DefaultModuleMetadata implements ModuleMetadata {
2529

2630
private final JavaVersion javaVersion;
27-
private final String moduleKey;
31+
private final ProjectDefinition projectDefinition;
2832
private final boolean ignoreUnnamedModuleForSplitPackage;
2933

30-
public DefaultModuleMetadata(SonarComponents sonarComponents, Configuration configuration) {
34+
public DefaultModuleMetadata(ProjectDefinition projectDefinition, Configuration configuration) {
3135
this.javaVersion = JavaVersionImpl.readFromConfiguration(configuration);
32-
this.moduleKey = sonarComponents.getModuleKey();
33-
this.ignoreUnnamedModuleForSplitPackage = sonarComponents.shouldIgnoreUnnamedModuleForSplitPackage();
36+
this.projectDefinition = projectDefinition;
37+
this.ignoreUnnamedModuleForSplitPackage = configuration.getBoolean(SONAR_IGNORE_UNNAMED_MODULE_FOR_SPLIT_PACKAGE).orElse(false);
3438
}
3539

3640
@Override
@@ -40,12 +44,30 @@ public JavaVersion javaVersion() {
4044

4145
@Override
4246
public String moduleKey() {
43-
return moduleKey;
47+
var root = getRootProject();
48+
if (root != null && projectDefinition != null) {
49+
var rootBase = root.getBaseDir().toPath();
50+
var moduleBase = projectDefinition.getBaseDir().toPath();
51+
return rootBase.relativize(moduleBase).toString().replace('\\', '/');
52+
}
53+
return "";
4454
}
4555

4656
@Override
4757
public boolean shouldIgnoreUnnamedModuleForSplitPackage() {
4858
return ignoreUnnamedModuleForSplitPackage;
4959
}
5060

61+
@CheckForNull
62+
private ProjectDefinition getRootProject() {
63+
ProjectDefinition current = projectDefinition;
64+
if (current == null) {
65+
return null;
66+
}
67+
while (current.getParent() != null) {
68+
current = current.getParent();
69+
}
70+
return current;
71+
}
72+
5173
}

java-frontend/src/test/java/org/sonar/java/DefaultModuleMetadataTest.java

Lines changed: 8 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020
import java.util.Optional;
2121
import org.junit.jupiter.api.Test;
2222
import org.sonar.api.batch.bootstrap.ProjectDefinition;
23-
import org.sonar.api.batch.sensor.SensorContext;
2423
import org.sonar.api.config.Configuration;
2524

2625
import static org.assertj.core.api.Assertions.assertThat;
@@ -31,10 +30,9 @@ class DefaultModuleMetadataTest {
3130

3231
@Test
3332
void test() {
34-
var sonarComponents = mockSonarComponents();
33+
var projectDefinition = mockProjectDefinition();
3534
var config = mockConfiguration();
36-
sonarComponents.setSensorContext(mockSensorContext(config));
37-
var defaultModuleMetadata = new DefaultModuleMetadata(sonarComponents, config);
35+
var defaultModuleMetadata = new DefaultModuleMetadata(projectDefinition, config);
3836

3937
assertThat(defaultModuleMetadata.moduleKey()).isEqualTo("pmodule/cmodule");
4038
assertThat(defaultModuleMetadata.javaVersion().asInt()).isEqualTo(-1);
@@ -43,34 +41,32 @@ void test() {
4341

4442
@Test
4543
void testWithJavaVersion() {
46-
var sonarComponents = mockSonarComponents();
44+
var projectDefinition = mockProjectDefinition();
4745
var config = mockConfiguration("sonar.java.source", "11");
48-
sonarComponents.setSensorContext(mockSensorContext(config));
49-
var defaultModuleMetadata = new DefaultModuleMetadata(sonarComponents, config);
46+
var defaultModuleMetadata = new DefaultModuleMetadata(projectDefinition, config);
5047

5148
assertThat(defaultModuleMetadata.moduleKey()).isEqualTo("pmodule/cmodule");
5249
assertThat(defaultModuleMetadata.javaVersion().asInt()).isEqualTo(11);
5350
}
5451

5552
@Test
5653
void testWithShouldIgnoreUnnamed() {
57-
var sonarComponents = mockSonarComponents();
54+
var projectDefinition = mockProjectDefinition();
5855
var config = mockConfiguration("sonar.java.ignoreUnnamedModuleForSplitPackage", "true");
59-
sonarComponents.setSensorContext(mockSensorContext(config));
60-
var defaultModuleMetadata = new DefaultModuleMetadata(sonarComponents, config);
56+
var defaultModuleMetadata = new DefaultModuleMetadata(projectDefinition, config);
6157

6258
assertThat(defaultModuleMetadata.moduleKey()).isEqualTo("pmodule/cmodule");
6359
assertThat(defaultModuleMetadata.shouldIgnoreUnnamedModuleForSplitPackage()).isTrue();
6460
}
6561

66-
private SonarComponents mockSonarComponents() {
62+
private ProjectDefinition mockProjectDefinition() {
6763
var rootProj = mock(ProjectDefinition.class);
6864
doReturn(new File("/foo/bar/proj")).when(rootProj).getBaseDir();
6965
var childModule = mock(ProjectDefinition.class);
7066
doReturn(new File("/foo/bar/proj/pmodule/cmodule")).when(childModule).getBaseDir();
7167
doReturn(rootProj).when(childModule).getParent();
7268

73-
return new SonarComponents(null, null, null, null, null, null, childModule);
69+
return childModule;
7470
}
7571

7672
private Configuration mockConfiguration(String... keysAndValues) {
@@ -86,10 +82,4 @@ private Configuration mockConfiguration(String... keysAndValues) {
8682
return configuration;
8783
}
8884

89-
private SensorContext mockSensorContext(Configuration config) {
90-
var sctx = mock(SensorContext.class);
91-
doReturn(config).when(sctx).config();
92-
return sctx;
93-
}
94-
9585
}

0 commit comments

Comments
 (0)