diff --git a/java-frontend/src/main/java/org/sonar/java/DefaultModuleMetadata.java b/java-frontend/src/main/java/org/sonar/java/DefaultModuleMetadata.java new file mode 100644 index 00000000000..e9f374f9a09 --- /dev/null +++ b/java-frontend/src/main/java/org/sonar/java/DefaultModuleMetadata.java @@ -0,0 +1,44 @@ +/* + * SonarQube Java + * Copyright (C) 2012-2025 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 Sonar Source-Available License Version 1, as published by SonarSource SA. + * + * 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 Sonar Source-Available License for more details. + * + * You should have received a copy of the Sonar Source-Available License + * along with this program; if not, see https://sonarsource.com/license/ssal/ + */ +package org.sonar.java; + +import org.sonar.api.config.Configuration; +import org.sonar.java.model.JavaVersionImpl; +import org.sonar.plugins.java.api.JavaVersion; +import org.sonar.plugins.java.api.internal.ModuleMetadata; + +public class DefaultModuleMetadata implements ModuleMetadata { + + private final JavaVersion javaVersion; + private final String moduleKey; + + public DefaultModuleMetadata(SonarComponents sonarComponents, Configuration configuration) { + this.javaVersion = JavaVersionImpl.readFromConfiguration(configuration); + this.moduleKey = sonarComponents.getModuleKey(); + } + + @Override + public JavaVersion javaVersion() { + return javaVersion; + } + + @Override + public String moduleKey() { + return moduleKey; + } + +} diff --git a/java-frontend/src/main/java/org/sonar/java/annotations/Internal.java b/java-frontend/src/main/java/org/sonar/java/annotations/Internal.java new file mode 100644 index 00000000000..7f2c79a37da --- /dev/null +++ b/java-frontend/src/main/java/org/sonar/java/annotations/Internal.java @@ -0,0 +1,33 @@ +/* + * SonarQube Java + * Copyright (C) 2012-2025 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 Sonar Source-Available License Version 1, as published by SonarSource SA. + * + * 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 Sonar Source-Available License for more details. + * + * You should have received a copy of the Sonar Source-Available License + * along with this program; if not, see https://sonarsource.com/license/ssal/ + */ +package org.sonar.java.annotations; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * This annotation should be placed on api elements that are meant to only be consumed by plugins maintained by SonarSource. + * Elements with this annotation are not stable and can change at any time. + */ +@Retention(RetentionPolicy.CLASS) +@Target({ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR, ElementType.FIELD, ElementType.METHOD, ElementType.TYPE}) +@Documented +public @interface Internal { +} diff --git a/java-frontend/src/main/java/org/sonar/java/model/JavaVersionImpl.java b/java-frontend/src/main/java/org/sonar/java/model/JavaVersionImpl.java index 61b4dd478dd..c105d76756e 100644 --- a/java-frontend/src/main/java/org/sonar/java/model/JavaVersionImpl.java +++ b/java-frontend/src/main/java/org/sonar/java/model/JavaVersionImpl.java @@ -17,8 +17,10 @@ package org.sonar.java.model; import java.util.Locale; +import java.util.Optional; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.sonar.api.config.Configuration; import org.sonar.plugins.java.api.JavaVersion; public class JavaVersionImpl implements JavaVersion { @@ -230,4 +232,22 @@ private static int convertJavaVersionString(String javaVersion) { return Integer.parseInt(cleanedVersion); } + public static JavaVersion readFromConfiguration(Configuration config) { + Optional javaVersionAsString = config.get(SOURCE_VERSION); + if (!javaVersionAsString.isPresent()) { + return new JavaVersionImpl(); + } + String enablePreviewAsString = config.get(ENABLE_PREVIEW).orElse("false"); + + JavaVersion javaVersion = fromString(javaVersionAsString.get(), enablePreviewAsString); + if (javaVersion.arePreviewFeaturesEnabled() && javaVersion.asInt() < MAX_SUPPORTED) { + LOG.warn("sonar.java.enablePreview is set but will be discarded as the Java version is less than the max" + + " supported version ({} < {})", javaVersion.asInt(), MAX_SUPPORTED); + javaVersion = new JavaVersionImpl(javaVersion.asInt(), false); + } + LOG.info("Configured Java source version ({}): {}, preview features enabled ({}): {}", + SOURCE_VERSION, javaVersion.asInt(), ENABLE_PREVIEW, javaVersion.arePreviewFeaturesEnabled()); + return javaVersion; + } + } diff --git a/java-frontend/src/main/java/org/sonar/plugins/java/api/internal/ModuleMetadata.java b/java-frontend/src/main/java/org/sonar/plugins/java/api/internal/ModuleMetadata.java index de257d5b5d8..0ca2e4e7aab 100644 --- a/java-frontend/src/main/java/org/sonar/plugins/java/api/internal/ModuleMetadata.java +++ b/java-frontend/src/main/java/org/sonar/plugins/java/api/internal/ModuleMetadata.java @@ -17,15 +17,14 @@ package org.sonar.plugins.java.api.internal; import org.sonar.api.scanner.ScannerSide; -import org.sonar.java.annotations.Beta; +import org.sonar.java.annotations.Internal; import org.sonar.plugins.java.api.JavaVersion; /** * Interface to access metadata about the module being analyzed by a Sensor. - * For internal use only, this API will not be supported for custom plugins. */ -@Beta +@Internal @ScannerSide public interface ModuleMetadata { diff --git a/sonar-java-plugin/src/main/java/org/sonar/plugins/java/JavaPlugin.java b/sonar-java-plugin/src/main/java/org/sonar/plugins/java/JavaPlugin.java index 588f60e88a5..236a7277e1d 100644 --- a/sonar-java-plugin/src/main/java/org/sonar/plugins/java/JavaPlugin.java +++ b/sonar-java-plugin/src/main/java/org/sonar/plugins/java/JavaPlugin.java @@ -28,6 +28,7 @@ import org.sonar.api.config.PropertyDefinition; import org.sonar.java.AnalysisWarningsWrapper; import org.sonar.java.DefaultJavaResourceLocator; +import org.sonar.java.DefaultModuleMetadata; import org.sonar.java.JavaConstants; import org.sonar.java.SonarComponents; import org.sonar.java.classpath.ClasspathForMain; @@ -36,8 +37,8 @@ import org.sonar.java.classpath.ClasspathProperties; import org.sonar.java.filters.PostAnalysisIssueFilter; import org.sonar.java.jsp.Jasper; -import org.sonar.java.telemetry.NoOpTelemetry; import org.sonar.java.telemetry.DefaultTelemetry; +import org.sonar.java.telemetry.NoOpTelemetry; import org.sonar.plugins.java.api.JavaVersion; import org.sonar.plugins.java.api.caching.SonarLintCache; import org.sonar.plugins.surefire.SurefireExtensions; @@ -62,6 +63,7 @@ public void define(Context context) { list.add(DroppedPropertiesSensor.class); list.add(JavaSonarWayProfile.class); list.add(ClasspathForMain.class); + list.add(DefaultModuleMetadata.class); ExternalReportExtensions.define(context); } @@ -105,8 +107,7 @@ public void define(Context context) { " When a package or class is found in both the unnamed module and a named one, modularization is broken." + " As a result, the parser may be unable to build the project semantic successfully, leading to analysis failure." + " This parameter allows users to bypass Java platform modularity enforcement to prevent analysis failure." + - "

" - ) + "

") .category(JavaConstants.JAVA_CATEGORY) .subCategory("Language") .onConfigScopes(Set.of(PropertyDefinition.ConfigScope.PROJECT)) diff --git a/sonar-java-plugin/src/main/java/org/sonar/plugins/java/JavaSensor.java b/sonar-java-plugin/src/main/java/org/sonar/plugins/java/JavaSensor.java index b4dc7693661..2219aec774d 100644 --- a/sonar-java-plugin/src/main/java/org/sonar/plugins/java/JavaSensor.java +++ b/sonar-java-plugin/src/main/java/org/sonar/plugins/java/JavaSensor.java @@ -111,7 +111,7 @@ public void execute(SensorContext context) { Measurer measurer = new Measurer(context, noSonarFilter); - JavaVersion javaVersion = getJavaVersion(); + JavaVersion javaVersion = JavaVersionImpl.readFromConfiguration(settings); telemetry.aggregateAsSortedSet(JAVA_LANGUAGE_VERSION, javaVersion.toString()); telemetry.aggregateAsCounter(JAVA_MODULE_COUNT, 1L); @@ -181,24 +181,6 @@ private Iterable javaFiles(InputFile.Type type) { return fs.inputFiles(fs.predicates().and(fs.predicates().hasLanguage(Java.KEY), fs.predicates().hasType(type))); } - private JavaVersion getJavaVersion() { - Optional javaVersionAsString = settings.get(JavaVersion.SOURCE_VERSION); - if (!javaVersionAsString.isPresent()) { - return new JavaVersionImpl(); - } - String enablePreviewAsString = settings.get(JavaVersion.ENABLE_PREVIEW).orElse("false"); - - JavaVersion javaVersion = JavaVersionImpl.fromString(javaVersionAsString.get(), enablePreviewAsString); - if (javaVersion.arePreviewFeaturesEnabled() && javaVersion.asInt() < JavaVersionImpl.MAX_SUPPORTED) { - LOG.warn("sonar.java.enablePreview is set but will be discarded as the Java version is less than the max" + - " supported version ({} < {})", javaVersion.asInt(), JavaVersionImpl.MAX_SUPPORTED); - javaVersion = new JavaVersionImpl(javaVersion.asInt(), false); - } - LOG.info("Configured Java source version ({}): {}, preview features enabled ({}): {}", - JavaVersion.SOURCE_VERSION, javaVersion.asInt(), JavaVersion.ENABLE_PREVIEW, javaVersion.arePreviewFeaturesEnabled()); - return javaVersion; - } - @Override public String toString() { return getClass().getSimpleName(); diff --git a/sonar-java-plugin/src/test/java/org/sonar/plugins/java/JavaPluginTest.java b/sonar-java-plugin/src/test/java/org/sonar/plugins/java/JavaPluginTest.java index dcea09ca414..794c1781f72 100644 --- a/sonar-java-plugin/src/test/java/org/sonar/plugins/java/JavaPluginTest.java +++ b/sonar-java-plugin/src/test/java/org/sonar/plugins/java/JavaPluginTest.java @@ -44,14 +44,13 @@ void sonarLint_9_9_extensions() { .contains(SonarLintCache.class); } - @Test void sonarqube_9_9_extensions() { SonarRuntime sqCommunity = SonarRuntimeImpl.forSonarQube(VERSION_9_9, SonarQubeSide.SCANNER, SonarEdition.COMMUNITY); Plugin.Context context = new Plugin.Context(sqCommunity); javaPlugin.define(context); assertThat(context.getExtensions()) - .hasSize(35) + .hasSize(36) .doesNotContain(Jasper.class); } @@ -61,7 +60,7 @@ void sonarqube_9_9_commercial_extensions() { Plugin.Context context = new Plugin.Context(sqEnterprise); javaPlugin.define(context); assertThat(context.getExtensions()) - .hasSize(36) + .hasSize(37) .contains(Jasper.class); }