Skip to content

Commit 10ca512

Browse files
author
Antoine Boyer
committed
Added support for GraphQL Union type. Version bump to 0.1.0
1 parent 7ef6031 commit 10ca512

File tree

7 files changed

+353
-14
lines changed

7 files changed

+353
-14
lines changed

build.gradle

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
description = "GraphQL schema to Code"
22

3-
version = '0.0.1'
3+
version = '0.1.0'
44
group = 'com.graphql_codegen'
55

66
buildscript {
@@ -34,6 +34,7 @@ dependencies {
3434
compile 'com.samskivert:jmustache:1.11'
3535
compile 'io.airlift:airline:0.7'
3636
compile 'com.mashape.unirest:unirest-java:1.4.7'
37+
compile 'com.graphql-java:graphql-java:2.0.0'
3738

3839
testCompile group: 'junit', name: 'junit', version: '4.11'
3940
testCompile 'org.spockframework:spock-core:1.0-groovy-2.4'

src/main/java/graphql_codegen/builder/java/JavaGenerator.java

+3-3
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,7 @@ public Code convertFromGraphQLTypeToCode(GraphQLTypeDescription type) {
3434
return convertGraphQLInterfaceTypeToCode(type);
3535
case ENUM:
3636
return convertFromGraphQLEnumTypeToCode(type);
37-
case UNION:
38-
System.out.println("Unable to handle " + type.getKind() + " with name " + type.getName());
39-
return null;
37+
case UNION: // is handled with generic types
4038
default:
4139
return null;
4240
}
@@ -206,6 +204,8 @@ public static JavaTypeReference getJavaTypeReference(GraphQLTypeDescription type
206204
return new JavaTypeReference("INVALID_TYPE");
207205
}
208206
return getJavaTypeReference(type.getOfType());
207+
case UNION:
208+
return new JavaTypeReference(Util.capitalizeFirstLetter(type.getName()), true);
209209
default:
210210
return new JavaTypeReference(Util.capitalizeFirstLetter(type.getName()));
211211
}

src/main/java/graphql_codegen/builder/java/JavaType.java

+28-9
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,9 @@
22

33
import graphql_codegen.Util;
44

5-
import java.util.HashMap;
6-
import java.util.List;
7-
import java.util.Map;
8-
import java.util.Set;
5+
import java.util.*;
6+
import java.util.stream.Collectors;
7+
import java.util.stream.Stream;
98

109
import static com.google.common.base.Preconditions.checkNotNull;
1110

@@ -19,18 +18,20 @@ public class JavaType extends JavaCode {
1918
private final String superClass;
2019
private final List<JavaField> members;
2120
private final List<JavaTypeReference> inheritedTypes;
21+
private final List<String> genericTypes; // contains the generic types in "class SomeClass<Type1,Type2>"
2222
private final boolean serializable;
2323
private final String description;
2424

2525
private JavaType(String superClass, Set<String> imports,
2626
List<JavaTypeReference> inheritedTypes, List<JavaField> members,
27-
String name, String packagePath, boolean serializable, String description) {
27+
String name, String packagePath, List<String> genericTypes, boolean serializable, String description) {
2828
this.superClass = superClass;
2929
this.imports = imports;
3030
this.inheritedTypes = inheritedTypes;
3131
this.members = members;
3232
this.name = name;
3333
this.packagePath = packagePath;
34+
this.genericTypes = genericTypes;
3435
this.serializable = serializable;
3536
this.description = description;
3637
}
@@ -72,27 +73,31 @@ public String getDescription() {
7273
return description;
7374
}
7475

76+
public List<String> getGenericTypes() {
77+
return genericTypes;
78+
}
79+
7580
public static Builder newJavaTypeBuilder() {
7681
return new Builder();
7782
}
7883

7984
public static class Builder {
8085
private String superClass;
8186
private List<JavaTypeReference> inheritedTypes;
82-
private List<JavaField> members;
87+
private List<JavaField> members = new ArrayList<>();
8388
private String name;
8489
private String packagePath;
8590
private boolean serializable;
8691
private String description;
8792
private Map<String, String> typeNameToPackageOverrideMap = new HashMap<>();
93+
private List<String> genericTypes;
8894

8995
public Builder withImportMapOverride(Map<String,String> typeNameToPackageOverrideMap) {
9096
checkNotNull(typeNameToPackageOverrideMap);
9197
this.typeNameToPackageOverrideMap = typeNameToPackageOverrideMap;
9298
return this;
9399
}
94100

95-
96101
public Builder addImportOverride(String typeName, String packagePath) {
97102
typeNameToPackageOverrideMap.put(typeName, packagePath);
98103
return this;
@@ -109,7 +114,7 @@ public Builder withInheritedTypes(List<JavaTypeReference> inheritedTypes) {
109114
}
110115

111116
public Builder withMembers(List<JavaField> members) {
112-
this.members = members;
117+
this.members.addAll(members);
113118
return this;
114119
}
115120

@@ -134,7 +139,21 @@ public Builder withDescription(String description) {
134139
}
135140

136141
public JavaType build() {
137-
return new JavaType(superClass, buildImports(members, inheritedTypes, typeNameToPackageOverrideMap), inheritedTypes, members, name, packagePath, serializable, description);
142+
143+
Stream<String> membersStream = members.stream()
144+
.filter(javaField -> javaField.getTypeReference() != null && javaField.getTypeReference().isGeneric())
145+
.map(javaField -> javaField.getTypeReference().getTypeName());
146+
147+
Stream<String> membersGenericStream = members.stream()
148+
.filter(javaField -> javaField.getTypeReference() != null && !javaField.getTypeReference().getGenericParameters().isEmpty())
149+
.flatMap(javaField -> javaField.getTypeReference().getGenericParameters().stream())
150+
.filter(JavaTypeReference::isGeneric)
151+
.map(JavaTypeReference::getTypeName);
152+
153+
genericTypes = Stream.concat(membersGenericStream, membersStream).collect(Collectors.toList());
154+
155+
return new JavaType(superClass, buildImports(members, inheritedTypes, typeNameToPackageOverrideMap), inheritedTypes, members, name, packagePath,
156+
genericTypes, serializable, description);
138157
}
139158
}
140159
}

src/main/java/graphql_codegen/builder/java/JavaTypeReference.java

+14
Original file line numberDiff line numberDiff line change
@@ -4,22 +4,32 @@
44
import java.util.List;
55
import java.util.stream.Collectors;
66

7+
import static com.google.common.base.Preconditions.checkNotNull;
8+
79
public class JavaTypeReference {
810

911
private String typeName;
1012
private List<JavaTypeReference> genericParameters;
1113
private String generatedType;
14+
private boolean generic; // whether it's a genericType e.g <T>
1215

1316
public JavaTypeReference(String typeName, List<JavaTypeReference> genericParameters) {
17+
checkNotNull(genericParameters);
1418
this.genericParameters = genericParameters;
1519
this.typeName = typeName;
1620
this.generatedType = code();
21+
this.generic = false;
1722
}
1823

1924
public JavaTypeReference(String typeName) {
2025
this(typeName, new ArrayList<>());
2126
}
2227

28+
public JavaTypeReference(String typeName, boolean generic) {
29+
this(typeName, new ArrayList<>());
30+
this.generic = generic;
31+
}
32+
2333
public String getGeneratedType() {
2434
return generatedType;
2535
}
@@ -32,6 +42,10 @@ public List<JavaTypeReference> getGenericParameters() {
3242
return genericParameters;
3343
}
3444

45+
public boolean isGeneric() {
46+
return generic;
47+
}
48+
3549
public String code() {
3650
switch (typeName) {
3751
case "List":

src/main/resources/java/type.mustache

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ package {{packagePath}};
88
* {{description}}
99
**/
1010
{{/description}}
11-
public class {{name}}{{#superClass}} extends {{{superClass}}}{{/superClass}}{{#inheritedTypes}} implements {{typeName}}{{^-last}}, {{/-last}}{{/inheritedTypes}} {
11+
public class {{name}}{{#genericTypes}}<{{this}}{{^-last}}, {{/-last}}>{{/genericTypes}}{{#superClass}} extends {{{superClass}}}{{/superClass}}{{#inheritedTypes}} implements {{typeName}}{{^-last}}, {{/-last}}{{/inheritedTypes}} {
1212
1313
{{#members}}
1414
{{>field}}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,184 @@
1+
package graphql_codegen
2+
3+
import graphql.Scalars
4+
import graphql.schema.*
5+
6+
import static graphql.schema.GraphQLFieldDefinition.newFieldDefinition
7+
import static graphql.schema.GraphQLInterfaceType.newInterface
8+
import static graphql.schema.GraphQLObjectType.newObject
9+
import static graphql.schema.GraphQLUnionType.newUnionType
10+
11+
class GarfieldSchema {
12+
13+
public interface Named {
14+
String getName();
15+
}
16+
17+
public static class Dog implements Named {
18+
private final String name;
19+
20+
21+
private final boolean barks;
22+
23+
public Dog(String name, boolean barks) {
24+
this.name = name;
25+
this.barks = barks;
26+
}
27+
28+
public boolean isBarks() {
29+
return barks;
30+
}
31+
32+
@Override
33+
public String getName() {
34+
return name;
35+
}
36+
}
37+
38+
public static class Cat implements Named {
39+
private final String name;
40+
41+
private final boolean meows;
42+
43+
public Cat(String name, boolean meows) {
44+
this.name = name;
45+
this.meows = meows;
46+
}
47+
48+
public boolean isMeows() {
49+
return meows;
50+
}
51+
52+
@Override
53+
public String getName() {
54+
return name;
55+
}
56+
}
57+
58+
public static class Person implements Named {
59+
private final String name;
60+
private List<Dog> dogs;
61+
private List<Cat> cats;
62+
private List<Named> friends;
63+
64+
public Person(String name) {
65+
this(name, Collections.<Cat>emptyList(), Collections.<Dog>emptyList(), Collections.<Named>emptyList());
66+
}
67+
68+
public Person(String name, List<Cat> cats, List<Dog> dogs, List<Named> friends) {
69+
this.name = name;
70+
this.dogs = dogs;
71+
this.cats = cats;
72+
this.friends = friends;
73+
}
74+
75+
public List<Object> getPets() {
76+
List<Object> pets = new ArrayList<Object>();
77+
pets.addAll(cats);
78+
pets.addAll(dogs);
79+
return pets;
80+
}
81+
82+
@Override
83+
public String getName() {
84+
return name;
85+
}
86+
87+
public List<Named> getFriends() {
88+
return friends;
89+
}
90+
}
91+
92+
public static Cat garfield = new Cat("Garfield", false);
93+
public static Dog odie = new Dog("Odie", true);
94+
public static Person liz = new Person("Liz");
95+
public static Person john = new Person("John", Arrays.asList(garfield), Arrays.asList(odie), Arrays.asList(liz, odie));
96+
97+
public static GraphQLInterfaceType NamedType = newInterface()
98+
.name("Named")
99+
.field(newFieldDefinition()
100+
.name("name")
101+
.type(Scalars.GraphQLString)
102+
.build())
103+
.typeResolver(new TypeResolver() {
104+
@Override
105+
public GraphQLObjectType getType(Object object) {
106+
if (object instanceof Dog) {
107+
return DogType;
108+
}
109+
if (object instanceof Person) {
110+
return PersonType;
111+
}
112+
if (object instanceof Cat) {
113+
return CatType;
114+
}
115+
return null;
116+
}
117+
})
118+
.build();
119+
120+
public static GraphQLObjectType DogType = newObject()
121+
.name("Dog")
122+
.field(newFieldDefinition()
123+
.name("name")
124+
.type(Scalars.GraphQLString)
125+
.build())
126+
.field(newFieldDefinition()
127+
.name("barks")
128+
.type(Scalars.GraphQLBoolean)
129+
.build())
130+
.withInterface(NamedType)
131+
.build();
132+
133+
public static GraphQLObjectType CatType = newObject()
134+
.name("Cat")
135+
.field(newFieldDefinition()
136+
.name("name")
137+
.type(Scalars.GraphQLString)
138+
.build())
139+
.field(newFieldDefinition()
140+
.name("meows")
141+
.type(Scalars.GraphQLBoolean)
142+
.build())
143+
.withInterface(NamedType)
144+
.build();
145+
146+
public static GraphQLUnionType PetType = newUnionType()
147+
.name("Pet")
148+
.possibleType(CatType)
149+
.possibleType(DogType)
150+
.typeResolver(new TypeResolver() {
151+
@Override
152+
public GraphQLObjectType getType(Object object) {
153+
if (object instanceof Cat) {
154+
return CatType;
155+
}
156+
if (object instanceof Dog) {
157+
return DogType;
158+
}
159+
return null;
160+
}
161+
})
162+
.build();
163+
164+
public static GraphQLObjectType PersonType = newObject()
165+
.name("Person")
166+
.field(newFieldDefinition()
167+
.name("name")
168+
.type(Scalars.GraphQLString)
169+
.build())
170+
.field(newFieldDefinition()
171+
.name("pets")
172+
.type(new GraphQLList(PetType))
173+
.build())
174+
.field(newFieldDefinition()
175+
.name("friends")
176+
.type(new GraphQLList(NamedType))
177+
.build())
178+
.withInterface(NamedType)
179+
.build();
180+
181+
public static GraphQLSchema GarfieldSchema = GraphQLSchema.newSchema()
182+
.query(PersonType)
183+
.build();
184+
}

0 commit comments

Comments
 (0)