Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Configuration for Kotlin's All-Open Plugin for JPA Entities #1576

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
*
* @author Stephane Nicoll
* @author Moritz Halbritter
* @author Sijun Yang
*/
public class BuildMetadataResolver {

Expand Down Expand Up @@ -65,4 +66,16 @@ public boolean hasFacet(Build build, String facet) {
return dependencies(build).anyMatch((dependency) -> dependency.getFacets().contains(facet));
}

/**
* Checks if the given {@link Build} contains dependencies with the given
* {@code groupId}.
* @param build the build to query
* @param groupId the groupId to query
* @return {@code true} if this build defines at least a dependency with that groupId,
* {@code false} otherwise
*/
public boolean hasGroupId(Build build, String groupId) {
return dependencies(build).anyMatch((dependency) -> dependency.getGroupId().equals(groupId));
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -28,25 +28,38 @@
* related dependency is present.
*
* @author Madhura Bhave
* @author Sijun Yang
*/
public class KotlinJpaGradleBuildCustomizer implements BuildCustomizer<GradleBuild> {

private final BuildMetadataResolver buildMetadataResolver;

private final KotlinProjectSettings settings;

private final char quote;

public KotlinJpaGradleBuildCustomizer(InitializrMetadata metadata, KotlinProjectSettings settings,
ProjectDescription projectDescription) {
ProjectDescription projectDescription, char quote) {
this.buildMetadataResolver = new BuildMetadataResolver(metadata, projectDescription.getPlatformVersion());
this.settings = settings;
this.quote = quote;
}

@Override
public void customize(GradleBuild build) {
if (this.buildMetadataResolver.hasFacet(build, "jpa")) {
build.plugins()
.add("org.jetbrains.kotlin.plugin.jpa", (plugin) -> plugin.setVersion(this.settings.getVersion()));
build.extensions().customize("allOpen", (allOpen) -> {
allOpen.invoke("annotation", quote("jakarta.persistence.Entity"));
allOpen.invoke("annotation", quote("jakarta.persistence.MappedSuperclass"));
allOpen.invoke("annotation", quote("jakarta.persistence.Embeddable"));
});
}
}

private String quote(String element) {
return this.quote + element + this.quote;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
*
* @author Madhura Bhave
* @author Sebastien Deleuze
* @author Sijun Yang
*/
public class KotlinJpaMavenBuildCustomizer implements BuildCustomizer<MavenBuild> {

Expand All @@ -41,8 +42,15 @@ public KotlinJpaMavenBuildCustomizer(InitializrMetadata metadata, ProjectDescrip
public void customize(MavenBuild build) {
if (this.buildMetadataResolver.hasFacet(build, "jpa")) {
build.plugins().add("org.jetbrains.kotlin", "kotlin-maven-plugin", (kotlinPlugin) -> {
kotlinPlugin.configuration((configuration) -> configuration.configure("compilerPlugins",
(compilerPlugins) -> compilerPlugins.add("plugin", "jpa")));
kotlinPlugin.configuration((configuration) -> {
configuration.configure("compilerPlugins",
(compilerPlugins) -> compilerPlugins.add("plugin", "jpa"));
configuration.configure("pluginOptions", (option) -> {
option.add("option", "all-open:annotation=jakarta.persistence.Entity");
option.add("option", "all-open:annotation=jakarta.persistence.MappedSuperclass");
option.add("option", "all-open:annotation=jakarta.persistence.Embeddable");
});
});
kotlinPlugin.dependency("org.jetbrains.kotlin", "kotlin-maven-noarg", "${kotlin.version}");
});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
* @author Stephane Nicoll
* @author Jean-Baptiste Nizet
* @author Moritz Halbritter
* @author Sijun Yang
*/
@Configuration
class KotlinProjectGenerationDefaultContributorsConfiguration {
Expand All @@ -67,10 +68,17 @@ BuildCustomizer<Build> kotlinDependenciesConfigurer() {
}

@Bean
@ConditionalOnBuildSystem(GradleBuildSystem.ID)
KotlinJpaGradleBuildCustomizer kotlinJpaGradleBuildCustomizer(InitializrMetadata metadata,
@ConditionalOnBuildSystem(value = GradleBuildSystem.ID, dialect = GradleBuildSystem.DIALECT_KOTLIN)
KotlinJpaGradleBuildCustomizer kotlinJpaGradleBuildCustomizerKotlinDsl(InitializrMetadata metadata,
KotlinProjectSettings settings, ProjectDescription projectDescription) {
return new KotlinJpaGradleBuildCustomizer(metadata, settings, projectDescription, '\"');
}

@Bean
@ConditionalOnBuildSystem(value = GradleBuildSystem.ID, dialect = GradleBuildSystem.DIALECT_GROOVY)
KotlinJpaGradleBuildCustomizer kotlinJpaGradleBuildCustomizerGroovyDsl(InitializrMetadata metadata,
KotlinProjectSettings settings, ProjectDescription projectDescription) {
return new KotlinJpaGradleBuildCustomizer(metadata, settings, projectDescription);
return new KotlinJpaGradleBuildCustomizer(metadata, settings, projectDescription, '\'');
}

@Bean
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
package io.spring.initializr.generator.spring.code.kotlin;

import java.util.Collections;
import java.util.List;
import java.util.Objects;

import io.spring.initializr.generator.buildsystem.gradle.GradleBuild;
import io.spring.initializr.generator.buildsystem.gradle.GradlePlugin;
Expand All @@ -35,6 +37,7 @@
* Tests for {@link KotlinJpaGradleBuildCustomizer}.
*
* @author Madhura Bhave
* @author Sijun Yang
*/
class KotlinJpaGradleBuildCustomizerTests {

Expand All @@ -58,6 +61,32 @@ void customizeWhenJpaFacetAbsentShouldNotAddKotlinJpaPlugin() {
assertThat(build.plugins().values()).isEmpty();
}

@Test
void customizeWhenJpaFacetPresentShouldCustomizeAllOpen() {
Dependency dependency = Dependency.withId("foo");
dependency.setFacets(Collections.singletonList("jpa"));
GradleBuild build = getCustomizedBuild(dependency);
assertThat(build.extensions().values()).singleElement().satisfies((extension) -> {
assertThat(extension.getName()).isEqualTo("allOpen");
assertThat(extension.getInvocations())
.filteredOn((invocation) -> Objects.equals(invocation.getTarget(), "annotation"))
.extracting("arguments")
.containsExactlyInAnyOrder(List.of("\"jakarta.persistence.Entity\""),
List.of("\"jakarta.persistence.MappedSuperclass\""),
List.of("\"jakarta.persistence.Embeddable\""));
});
}

@Test
void customizeWhenJpaFacetAbsentShouldNotCustomizeAllOpen() {
Dependency dependency = Dependency.withId("foo");
GradleBuild build = getCustomizedBuild(dependency);
assertThat(build.extensions().values())
.filteredOn((extension) -> Objects.equals(extension.getName(), "allOpen"))
.isEmpty();
assertThat(build.extensions().values()).isEmpty();
}

private GradleBuild getCustomizedBuild(Dependency dependency) {
InitializrMetadata metadata = InitializrMetadataTestBuilder.withDefaults()
.addDependencyGroup("test", dependency)
Expand All @@ -66,7 +95,7 @@ private GradleBuild getCustomizedBuild(Dependency dependency) {
MutableProjectDescription projectDescription = new MutableProjectDescription();
projectDescription.setPlatformVersion(Version.parse("1.0.0"));
KotlinJpaGradleBuildCustomizer customizer = new KotlinJpaGradleBuildCustomizer(metadata, settings,
projectDescription);
projectDescription, '\"');
GradleBuild build = new GradleBuild(new MetadataBuildItemResolver(metadata, Version.parse("2.0.0.RELEASE")));
build.dependencies().add("foo");
customizer.customize(build);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
package io.spring.initializr.generator.spring.code.kotlin;

import java.util.Collections;
import java.util.List;
import java.util.Objects;

import io.spring.initializr.generator.buildsystem.maven.MavenBuild;
import io.spring.initializr.generator.buildsystem.maven.MavenPlugin;
Expand All @@ -36,6 +38,7 @@
*
* @author Madhura Bhave
* @author Sebastien Deleuze
* @author Sijun Yang
*/
class KotlinJpaMavenBuildCustomizerTests {

Expand Down Expand Up @@ -67,6 +70,34 @@ void customizeWhenJpaFacetAbsentShouldNotAddKotlinJpaPlugin() {
assertThat(build.plugins().isEmpty()).isTrue();
}

@Test
void customizeWhenJpaFacetPresentShouldCustomizeAllOpen() {
Dependency dependency = Dependency.withId("foo");
dependency.setFacets(Collections.singletonList("jpa"));
MavenBuild build = getCustomizedBuild(dependency);

assertThat(build.plugins().values()).singleElement().satisfies((plugin) -> {
MavenPlugin.Configuration configuration = plugin.getConfiguration();

assertThat(configuration.getSettings()).filteredOn((setting) -> setting.getName().equals("pluginOptions"))
.isNotEmpty()
.first()
.satisfies((pluginOptions) -> assertThat(((List<MavenPlugin.Setting>) pluginOptions.getValue()))
.filteredOn((option) -> Objects.equals(option.getName(), "option"))
.map(MavenPlugin.Setting::getValue)
.containsExactlyInAnyOrder("all-open:annotation=jakarta.persistence.Entity",
"all-open:annotation=jakarta.persistence.MappedSuperclass",
"all-open:annotation=jakarta.persistence.Embeddable"));
});
}

@Test
void customizeWhenJpaFacetAbsentShouldNotCustomizeAllOpen() {
Dependency dependency = Dependency.withId("foo");
MavenBuild build = getCustomizedBuild(dependency);
assertThat(build.plugins().values()).isEmpty();
}

private MavenBuild getCustomizedBuild(Dependency dependency) {
InitializrMetadata metadata = InitializrMetadataTestBuilder.withDefaults()
.addDependencyGroup("test", dependency)
Expand Down