Skip to content

Commit 0b212e6

Browse files
veloMarvin Froederkobylynskyi
authored
Support overriding FreeMarker templates #860 (#1048)
--------- Co-authored-by: Marvin Froeder <[email protected]> Co-authored-by: Bogdan Kobylynskyi <[email protected]> Co-authored-by: Marvin Froeder <[email protected]>
1 parent 134bc89 commit 0b212e6

File tree

14 files changed

+255
-87
lines changed

14 files changed

+255
-87
lines changed

.gitignore

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,10 @@ build
66
modules.xml
77
.idea/misc.xml
88
*.ipr
9-
9+
bin/
10+
.classpath
11+
.project
12+
.settings/
1013

1114
### Maven ###
1215
target/

CONTRIBUTING.md

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,7 @@ Please follow the steps below in order to make the changes:
3636
./gradlew -p plugins/gradle/graphql-java-codegen-gradle-plugin clean build
3737

3838
# Build Maven plugin
39-
cd plugins/maven/graphql-java-codegen-maven-plugin
40-
mvn clean verify
39+
mvn clean verify -f plugins/maven/graphql-java-codegen-maven-plugin/pom.xml
4140
```
4241

4342
9. Make changes to the plugin code
@@ -48,8 +47,7 @@ Please follow the steps below in order to make the changes:
4847
./gradlew -p plugins/gradle/graphql-java-codegen-gradle-plugin clean build publishToMavenLocal
4948

5049
# Install Maven plugin
51-
cd plugins/maven/graphql-java-codegen-maven-plugin
52-
mvn clean install
50+
mvn clean install -f plugins/maven/graphql-java-codegen-maven-plugin/pom.xml
5351
```
5452

5553
11. Make sure that `example` projects are compiling and running.

docs/codegen-options.md

Lines changed: 66 additions & 65 deletions
Large diffs are not rendered by default.

plugins/gradle/graphql-java-codegen-gradle-plugin/src/main/java/io/github/kobylynskyi/graphql/codegen/gradle/GraphQLCodegenGradleTask.java

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package io.github.kobylynskyi.graphql.codegen.gradle;
22

33
import com.kobylynskyi.graphql.codegen.GraphQLCodegen;
4+
import com.kobylynskyi.graphql.codegen.generators.FreeMarkerTemplateType;
45
import com.kobylynskyi.graphql.codegen.java.JavaGraphQLCodegen;
56
import com.kobylynskyi.graphql.codegen.kotlin.KotlinGraphQLCodegen;
67
import com.kobylynskyi.graphql.codegen.model.ApiInterfaceStrategy;
@@ -54,6 +55,7 @@ public class GraphQLCodegenGradleTask extends DefaultTask implements GraphQLCode
5455

5556
private Map<String, String> customTypesMapping = new HashMap<>();
5657
private Map<String, List<String>> customAnnotationsMapping = new HashMap<>();
58+
private Map<FreeMarkerTemplateType, String> customTemplates = new HashMap<>();
5759
private Map<String, List<String>> directiveAnnotationsMapping = new HashMap<>();
5860
private String packageName;
5961
private String apiPackageName;
@@ -133,8 +135,8 @@ public void generate() throws Exception {
133135
mappingConfig.setPackageName(packageName);
134136
mappingConfig.setCustomTypesMapping(
135137
customTypesMapping != null ? customTypesMapping : new HashMap<>());
136-
mappingConfig.setCustomAnnotationsMapping(
137-
customAnnotationsMapping != null ? customAnnotationsMapping : new HashMap<>());
138+
mappingConfig.setCustomTemplates(
139+
customTemplates != null ? customTemplates : new HashMap<>());
138140
mappingConfig.setDirectiveAnnotationsMapping(
139141
directiveAnnotationsMapping != null ? directiveAnnotationsMapping : new HashMap<>());
140142
mappingConfig.setApiNameSuffix(apiNameSuffix);
@@ -333,6 +335,17 @@ public void setCustomTypesMapping(Map<String, String> customTypesMapping) {
333335
this.customTypesMapping = customTypesMapping;
334336
}
335337

338+
@Input
339+
@Optional
340+
@Override
341+
public Map<FreeMarkerTemplateType, String> getCustomTemplates() {
342+
return customTemplates;
343+
}
344+
345+
public void setCustomTemplates(Map<FreeMarkerTemplateType, String> customTemplates) {
346+
this.customTemplates = customTemplates;
347+
}
348+
336349
@Input
337350
@Optional
338351
@Override

plugins/maven/graphql-java-codegen-maven-plugin/src/main/java/io/github/kobylynskyi/graphql/codegen/GraphQLCodegenMojo.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package io.github.kobylynskyi.graphql.codegen;
22

33
import com.kobylynskyi.graphql.codegen.GraphQLCodegen;
4+
import com.kobylynskyi.graphql.codegen.generators.FreeMarkerTemplateType;
45
import com.kobylynskyi.graphql.codegen.java.JavaGraphQLCodegen;
56
import com.kobylynskyi.graphql.codegen.kotlin.KotlinGraphQLCodegen;
67
import com.kobylynskyi.graphql.codegen.model.ApiInterfaceStrategy;
@@ -65,6 +66,9 @@ public class GraphQLCodegenMojo extends AbstractMojo implements GraphQLCodegenCo
6566
@Parameter
6667
private Map<String, Properties> customAnnotationsMapping;
6768

69+
@Parameter
70+
private Map<FreeMarkerTemplateType, String> customTemplates;
71+
6872
@Parameter
6973
private Map<String, Properties> directiveAnnotationsMapping;
7074

@@ -246,6 +250,7 @@ public void execute() throws MojoExecutionException {
246250
MappingConfig mappingConfig = new MappingConfig();
247251
mappingConfig.setPackageName(packageName);
248252
mappingConfig.setCustomTypesMapping(convertToMap(customTypesMapping));
253+
mappingConfig.setCustomTemplates(customTemplates);
249254
mappingConfig.setCustomAnnotationsMapping(convertToListsMap(customAnnotationsMapping));
250255
mappingConfig.setDirectiveAnnotationsMapping(convertToListsMap(directiveAnnotationsMapping));
251256
mappingConfig.setApiNameSuffix(apiNameSuffix);
@@ -737,4 +742,12 @@ private static Map<String, String> convertToMap(Properties properties) {
737742
return result;
738743
}
739744

745+
@Override
746+
public Map<FreeMarkerTemplateType, String> getCustomTemplates() {
747+
if (customTemplates == null) {
748+
return new HashMap<>();
749+
}
750+
return customTemplates;
751+
}
752+
740753
}

plugins/sbt/graphql-java-codegen-sbt-plugin/src/main/scala/io/github/dreamylost/graphql/codegen/GraphQLCodegenKeys.scala

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package io.github.dreamylost.graphql.codegen
33
import java.util
44

55
import com.kobylynskyi.graphql.codegen.model._
6+
import com.kobylynskyi.graphql.codegen.generators._
67
import sbt._
78

89
/** @author
@@ -43,6 +44,8 @@ trait GraphQLCodegenKeys {
4344

4445
val customAnnotationsMapping = settingKey[util.Map[String, util.List[String]]]("customAnnotationsMapping")
4546

47+
val customTemplates = settingKey[util.Map[FreeMarkerTemplateType, String]]("customTemplates")
48+
4649
val generateEqualsAndHashCode =
4750
settingKey[Boolean]("Specifies whether generated model classes should have equals and hashCode methods defined.")
4851

plugins/sbt/graphql-java-codegen-sbt-plugin/src/main/scala/io/github/dreamylost/graphql/codegen/GraphQLCodegenPlugin.scala

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import com.kobylynskyi.graphql.codegen.model.exception.LanguageNotSupportedExcep
77
import com.kobylynskyi.graphql.codegen.model.GeneratedLanguage._
88
import com.kobylynskyi.graphql.codegen.scala.ScalaGraphQLCodegen
99
import com.kobylynskyi.graphql.codegen.supplier._
10+
import com.kobylynskyi.graphql.codegen.generators.FreeMarkerTemplateType
1011
import sbt.{ AutoPlugin, PluginTrigger, _ }
1112
import sbt.Keys.{ sLog, sourceManaged, _ }
1213
import sbt.internal.util.complete.DefaultParsers.spaceDelimited
@@ -67,6 +68,7 @@ class GraphQLCodegenPlugin(configuration: Configuration, private[codegen] val co
6768
generateJacksonTypeIdResolver := MappingConfigConstants.DEFAULT_GENERATE_JACKSON_TYPE_ID_RESOLVER,
6869
customTypesMapping := new JHashMap[String, String](), // TODO use scala Map, convert to java Map
6970
customAnnotationsMapping := new JHashMap[String, JList[String]](),
71+
customTemplates := new JHashMap[FreeMarkerTemplateType, String](),
7072
directiveAnnotationsMapping := new JHashMap[String, JList[String]](),
7173
javaxValidationApiVersion := None,
7274
graphqlJavaCodegenVersion := None,
@@ -118,17 +120,17 @@ class GraphQLCodegenPlugin(configuration: Configuration, private[codegen] val co
118120
generateBuilder := MappingConfigConstants.DEFAULT_BUILDER,
119121
generateApis := MappingConfigConstants.DEFAULT_GENERATE_APIS,
120122
generateEqualsAndHashCode := MappingConfigConstants.DEFAULT_EQUALS_AND_HASHCODE,
121-
generateImmutableModels := MappingConfigConstants.DEFAULT_GENERATE_IMMUTABLE_MODELS, // TODO change default value
122-
generateToString := MappingConfigConstants.DEFAULT_TO_STRING,
123+
generateImmutableModels := MappingConfigConstants.DEFAULT_GENERATE_IMMUTABLE_MODELS, // TODO change default value
124+
generateToString := MappingConfigConstants.DEFAULT_TO_STRING,
123125
// parent interfaces configs:
124-
parentInterfaces := parentInterfacesConfig,
125-
generateAllMethodInProjection := MappingConfigConstants.DEFAULT_GENERATE_ALL_METHOD,
126-
responseProjectionMaxDepth := MappingConfigConstants.DEFAULT_RESPONSE_PROJECTION_MAX_DEPTH,
127-
supportUnknownFields := MappingConfigConstants.DEFAULT_SUPPORT_UNKNOWN_FIELDS,
128-
unknownFieldsPropertyName := MappingConfigConstants.DEFAULT_UNKNOWN_FIELDS_PROPERTY_NAME,
129-
generateNoArgsConstructorOnly := MappingConfigConstants.DEFAULT_GENERATE_NOARGS_CONSTRUCTOR_ONLY,
130-
generateModelsWithPublicFields := MappingConfigConstants.DEFAULT_GENERATE_MODELS_WITH_PUBLIC_FIELDS,
131-
skip := false
126+
parentInterfaces := parentInterfacesConfig,
127+
generateAllMethodInProjection := MappingConfigConstants.DEFAULT_GENERATE_ALL_METHOD,
128+
responseProjectionMaxDepth := MappingConfigConstants.DEFAULT_RESPONSE_PROJECTION_MAX_DEPTH,
129+
supportUnknownFields := MappingConfigConstants.DEFAULT_SUPPORT_UNKNOWN_FIELDS,
130+
unknownFieldsPropertyName := MappingConfigConstants.DEFAULT_UNKNOWN_FIELDS_PROPERTY_NAME,
131+
generateNoArgsConstructorOnly := MappingConfigConstants.DEFAULT_GENERATE_NOARGS_CONSTRUCTOR_ONLY,
132+
generateModelsWithPublicFields := MappingConfigConstants.DEFAULT_GENERATE_MODELS_WITH_PUBLIC_FIELDS,
133+
skip := false
132134
)
133135

134136
private def getMappingConfig(): Def.Initialize[MappingConfig] = Def.setting {
@@ -149,6 +151,7 @@ class GraphQLCodegenPlugin(configuration: Configuration, private[codegen] val co
149151
mappingConfig.setTypeResolverPrefix((GraphQLCodegenConfig / typeResolverPrefix).value.orNull)
150152
mappingConfig.setModelValidationAnnotation((GraphQLCodegenConfig / modelValidationAnnotation).value)
151153
mappingConfig.setCustomAnnotationsMapping((GraphQLCodegenConfig / customAnnotationsMapping).value)
154+
mappingConfig.setCustomTemplates((GraphQLCodegenConfig / customTemplates).value)
152155
mappingConfig.setGenerateEqualsAndHashCode((GraphQLCodegenConfig / generateEqualsAndHashCode).value)
153156
mappingConfig.setGenerateImmutableModels((GraphQLCodegenConfig / generateImmutableModels).value)
154157
mappingConfig.setGenerateToString((GraphQLCodegenConfig / generateToString).value)

src/main/java/com/kobylynskyi/graphql/codegen/generators/FreeMarkerTemplateFilesCreator.java

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,14 +48,28 @@ public static File create(MappingContext mappingContext,
4848
}
4949

5050
try (FileWriter fileWriter = new FileWriter(javaSourceFile)) {
51-
Template template = FreeMarkerTemplatesRegistry.getTemplateWithLang(language, templateType);
51+
Template template = getTemplateForTypeAndLanguage(mappingContext, templateType, language);
5252
template.process(dataModel, fileWriter);
5353
} catch (Exception e) {
5454
throw new UnableToCreateFileException(e);
5555
}
5656
return javaSourceFile;
5757
}
5858

59+
private static Template getTemplateForTypeAndLanguage(MappingContext mappingContext,
60+
FreeMarkerTemplateType templateType,
61+
GeneratedLanguage language) {
62+
String templatePath = null;
63+
if (mappingContext.getCustomTemplates() != null) {
64+
templatePath = mappingContext.getCustomTemplates().get(templateType);
65+
}
66+
if (templatePath != null) {
67+
return FreeMarkerTemplatesRegistry.getCustomTemplates(templatePath);
68+
} else {
69+
return FreeMarkerTemplatesRegistry.getTemplateWithLang(language, templateType);
70+
}
71+
}
72+
5973
private static File getFileTargetDirectory(Map<String, Object> dataModel, File outputDir) {
6074
File targetDir;
6175
Object packageName = dataModel.get(DataModelFields.PACKAGE);

src/main/java/com/kobylynskyi/graphql/codegen/generators/FreeMarkerTemplatesRegistry.java

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,9 @@ class FreeMarkerTemplatesRegistry {
2222
private static final EnumMap<GeneratedLanguage, EnumMap<FreeMarkerTemplateType, Template>> templateMap =
2323
new EnumMap<>(GeneratedLanguage.class);
2424

25+
private static final Configuration configuration = buildFreeMarkerTemplateConfiguration();
26+
2527
static {
26-
Configuration configuration = buildFreeMarkerTemplateConfiguration();
27-
2828
try {
2929
templateMap.put(GeneratedLanguage.JAVA, getTemplates(configuration, GeneratedLanguage.JAVA));
3030
templateMap.put(GeneratedLanguage.SCALA, getTemplates(configuration, GeneratedLanguage.SCALA));
@@ -70,4 +70,12 @@ private static Configuration buildFreeMarkerTemplateConfiguration() {
7070
return configuration;
7171
}
7272

73+
public static Template getCustomTemplates(String templatePath) {
74+
try {
75+
return configuration.getTemplate(templatePath);
76+
} catch (IOException e) {
77+
throw new UnableToLoadFreeMarkerTemplateException(e);
78+
}
79+
}
80+
7381
}

src/main/java/com/kobylynskyi/graphql/codegen/model/GraphQLCodegenConfiguration.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.kobylynskyi.graphql.codegen.model;
22

3+
import com.kobylynskyi.graphql.codegen.generators.FreeMarkerTemplateType;
34
import java.util.List;
45
import java.util.Map;
56
import java.util.Set;
@@ -27,6 +28,13 @@ public interface GraphQLCodegenConfiguration {
2728
* @return mappings from GraphqlType to JavaType
2829
*/
2930
Map<String, String> getCustomTypesMapping();
31+
32+
/**
33+
* Can be used to supply paths to custom FreeMarker templates for code generation.
34+
*
35+
* @return a map, where key is a tempalte type and a value is path to a FreeMarker template
36+
*/
37+
Map<FreeMarkerTemplateType, String> getCustomTemplates();
3038

3139
/**
3240
* Can be used to supply custom annotations (serializers) for scalars.

0 commit comments

Comments
 (0)