|
2 | 2 |
|
3 | 3 | import com.kobylynskyi.graphql.codegen.model.MappingContext; |
4 | 4 | import com.kobylynskyi.graphql.codegen.model.ProjectionParameterDefinition; |
| 5 | +import com.kobylynskyi.graphql.codegen.model.definitions.ExtendedDefinition; |
5 | 6 | import com.kobylynskyi.graphql.codegen.model.definitions.ExtendedFieldDefinition; |
6 | 7 | import com.kobylynskyi.graphql.codegen.model.definitions.ExtendedObjectTypeDefinition; |
| 8 | +import com.kobylynskyi.graphql.codegen.model.definitions.ExtendedUnionTypeDefinition; |
7 | 9 | import com.kobylynskyi.graphql.codegen.utils.Utils; |
8 | 10 |
|
9 | 11 | import java.util.Collection; |
@@ -41,17 +43,17 @@ private RequestResponseDefinitionToDataModelMapper() { |
41 | 43 | * Map type definition to a Freemarker data model of Response Projection. |
42 | 44 | * |
43 | 45 | * @param mappingContext Global mapping context |
44 | | - * @param typeDefinition GraphQL type definition |
| 46 | + * @param definition GraphQL definition (type or union) |
45 | 47 | * @return Freemarker data model of the GraphQL Response Projection |
46 | 48 | */ |
47 | 49 | public static Map<String, Object> mapResponseProjection(MappingContext mappingContext, |
48 | | - ExtendedObjectTypeDefinition typeDefinition) { |
| 50 | + ExtendedDefinition<?, ?> definition) { |
49 | 51 | Map<String, Object> dataModel = new HashMap<>(); |
50 | 52 | // ResponseProjection classes are sharing the package with the model classes, so no imports are needed |
51 | 53 | dataModel.put(PACKAGE, MapperUtils.getModelPackageName(mappingContext)); |
52 | | - dataModel.put(CLASS_NAME, Utils.capitalize(typeDefinition.getName()) + mappingContext.getResponseProjectionSuffix()); |
53 | | - dataModel.put(JAVA_DOC, Collections.singletonList("Response projection for " + typeDefinition.getName())); |
54 | | - dataModel.put(FIELDS, getProjectionFields(mappingContext, typeDefinition)); |
| 54 | + dataModel.put(CLASS_NAME, Utils.capitalize(definition.getName()) + mappingContext.getResponseProjectionSuffix()); |
| 55 | + dataModel.put(JAVA_DOC, Collections.singletonList("Response projection for " + definition.getName())); |
| 56 | + dataModel.put(FIELDS, getProjectionFields(mappingContext, definition)); |
55 | 57 | dataModel.put(BUILDER, mappingContext.getGenerateBuilder()); |
56 | 58 | dataModel.put(EQUALS_AND_HASH_CODE, mappingContext.getGenerateEqualsAndHashCode()); |
57 | 59 | dataModel.put(GENERATED_INFO, mappingContext.getGeneratedInformation()); |
@@ -167,23 +169,39 @@ private static String getClassName(ExtendedFieldDefinition operationDef, |
167 | 169 | * Get merged attributes from the type and attributes from the interface. |
168 | 170 | * |
169 | 171 | * @param mappingContext Global mapping context |
170 | | - * @param typeDefinition GraphQL type definition |
| 172 | + * @param definition GraphQL definition (type or union) |
171 | 173 | * @return Freemarker data model of the GraphQL type |
172 | 174 | */ |
173 | 175 | private static Collection<ProjectionParameterDefinition> getProjectionFields(MappingContext mappingContext, |
174 | | - ExtendedObjectTypeDefinition typeDefinition) { |
| 176 | + ExtendedDefinition<?, ?> definition) { |
175 | 177 | // using the map to exclude duplicate fields from the type and interfaces |
176 | 178 | Map<String, ProjectionParameterDefinition> allParameters = new LinkedHashMap<>(); |
177 | 179 |
|
178 | | - // includes parameters from the base definition and extensions |
179 | | - FieldDefinitionToParameterMapper.mapProjectionFields(mappingContext, typeDefinition.getFieldDefinitions(), typeDefinition) |
180 | | - .forEach(p -> allParameters.put(p.getName(), p)); |
181 | | - // includes parameters from the interface |
182 | | - MapperUtils.getInterfacesOfType(typeDefinition, mappingContext.getDocument()).stream() |
183 | | - .map(i -> FieldDefinitionToParameterMapper.mapProjectionFields(mappingContext, i.getFieldDefinitions(), i)) |
184 | | - .flatMap(Collection::stream) |
185 | | - .filter(paramDef -> !allParameters.containsKey(paramDef.getName())) |
186 | | - .forEach(paramDef -> allParameters.put(paramDef.getName(), paramDef)); |
| 180 | + if (definition instanceof ExtendedObjectTypeDefinition) { |
| 181 | + ExtendedObjectTypeDefinition typeDefinition = (ExtendedObjectTypeDefinition) definition; |
| 182 | + // includes parameters from the base definition and extensions |
| 183 | + FieldDefinitionToParameterMapper.mapProjectionFields(mappingContext, typeDefinition.getFieldDefinitions(), typeDefinition) |
| 184 | + .forEach(p -> allParameters.put(p.getName(), p)); |
| 185 | + // includes parameters from the interface |
| 186 | + MapperUtils.getInterfacesOfType(typeDefinition, mappingContext.getDocument()).stream() |
| 187 | + .map(i -> FieldDefinitionToParameterMapper.mapProjectionFields(mappingContext, i.getFieldDefinitions(), i)) |
| 188 | + .flatMap(Collection::stream) |
| 189 | + .filter(paramDef -> !allParameters.containsKey(paramDef.getName())) |
| 190 | + .forEach(paramDef -> allParameters.put(paramDef.getName(), paramDef)); |
| 191 | + } else if (definition instanceof ExtendedUnionTypeDefinition) { |
| 192 | + ExtendedUnionTypeDefinition unionDefinition = (ExtendedUnionTypeDefinition) definition; |
| 193 | + for (String memberTypeName : unionDefinition.getMemberTypeNames()) { |
| 194 | + ProjectionParameterDefinition parameter = new ProjectionParameterDefinition(); |
| 195 | + parameter.setName("...on " + memberTypeName); |
| 196 | + parameter.setMethodName("on" + memberTypeName); |
| 197 | + parameter.setType(memberTypeName + mappingContext.getResponseProjectionSuffix()); |
| 198 | + allParameters.put(parameter.getName(), parameter); |
| 199 | + } |
| 200 | + ProjectionParameterDefinition typeNameProjParamDef = new ProjectionParameterDefinition(); |
| 201 | + typeNameProjParamDef.setName("__typename"); |
| 202 | + typeNameProjParamDef.setMethodName("typename"); |
| 203 | + allParameters.put(typeNameProjParamDef.getName(), typeNameProjParamDef); |
| 204 | + } |
187 | 205 | return allParameters.values(); |
188 | 206 | } |
189 | 207 |
|
|
0 commit comments