15
15
*/
16
16
package org .springframework .data .repository .aot .generate ;
17
17
18
+ import java .util .function .Consumer ;
19
+ import java .util .function .Function ;
20
+
21
+ import org .jspecify .annotations .Nullable ;
22
+
23
+ import org .springframework .beans .factory .config .BeanReference ;
18
24
import org .springframework .core .ResolvableType ;
19
25
import org .springframework .javapoet .CodeBlock ;
26
+ import org .springframework .util .Assert ;
20
27
21
28
/**
22
29
* Builder for AOT Repository Constructors.
@@ -65,7 +72,31 @@ default void addParameter(String parameterName, Class<?> type, boolean bindToFie
65
72
* @param type parameter type.
66
73
* @param bindToField whether to create a field for the parameter and assign its value to the field.
67
74
*/
68
- void addParameter (String parameterName , ResolvableType type , boolean bindToField );
75
+ default void addParameter (String parameterName , ResolvableType type , boolean bindToField ) {
76
+ addParameter (parameterName , type , c -> c .bindToField (bindToField ));
77
+ }
78
+
79
+ /**
80
+ * Add constructor parameter.
81
+ *
82
+ * @param parameterName name of the parameter.
83
+ * @param type parameter type.
84
+ * @param parameterCustomizer customizer for the parameter.
85
+ */
86
+ default void addParameter (String parameterName , Class <?> type ,
87
+ Consumer <ConstructorParameterCustomizer > parameterCustomizer ) {
88
+ addParameter (parameterName , ResolvableType .forClass (type ), parameterCustomizer );
89
+ }
90
+
91
+ /**
92
+ * Add constructor parameter.
93
+ *
94
+ * @param parameterName name of the parameter.
95
+ * @param type parameter type.
96
+ * @param parameterCustomizer customizer for the parameter.
97
+ */
98
+ void addParameter (String parameterName , ResolvableType type ,
99
+ Consumer <ConstructorParameterCustomizer > parameterCustomizer );
69
100
70
101
/**
71
102
* Add constructor body customizer. The customizer is invoked after adding constructor arguments and before assigning
@@ -89,4 +120,147 @@ interface ConstructorCustomizer {
89
120
90
121
}
91
122
123
+ /**
124
+ * Customizer for a AOT repository constructor parameter.
125
+ */
126
+ interface ConstructorParameterCustomizer {
127
+
128
+ /**
129
+ * Bind the constructor parameter to a field of the same type using the original parameter name.
130
+ *
131
+ * @return {@code this} for method chaining.
132
+ */
133
+ default ConstructorParameterCustomizer bindToField () {
134
+ return bindToField (true );
135
+ }
136
+
137
+ /**
138
+ * Bind the constructor parameter to a field of the same type using the original parameter name.
139
+ *
140
+ * @return {@code this} for method chaining.
141
+ */
142
+ ConstructorParameterCustomizer bindToField (boolean bindToField );
143
+
144
+ /**
145
+ * Use the given {@link BeanReference} to define the constructor parameter origin. Bean references can be by name,
146
+ * by type or by type and name. Using a bean reference renders a lookup to a local variable using the parameter name
147
+ * as guidance for the local variable name
148
+ *
149
+ * @see FragmentParameterContext#localVariable(String)
150
+ */
151
+ void origin (BeanReference reference );
152
+
153
+ /**
154
+ * Use the given {@link BeanReference} to define the constructor parameter origin. Bean references can be by name,
155
+ * by type or by type and name.
156
+ */
157
+ void origin (Function <FragmentParameterContext , ParameterOrigin > originFunction );
158
+
159
+ }
160
+
161
+ /**
162
+ * Context to obtain a constructor parameter value when declaring the constructor parameter origin.
163
+ */
164
+ interface FragmentParameterContext {
165
+
166
+ /**
167
+ * @return variable name of the {@link org.springframework.beans.factory.BeanFactory}.
168
+ */
169
+ String beanFactory ();
170
+
171
+ /**
172
+ * @return parameter origin to obtain the {@link org.springframework.beans.factory.BeanFactory}.
173
+ */
174
+ default ParameterOrigin getBeanFactory () {
175
+ return ParameterOrigin .ofReference (beanFactory ());
176
+ }
177
+
178
+ /**
179
+ * @return variable name of the
180
+ * {@link org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.FragmentCreationContext}.
181
+ */
182
+ String fragmentCreationContext ();
183
+
184
+ /**
185
+ * @return parameter origin to obtain the fragment creation context.
186
+ */
187
+ default ParameterOrigin getFragmentCreationContext () {
188
+ return ParameterOrigin .ofReference (fragmentCreationContext ());
189
+ }
190
+
191
+ /**
192
+ * Obtain a naming-clash free variant for the given logical variable name within the local method context. Returns
193
+ * the target variable name when called multiple times with the same {@code variableName}.
194
+ *
195
+ * @param variableName the logical variable name.
196
+ * @return the variable name used in the generated code.
197
+ */
198
+ String localVariable (String variableName );
199
+
200
+ }
201
+
202
+ /**
203
+ * Interface describing the origin of a constructor parameter. The parameter value can be obtained either from a
204
+ * {@link #getReference() reference} variable, a {@link #getCodeBlock() code block} or a combination of both.
205
+ *
206
+ * @author Mark Paluch
207
+ * @since 4.0
208
+ */
209
+ interface ParameterOrigin {
210
+
211
+ /**
212
+ * Construct a {@link ParameterOrigin} from the given {@link CodeBlock} and reference name.
213
+ *
214
+ * @param reference the reference name to obtain the parameter value from.
215
+ * @param codeBlock the code block that is required to set up the parameter value.
216
+ * @return a {@link ParameterOrigin} from the given {@link CodeBlock} and reference name.
217
+ */
218
+ static ParameterOrigin of (String reference , CodeBlock codeBlock ) {
219
+
220
+ Assert .hasText (reference , "Parameter reference must not be empty" );
221
+
222
+ return new DefaultParameterOrigin (reference , codeBlock );
223
+ }
224
+
225
+ /**
226
+ * Construct a {@link ParameterOrigin} from the given {@link CodeBlock}.
227
+ *
228
+ * @param codeBlock the code block that produces the parameter value.
229
+ * @return a {@link ParameterOrigin} from the given {@link CodeBlock}.
230
+ */
231
+ static ParameterOrigin of (CodeBlock codeBlock ) {
232
+
233
+ Assert .notNull (codeBlock , "CodeBlock reference must not be empty" );
234
+
235
+ return new DefaultParameterOrigin (null , codeBlock );
236
+ }
237
+
238
+ /**
239
+ * Construct a {@link ParameterOrigin} from the given reference name.
240
+ *
241
+ * @param reference the reference name of the variable to obtain the parameter value from.
242
+ * @return a {@link ParameterOrigin} from the given reference name.
243
+ */
244
+ static ParameterOrigin ofReference (String reference ) {
245
+
246
+ Assert .hasText (reference , "Parameter reference must not be empty" );
247
+
248
+ return of (reference , CodeBlock .builder ().build ());
249
+ }
250
+
251
+ /**
252
+ * Obtain the reference name to obtain the parameter value from. Can be {@code null} if the parameter value is
253
+ * solely obtained from the {@link #getCodeBlock() code block}.
254
+ *
255
+ * @return name of the reference or {@literal null} if absent.
256
+ */
257
+ @ Nullable
258
+ String getReference ();
259
+
260
+ /**
261
+ * Obtain the code block to obtain the parameter value from. Never {@literal null}, can be empty.
262
+ */
263
+ CodeBlock getCodeBlock ();
264
+
265
+ }
92
266
}
0 commit comments