GraphqlTypeToJavaTypeMapper.java 7.7 KB
Newer Older
1 2
package com.kobylynskyi.graphql.codegen.mapper;

3 4
import static graphql.language.OperationDefinition.*;

5
import com.kobylynskyi.graphql.codegen.model.MappingConfig;
6 7
import com.kobylynskyi.graphql.codegen.model.ParameterDefinition;
import graphql.language.*;
8

9 10
import java.util.ArrayList;
import java.util.List;
11 12 13 14 15 16 17 18 19
import java.util.Map;

/**
 * Map GraphQL type to Java type
 *
 * @author kobylynskyi
 */
class GraphqlTypeToJavaTypeMapper {

20
    /**
21
     * Map GraphQL's FieldDefinition to a Freemarker-understandable format of parameter
22 23 24 25 26 27
     *
     * @param mappingConfig  Global mapping configuration
     * @param fieldDef       GraphQL field definition
     * @param parentTypeName Name of the parent type
     * @return Freemarker-understandable format of parameter (field)
     */
28 29 30 31
    public static ParameterDefinition map(MappingConfig mappingConfig, FieldDefinition fieldDef, String parentTypeName) {
        ParameterDefinition parameter = new ParameterDefinition();
        parameter.setName(MapperUtils.capitalizeIfRestricted(fieldDef.getName()));
        parameter.setType(getJavaType(mappingConfig, fieldDef.getType(), fieldDef.getName(), parentTypeName));
32
        parameter.setAnnotations(getAnnotations(mappingConfig, fieldDef.getType(), fieldDef.getName(), parentTypeName, false));
33
        return parameter;
34 35
    }

36 37 38 39 40 41 42 43
    /**
     * Map GraphQL's InputValueDefinition to a Freemarker-understandable format of operation
     *
     * @param mappingConfig        Global mapping configuration
     * @param inputValueDefinition GraphQL input value definition
     * @param parentTypeName       Name of the parent type
     * @return Freemarker-understandable format of parameter (field)
     */
44
    public static ParameterDefinition map(MappingConfig mappingConfig, InputValueDefinition inputValueDefinition, String parentTypeName) {
45 46 47
        ParameterDefinition parameter = new ParameterDefinition();
        parameter.setName(MapperUtils.capitalizeIfRestricted(inputValueDefinition.getName()));
        parameter.setType(getJavaType(mappingConfig, inputValueDefinition.getType()));
48
        parameter.setAnnotations(getAnnotations(mappingConfig, inputValueDefinition.getType(), inputValueDefinition.getName(), parentTypeName));
49 50 51
        return parameter;
    }

52 53 54 55 56 57 58
    /**
     * Convert GraphQL type to a corresponding Java type
     *
     * @param mappingConfig Global mapping configuration
     * @param type          GraphQL type
     * @return Corresponding Java type
     */
59 60 61 62
    static String getJavaType(MappingConfig mappingConfig, Type type) {
        return getJavaType(mappingConfig, type, null, null);
    }

63 64 65 66
    /**
     * Convert GraphQL type to a corresponding Java type
     *
     * @param mappingConfig  Global mapping configuration
67
     * @param graphqlType    GraphQL type
68 69 70 71
     * @param name           GraphQL type name
     * @param parentTypeName Name of the parent type
     * @return Corresponding Java type
     */
72 73 74 75 76
    static String getJavaType(MappingConfig mappingConfig, Type graphqlType, String name, String parentTypeName) {
        if (graphqlType instanceof TypeName) {
            return getJavaType(mappingConfig, ((TypeName) graphqlType).getName(), name, parentTypeName);
        } else if (graphqlType instanceof ListType) {
            String mappedCollectionType = getJavaType(mappingConfig, ((ListType) graphqlType).getType(), name, parentTypeName);
77
            return wrapIntoJavaCollection(mappedCollectionType);
78 79
        } else if (graphqlType instanceof NonNullType) {
            return getJavaType(mappingConfig, ((NonNullType) graphqlType).getType(), name, parentTypeName);
80 81 82 83
        }
        return null;
    }

84 85 86 87 88 89 90 91 92
    /**
     * Convert GraphQL type to a corresponding Java type
     *
     * @param mappingConfig  Global mapping configuration
     * @param graphlType     GraphQL type
     * @param name           GraphQL type name
     * @param parentTypeName Name of the parent type
     * @return Corresponding Java type
     */
93
    private static String getJavaType(MappingConfig mappingConfig, String graphlType, String name, String parentTypeName) {
94 95 96 97 98
        Map<String, String> customTypesMapping = mappingConfig.getCustomTypesMapping();
        if (name != null && parentTypeName != null && customTypesMapping.containsKey(parentTypeName + "." + name)) {
            return customTypesMapping.get(parentTypeName + "." + name);
        } else if (customTypesMapping.containsKey(graphlType)) {
            return customTypesMapping.get(graphlType);
99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114
        }
        switch (graphlType) {
            case "ID":
                return "String";
            case "Int":
                return "Integer";
            case "String":
            case "Float":
            case "Boolean":
                return graphlType;
            default:
                // We need to refer other custom types/interfaces/unions with prefix and suffix
                return MapperUtils.getClassNameWithPrefixAndSuffix(mappingConfig, graphlType);
        }
    }

115 116 117 118 119 120 121 122 123 124 125
    /**
     * Get annotations for a given GraphQL type
     *
     * @param mappingConfig  Global mapping configuration
     * @param graphlType     GraphQL type
     * @param name           GraphQL type name
     * @param parentTypeName Name of the parent type
     * @return list of Java annotations for a given GraphQL type
     */
    static List<String> getAnnotations(MappingConfig mappingConfig, Type graphlType, String name, String parentTypeName) {
        return getAnnotations(mappingConfig, graphlType, name, parentTypeName, false);
126 127 128 129
    }

    private static List<String> getAnnotations(MappingConfig mappingConfig, Type type, String name, String parentTypeName,
                                               boolean mandatory) {
130
        if (type instanceof TypeName) {
131
            return getAnnotations(mappingConfig, ((TypeName) type).getName(), name, parentTypeName, mandatory);
132
        } else if (type instanceof ListType) {
133
            return getAnnotations(mappingConfig, ((ListType) type).getType(), name, parentTypeName, mandatory);
134
        } else if (type instanceof NonNullType) {
135
            return getAnnotations(mappingConfig, ((NonNullType) type).getType(), name, parentTypeName, true);
136 137 138 139
        }
        return null;
    }

140
    private static List<String> getAnnotations(MappingConfig mappingConfig, String graphlType, String name, String parentTypeName, boolean mandatory) {
141
        List<String> annotations = new ArrayList<>();
142 143 144 145 146 147
        if (mandatory) {
            String modelValidationAnnotation = mappingConfig.getModelValidationAnnotation();
            if (modelValidationAnnotation != null && !modelValidationAnnotation.trim().isEmpty()) {
                annotations.add(modelValidationAnnotation);
            }
        }
148 149 150 151 152 153 154 155 156
        Map<String, String> customAnnotationsMapping = mappingConfig.getCustomAnnotationsMapping();
        if (name != null && parentTypeName != null && customAnnotationsMapping.containsKey(parentTypeName + "." + name)) {
            annotations.add(customAnnotationsMapping.get(parentTypeName + "." + name));
        } else if (customAnnotationsMapping.containsKey(graphlType)) {
            annotations.add(customAnnotationsMapping.get(graphlType));
        }
        return annotations;
    }

157 158 159 160
    private static String wrapIntoJavaCollection(String type) {
        return String.format("Collection<%s>", type);
    }

161 162 163 164 165 166 167 168 169
    static String wrapIntoSubscriptionIfRequired(MappingConfig mappingConfig, String javaTypeName, String parentTypeName) {
        if (parentTypeName.equalsIgnoreCase(Operation.SUBSCRIPTION.name())
                && mappingConfig.getSubscriptionReturnType() != null
                && !mappingConfig.getSubscriptionReturnType().trim().isEmpty()) {
            return String.format("%s<%s>", mappingConfig.getSubscriptionReturnType(), javaTypeName);
        }
        return javaTypeName;
    }

170
}