@@ -59,29 +59,31 @@ public class QueryTraversal {
5959 private final ChildrenOfSelectionProvider childrenOfSelectionProvider ;
6060 private final GraphQLObjectType rootParentType ;
6161
62- public QueryTraversal (GraphQLSchema schema ,
63- Document document ,
64- String operation ,
65- Map <String , Object > variables ) {
62+ private QueryTraversal (GraphQLSchema schema ,
63+ Document document ,
64+ String operation ,
65+ Map <String , Object > variables ) {
66+ assertNotNull (document , "document can't be null" );
6667 NodeUtil .GetOperationResult getOperationResult = NodeUtil .getOperation (document , operation );
67- this .schema = schema ;
68- this .variables = variables ;
68+ this .schema = assertNotNull ( schema , "schema can't be null" ) ;
69+ this .variables = assertNotNull ( variables , "variables can't be null" ) ;
6970 this .fragmentsByName = getOperationResult .fragmentsByName ;
7071 this .roots = getOperationResult .operationDefinition .getSelectionSet ().getChildren ();
7172 this .rootParentType = getRootTypeFromOperation (getOperationResult .operationDefinition );
7273 this .childrenOfSelectionProvider = new ChildrenOfSelectionProvider (fragmentsByName );
7374 }
7475
75- public QueryTraversal (GraphQLSchema schema ,
76- Node root ,
77- GraphQLObjectType rootParentType ,
78- Map <String , FragmentDefinition > fragmentsByName ,
79- Map <String , Object > variables ) {
80- this .schema = schema ;
81- this .variables = variables ;
76+ private QueryTraversal (GraphQLSchema schema ,
77+ Node root ,
78+ GraphQLObjectType rootParentType ,
79+ Map <String , FragmentDefinition > fragmentsByName ,
80+ Map <String , Object > variables ) {
81+ this .schema = assertNotNull (schema , "schema can't be null" );
82+ this .variables = assertNotNull (variables , "variables can't be null" );
83+ assertNotNull (root , "root can't be null" );
8284 this .roots = Collections .singleton (root );
83- this .rootParentType = rootParentType ;
84- this .fragmentsByName = fragmentsByName ;
85+ this .rootParentType = assertNotNull ( rootParentType , "rootParentType can't be null" ) ;
86+ this .fragmentsByName = assertNotNull ( fragmentsByName , "fragmentsByName can't be null" ) ;
8587 this .childrenOfSelectionProvider = new ChildrenOfSelectionProvider (fragmentsByName );
8688 }
8789
@@ -277,4 +279,126 @@ public TraversalControl visitField(Field field, TraverserContext<Node> context)
277279 }
278280
279281 }
282+
283+ public static Builder newQueryTraversal () {
284+ return new Builder ();
285+ }
286+
287+ @ PublicApi
288+ public static class Builder {
289+ private GraphQLSchema schema ;
290+ private Document document ;
291+ private String operation ;
292+ private Map <String , Object > variables ;
293+
294+ private Node root ;
295+ private GraphQLObjectType rootParentType ;
296+ private Map <String , FragmentDefinition > fragmentsByName ;
297+
298+
299+ /**
300+ * The schema used to identify the types of the query.
301+ *
302+ * @param schema
303+ *
304+ * @return
305+ */
306+ public Builder schema (GraphQLSchema schema ) {
307+ this .schema = schema ;
308+ return this ;
309+ }
310+
311+ /**
312+ * specify the operation if a document is traversed and there
313+ * are more than one operation.
314+ *
315+ * @param operationName
316+ *
317+ * @return
318+ */
319+ public Builder operationName (String operationName ) {
320+ this .operation = operationName ;
321+ return this ;
322+ }
323+
324+ /**
325+ * document to be used to traverse the whole query.
326+ * If set a {@link Builder#operationName(String)} might be required.
327+ *
328+ * @param document
329+ *
330+ * @return
331+ */
332+ public Builder document (Document document ) {
333+ this .document = document ;
334+ return this ;
335+ }
336+
337+ /**
338+ * Variables used in the query.
339+ *
340+ * @param variables
341+ *
342+ * @return
343+ */
344+ public Builder variables (Map <String , Object > variables ) {
345+ this .variables = variables ;
346+ return this ;
347+ }
348+
349+ /**
350+ * Specify the root node for the traversal. Needs to be provided if there is
351+ * no {@link Builder#document(Document)}.
352+ *
353+ * @param root
354+ *
355+ * @return
356+ */
357+ public Builder root (Node root ) {
358+ this .root = root ;
359+ return this ;
360+ }
361+
362+ /**
363+ * The type of the parent of the root node. (See {@link Builder#root(Node)}
364+ *
365+ * @param rootParentType
366+ *
367+ * @return
368+ */
369+ public Builder rootParentType (GraphQLObjectType rootParentType ) {
370+ this .rootParentType = rootParentType ;
371+ return this ;
372+ }
373+
374+ /**
375+ * Fragment by name map. Needs to be provided together with a {@link Builder#root(Node)} and {@link Builder#rootParentType(GraphQLObjectType)}
376+ *
377+ * @param fragmentsByName
378+ *
379+ * @return
380+ */
381+ public Builder fragmentsByName (Map <String , FragmentDefinition > fragmentsByName ) {
382+ this .fragmentsByName = fragmentsByName ;
383+ return this ;
384+ }
385+
386+ public QueryTraversal build () {
387+ checkState ();
388+ if (document != null ) {
389+ return new QueryTraversal (schema , document , operation , variables );
390+ } else {
391+ return new QueryTraversal (schema , root , rootParentType , fragmentsByName , variables );
392+ }
393+ }
394+
395+ private void checkState () {
396+ if (document != null || operation != null ) {
397+ if (root != null || rootParentType != null || fragmentsByName != null ) {
398+ throw new IllegalStateException ("ambiguous builder" );
399+ }
400+ }
401+ }
402+
403+ }
280404}
0 commit comments