41
41
import org .springframework .javapoet .ClassName ;
42
42
import org .springframework .javapoet .FieldSpec ;
43
43
import org .springframework .javapoet .JavaFile ;
44
+ import org .springframework .javapoet .MethodSpec ;
44
45
import org .springframework .javapoet .TypeName ;
45
46
import org .springframework .javapoet .TypeSpec ;
46
47
53
54
class AotRepositoryBuilder {
54
55
55
56
private final RepositoryInformation repositoryInformation ;
57
+ private final String moduleName ;
56
58
private final ProjectionFactory projectionFactory ;
57
59
private final AotRepositoryFragmentMetadata generationMetadata ;
58
60
59
61
private @ Nullable Consumer <AotRepositoryConstructorBuilder > constructorCustomizer ;
60
62
private @ Nullable BiFunction <Method , RepositoryInformation , @ Nullable MethodContributor <? extends QueryMethod >> methodContributorFunction ;
61
63
private ClassCustomizer customizer ;
62
64
63
- private AotRepositoryBuilder (RepositoryInformation repositoryInformation , ProjectionFactory projectionFactory ) {
65
+ private AotRepositoryBuilder (RepositoryInformation repositoryInformation , String moduleName ,
66
+ ProjectionFactory projectionFactory ) {
64
67
65
68
this .repositoryInformation = repositoryInformation ;
69
+ this .moduleName = moduleName ;
66
70
this .projectionFactory = projectionFactory ;
67
71
68
72
this .generationMetadata = new AotRepositoryFragmentMetadata (className ());
@@ -74,54 +78,71 @@ private AotRepositoryBuilder(RepositoryInformation repositoryInformation, Projec
74
78
this .customizer = (info , metadata , builder ) -> {};
75
79
}
76
80
77
- public static <M extends QueryMethod > AotRepositoryBuilder forRepository (RepositoryInformation repositoryInformation ,
81
+ /**
82
+ * Create a new {@code AotRepositoryBuilder} for the given {@link RepositoryInformation}.
83
+ *
84
+ * @param information must not be {@literal null}.
85
+ * @param moduleName must not be {@literal null}.
86
+ * @param projectionFactory must not be {@literal null}.
87
+ * @return
88
+ */
89
+ public static AotRepositoryBuilder forRepository (RepositoryInformation information , String moduleName ,
78
90
ProjectionFactory projectionFactory ) {
79
- return new AotRepositoryBuilder (repositoryInformation , projectionFactory );
91
+ return new AotRepositoryBuilder (information , moduleName , projectionFactory );
80
92
}
81
93
94
+ /**
95
+ * Configure a {@link ClassCustomizer} customizer.
96
+ *
97
+ * @param classCustomizer must not be {@literal null}.
98
+ * @return {@code this}.
99
+ */
100
+ public AotRepositoryBuilder withClassCustomizer (ClassCustomizer classCustomizer ) {
101
+
102
+ this .customizer = classCustomizer ;
103
+ return this ;
104
+ }
105
+
106
+ /**
107
+ * Configure a {@link AotRepositoryConstructorBuilder} customizer.
108
+ *
109
+ * @param constructorCustomizer must not be {@literal null}.
110
+ * @return {@code this}.
111
+ */
82
112
public AotRepositoryBuilder withConstructorCustomizer (
83
113
Consumer <AotRepositoryConstructorBuilder > constructorCustomizer ) {
84
114
85
115
this .constructorCustomizer = constructorCustomizer ;
86
116
return this ;
87
117
}
88
118
119
+ /**
120
+ * Configure a {@link MethodContributor}.
121
+ *
122
+ * @param methodContributorFunction must not be {@literal null}.
123
+ * @return {@code this}.
124
+ */
89
125
public AotRepositoryBuilder withQueryMethodContributor (
90
126
BiFunction <Method , RepositoryInformation , @ Nullable MethodContributor <? extends QueryMethod >> methodContributorFunction ) {
91
- this .methodContributorFunction = methodContributorFunction ;
92
- return this ;
93
- }
94
127
95
- public AotRepositoryBuilder withClassCustomizer (ClassCustomizer classCustomizer ) {
96
-
97
- this .customizer = classCustomizer ;
128
+ this .methodContributorFunction = methodContributorFunction ;
98
129
return this ;
99
130
}
100
131
101
132
public AotBundle build () {
102
133
134
+ List <AotRepositoryMethod > methodMetadata = new ArrayList <>();
135
+ RepositoryComposition repositoryComposition = repositoryInformation .getRepositoryComposition ();
136
+
103
137
// start creating the type
104
138
TypeSpec .Builder builder = TypeSpec .classBuilder (this .generationMetadata .getTargetTypeName ()) //
105
139
.addModifiers (Modifier .PUBLIC ) //
106
140
.addAnnotation (Generated .class ) //
107
- .addJavadoc ("AOT generated repository implementation for {@link $T}.\n " ,
141
+ .addJavadoc ("AOT generated $L repository implementation for {@link $T}.\n " , moduleName ,
108
142
repositoryInformation .getRepositoryInterface ());
109
143
110
144
// create the constructor
111
- AotRepositoryConstructorBuilder constructorBuilder = new AotRepositoryConstructorBuilder (repositoryInformation ,
112
- generationMetadata );
113
- if (constructorCustomizer != null ) {
114
- constructorCustomizer .accept (constructorBuilder );
115
- }
116
-
117
- builder .addMethod (constructorBuilder .buildConstructor ());
118
-
119
- List <AotRepositoryMethod > methodMetadata = new ArrayList <>();
120
- AotRepositoryMetadata .RepositoryType repositoryType = repositoryInformation .isReactiveRepository ()
121
- ? AotRepositoryMetadata .RepositoryType .REACTIVE
122
- : AotRepositoryMetadata .RepositoryType .IMPERATIVE ;
123
-
124
- RepositoryComposition repositoryComposition = repositoryInformation .getRepositoryComposition ();
145
+ builder .addMethod (buildConstructor ());
125
146
126
147
Arrays .stream (repositoryInformation .getRepositoryInterface ().getMethods ())
127
148
.sorted (Comparator .<Method , String > comparing (it -> {
@@ -136,12 +157,35 @@ public AotBundle build() {
136
157
137
158
// finally customize the file itself
138
159
this .customizer .customize (repositoryInformation , generationMetadata , builder );
160
+
139
161
JavaFile javaFile = JavaFile .builder (packageName (), builder .build ()).build ();
162
+ AotRepositoryMetadata metadata = getAotRepositoryMetadata (methodMetadata );
163
+
164
+ return new AotBundle (javaFile , metadata );
165
+ }
166
+
167
+ private MethodSpec buildConstructor () {
168
+
169
+ AotRepositoryConstructorBuilder constructorBuilder = new AotRepositoryConstructorBuilder (repositoryInformation ,
170
+ generationMetadata );
171
+
172
+ if (constructorCustomizer != null ) {
173
+ constructorCustomizer .accept (constructorBuilder );
174
+ }
175
+
176
+ return constructorBuilder .buildConstructor ();
177
+ }
140
178
141
- AotRepositoryMetadata metadata = new AotRepositoryMetadata (repositoryInformation .getRepositoryInterface ().getName (),
142
- repositoryInformation .moduleName () != null ? repositoryInformation .moduleName () : "" , repositoryType , methodMetadata );
179
+ private AotRepositoryMetadata getAotRepositoryMetadata (List <AotRepositoryMethod > methodMetadata ) {
143
180
144
- return new AotBundle (javaFile , metadata .toJson ());
181
+ AotRepositoryMetadata .RepositoryType repositoryType = repositoryInformation .isReactiveRepository ()
182
+ ? AotRepositoryMetadata .RepositoryType .REACTIVE
183
+ : AotRepositoryMetadata .RepositoryType .IMPERATIVE ;
184
+
185
+ String jsonModuleName = moduleName .replaceAll ("Reactive" , "" ).trim ();
186
+
187
+ return new AotRepositoryMetadata (repositoryInformation .getRepositoryInterface ().getName (), jsonModuleName ,
188
+ repositoryType , methodMetadata );
145
189
}
146
190
147
191
private void contributeMethod (Method method , RepositoryComposition repositoryComposition ,
@@ -185,8 +229,7 @@ private void contributeMethod(Method method, RepositoryComposition repositoryCom
185
229
private AotRepositoryMethod getFragmentMetadata (Method method , RepositoryFragment <?> fragment ) {
186
230
187
231
String signature = fragment .getSignatureContributor ().getName ();
188
- String implementation = fragment .getImplementation ().map (it -> it .getClass ().getName ()).orElse (null );
189
-
232
+ String implementation = fragment .getImplementationClass ().map (Class ::getName ).orElse (null );
190
233
AotFragmentTarget fragmentTarget = new AotFragmentTarget (signature , implementation );
191
234
192
235
return new AotRepositoryMethod (method .getName (), method .toGenericString (), null , fragmentTarget );
@@ -240,7 +283,7 @@ public interface ClassCustomizer {
240
283
241
284
}
242
285
243
- record AotBundle (JavaFile javaFile , JSONObject metadata ) {
286
+ record AotBundle (JavaFile javaFile , AotRepositoryMetadata metadata ) {
244
287
}
245
288
246
289
}
0 commit comments