GraphQLCodegen.java 22.8 KB
Newer Older
1 2
package com.kobylynskyi.graphql.codegen;

3 4 5 6 7 8 9 10
import com.kobylynskyi.graphql.codegen.mapper.EnumDefinitionToDataModelMapper;
import com.kobylynskyi.graphql.codegen.mapper.FieldDefinitionToParameterMapper;
import com.kobylynskyi.graphql.codegen.mapper.FieldDefinitionsToResolverDataModelMapper;
import com.kobylynskyi.graphql.codegen.mapper.InputDefinitionToDataModelMapper;
import com.kobylynskyi.graphql.codegen.mapper.InterfaceDefinitionToDataModelMapper;
import com.kobylynskyi.graphql.codegen.mapper.RequestResponseDefinitionToDataModelMapper;
import com.kobylynskyi.graphql.codegen.mapper.TypeDefinitionToDataModelMapper;
import com.kobylynskyi.graphql.codegen.mapper.UnionDefinitionToDataModelMapper;
11 12
import com.kobylynskyi.graphql.codegen.model.ApiNamePrefixStrategy;
import com.kobylynskyi.graphql.codegen.model.ApiRootInterfaceStrategy;
13
import com.kobylynskyi.graphql.codegen.model.GeneratedInformation;
14
import com.kobylynskyi.graphql.codegen.model.MappingConfig;
15
import com.kobylynskyi.graphql.codegen.model.MappingConfigConstants;
16
import com.kobylynskyi.graphql.codegen.model.MappingContext;
17 18 19 20 21 22 23 24
import com.kobylynskyi.graphql.codegen.model.definitions.ExtendedDocument;
import com.kobylynskyi.graphql.codegen.model.definitions.ExtendedEnumTypeDefinition;
import com.kobylynskyi.graphql.codegen.model.definitions.ExtendedFieldDefinition;
import com.kobylynskyi.graphql.codegen.model.definitions.ExtendedInputObjectTypeDefinition;
import com.kobylynskyi.graphql.codegen.model.definitions.ExtendedInterfaceTypeDefinition;
import com.kobylynskyi.graphql.codegen.model.definitions.ExtendedObjectTypeDefinition;
import com.kobylynskyi.graphql.codegen.model.definitions.ExtendedScalarTypeDefinition;
import com.kobylynskyi.graphql.codegen.model.definitions.ExtendedUnionTypeDefinition;
A
Alberto Valiña 已提交
25
import com.kobylynskyi.graphql.codegen.supplier.MappingConfigSupplier;
26
import com.kobylynskyi.graphql.codegen.utils.Utils;
27 28
import graphql.language.FieldDefinition;
import graphql.language.ScalarTypeExtensionDefinition;
29 30

import java.io.File;
B
Bogdan Kobylynskyi 已提交
31
import java.io.IOException;
32 33 34 35 36 37
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Optional;
38

39 40
import static java.util.stream.Collectors.toList;

41 42
/**
 * Generator of:
43 44 45
 * - Interface for each GraphQL query, mutation, subscription, union and field resolvers
 * - POJO Class for each GraphQL type and input
 * - Enum Class for each GraphQL enum
46 47
 *
 * @author kobylynskyi
A
Alberto Valiña 已提交
48
 * @author valinhadev
49
 */
50
public class GraphQLCodegen {
51

52 53 54 55
    private final List<String> schemas;
    private final File outputDir;
    private final MappingConfig mappingConfig;
    private final GeneratedInformation generatedInformation;
56

57 58 59 60 61
    public GraphQLCodegen(List<String> schemas,
                          File outputDir,
                          MappingConfig mappingConfig,
                          GeneratedInformation generatedInformation) {
        this(schemas, outputDir, mappingConfig, null, generatedInformation);
A
Alberto Valiña 已提交
62 63
    }

64 65 66 67 68 69 70 71 72 73 74 75
    public GraphQLCodegen(List<String> schemas,
                          File outputDir,
                          MappingConfig mappingConfig,
                          MappingConfigSupplier externalMappingConfigSupplier) {
        this(schemas, outputDir, mappingConfig, externalMappingConfigSupplier, new GeneratedInformation());
    }

    public GraphQLCodegen(List<String> schemas,
                          File outputDir,
                          MappingConfig mappingConfig,
                          MappingConfigSupplier externalMappingConfigSupplier,
                          GeneratedInformation generatedInformation) {
76 77 78
        this.schemas = schemas;
        this.outputDir = outputDir;
        this.mappingConfig = mappingConfig;
A
Alberto Valiña 已提交
79 80
        this.mappingConfig.combine(externalMappingConfigSupplier != null ? externalMappingConfigSupplier.get() : null);
        initDefaultValues(mappingConfig);
81
        validateConfigs(mappingConfig);
82
        sanitizeValues(mappingConfig);
83
        this.generatedInformation = generatedInformation;
A
Alberto Valiña 已提交
84 85
    }

86
    private static void initDefaultValues(MappingConfig mappingConfig) {
A
Alberto Valiña 已提交
87
        if (mappingConfig.getModelValidationAnnotation() == null) {
88
            mappingConfig.setModelValidationAnnotation(MappingConfigConstants.DEFAULT_VALIDATION_ANNOTATION);
A
Alberto Valiña 已提交
89
        }
90
        if (mappingConfig.getGenerateBuilder() == null) {
91
            mappingConfig.setGenerateBuilder(MappingConfigConstants.DEFAULT_BUILDER);
92
        }
A
Alberto Valiña 已提交
93
        if (mappingConfig.getGenerateEqualsAndHashCode() == null) {
94
            mappingConfig.setGenerateEqualsAndHashCode(MappingConfigConstants.DEFAULT_EQUALS_AND_HASHCODE);
A
Alberto Valiña 已提交
95
        }
96 97
        if (mappingConfig.getGenerateClient() == null) {
            mappingConfig.setGenerateClient(MappingConfigConstants.DEFAULT_GENERATE_CLIENT);
98 99
        }
        if (mappingConfig.getRequestSuffix() == null) {
100
            mappingConfig.setRequestSuffix(MappingConfigConstants.DEFAULT_REQUEST_SUFFIX);
101
        }
102 103 104
        if (mappingConfig.getResponseSuffix() == null) {
            mappingConfig.setResponseSuffix(MappingConfigConstants.DEFAULT_RESPONSE_SUFFIX);
        }
105
        if (mappingConfig.getResponseProjectionSuffix() == null) {
106
            mappingConfig.setResponseProjectionSuffix(MappingConfigConstants.DEFAULT_RESPONSE_PROJECTION_SUFFIX);
107
        }
108
        if (mappingConfig.getParametrizedInputSuffix() == null) {
109
            mappingConfig.setParametrizedInputSuffix(MappingConfigConstants.DEFAULT_PARAMETRIZED_INPUT_SUFFIX);
110
        }
111 112 113
        if (mappingConfig.getGenerateImmutableModels() == null) {
            mappingConfig.setGenerateImmutableModels(MappingConfigConstants.DEFAULT_GENERATE_IMMUTABLE_MODELS);
        }
A
Alberto Valiña 已提交
114
        if (mappingConfig.getGenerateToString() == null) {
115
            mappingConfig.setGenerateToString(MappingConfigConstants.DEFAULT_TO_STRING);
A
Alberto Valiña 已提交
116 117
        }
        if (mappingConfig.getGenerateApis() == null) {
118
            mappingConfig.setGenerateApis(MappingConfigConstants.DEFAULT_GENERATE_APIS);
A
Alberto Valiña 已提交
119
        }
120
        if (mappingConfig.getApiNameSuffix() == null) {
121 122 123 124
            mappingConfig.setApiNameSuffix(MappingConfigConstants.DEFAULT_RESOLVER_SUFFIX);
        }
        if (mappingConfig.getTypeResolverSuffix() == null) {
            mappingConfig.setTypeResolverSuffix(MappingConfigConstants.DEFAULT_RESOLVER_SUFFIX);
125
        }
126
        if (mappingConfig.getGenerateAsyncApi() == null) {
127
            mappingConfig.setGenerateAsyncApi(MappingConfigConstants.DEFAULT_GENERATE_ASYNC_APIS);
128
        }
129 130 131
        if (mappingConfig.getApiAsyncReturnType() == null) {
            mappingConfig.setApiAsyncReturnType(MappingConfigConstants.DEFAULT_API_ASYNC_RETURN_TYPE);
        }
132
        if (mappingConfig.getGenerateParameterizedFieldsResolvers() == null) {
133
            mappingConfig.setGenerateParameterizedFieldsResolvers(MappingConfigConstants.DEFAULT_GENERATE_PARAMETERIZED_FIELDS_RESOLVERS);
134
        }
135
        if (mappingConfig.getGenerateExtensionFieldsResolvers() == null) {
136
            mappingConfig.setGenerateExtensionFieldsResolvers(MappingConfigConstants.DEFAULT_GENERATE_EXTENSION_FIELDS_RESOLVERS);
137
        }
138
        if (mappingConfig.getGenerateDataFetchingEnvironmentArgumentInApis() == null) {
139
            mappingConfig.setGenerateDataFetchingEnvironmentArgumentInApis(MappingConfigConstants.DEFAULT_GENERATE_DATA_FETCHING_ENV);
140
        }
141 142 143
        if (mappingConfig.getGenerateModelsForRootTypes() == null) {
            mappingConfig.setGenerateModelsForRootTypes(MappingConfigConstants.DEFAULT_GENERATE_MODELS_FOR_ROOT_TYPES);
        }
144 145 146 147 148 149
        if (mappingConfig.getApiNamePrefixStrategy() == null) {
            mappingConfig.setApiNamePrefixStrategy(MappingConfigConstants.DEFAULT_API_NAME_PREFIX_STRATEGY);
        }
        if (mappingConfig.getApiRootInterfaceStrategy() == null) {
            mappingConfig.setApiRootInterfaceStrategy(MappingConfigConstants.DEFAULT_API_ROOT_INTERFACE_STRATEGY);
        }
B
Bogdan Kobylynskyi 已提交
150
        if (Boolean.TRUE.equals(mappingConfig.getGenerateClient())) {
151 152 153
            // required for request serialization
            mappingConfig.setGenerateToString(true);
        }
154 155 156
    }

    private static void validateConfigs(MappingConfig mappingConfig) {
157 158
        if (mappingConfig.getApiRootInterfaceStrategy() == ApiRootInterfaceStrategy.INTERFACE_PER_SCHEMA &&
                mappingConfig.getApiNamePrefixStrategy() == ApiNamePrefixStrategy.CONSTANT) {
159
            // we will have a conflict in case there is "type Query" in multiple graphql schema files
160 161
            throw new IllegalArgumentException("API prefix should not be CONSTANT for INTERFACE_PER_SCHEMA option");
        }
162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177
        if (mappingConfig.getGenerateApis() &&
                mappingConfig.getGenerateModelsForRootTypes() &&
                mappingConfig.getApiNamePrefixStrategy() == ApiNamePrefixStrategy.CONSTANT) {
            // checking for conflict between root type model classes and api interfaces
            if (Utils.stringsEqualIgnoreSpaces(mappingConfig.getApiNamePrefix(), mappingConfig.getModelNamePrefix()) &&
                    Utils.stringsEqualIgnoreSpaces(mappingConfig.getApiNameSuffix(), mappingConfig.getModelNameSuffix())) {
                // we will have a conflict between model pojo (Query.java) and api interface (Query.java)
                throw new IllegalArgumentException("Either disable APIs generation or set different Prefix/Suffix for API classes and model classes");
            }
            // checking for conflict between root type model resolver classes and api interfaces
            if (Utils.stringsEqualIgnoreSpaces(mappingConfig.getApiNamePrefix(), mappingConfig.getTypeResolverPrefix()) &&
                    Utils.stringsEqualIgnoreSpaces(mappingConfig.getApiNameSuffix(), mappingConfig.getTypeResolverSuffix())) {
                // we will have a conflict between model resolver interface (QueryResolver.java) and api interface resolver (QueryResolver.java)
                throw new IllegalArgumentException("Either disable APIs generation or set different Prefix/Suffix for API classes and type resolver classes");
            }
        }
178 179
    }

180 181 182 183 184 185 186 187 188 189 190 191
    private static void sanitizeValues(MappingConfig mappingConfig) {
        mappingConfig.setModelValidationAnnotation(
                Utils.replaceLeadingAtSign(mappingConfig.getModelValidationAnnotation()));

        Map<String, String> customAnnotationsMapping = mappingConfig.getCustomAnnotationsMapping();
        if (customAnnotationsMapping != null) {
            for (Map.Entry<String, String> entry : customAnnotationsMapping.entrySet()) {
                entry.setValue(Utils.replaceLeadingAtSign(entry.getValue()));
            }
        }
    }

B
Bogdan Kobylynskyi 已提交
192
    public List<File> generate() throws IOException {
193
        GraphQLCodegenFileCreator.prepareOutputDir(outputDir);
194
        long startTime = System.currentTimeMillis();
195
        List<File> generatedFiles = Collections.emptyList();
196
        if (!schemas.isEmpty()) {
197
            ExtendedDocument document = GraphQLDocumentParser.getDocument(mappingConfig, schemas);
198
            initCustomTypeMappings(document.getScalarDefinitions());
199
            generatedFiles = processDefinitions(document);
200
        }
201
        long elapsed = System.currentTimeMillis() - startTime;
202
        System.out.println(String.format("Finished processing %d schema(s) in %d ms", schemas.size(), elapsed));
203
        return generatedFiles;
204 205
    }

206
    private List<File> processDefinitions(ExtendedDocument document) {
207
        MappingContext context = new MappingContext(mappingConfig, document, generatedInformation);
208

209 210
        List<File> generatedFiles = new ArrayList<>();
        for (ExtendedObjectTypeDefinition extendedObjectTypeDefinition : document.getTypeDefinitions()) {
211
            generatedFiles.addAll(generateType(context, extendedObjectTypeDefinition));
212 213
        }
        for (ExtendedObjectTypeDefinition extendedObjectTypeDefinition : document.getTypeDefinitions()) {
214
            generateFieldResolver(context, extendedObjectTypeDefinition.getFieldDefinitions(), extendedObjectTypeDefinition.getName())
215 216 217
                    .ifPresent(generatedFiles::add);
        }
        for (ExtendedObjectTypeDefinition extendedObjectTypeDefinition : document.getOperationDefinitions()) {
B
Bogdan Kobylynskyi 已提交
218
            if (Boolean.TRUE.equals(mappingConfig.getGenerateApis())) {
219 220
                generatedFiles.addAll(generateServerOperations(context, extendedObjectTypeDefinition));
            }
B
Bogdan Kobylynskyi 已提交
221
            if (Boolean.TRUE.equals(mappingConfig.getGenerateClient())) {
222 223
                generatedFiles.addAll(generateClient(context, extendedObjectTypeDefinition));
            }
224 225
        }
        for (ExtendedInputObjectTypeDefinition extendedInputObjectTypeDefinition : document.getInputDefinitions()) {
226
            generatedFiles.add(generateInput(context, extendedInputObjectTypeDefinition));
227 228
        }
        for (ExtendedEnumTypeDefinition extendedEnumTypeDefinition : document.getEnumDefinitions()) {
229
            generatedFiles.add(generateEnum(context, extendedEnumTypeDefinition));
230 231
        }
        for (ExtendedUnionTypeDefinition extendedUnionTypeDefinition : document.getUnionDefinitions()) {
232
            generatedFiles.addAll(generateUnion(context, extendedUnionTypeDefinition));
233 234
        }
        for (ExtendedInterfaceTypeDefinition extendedInterfaceTypeDefinition : document.getInterfaceDefinitions()) {
235
            generatedFiles.addAll(generateInterface(context, extendedInterfaceTypeDefinition));
236 237
        }
        for (ExtendedInterfaceTypeDefinition definition : document.getInterfaceDefinitions()) {
238
            generateFieldResolver(context, definition.getFieldDefinitions(), definition.getName())
239 240 241 242 243
                    .ifPresent(generatedFiles::add);
        }
        System.out.println(String.format("Generated %d definition classes in folder %s",
                generatedFiles.size(), outputDir.getAbsolutePath()));
        return generatedFiles;
244 245
    }

246 247
    private List<File> generateUnion(MappingContext mappingContext, ExtendedUnionTypeDefinition definition) {
        List<File> generatedFiles = new ArrayList<>();
248
        Map<String, Object> dataModel = UnionDefinitionToDataModelMapper.map(mappingContext, definition);
249 250 251 252 253 254 255
        generatedFiles.add(GraphQLCodegenFileCreator.generateFile(FreeMarkerTemplatesRegistry.unionTemplate, dataModel, outputDir));

        if (Boolean.TRUE.equals(mappingConfig.getGenerateClient())) {
            Map<String, Object> responseProjDataModel = RequestResponseDefinitionToDataModelMapper.mapResponseProjection(mappingContext, definition);
            generatedFiles.add(GraphQLCodegenFileCreator.generateFile(FreeMarkerTemplatesRegistry.responseProjectionTemplate, responseProjDataModel, outputDir));
        }
        return generatedFiles;
256 257
    }

258 259
    private List<File> generateInterface(MappingContext mappingContext, ExtendedInterfaceTypeDefinition definition) {
        List<File> generatedFiles = new ArrayList<>();
260
        Map<String, Object> dataModel = InterfaceDefinitionToDataModelMapper.map(mappingContext, definition);
261 262 263 264 265 266 267
        generatedFiles.add(GraphQLCodegenFileCreator.generateFile(FreeMarkerTemplatesRegistry.interfaceTemplate, dataModel, outputDir));

        if (Boolean.TRUE.equals(mappingConfig.getGenerateClient())) {
            Map<String, Object> responseProjDataModel = RequestResponseDefinitionToDataModelMapper.mapResponseProjection(mappingContext, definition);
            generatedFiles.add(GraphQLCodegenFileCreator.generateFile(FreeMarkerTemplatesRegistry.responseProjectionTemplate, responseProjDataModel, outputDir));
        }
        return generatedFiles;
268 269
    }

270
    private List<File> generateServerOperations(MappingContext mappingContext, ExtendedObjectTypeDefinition definition) {
271
        List<File> generatedFiles = new ArrayList<>();
272 273 274 275 276 277 278 279 280 281 282 283 284 285 286
        // Generate a root interface with all operations inside
        // Relates to https://github.com/facebook/relay/issues/112
        switch (mappingContext.getApiRootInterfaceStrategy()) {
            case INTERFACE_PER_SCHEMA:
                for (ExtendedObjectTypeDefinition defInFile : definition.groupBySourceLocationFile().values()) {
                    generatedFiles.add(generateRootApi(mappingContext, defInFile));
                }
                break;
            case SINGLE_INTERFACE:
            default:
                generatedFiles.add(generateRootApi(mappingContext, definition));
                break;
        }

        // Generate separate interfaces for all queries, mutations and subscriptions
287
        List<String> fieldNames = definition.getFieldDefinitions().stream().map(FieldDefinition::getName).collect(toList());
288 289 290 291 292 293 294 295 296 297 298 299 300 301 302
        switch (mappingContext.getApiNamePrefixStrategy()) {
            case FOLDER_NAME_AS_PREFIX:
                for (ExtendedObjectTypeDefinition fileDef : definition.groupBySourceLocationFolder().values()) {
                    generatedFiles.addAll(generateApis(mappingContext, fileDef, fieldNames));
                }
                break;
            case FILE_NAME_AS_PREFIX:
                for (ExtendedObjectTypeDefinition fileDef : definition.groupBySourceLocationFile().values()) {
                    generatedFiles.addAll(generateApis(mappingContext, fileDef, fieldNames));
                }
                break;
            case CONSTANT:
            default:
                generatedFiles.addAll(generateApis(mappingContext, definition, fieldNames));
                break;
303
        }
304 305
        return generatedFiles;
    }
306

307 308 309 310 311 312
    private List<File> generateClient(MappingContext mappingContext, ExtendedObjectTypeDefinition definition) {
        List<File> generatedFiles = new ArrayList<>();
        List<String> fieldNames = definition.getFieldDefinitions().stream().map(FieldDefinition::getName).collect(toList());
        for (ExtendedFieldDefinition operationDef : definition.getFieldDefinitions()) {
            Map<String, Object> requestDataModel = RequestResponseDefinitionToDataModelMapper.mapRequest(mappingContext, operationDef, definition.getName(), fieldNames);
            generatedFiles.add(GraphQLCodegenFileCreator.generateFile(FreeMarkerTemplatesRegistry.requestTemplate, requestDataModel, outputDir));
313

314 315
            Map<String, Object> responseDataModel = RequestResponseDefinitionToDataModelMapper.mapResponse(mappingContext, operationDef, definition.getName(), fieldNames);
            generatedFiles.add(GraphQLCodegenFileCreator.generateFile(FreeMarkerTemplatesRegistry.responseTemplate, responseDataModel, outputDir));
316
        }
317
        return generatedFiles;
318 319
    }

320 321 322 323 324 325 326 327 328 329 330 331 332 333
    private List<File> generateApis(MappingContext mappingContext, ExtendedObjectTypeDefinition definition, List<String> fieldNames) {
        List<File> generatedFiles = new ArrayList<>();
        for (ExtendedFieldDefinition operationDef : definition.getFieldDefinitions()) {
            Map<String, Object> dataModel = FieldDefinitionsToResolverDataModelMapper.mapRootTypeField(mappingContext, operationDef, definition.getName(), fieldNames);
            generatedFiles.add(GraphQLCodegenFileCreator.generateFile(FreeMarkerTemplatesRegistry.operationsTemplate, dataModel, outputDir));
        }
        return generatedFiles;
    }

    private File generateRootApi(MappingContext mappingContext, ExtendedObjectTypeDefinition definition) {
        Map<String, Object> dataModel = FieldDefinitionsToResolverDataModelMapper.mapRootTypeFields(mappingContext, definition);
        return GraphQLCodegenFileCreator.generateFile(FreeMarkerTemplatesRegistry.operationsTemplate, dataModel, outputDir);
    }

334
    private List<File> generateType(MappingContext mappingContext, ExtendedObjectTypeDefinition definition) {
335
        List<File> generatedFiles = new ArrayList<>();
336
        Map<String, Object> dataModel = TypeDefinitionToDataModelMapper.map(mappingContext, definition);
337
        generatedFiles.add(GraphQLCodegenFileCreator.generateFile(FreeMarkerTemplatesRegistry.typeTemplate, dataModel, outputDir));
338

B
Bogdan Kobylynskyi 已提交
339
        if (Boolean.TRUE.equals(mappingConfig.getGenerateClient())) {
340
            Map<String, Object> responseProjDataModel = RequestResponseDefinitionToDataModelMapper.mapResponseProjection(mappingContext, definition);
341
            generatedFiles.add(GraphQLCodegenFileCreator.generateFile(FreeMarkerTemplatesRegistry.responseProjectionTemplate, responseProjDataModel, outputDir));
342 343 344

            for (ExtendedFieldDefinition fieldDefinition : definition.getFieldDefinitions()) {
                if (!Utils.isEmpty(fieldDefinition.getInputValueDefinitions())) {
345
                    Map<String, Object> fieldProjDataModel = RequestResponseDefinitionToDataModelMapper.mapParametrizedInput(mappingContext, fieldDefinition, definition);
346 347 348
                    generatedFiles.add(GraphQLCodegenFileCreator.generateFile(FreeMarkerTemplatesRegistry.parametrizedInputTemplate, fieldProjDataModel, outputDir));
                }
            }
349
        }
350
        return generatedFiles;
351 352
    }

353
    private Optional<File> generateFieldResolver(MappingContext mappingContext, List<ExtendedFieldDefinition> fieldDefinitions, String definitionName) {
354
        List<ExtendedFieldDefinition> fieldDefsWithResolvers = fieldDefinitions.stream()
355
                .filter(fieldDef -> FieldDefinitionToParameterMapper.generateResolversForField(mappingContext, fieldDef, definitionName))
356 357
                .collect(toList());
        if (!fieldDefsWithResolvers.isEmpty()) {
358
            Map<String, Object> dataModel = FieldDefinitionsToResolverDataModelMapper.mapToTypeResolver(mappingContext, fieldDefsWithResolvers, definitionName);
359
            return Optional.of(GraphQLCodegenFileCreator.generateFile(FreeMarkerTemplatesRegistry.operationsTemplate, dataModel, outputDir));
360
        }
361
        return Optional.empty();
362 363
    }

364 365
    private File generateInput(MappingContext mappingContext, ExtendedInputObjectTypeDefinition definition) {
        Map<String, Object> dataModel = InputDefinitionToDataModelMapper.map(mappingContext, definition);
366
        return GraphQLCodegenFileCreator.generateFile(FreeMarkerTemplatesRegistry.typeTemplate, dataModel, outputDir);
367 368
    }

369 370
    private File generateEnum(MappingContext mappingContext, ExtendedEnumTypeDefinition definition) {
        Map<String, Object> dataModel = EnumDefinitionToDataModelMapper.map(mappingContext, definition);
371
        return GraphQLCodegenFileCreator.generateFile(FreeMarkerTemplatesRegistry.enumTemplate, dataModel, outputDir);
372 373
    }

374 375
    private void initCustomTypeMappings(Collection<ExtendedScalarTypeDefinition> scalarTypeDefinitions) {
        for (ExtendedScalarTypeDefinition definition : scalarTypeDefinitions) {
376 377 378
            if (definition.getDefinition() != null) {
                mappingConfig.putCustomTypeMappingIfAbsent(definition.getDefinition().getName(), "String");
            }
379 380
            for (ScalarTypeExtensionDefinition extension : definition.getExtensions()) {
                mappingConfig.putCustomTypeMappingIfAbsent(extension.getName(), "String");
381 382
            }
        }
383 384 385 386 387
        mappingConfig.putCustomTypeMappingIfAbsent("ID", "String");
        mappingConfig.putCustomTypeMappingIfAbsent("String", "String");
        mappingConfig.putCustomTypeMappingIfAbsent("Int", "Integer");
        mappingConfig.putCustomTypeMappingIfAbsent("Float", "Double");
        mappingConfig.putCustomTypeMappingIfAbsent("Boolean", "Boolean");
388
    }
389

390
}