Skip to content

Commit e120188

Browse files
authored
Merge pull request #159 from osher-sade/support-arrays
Added support for arrays
2 parents 9f8fb61 + 61d892b commit e120188

File tree

4 files changed

+207
-5
lines changed

4 files changed

+207
-5
lines changed
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
/**
2+
* Copyright 2016 Yurii Rashkovskii
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
*/
15+
package graphql.annotations.processor.typeFunctions;
16+
17+
import graphql.annotations.processor.ProcessingElementsContainer;
18+
import graphql.schema.GraphQLList;
19+
import graphql.schema.GraphQLType;
20+
21+
import java.lang.reflect.AnnotatedArrayType;
22+
import java.lang.reflect.AnnotatedType;
23+
import java.lang.reflect.ParameterizedType;
24+
25+
public class ArrayFunction implements TypeFunction {
26+
27+
private DefaultTypeFunction defaultTypeFunction;
28+
29+
public ArrayFunction(DefaultTypeFunction defaultTypeFunction) {
30+
this.defaultTypeFunction = defaultTypeFunction;
31+
}
32+
33+
@Override
34+
public boolean canBuildType(Class<?> aClass, AnnotatedType annotatedType) {
35+
return aClass.isArray();
36+
}
37+
38+
@Override
39+
public GraphQLType buildType(boolean input, Class<?> aClass, AnnotatedType annotatedType, ProcessingElementsContainer container) {
40+
if (!(annotatedType instanceof AnnotatedArrayType)) {
41+
throw new IllegalArgumentException("Array type parameter should be specified");
42+
}
43+
AnnotatedArrayType parameterizedType = (AnnotatedArrayType) annotatedType;
44+
AnnotatedType arg = parameterizedType.getAnnotatedGenericComponentType();
45+
Class<?> klass;
46+
if (arg.getType() instanceof ParameterizedType) {
47+
klass = (Class<?>) ((ParameterizedType) (arg.getType())).getRawType();
48+
} else {
49+
klass = (Class<?>) arg.getType();
50+
}
51+
return new GraphQLList(defaultTypeFunction.buildType(input, klass, arg, container));
52+
}
53+
}

src/main/java/graphql/annotations/processor/typeFunctions/DefaultTypeFunction.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ public void activate() {
6262
typeFunctions.add(new BigDecimalFunction());
6363
typeFunctions.add(new CharFunction());
6464
typeFunctions.add(new IterableFunction(DefaultTypeFunction.this));
65+
typeFunctions.add(new ArrayFunction(DefaultTypeFunction.this));
6566
typeFunctions.add(new StreamFunction(DefaultTypeFunction.this));
6667
typeFunctions.add(new OptionalFunction(DefaultTypeFunction.this));
6768
typeFunctions.add(new ObjectFunction(graphQLInputProcessor, graphQLOutputProcessor));

src/main/java/graphql/annotations/processor/typeFunctions/IterableFunction.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,12 @@
2525
/**
2626
* Support for the Iterable things like Lists / Sets / Collections and so on..
2727
*/
28-
class IterableFunction implements TypeFunction {
28+
class IterableFunction implements TypeFunction {
2929

3030
private DefaultTypeFunction defaultTypeFunction;
3131

32-
public IterableFunction(DefaultTypeFunction defaultTypeFunction){
33-
this.defaultTypeFunction=defaultTypeFunction;
32+
public IterableFunction(DefaultTypeFunction defaultTypeFunction) {
33+
this.defaultTypeFunction = defaultTypeFunction;
3434
}
3535

3636
@Override
@@ -51,6 +51,6 @@ public GraphQLType buildType(boolean input, Class<?> aClass, AnnotatedType annot
5151
} else {
5252
klass = (Class<?>) arg.getType();
5353
}
54-
return new GraphQLList(defaultTypeFunction.buildType(input, klass, arg,container));
54+
return new GraphQLList(defaultTypeFunction.buildType(input, klass, arg, container));
5555
}
56-
}
56+
}
Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
/**
2+
* Copyright 2016 Yurii Rashkovskii
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
*/
15+
package graphql.annotations;
16+
17+
import graphql.ExecutionResult;
18+
import graphql.GraphQL;
19+
import graphql.annotations.annotationTypes.GraphQLDataFetcher;
20+
import graphql.annotations.annotationTypes.GraphQLField;
21+
import graphql.annotations.processor.GraphQLAnnotations;
22+
import graphql.schema.DataFetcher;
23+
import graphql.schema.DataFetchingEnvironment;
24+
import graphql.schema.GraphQLObjectType;
25+
import graphql.schema.GraphQLSchema;
26+
import org.testng.annotations.BeforeMethod;
27+
import org.testng.annotations.Test;
28+
29+
import java.util.ArrayList;
30+
import java.util.Collections;
31+
import java.util.LinkedHashMap;
32+
import java.util.List;
33+
34+
import static graphql.schema.GraphQLSchema.newSchema;
35+
import static org.testng.Assert.assertEquals;
36+
import static org.testng.Assert.assertTrue;
37+
38+
public class GraphQLIterableAndArrayTest {
39+
@BeforeMethod
40+
public void init() {
41+
GraphQLAnnotations.getInstance().getTypeRegistry().clear();
42+
}
43+
44+
static class TestMappedObject {
45+
@GraphQLField
46+
public String name;
47+
48+
@GraphQLField
49+
public String foo;
50+
}
51+
52+
static class TestObjectDB {
53+
private String foo;
54+
55+
private String name;
56+
57+
TestObjectDB(String name, String foo) {
58+
this.name = name;
59+
this.foo = foo;
60+
}
61+
}
62+
63+
public static class IterableAndArrayTestQuery {
64+
@GraphQLField
65+
@GraphQLDataFetcher(ArrayFetcher.class)
66+
public TestMappedObject[] array;
67+
68+
@GraphQLField
69+
@GraphQLDataFetcher(ListFetcher.class)
70+
public List<TestMappedObject> list;
71+
72+
@GraphQLField
73+
@GraphQLDataFetcher(ArrayWithinArrayFetcher.class)
74+
public TestMappedObject[][] arrayWithinArray;
75+
}
76+
77+
public static class ArrayFetcher implements DataFetcher<TestObjectDB[]> {
78+
79+
@Override
80+
public TestObjectDB[] get(DataFetchingEnvironment environment) {
81+
return new TestObjectDB[]{new TestObjectDB("hello", "world")};
82+
}
83+
}
84+
85+
public static class ListFetcher implements DataFetcher<List<TestObjectDB>> {
86+
87+
@Override
88+
public List<TestObjectDB> get(DataFetchingEnvironment environment) {
89+
return Collections.singletonList(new TestObjectDB("test name", "test foo"));
90+
}
91+
}
92+
93+
public static class ArrayWithinArrayFetcher implements DataFetcher<TestObjectDB[][]> {
94+
95+
@Override
96+
public TestObjectDB[][] get(DataFetchingEnvironment environment) {
97+
return new TestObjectDB[][]{
98+
{new TestObjectDB("hello", "world")},
99+
{new TestObjectDB("a", "b"), new TestObjectDB("c", "d")}
100+
};
101+
}
102+
}
103+
104+
@Test
105+
public void queryWithArray() {
106+
GraphQLObjectType object = GraphQLAnnotations.object(IterableAndArrayTestQuery.class);
107+
GraphQLSchema schema = newSchema().query(object).build();
108+
109+
ExecutionResult result = GraphQL.newGraphQL(schema).build().execute("{array {name foo}}");
110+
assertTrue(result.getErrors().isEmpty());
111+
assertEquals(((LinkedHashMap) getQueryResultAtIndex(result, "array", 0)).get("name"), "hello");
112+
assertEquals(((LinkedHashMap) getQueryResultAtIndex(result, "array", 0)).get("foo"), "world");
113+
}
114+
115+
@Test
116+
public void queryWithList() {
117+
GraphQLObjectType object = GraphQLAnnotations.object(IterableAndArrayTestQuery.class);
118+
GraphQLSchema schema = newSchema().query(object).build();
119+
120+
ExecutionResult result = GraphQL.newGraphQL(schema).build().execute("{list {name foo}}");
121+
assertTrue(result.getErrors().isEmpty());
122+
assertEquals(((LinkedHashMap) getQueryResultAtIndex(result, "list", 0)).get("name"), "test name");
123+
assertEquals(((LinkedHashMap) getQueryResultAtIndex(result, "list", 0)).get("foo"), "test foo");
124+
}
125+
126+
@Test
127+
public void queryWithArrayWithinAnArray() {
128+
GraphQLObjectType object = GraphQLAnnotations.object(IterableAndArrayTestQuery.class);
129+
GraphQLSchema schema = newSchema().query(object).build();
130+
131+
ExecutionResult result = GraphQL.newGraphQL(schema).build().execute("{arrayWithinArray {name foo}}");
132+
assertTrue(result.getErrors().isEmpty());
133+
assertEquals(((LinkedHashMap) getQueryResultAtCell(result, "arrayWithinArray", 0, 0)).get("name"), "hello");
134+
assertEquals(((LinkedHashMap) getQueryResultAtCell(result, "arrayWithinArray", 0, 0)).get("foo"), "world");
135+
assertEquals(((LinkedHashMap) getQueryResultAtCell(result, "arrayWithinArray", 1, 0)).get("name"), "a");
136+
assertEquals(((LinkedHashMap) getQueryResultAtCell(result, "arrayWithinArray", 1, 0)).get("foo"), "b");
137+
assertEquals(((LinkedHashMap) getQueryResultAtCell(result, "arrayWithinArray", 1, 1)).get("name"), "c");
138+
assertEquals(((LinkedHashMap) getQueryResultAtCell(result, "arrayWithinArray", 1, 1)).get("foo"), "d");
139+
}
140+
141+
private Object getQueryResultAtIndex(ExecutionResult result, String queryName, int index) {
142+
return ((ArrayList) (((LinkedHashMap) result.getData()).get(queryName))).get(index);
143+
}
144+
145+
private Object getQueryResultAtCell(ExecutionResult result, String queryName, int rowIndex, int columnIndex) {
146+
return (((ArrayList) (getQueryResultAtIndex(result, queryName, rowIndex))).get(columnIndex));
147+
}
148+
}

0 commit comments

Comments
 (0)