@@ -20,13 +20,15 @@ final class ClassReader implements BeanReader {
20
20
21
21
private final MethodReader constructor ;
22
22
private final List <FieldReader > allFields ;
23
+ private final List <MethodProperty > methodProperties ;
23
24
private final Set <String > importTypes = new TreeSet <>();
24
25
private final NamingConvention namingConvention ;
25
26
private final boolean hasSubTypes ;
26
27
private final TypeReader typeReader ;
27
28
private final String typeProperty ;
28
29
private final boolean nonAccessibleField ;
29
30
private final boolean caseInsensitiveKeys ;
31
+ private final boolean readOnlyInterface ;
30
32
private FieldReader unmappedField ;
31
33
private boolean hasRaw ;
32
34
private final boolean isRecord ;
@@ -37,6 +39,7 @@ final class ClassReader implements BeanReader {
37
39
private final Map <String , Integer > frequencyMap = new HashMap <>();
38
40
private final Map <String , Boolean > isCommonFieldMap = new HashMap <>();
39
41
private final boolean optional ;
42
+ private final List <TypeSubTypeMeta > subTypes ;
40
43
41
44
ClassReader (TypeElement beanType ) {
42
45
this (beanType , null );
@@ -58,7 +61,11 @@ final class ClassReader implements BeanReader {
58
61
this .constructor = typeReader .constructor ();
59
62
this .optional = typeReader .hasOptional ();
60
63
this .isRecord = isRecord (beanType );
61
- typeReader .subTypes ().stream ().map (TypeSubTypeMeta ::type ).forEach (importTypes ::add );
64
+ this .subTypes = typeReader .subTypes ();
65
+ this .readOnlyInterface = allFields .isEmpty () && subTypes .isEmpty ();
66
+ this .methodProperties = typeReader .methodProperties ();
67
+
68
+ subTypes .stream ().map (TypeSubTypeMeta ::type ).forEach (importTypes ::add );
62
69
63
70
final var userTypeField = allFields .stream ().filter (f -> f .propertyName ().equals (typePropertyKey ())).findAny ();
64
71
@@ -132,6 +139,9 @@ public void read() {
132
139
unmappedField = field ;
133
140
}
134
141
}
142
+ for (final MethodProperty methodProperty : methodProperties ) {
143
+ methodProperty .addImports (importTypes );
144
+ }
135
145
}
136
146
137
147
private Set <String > importTypes () {
@@ -151,6 +161,9 @@ private Set<String> importTypes() {
151
161
for (final FieldReader allField : allFields ) {
152
162
allField .addImports (importTypes );
153
163
}
164
+ for (final MethodProperty methodProperty : methodProperties ) {
165
+ methodProperty .addImports (importTypes );
166
+ }
154
167
return importTypes ;
155
168
}
156
169
@@ -194,6 +207,11 @@ public void writeFields(Append writer) {
194
207
allField .writeField (writer );
195
208
}
196
209
}
210
+ for (final MethodProperty methodProperty : methodProperties ) {
211
+ if (uniqueTypes .add (methodProperty .adapterShortType ())) {
212
+ methodProperty .writeField (writer );
213
+ }
214
+ }
197
215
writer .append (" private final PropertyNames names;" ).eol ();
198
216
writer .eol ();
199
217
}
@@ -221,12 +239,25 @@ public void writeConstructor(Append writer) {
221
239
allField .writeConstructor (writer );
222
240
}
223
241
}
242
+ for (MethodProperty methodProperty : methodProperties ) {
243
+ if (uniqueTypes .add (methodProperty .adapterShortType ())) {
244
+ methodProperty .writeConstructor (writer );
245
+ }
246
+ }
224
247
writer .append (" this.names = jsonb.properties(" );
225
248
if (hasSubTypes ) {
226
249
writer .append ("\" " ).append (typeProperty ).append ("\" , " );
227
250
}
228
- final StringBuilder builder = new StringBuilder ();
251
+ writer .append (propertyNames ());
252
+ writer .append (");" ).eol ();
253
+ }
254
+
255
+ private String propertyNames () {
256
+ return readOnlyInterface ? propertyNamesReadOnly () : propertyNamesFields ();
257
+ }
229
258
259
+ private String propertyNamesFields () {
260
+ final StringBuilder builder = new StringBuilder ();
230
261
//set to prevent writing same key twice
231
262
final var seen = new HashSet <String >();
232
263
for (int i = 0 , size = allFields .size (); i < size ; i ++) {
@@ -243,8 +274,18 @@ public void writeConstructor(Append writer) {
243
274
}
244
275
builder .append ("\" " ).append (fieldReader .propertyName ()).append ("\" " );
245
276
}
246
- writer .append (builder .toString ().replace (" , " , "" ));
247
- writer .append (");" ).eol ();
277
+ return builder .toString ().replace (" , " , "" );
278
+ }
279
+
280
+ private String propertyNamesReadOnly () {
281
+ final StringBuilder builder = new StringBuilder ();
282
+ for (int i = 0 ; i < methodProperties .size (); i ++) {
283
+ if (i > 0 ) {
284
+ builder .append (", " );
285
+ }
286
+ builder .append ("\" " ).append (methodProperties .get (i ).propertyName ()).append ("\" " );
287
+ }
288
+ return builder .toString ().replace (" , " , "" );
248
289
}
249
290
250
291
@ Override
@@ -271,13 +312,14 @@ private void writeViewBuild(Append writer) {
271
312
writer .append (" @Override" ).eol ();
272
313
writer .append (" public void build(ViewBuilder builder, String name, MethodHandle handle) {" ).eol ();
273
314
writer .append (" builder.beginObject(name, handle);" ).eol ();
274
- if (!hasSubTypes ) {
275
- for (final FieldReader allField : allFields ) {
276
- if (allField .includeToJson (null )) {
277
- allField .writeViewBuilder (writer , shortName );
278
- }
315
+ for (final FieldReader allField : allFields ) {
316
+ if (allField .includeToJson (null )) {
317
+ allField .writeViewBuilder (writer , shortName );
279
318
}
280
319
}
320
+ for (final MethodProperty methodProperty : methodProperties ) {
321
+ methodProperty .writeViewBuilder (writer , shortName );
322
+ }
281
323
writer .append (" builder.endObject();" ).eol ();
282
324
writer .append (" }" ).eol ();
283
325
}
@@ -300,7 +342,6 @@ public void writeToJson(Append writer) {
300
342
301
343
private void writeToJsonForSubtypes (Append writer , String varName ) {
302
344
if (hasSubTypes ) {
303
- final List <TypeSubTypeMeta > subTypes = typeReader .subTypes ();
304
345
for (int i = 0 ; i < subTypes .size (); i ++) {
305
346
final TypeSubTypeMeta subTypeMeta = subTypes .get (i );
306
347
final String subType = subTypeMeta .type ();
@@ -330,6 +371,9 @@ private void writeToJsonForType(Append writer, String varName, String prefix, St
330
371
allField .writeToJson (writer , varName , prefix );
331
372
}
332
373
}
374
+ for (final MethodProperty methodProperty : methodProperties ) {
375
+ methodProperty .writeToJson (writer , varName , prefix );
376
+ }
333
377
}
334
378
335
379
@ Override
@@ -338,6 +382,12 @@ public void writeFromJson(Append writer) {
338
382
writer .eol ();
339
383
writer .append (" @Override" ).eol ();
340
384
writer .append (" public %s fromJson(JsonReader reader) {" , shortName , varName ).eol ();
385
+ if (readOnlyInterface ) {
386
+ writer .append (" throw new UnsupportedOperationException();" ).eol ();
387
+ writer .append (" }" ).eol ();
388
+ return ;
389
+ }
390
+
341
391
final boolean directLoad = (constructor == null && !hasSubTypes && !optional );
342
392
if (directLoad ) {
343
393
// default public constructor
@@ -401,7 +451,7 @@ private void writeJsonBuildResult(Append writer, String varName) {
401
451
402
452
private void writeFromJsonWithSubTypes (Append writer ) {
403
453
final var typeVar = usesTypeProperty ? "_val$" + typePropertyKey () : "type" ;
404
- final var useSwitch = typeReader . subTypes () .size () >= 3 ;
454
+ final var useSwitch = subTypes .size () >= 3 ;
405
455
406
456
if (!useSwitch || !nullSwitch ) {
407
457
writer .append (" if (%s == null) {" , typeVar ).eol ();
@@ -422,7 +472,7 @@ private void writeFromJsonWithSubTypes(Append writer) {
422
472
final Map <String , Integer > frequencyMap2 = new HashMap <>();
423
473
final var req = new SubTypeRequest (typeVar , this , useSwitch , useEnum , frequencyMap2 , isCommonFieldMap );
424
474
425
- for (final TypeSubTypeMeta subTypeMeta : typeReader . subTypes () ) {
475
+ for (final TypeSubTypeMeta subTypeMeta : subTypes ) {
426
476
final var varName = Util .initLower (Util .shortName (subTypeMeta .type ()));
427
477
subTypeMeta .writeFromJsonBuild (writer , varName , req );
428
478
}
0 commit comments