未验证 提交 d3eb4c93 编写于 作者: I Isaac Mercieca 提交者: GitHub

Ability to supply a root directory with custom templates: "customTemplatesRoot" #1158 (#1198)

* added support for specifying the template source for custom templates

* formatted test sources

* resolved issues with sbt plugin

* formatted source class according to checkstyle rules

* updated scala plugin to resolve to the working directory

---------
Co-authored-by: NIsaac Mercieca <isaac.mercieca@rs2.com>
上级 a300a409
......@@ -31,7 +31,8 @@
| `typeResolverPrefix` | String | Empty | Sets the prefix for GraphQL type resolver classes. |
| `typeResolverSuffix` | String | `Resolver` | Sets the suffix for GraphQL type resolver classes. |
| `customTypesMapping` | Map(String,String) | Empty | *See [CustomTypesMapping](#option-customtypesmapping)* |
| `customTemplates` | Map(String,String) | Empty | Use to supply paths to custom FreeMarker templates for code generation. |
| `customTemplatesRoot` | File | Project's dir | Use to supply the path the to custom FreeMarker templates root directory. |
| `customTemplates` | Map(String,String) | Empty | Use to supply paths to custom FreeMarker templates for code generation. |
| `customAnnotationsMapping` | Map(String,String[]) | Empty | *See [CustomAnnotationsMapping](#option-customannotationsmapping)* |
| `directiveAnnotationsMapping` | Map(String,String[]) | Empty | *See [DirectiveAnnotationsMapping](#option-directiveannotationsmapping)* |
| `fieldsWithResolvers` | Set(String) | Empty | Fields that require Resolvers should be defined here in format: `TypeName.fieldName` or `TypeName` or `@directive`. E.g.: `Person`, `Person.friends`, `@customResolver`. |
......
......@@ -54,7 +54,10 @@ public class GraphQLCodegenGradleTask extends DefaultTask implements GraphQLCode
private Map<String, String> customTypesMapping = new HashMap<>();
private Map<String, List<String>> customAnnotationsMapping = new HashMap<>();
private File customTemplatesRoot = null;
private Map<String, String> customTemplates = new HashMap<>();
private Map<String, List<String>> directiveAnnotationsMapping = new HashMap<>();
private String packageName;
private String apiPackageName;
......@@ -136,6 +139,9 @@ public class GraphQLCodegenGradleTask extends DefaultTask implements GraphQLCode
customTypesMapping != null ? customTypesMapping : new HashMap<>());
mappingConfig.setCustomAnnotationsMapping(
customAnnotationsMapping != null ? customAnnotationsMapping : new HashMap<>());
mappingConfig.setCustomTemplatesRoot(
customTemplatesRoot != null ? customTemplatesRoot : getProject().getProjectDir()
);
mappingConfig.setCustomTemplates(
customTemplates != null ? customTemplates : new HashMap<>());
mappingConfig.setDirectiveAnnotationsMapping(
......@@ -336,6 +342,17 @@ public class GraphQLCodegenGradleTask extends DefaultTask implements GraphQLCode
this.customTypesMapping = customTypesMapping;
}
@InputFile
@Optional
@Override
public File getCustomTemplatesRoot() {
return customTemplatesRoot;
}
public void setCustomTemplatesRoot(File customTemplatesRoot) {
this.customTemplatesRoot = customTemplatesRoot;
}
@Input
@Optional
@Override
......
......@@ -65,6 +65,9 @@ public class GraphQLCodegenMojo extends AbstractMojo implements GraphQLCodegenCo
@Parameter
private Map<String, Properties> customAnnotationsMapping;
@Parameter
private File customTemplatesRoot;
@Parameter
private Map<String, String> customTemplates;
......@@ -249,6 +252,7 @@ public class GraphQLCodegenMojo extends AbstractMojo implements GraphQLCodegenCo
MappingConfig mappingConfig = new MappingConfig();
mappingConfig.setPackageName(packageName);
mappingConfig.setCustomTypesMapping(convertToMap(customTypesMapping));
mappingConfig.setCustomTemplatesRoot(customTemplatesRoot);
mappingConfig.setCustomTemplates(customTemplates);
mappingConfig.setCustomAnnotationsMapping(convertToListsMap(customAnnotationsMapping));
mappingConfig.setDirectiveAnnotationsMapping(convertToListsMap(directiveAnnotationsMapping));
......@@ -739,6 +743,11 @@ public class GraphQLCodegenMojo extends AbstractMojo implements GraphQLCodegenCo
result.put(name, properties.getProperty(name));
}
return result;
}
@Override
public File getCustomTemplatesRoot() {
return customTemplatesRoot == null ? project.getBasedir() : customTemplatesRoot;
}
@Override
......
......@@ -43,6 +43,8 @@ trait GraphQLCodegenKeys {
val customAnnotationsMapping = settingKey[util.Map[String, util.List[String]]]("customAnnotationsMapping")
val customTemplatesRoot = settingKey[File]("customTemplatesRoot")
val customTemplates = settingKey[util.Map[String, String]]("customTemplates")
val generateEqualsAndHashCode =
......
......@@ -67,6 +67,7 @@ class GraphQLCodegenPlugin(configuration: Configuration, private[codegen] val co
generateJacksonTypeIdResolver := MappingConfigConstants.DEFAULT_GENERATE_JACKSON_TYPE_ID_RESOLVER,
customTypesMapping := new JHashMap[String, String](), // TODO use scala Map, convert to java Map
customAnnotationsMapping := new JHashMap[String, JList[String]](),
customTemplatesRoot := file("."),
customTemplates := new JHashMap[String, String](),
directiveAnnotationsMapping := new JHashMap[String, JList[String]](),
javaxValidationApiVersion := None,
......@@ -150,6 +151,7 @@ class GraphQLCodegenPlugin(configuration: Configuration, private[codegen] val co
mappingConfig.setTypeResolverPrefix((GraphQLCodegenConfig / typeResolverPrefix).value.orNull)
mappingConfig.setModelValidationAnnotation((GraphQLCodegenConfig / modelValidationAnnotation).value)
mappingConfig.setCustomAnnotationsMapping((GraphQLCodegenConfig / customAnnotationsMapping).value)
mappingConfig.setCustomTemplatesRoot((GraphQLCodegenConfig / customTemplatesRoot).value)
mappingConfig.setCustomTemplates((GraphQLCodegenConfig / customTemplates).value)
mappingConfig.setGenerateEqualsAndHashCode((GraphQLCodegenConfig / generateEqualsAndHashCode).value)
mappingConfig.setGenerateImmutableModels((GraphQLCodegenConfig / generateImmutableModels).value)
......
......@@ -63,8 +63,9 @@ public class FreeMarkerTemplateFilesCreator {
if (mappingContext.getCustomTemplates() != null) {
templatePath = mappingContext.getCustomTemplates().get(templateType.name());
}
if (templatePath != null) {
return FreeMarkerTemplatesRegistry.getCustomTemplates(templatePath);
return FreeMarkerTemplatesRegistry.getCustomTemplate(mappingContext.getCustomTemplatesRoot(), templatePath);
} else {
return FreeMarkerTemplatesRegistry.getTemplateWithLang(language, templateType);
}
......
......@@ -5,7 +5,6 @@ import com.kobylynskyi.graphql.codegen.model.GeneratedLanguage;
import com.kobylynskyi.graphql.codegen.model.exception.UnableToLoadFreeMarkerTemplateException;
import freemarker.cache.ClassTemplateLoader;
import freemarker.cache.FileTemplateLoader;
import freemarker.cache.MultiTemplateLoader;
import freemarker.cache.TemplateLoader;
import freemarker.core.PlainTextOutputFormat;
import freemarker.ext.beans.BeansWrapper;
......@@ -28,7 +27,7 @@ class FreeMarkerTemplatesRegistry {
new EnumMap<>(GeneratedLanguage.class);
private static final Configuration configuration;
static {
try {
configuration = buildFreeMarkerTemplateConfiguration();
......@@ -64,24 +63,34 @@ class FreeMarkerTemplatesRegistry {
templateType.name().toLowerCase());
}
private static Configuration buildFreeMarkerTemplateConfiguration() throws IOException {
Configuration configuration = new Configuration(FREEMARKER_TEMPLATE_VERSION);
private static Configuration buildFreeMarkerTemplateConfiguration() {
ClassTemplateLoader classTemplateLoader = new ClassTemplateLoader(GraphQLCodegen.class.getClassLoader(), "");
FileTemplateLoader fileTemplateLoader = new FileTemplateLoader(new File("."));
configuration.setTemplateLoader(
new MultiTemplateLoader(new TemplateLoader[] {classTemplateLoader, fileTemplateLoader}));
return buildFreeMarkerTemplateConfiguration(classTemplateLoader);
}
private static Configuration buildFreeMarkerTemplateConfiguration(TemplateLoader templateLoader) {
Configuration configuration = new Configuration(FREEMARKER_TEMPLATE_VERSION);
configuration.setTemplateLoader(templateLoader);
configuration.setDefaultEncoding(DEFAULT_ENCODING);
configuration.setOutputFormat(PlainTextOutputFormat.INSTANCE);
configuration.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER);
configuration.setLogTemplateExceptions(false);
configuration.setWrapUncheckedExceptions(true);
configuration.setSharedVariable("statics", new BeansWrapper(FREEMARKER_TEMPLATE_VERSION).getStaticModels());
return configuration;
}
public static Template getCustomTemplates(String templatePath) {
private static Configuration buildFreeMarkerCustomTemplateConfiguration(File file) throws IOException {
FileTemplateLoader fileTemplateLoader = new FileTemplateLoader(file);
return buildFreeMarkerTemplateConfiguration(fileTemplateLoader);
}
public static Template getCustomTemplate(File templateRoot, String templatePath) {
try {
return configuration.getTemplate(templatePath);
return buildFreeMarkerCustomTemplateConfiguration(templateRoot).getTemplate(templatePath);
} catch (IOException e) {
throw new UnableToLoadFreeMarkerTemplateException(e);
}
......
package com.kobylynskyi.graphql.codegen.model;
import com.kobylynskyi.graphql.codegen.generators.FreeMarkerTemplateType;
import java.io.File;
import java.util.List;
import java.util.Map;
import java.util.Set;
......@@ -29,10 +31,17 @@ public interface GraphQLCodegenConfiguration {
*/
Map<String, String> getCustomTypesMapping();
/**
* Can be used to specify the root directory for the custom FreeMaker templates
*
* @return the directory source for the root directory
*/
File getCustomTemplatesRoot();
/**
* Can be used to supply paths to custom FreeMarker templates for code generation.
*
* @return a map, where key is a tempalte type and a value is path to a FreeMarker template
* @return a map, where key is a template type and a value is path to a FreeMarker template
*/
Map<String, String> getCustomTemplates();
......
package com.kobylynskyi.graphql.codegen.model;
import com.kobylynskyi.graphql.codegen.generators.FreeMarkerTemplateType;
import java.io.File;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
......@@ -86,6 +88,8 @@ public class MappingConfig implements GraphQLCodegenConfiguration, Combinable<Ma
private Set<String> parametrizedResolverAnnotations = new HashSet<>();
private Map<String, String> customTypesMapping = new HashMap<>();
private File customTemplatesRoot = new File(".");
private Map<String, String> customTemplates = new HashMap<>();
private Set<String> typesAsInterfaces = new HashSet<>();
......@@ -247,6 +251,24 @@ public class MappingConfig implements GraphQLCodegenConfiguration, Combinable<Ma
this.customTypesMapping = customTypesMapping;
}
@Override
public File getCustomTemplatesRoot() {
return customTemplatesRoot;
}
public void setCustomTemplatesRoot(File customTemplatesRoot) {
this.customTemplatesRoot = customTemplatesRoot;
}
@Override
public Map<String, String> getCustomTemplates() {
return customTemplates;
}
public void setCustomTemplates(Map<String, String> customTemplates) {
this.customTemplates = customTemplates;
}
/**
* Provide a path to a custom template for the specific FreeMarker template type (if absent).
*
......@@ -260,15 +282,6 @@ public class MappingConfig implements GraphQLCodegenConfiguration, Combinable<Ma
customTemplates.computeIfAbsent(from, k -> to);
}
@Override
public Map<String, String> getCustomTemplates() {
return customTemplates;
}
public void setCustomTemplates(Map<String, String> customTemplates) {
this.customTemplates = customTemplates;
}
@Override
public Map<String, List<String>> getCustomAnnotationsMapping() {
return customAnnotationsMapping;
......
......@@ -84,7 +84,12 @@ public class MappingContext implements GraphQLCodegenConfiguration {
public Map<String, String> getCustomTypesMapping() {
return config.getCustomTypesMapping();
}
@Override
public File getCustomTemplatesRoot() {
return config.getCustomTemplatesRoot();
}
@Override
public Map<String, String> getCustomTemplates() {
return config.getCustomTemplates();
......
......@@ -36,7 +36,10 @@ class GraphQLCodegenCustomTemplatesTest {
@Test
void generate_CustomTemplates_Type() throws Exception {
mappingConfig.putCustomTemplatesIfAbsent(FreeMarkerTemplateType.TYPE.name(), "/template/record_type.ftl");
mappingConfig.putCustomTemplatesIfAbsent(
FreeMarkerTemplateType.TYPE.name(),
"src/test/resources/template/record_type.ftl"
);
generate("src/test/resources/schemas/test.graphqls");
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册