6
6
import java .util .Collections ;
7
7
import java .util .Date ;
8
8
import java .util .List ;
9
+ import java .util .function .Consumer ;
9
10
11
+ import org .springframework .core .convert .converter .Converter ;
12
+ import org .springframework .core .convert .converter .ConverterFactory ;
13
+ import org .springframework .core .convert .converter .GenericConverter ;
14
+ import org .springframework .data .convert .ConverterBuilder ;
10
15
import org .springframework .data .convert .CustomConversions ;
11
16
import org .springframework .data .r2dbc .dialect .R2dbcDialect ;
12
17
import org .springframework .data .r2dbc .mapping .R2dbcSimpleTypeHolder ;
18
+ import org .springframework .data .relational .core .dialect .Dialect ;
19
+ import org .springframework .lang .Contract ;
20
+ import org .springframework .util .Assert ;
13
21
14
22
/**
15
23
* Value object to capture custom conversion. {@link R2dbcCustomConversions} also act as factory for
@@ -70,11 +78,27 @@ public static R2dbcCustomConversions of(R2dbcDialect dialect, Object... converte
70
78
* @since 1.2
71
79
*/
72
80
public static R2dbcCustomConversions of (R2dbcDialect dialect , Collection <?> converters ) {
81
+ return create (dialect , configurer -> configurer .registerConverters (converters ));
82
+ }
83
+
84
+ /**
85
+ * Create a new {@link R2dbcCustomConversions} instance using the given {@link R2dbcDialect} and
86
+ * {@link R2dbcConverterConfigurer} callback to configure converters.
87
+ *
88
+ * @param dialect the {@link Dialect} to use, must not be {@literal null}.
89
+ * @param configurer the configurer callback to configure converters, must not be {@literal null}.
90
+ * @return a new {@link R2dbcCustomConversions} instance configured from the given dialect and configured converters.
91
+ * @since 4.0
92
+ */
93
+ public static R2dbcCustomConversions create (R2dbcDialect dialect , Consumer <R2dbcConverterConfigurer > configurer ) {
73
94
74
- List < Object > storeConverters = new ArrayList <>( dialect . getConverters () );
75
- storeConverters . addAll ( R2dbcCustomConversions . STORE_CONVERTERS );
95
+ Assert . notNull ( dialect , "Dialect must not be null" );
96
+ Assert . notNull ( configurer , "R2dbcConverterConfigurer Consumer must not be null" );
76
97
77
- return new R2dbcCustomConversions (StoreConversions .of (dialect .getSimpleTypeHolder (), storeConverters ), converters );
98
+ R2dbcConverterConfigurer converterConfigurer = R2dbcConverterConfigurer .from (dialect );
99
+ configurer .accept (converterConfigurer );
100
+
101
+ return new R2dbcCustomConversions (converterConfigurer .createConfiguration ());
78
102
}
79
103
80
104
static class R2dbcCustomConversionsConfiguration extends ConverterConfiguration {
@@ -92,4 +116,112 @@ public R2dbcCustomConversionsConfiguration(StoreConversions storeConversions, Li
92
116
});
93
117
}
94
118
}
119
+
120
+ /**
121
+ * {@link R2dbcConverterConfigurer} encapsulates creation of {@link R2dbcCustomConversionsConfiguration} with R2DBC
122
+ * specifics.
123
+ *
124
+ * @author Mark Paluch
125
+ * @since 4.0
126
+ */
127
+ public static class R2dbcConverterConfigurer {
128
+
129
+ private final StoreConversions storeConversions ;
130
+ private final List <Object > customConverters = new ArrayList <>();
131
+
132
+ private R2dbcConverterConfigurer (StoreConversions storeConversions ) {
133
+ this .storeConversions = storeConversions ;
134
+ }
135
+
136
+ /**
137
+ * Create a {@link R2dbcConverterConfigurer} using the provided {@code dialect} and our own codecs for JSR-310
138
+ * types.
139
+ *
140
+ * @param dialect must not be {@literal null}.
141
+ * @return
142
+ */
143
+ static R2dbcConverterConfigurer from (R2dbcDialect dialect ) {
144
+
145
+ List <Object > converters = new ArrayList <>();
146
+ converters .addAll (dialect .getConverters ());
147
+ converters .addAll (R2dbcCustomConversions .STORE_CONVERTERS );
148
+
149
+ StoreConversions storeConversions = StoreConversions .of (dialect .getSimpleTypeHolder (), converters );
150
+
151
+ return new R2dbcConverterConfigurer (storeConversions );
152
+ }
153
+
154
+ /**
155
+ * Create a {@link R2dbcConverterConfigurer} using the provided {@code storeConversions}.
156
+ *
157
+ * @param storeConversions must not be {@literal null}.
158
+ * @return
159
+ */
160
+ static R2dbcConverterConfigurer from (StoreConversions storeConversions ) {
161
+ return new R2dbcConverterConfigurer (storeConversions );
162
+ }
163
+
164
+ /**
165
+ * Add a custom {@link Converter} implementation.
166
+ *
167
+ * @param converter must not be {@literal null}.
168
+ * @return this.
169
+ */
170
+ @ Contract ("_ -> this" )
171
+ public R2dbcConverterConfigurer registerConverter (Converter <?, ?> converter ) {
172
+
173
+ Assert .notNull (converter , "Converter must not be null" );
174
+ customConverters .add (converter );
175
+ return this ;
176
+ }
177
+
178
+ /**
179
+ * Add {@link Converter converters}, {@link ConverterFactory factories}, {@link ConverterBuilder.ConverterAware
180
+ * converter-aware objects}, and {@link GenericConverter generic converters}.
181
+ *
182
+ * @param converters must not be {@literal null} nor contain {@literal null} values.
183
+ * @return this.
184
+ */
185
+ @ Contract ("_ -> this" )
186
+ public R2dbcConverterConfigurer registerConverters (Object ... converters ) {
187
+ return registerConverters (Arrays .asList (converters ));
188
+ }
189
+
190
+ /**
191
+ * Add {@link Converter converters}, {@link ConverterFactory factories}, {@link ConverterBuilder.ConverterAware
192
+ * converter-aware objects}, and {@link GenericConverter generic converters}.
193
+ *
194
+ * @param converters must not be {@literal null} nor contain {@literal null} values.
195
+ * @return this.
196
+ */
197
+ @ Contract ("_ -> this" )
198
+ public R2dbcConverterConfigurer registerConverters (Collection <?> converters ) {
199
+
200
+ Assert .notNull (converters , "Converters must not be null" );
201
+ Assert .noNullElements (converters , "Converters must not be null nor contain null values" );
202
+
203
+ customConverters .addAll (converters );
204
+ return this ;
205
+ }
206
+
207
+ /**
208
+ * Add a custom {@link ConverterFactory} implementation.
209
+ *
210
+ * @param converterFactory must not be {@literal null}.
211
+ * @return this.
212
+ */
213
+ @ Contract ("_ -> this" )
214
+ public R2dbcConverterConfigurer registerConverterFactory (ConverterFactory <?, ?> converterFactory ) {
215
+
216
+ Assert .notNull (converterFactory , "ConverterFactory must not be null" );
217
+ customConverters .add (converterFactory );
218
+ return this ;
219
+ }
220
+
221
+ ConverterConfiguration createConfiguration () {
222
+ return new R2dbcCustomConversionsConfiguration (storeConversions , this .customConverters );
223
+ }
224
+
225
+ }
226
+
95
227
}
0 commit comments