diff --git a/graphql-dgs-codegen-core/src/main/kotlin/com/netflix/graphql/dgs/codegen/CodeGen.kt b/graphql-dgs-codegen-core/src/main/kotlin/com/netflix/graphql/dgs/codegen/CodeGen.kt index e47a0fe68..16db19d5e 100644 --- a/graphql-dgs-codegen-core/src/main/kotlin/com/netflix/graphql/dgs/codegen/CodeGen.kt +++ b/graphql-dgs-codegen-core/src/main/kotlin/com/netflix/graphql/dgs/codegen/CodeGen.kt @@ -35,21 +35,7 @@ import com.squareup.javapoet.JavaFile import com.squareup.javapoet.TypeSpec import com.squareup.kotlinpoet.FileSpec import com.squareup.kotlinpoet.KModifier -import graphql.language.Definition -import graphql.language.DirectivesContainer -import graphql.language.Document -import graphql.language.EnumTypeDefinition -import graphql.language.FieldDefinition -import graphql.language.InputObjectTypeDefinition -import graphql.language.InterfaceTypeDefinition -import graphql.language.NamedNode -import graphql.language.ObjectTypeDefinition -import graphql.language.ObjectTypeExtensionDefinition -import graphql.language.ScalarTypeDefinition -import graphql.language.Type -import graphql.language.TypeDefinition -import graphql.language.TypeName -import graphql.language.UnionTypeDefinition +import graphql.language.* import graphql.parser.InvalidSyntaxException import graphql.parser.MultiSourceReader import graphql.parser.Parser @@ -63,6 +49,8 @@ import java.io.Reader import java.lang.annotation.RetentionPolicy import java.nio.file.Path import java.nio.file.Paths +import java.util.* +import java.util.jar.JarFile import java.util.zip.ZipFile import javax.lang.model.element.Modifier import com.squareup.kotlinpoet.AnnotationSpec as KAnnotationSpec @@ -83,6 +71,8 @@ class CodeGen(private val config: CodeGenConfig) { ) fun generate(): CodeGenResult { + loadTypeMappingsFromDependencies() + val codeGenResult = when (config.language) { Language.JAVA -> generateJava() Language.KOTLIN -> generateKotlin() @@ -156,9 +146,30 @@ class CodeGen(private val config: CodeGenConfig) { } } } + return document } + private fun loadTypeMappingsFromDependencies() { + // process type mappings from dependencies + config.schemaJarFilesFromDependencies.forEach { file -> + JarFile(file).use { jarFile -> + val typeMappingsFile = jarFile.getJarEntry("META-INF/dgs.codegen.typemappings") + if (typeMappingsFile != null) { + jarFile.getInputStream(typeMappingsFile).use { typeMappingInput -> + val props = Properties() + props.load(typeMappingInput) + + // Add the new type mappings from dependencies to existing type mappings. + // The user provided config overrides mappings from the dependencies. + @Suppress("UNCHECKED_CAST") + config.typeMapping = (props as Map).plus(config.typeMapping) + } + } + } + } + } + /** * Loads the given [MultiSourceReader.Builder] references with the sources that will be used to provide * the schema information for the parser. diff --git a/graphql-dgs-codegen-core/src/test/kotlin/com/netflix/graphql/dgs/codegen/CodeGenTest.kt b/graphql-dgs-codegen-core/src/test/kotlin/com/netflix/graphql/dgs/codegen/CodeGenTest.kt index a0e5ce7b3..9ea9fdf10 100644 --- a/graphql-dgs-codegen-core/src/test/kotlin/com/netflix/graphql/dgs/codegen/CodeGenTest.kt +++ b/graphql-dgs-codegen-core/src/test/kotlin/com/netflix/graphql/dgs/codegen/CodeGenTest.kt @@ -42,6 +42,7 @@ import org.junit.jupiter.params.provider.ArgumentsSource import org.junit.jupiter.params.provider.MethodSource import org.junit.jupiter.params.provider.ValueSource import java.io.Serializable +import java.nio.file.Paths import java.util.stream.Stream class CodeGenTest { @@ -4990,4 +4991,53 @@ It takes a title and such. "com.netflix.graphql.dgs.codegen.tests.generated.types.com.netflix.graphql.dgs.codegen.tests.generated.types.B" ) } + + @Test + fun `Codegen should pick up type mappings for schema from JAR files in dependencies`() { + val typeMappingDependency = Paths.get("src/test/resources/dependencies/testDependency.jar").toAbsolutePath().toFile() + val schema = """ + type Query { + person: Person + } + scalar BigDecimal + + type Person { + firstname: String + data: BigDecimal + } + """.trimIndent() + + val result = CodeGen( + CodeGenConfig( + schemas = setOf(schema), + schemaJarFilesFromDependencies = listOf(typeMappingDependency) + ) + ).generate() + assertThat(result.javaDataTypes[0].typeSpec.fieldSpecs[1].type.toString() == "java.math.BigDecimal") + } + + @Test + fun `Codegen should use user specfied typemappings to override type mappings from typemappings in dependencies`() { + val typeMappingDependency = Paths.get("src/test/resources/dependencies/testDependency.jar").toAbsolutePath().toFile() + val schema = """ + type Query { + person: Person + } + scalar BigDecimal + + type Person { + firstname: String + data: BigDecimal + } + """.trimIndent() + + val result = CodeGen( + CodeGenConfig( + schemas = setOf(schema), + schemaJarFilesFromDependencies = listOf(typeMappingDependency), + typeMapping = mapOf("BigDecimal" to "java.lang.String") + ) + ).generate() + assertThat(result.javaDataTypes[0].typeSpec.fieldSpecs[1].type.toString() == "java.lang.String") + } } diff --git a/graphql-dgs-codegen-core/src/test/resources/dependencies/META-INF/dgs.codegen.typemappings b/graphql-dgs-codegen-core/src/test/resources/dependencies/META-INF/dgs.codegen.typemappings new file mode 100644 index 000000000..b2797bf53 --- /dev/null +++ b/graphql-dgs-codegen-core/src/test/resources/dependencies/META-INF/dgs.codegen.typemappings @@ -0,0 +1 @@ +BigDecimal:java.math.BigDecimal diff --git a/graphql-dgs-codegen-core/src/test/resources/dependencies/testDependency.jar b/graphql-dgs-codegen-core/src/test/resources/dependencies/testDependency.jar new file mode 100644 index 000000000..fba731bbb Binary files /dev/null and b/graphql-dgs-codegen-core/src/test/resources/dependencies/testDependency.jar differ