From 7cfb0c23e9c4472cdba321212731b10216d8a51f Mon Sep 17 00:00:00 2001 From: Madhura Bhave Date: Tue, 16 Jul 2019 12:37:40 -0700 Subject: [PATCH] Add jackson-module-kotlin when json facet and kotlin is in use Closes gh-957 --- .../kotlin/KotlinJacksonBuildCustomizer.java | 56 ++++++++++++ .../KotlinProjectGenerationConfiguration.java | 6 ++ .../KotlinJacksonBuildCustomizerTests.java | 89 +++++++++++++++++++ ...inProjectGenerationConfigurationTests.java | 27 +++++- 4 files changed, 176 insertions(+), 2 deletions(-) create mode 100644 initializr-generator-spring/src/main/java/io/spring/initializr/generator/spring/code/kotlin/KotlinJacksonBuildCustomizer.java create mode 100755 initializr-generator-spring/src/test/java/io/spring/initializr/generator/spring/code/kotlin/KotlinJacksonBuildCustomizerTests.java diff --git a/initializr-generator-spring/src/main/java/io/spring/initializr/generator/spring/code/kotlin/KotlinJacksonBuildCustomizer.java b/initializr-generator-spring/src/main/java/io/spring/initializr/generator/spring/code/kotlin/KotlinJacksonBuildCustomizer.java new file mode 100644 index 00000000..e443aab1 --- /dev/null +++ b/initializr-generator-spring/src/main/java/io/spring/initializr/generator/spring/code/kotlin/KotlinJacksonBuildCustomizer.java @@ -0,0 +1,56 @@ +/* + * Copyright 2012-2019 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.spring.initializr.generator.spring.code.kotlin; + +import io.spring.initializr.generator.buildsystem.Build; +import io.spring.initializr.generator.buildsystem.DependencyScope; +import io.spring.initializr.generator.language.kotlin.KotlinLanguage; +import io.spring.initializr.generator.project.ResolvedProjectDescription; +import io.spring.initializr.generator.spring.build.BuildCustomizer; +import io.spring.initializr.generator.spring.build.BuildMetadataResolver; +import io.spring.initializr.metadata.InitializrMetadata; + +import org.springframework.util.ClassUtils; + +/** + * A {@link BuildCustomizer} that automatically adds "jackson-module-kotlin" when Kotlin + * is used and a dependency has the "json" facet. + * + * @author Sebastien Deleuze + * @author Madhura Bhave + */ +public class KotlinJacksonBuildCustomizer implements BuildCustomizer { + + private final BuildMetadataResolver buildMetadataResolver; + + private final ResolvedProjectDescription description; + + public KotlinJacksonBuildCustomizer(InitializrMetadata metadata, ResolvedProjectDescription description) { + this.buildMetadataResolver = new BuildMetadataResolver(metadata); + this.description = description; + } + + @Override + public void customize(Build build) { + boolean isKotlin = ClassUtils.isAssignableValue(KotlinLanguage.class, this.description.getLanguage()); + if (this.buildMetadataResolver.hasFacet(build, "json") && isKotlin) { + build.dependencies().add("jackson-module-kotlin", "com.fasterxml.jackson.module", "jackson-module-kotlin", + DependencyScope.COMPILE); + } + } + +} diff --git a/initializr-generator-spring/src/main/java/io/spring/initializr/generator/spring/code/kotlin/KotlinProjectGenerationConfiguration.java b/initializr-generator-spring/src/main/java/io/spring/initializr/generator/spring/code/kotlin/KotlinProjectGenerationConfiguration.java index e7f25b97..028720d9 100644 --- a/initializr-generator-spring/src/main/java/io/spring/initializr/generator/spring/code/kotlin/KotlinProjectGenerationConfiguration.java +++ b/initializr-generator-spring/src/main/java/io/spring/initializr/generator/spring/code/kotlin/KotlinProjectGenerationConfiguration.java @@ -32,6 +32,7 @@ import io.spring.initializr.generator.spring.code.MainSourceCodeProjectContribut import io.spring.initializr.generator.spring.code.TestApplicationTypeCustomizer; import io.spring.initializr.generator.spring.code.TestSourceCodeCustomizer; import io.spring.initializr.generator.spring.code.TestSourceCodeProjectContributor; +import io.spring.initializr.metadata.InitializrMetadata; import org.springframework.beans.factory.ObjectProvider; import org.springframework.context.annotation.Bean; @@ -83,4 +84,9 @@ public class KotlinProjectGenerationConfiguration { return new SimpleKotlinProjectSettings(kotlinVersionResolver.resolveKotlinVersion(this.projectDescription)); } + @Bean + public KotlinJacksonBuildCustomizer kotlinJacksonBuildCustomizer(InitializrMetadata metadata) { + return new KotlinJacksonBuildCustomizer(metadata, this.projectDescription); + } + } diff --git a/initializr-generator-spring/src/test/java/io/spring/initializr/generator/spring/code/kotlin/KotlinJacksonBuildCustomizerTests.java b/initializr-generator-spring/src/test/java/io/spring/initializr/generator/spring/code/kotlin/KotlinJacksonBuildCustomizerTests.java new file mode 100755 index 00000000..4a3a623a --- /dev/null +++ b/initializr-generator-spring/src/test/java/io/spring/initializr/generator/spring/code/kotlin/KotlinJacksonBuildCustomizerTests.java @@ -0,0 +1,89 @@ +/* + * Copyright 2012-2019 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.spring.initializr.generator.spring.code.kotlin; + +import java.util.Collections; + +import io.spring.initializr.generator.buildsystem.maven.MavenBuild; +import io.spring.initializr.generator.language.java.JavaLanguage; +import io.spring.initializr.generator.language.kotlin.KotlinLanguage; +import io.spring.initializr.generator.project.ProjectDescription; +import io.spring.initializr.generator.spring.test.InitializrMetadataTestBuilder; +import io.spring.initializr.generator.version.Version; +import io.spring.initializr.metadata.Dependency; +import io.spring.initializr.metadata.InitializrMetadata; +import io.spring.initializr.metadata.support.MetadataBuildItemResolver; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link KotlinJacksonBuildCustomizer}. + * + * @author Sebastien Deleuze + * @author Stephane Nicoll + * @author Madhura Bhave + */ +class KotlinJacksonBuildCustomizerTests { + + @Test + void customizeWhenJsonFacetPresentShouldAddJacksonKotlinModule() { + Dependency dependency = Dependency.withId("foo"); + dependency.setFacets(Collections.singletonList("json")); + ProjectDescription description = new ProjectDescription(); + description.setLanguage(new KotlinLanguage()); + MavenBuild build = getCustomizedBuild(dependency, description); + io.spring.initializr.generator.buildsystem.Dependency jacksonKotlin = build.dependencies() + .get("jackson-module-kotlin"); + assertThat(jacksonKotlin.getArtifactId()).isEqualTo("jackson-module-kotlin"); + assertThat(jacksonKotlin.getGroupId()).isEqualTo("com.fasterxml.jackson.module"); + } + + @Test + void jacksonModuleKotlinIsNotAddedWithoutKotlin() { + Dependency dependency = Dependency.withId("foo"); + dependency.setFacets(Collections.singletonList("json")); + ProjectDescription description = new ProjectDescription(); + description.setLanguage(new JavaLanguage()); + MavenBuild build = getCustomizedBuild(dependency, description); + io.spring.initializr.generator.buildsystem.Dependency jacksonKotlin = build.dependencies() + .get("jackson-module-kotlin"); + assertThat(jacksonKotlin).isNull(); + } + + @Test + void jacksonModuleKotlinIsNotAddedWithoutJsonFacet() { + Dependency dependency = Dependency.withId("foo"); + ProjectDescription description = new ProjectDescription(); + description.setLanguage(new KotlinLanguage()); + MavenBuild build = getCustomizedBuild(dependency, description); + io.spring.initializr.generator.buildsystem.Dependency jacksonKotlin = build.dependencies() + .get("jackson-module-kotlin"); + assertThat(jacksonKotlin).isNull(); + } + + private MavenBuild getCustomizedBuild(Dependency dependency, ProjectDescription description) { + InitializrMetadata metadata = InitializrMetadataTestBuilder.withDefaults() + .addDependencyGroup("test", dependency).build(); + KotlinJacksonBuildCustomizer customizer = new KotlinJacksonBuildCustomizer(metadata, description.resolve()); + MavenBuild build = new MavenBuild(new MetadataBuildItemResolver(metadata, Version.parse("2.0.0.RELEASE"))); + build.dependencies().add("foo"); + customizer.customize(build); + return build; + } + +} diff --git a/initializr-generator-spring/src/test/java/io/spring/initializr/generator/spring/code/kotlin/KotlinProjectGenerationConfigurationTests.java b/initializr-generator-spring/src/test/java/io/spring/initializr/generator/spring/code/kotlin/KotlinProjectGenerationConfigurationTests.java index aa31d53e..d648ae55 100644 --- a/initializr-generator-spring/src/test/java/io/spring/initializr/generator/spring/code/kotlin/KotlinProjectGenerationConfigurationTests.java +++ b/initializr-generator-spring/src/test/java/io/spring/initializr/generator/spring/code/kotlin/KotlinProjectGenerationConfigurationTests.java @@ -17,16 +17,22 @@ package io.spring.initializr.generator.spring.code.kotlin; import java.nio.file.Path; +import java.util.Collections; import java.util.List; +import io.spring.initializr.generator.buildsystem.Dependency; import io.spring.initializr.generator.buildsystem.maven.MavenBuildSystem; import io.spring.initializr.generator.language.kotlin.KotlinLanguage; import io.spring.initializr.generator.packaging.war.WarPackaging; import io.spring.initializr.generator.project.ProjectDescription; +import io.spring.initializr.generator.spring.build.BuildProjectGenerationConfiguration; +import io.spring.initializr.generator.spring.build.maven.MavenProjectGenerationConfiguration; import io.spring.initializr.generator.spring.code.SourceCodeProjectGenerationConfiguration; +import io.spring.initializr.generator.spring.test.InitializrMetadataTestBuilder; import io.spring.initializr.generator.test.project.ProjectAssetTester; import io.spring.initializr.generator.test.project.ProjectStructure; import io.spring.initializr.generator.version.Version; +import io.spring.initializr.metadata.InitializrMetadata; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.io.TempDir; @@ -46,10 +52,16 @@ class KotlinProjectGenerationConfigurationTests { void setup(@TempDir Path directory) { this.projectTester = new ProjectAssetTester().withIndentingWriterFactory() .withConfiguration(SourceCodeProjectGenerationConfiguration.class, - KotlinProjectGenerationConfiguration.class) + KotlinProjectGenerationConfiguration.class, BuildProjectGenerationConfiguration.class, + MavenProjectGenerationConfiguration.class) .withDirectory(directory) .withBean(KotlinProjectSettings.class, () -> new SimpleKotlinProjectSettings("1.2.70")) - .withDescriptionCustomizer((description) -> { + .withBean(InitializrMetadata.class, () -> { + io.spring.initializr.metadata.Dependency dependency = io.spring.initializr.metadata.Dependency + .withId("foo"); + dependency.setFacets(Collections.singletonList("json")); + return InitializrMetadataTestBuilder.withDefaults().addDependencyGroup("test", dependency).build(); + }).withDescriptionCustomizer((description) -> { description.setLanguage(new KotlinLanguage()); if (description.getPlatformVersion() == null) { description.setPlatformVersion(Version.parse("2.1.0.RELEASE")); @@ -110,4 +122,15 @@ class KotlinProjectGenerationConfigurationTests { " return application.sources(KotlinDemoApplication::class.java)", " }", "", "}"); } + @Test + void jacksonKotlinModuleShouldBeAddedWhenJsonFacetPresent() { + ProjectDescription description = new ProjectDescription(); + description.addDependency("foo", Dependency.withCoordinates("com.example", "foo").build()); + ProjectStructure projectStructure = this.projectTester.generate(description); + List lines = projectStructure.readAllLines("pom.xml"); + assertThat(lines).contains(" ", + " com.fasterxml.jackson.module", + " jackson-module-kotlin", " "); + } + }