13
13
* See the License for the specific language governing permissions and
14
14
* limitations under the License.
15
15
*/
16
+
16
17
package org .springframework .graphql .client ;
17
18
19
+ import java .util .function .Consumer ;
20
+
18
21
import com .jayway .jsonpath .Configuration ;
19
22
import com .jayway .jsonpath .spi .json .JacksonJsonProvider ;
20
23
import com .jayway .jsonpath .spi .mapper .JacksonMappingProvider ;
21
24
25
+ import org .springframework .graphql .support .CachingDocumentSource ;
22
26
import org .springframework .graphql .support .DocumentSource ;
23
27
import org .springframework .graphql .support .ResourceDocumentSource ;
24
28
import org .springframework .lang .Nullable ;
25
29
import org .springframework .util .Assert ;
26
30
import org .springframework .util .ClassUtils ;
27
31
32
+
28
33
/**
29
- * Default implementation of {@link GraphQlClient.Builder}.
34
+ * Default {@link GraphQlClient.Builder} implementation that builds a
35
+ * {@link GraphQlClient} for use with any transport.
36
+ *
37
+ * <p>Intended for use as a base class for builders that do assist with building
38
+ * the underlying transport. Such extension
30
39
*
31
40
* @author Rossen Stoyanchev
32
41
* @since 1.0.0
33
42
*/
34
- class DefaultGraphQlClientBuilder implements GraphQlClient .Builder {
43
+ public class DefaultGraphQlClientBuilder < B extends DefaultGraphQlClientBuilder < B >> implements GraphQlClient .Builder < B > {
35
44
36
45
private static final boolean jackson2Present ;
37
46
@@ -42,53 +51,70 @@ class DefaultGraphQlClientBuilder implements GraphQlClient.Builder {
42
51
}
43
52
44
53
45
- private final GraphQlTransport transport ;
46
-
47
54
@ Nullable
48
- private Configuration jsonPathConfig ;
55
+ private GraphQlTransport transport ;
49
56
50
57
@ Nullable
51
58
private DocumentSource documentSource ;
52
59
53
-
60
+ /**
61
+ * Constructor with a given transport instance.
62
+ */
54
63
DefaultGraphQlClientBuilder (GraphQlTransport transport ) {
55
64
Assert .notNull (transport , "GraphQlTransport is required" );
56
65
this .transport = transport ;
57
66
}
58
67
68
+ /**
69
+ * Constructor for subclass builders that will call
70
+ * {@link #transport(GraphQlTransport)} to set the transport instance
71
+ * before {@link #build()}.
72
+ */
73
+ DefaultGraphQlClientBuilder () {
74
+ }
59
75
60
- @ Override
61
- public GraphQlClient .Builder jsonPathConfig (@ Nullable Configuration config ) {
62
- this .jsonPathConfig = config ;
63
- return this ;
76
+ protected void transport (GraphQlTransport transport ) {
77
+ this .transport = transport ;
64
78
}
65
79
66
80
@ Override
67
- public GraphQlClient . Builder documentSource (@ Nullable DocumentSource contentLoader ) {
81
+ public B documentSource (@ Nullable DocumentSource contentLoader ) {
68
82
this .documentSource = contentLoader ;
69
- return this ;
83
+ return self ();
84
+ }
85
+
86
+ @ SuppressWarnings ("unchecked" )
87
+ private <T extends B > T self () {
88
+ return (T ) this ;
70
89
}
71
90
72
91
@ Override
73
92
public GraphQlClient build () {
74
- return new DefaultGraphQlClient (this .transport , initJsonPathConfig (), initRequestNameResolver ());
93
+ Assert .notNull (this .transport , "No GraphQlTransport. Has a subclass not initialized it?" );
94
+ return new DefaultGraphQlClient (this .transport , initJsonPathConfig (), initDocumentSource (), getBuilderInitializer ());
75
95
}
76
96
77
97
private Configuration initJsonPathConfig () {
78
- if (this .jsonPathConfig != null ) {
79
- return this .jsonPathConfig ;
80
- }
81
- else if (jackson2Present ) {
82
- return Jackson2Configuration .create ();
83
- }
84
- else {
85
- return Configuration .builder ().build ();
86
- }
98
+ // Allow configuring JSONPath with codecs from transport subclasses
99
+ return (jackson2Present ? Jackson2Configuration .create () : Configuration .builder ().build ());
87
100
}
88
101
89
- private DocumentSource initRequestNameResolver () {
102
+ private DocumentSource initDocumentSource () {
90
103
return (this .documentSource == null ?
91
- new ResourceDocumentSource () : this .documentSource );
104
+ new CachingDocumentSource (new ResourceDocumentSource ()) : this .documentSource );
105
+ }
106
+
107
+ /**
108
+ * Exposes a {@code Consumer} to subclasses to initialize new builder instances
109
+ * from the configuration of "this" builder.
110
+ */
111
+ protected Consumer <GraphQlClient .Builder <?>> getBuilderInitializer () {
112
+ return builder -> {
113
+ if (this .documentSource != null ) {
114
+ builder .documentSource (documentSource );
115
+ }
116
+ };
117
+
92
118
}
93
119
94
120
0 commit comments