10
10
import java .util .HashMap ;
11
11
import java .util .HashSet ;
12
12
import java .util .Map ;
13
+ import java .util .Optional ;
13
14
import java .util .Set ;
14
15
15
16
import org .jboss .jandex .ClassInfo ;
16
17
import org .jboss .jandex .FieldInfo ;
17
18
import org .jboss .jandex .IndexView ;
18
19
import org .jboss .jandex .MethodInfo ;
20
+ import org .jboss .jandex .VoidType ;
19
21
22
+ import com .fasterxml .jackson .annotation .JsonValue ;
20
23
import com .fasterxml .jackson .core .JsonGenerator ;
21
24
import com .fasterxml .jackson .core .SerializableString ;
22
25
import com .fasterxml .jackson .core .io .SerializedString ;
@@ -183,15 +186,27 @@ protected boolean createSerializationMethod(ClassInfo classInfo, ClassCreator cl
183
186
"com.fasterxml.jackson.databind.SerializerProvider" )
184
187
.setModifiers (ACC_PUBLIC )
185
188
.addException (IOException .class );
189
+
186
190
boolean valid = serializeObject (classInfo , classCreator , beanClassName , serialize );
187
191
serialize .returnVoid ();
188
192
return valid ;
189
193
}
190
194
191
195
private boolean serializeObject (ClassInfo classInfo , ClassCreator classCreator , String beanClassName ,
192
196
MethodCreator serialize ) {
197
+
198
+ var jsonValueFieldSpecs = jsonValueFieldSpecs (classInfo );
199
+ if (jsonValueFieldSpecs == null ) {
200
+ return false ;
201
+ }
202
+
193
203
SerializationContext ctx = new SerializationContext (serialize , beanClassName );
194
204
205
+ if (jsonValueFieldSpecs .isPresent ()) {
206
+ serializeJsonValue (ctx , serialize , jsonValueFieldSpecs .get ());
207
+ return true ;
208
+ }
209
+
195
210
// jsonGenerator.writeStartObject();
196
211
MethodDescriptor writeStartObject = MethodDescriptor .ofMethod (JSON_GEN_CLASS_NAME , "writeStartObject" , "void" );
197
212
serialize .invokeVirtualMethod (writeStartObject , ctx .jsonGenerator );
@@ -212,6 +227,26 @@ private boolean serializeObject(ClassInfo classInfo, ClassCreator classCreator,
212
227
return valid ;
213
228
}
214
229
230
+ private Optional <FieldSpecs > jsonValueFieldSpecs (ClassInfo classInfo ) {
231
+ var jsonValueMethodFieldSpecs = classInfo .methods ().stream ()
232
+ .filter (mi -> mi .annotation (JsonValue .class ) != null )
233
+ .filter (this ::isJsonValueMethod ).findFirst ().map (FieldSpecs ::new );
234
+ var jsonValueFieldFieldSpecs = classInfo .fields ().stream ()
235
+ .filter (f -> f .annotation (JsonValue .class ) != null )
236
+ .findFirst ().map (FieldSpecs ::new );
237
+
238
+ if (jsonValueFieldFieldSpecs .isPresent ()) {
239
+ return jsonValueMethodFieldSpecs .isPresent () ? null : jsonValueFieldFieldSpecs ;
240
+ }
241
+ return jsonValueMethodFieldSpecs ;
242
+ }
243
+
244
+ private void serializeJsonValue (SerializationContext ctx , MethodCreator bytecode , FieldSpecs jsonValueFieldSpecs ) {
245
+ String typeName = jsonValueFieldSpecs .fieldType .toString ();
246
+ ResultHandle arg = jsonValueFieldSpecs .toValueReaderHandle (bytecode , ctx .valueHandle );
247
+ writeFieldValue (jsonValueFieldSpecs , bytecode , ctx , typeName , arg , null );
248
+ }
249
+
215
250
private boolean serializeObjectData (ClassInfo classInfo , ClassCreator classCreator , MethodCreator serialize ,
216
251
SerializationContext ctx , Set <String > serializedFields ) {
217
252
return serializeFields (classInfo , classCreator , serialize , ctx , serializedFields ) &&
@@ -258,6 +293,12 @@ private FieldSpecs fieldSpecsFromMethod(MethodInfo methodInfo) {
258
293
return !Modifier .isStatic (methodInfo .flags ()) && isGetterMethod (methodInfo ) ? new FieldSpecs (methodInfo ) : null ;
259
294
}
260
295
296
+ private boolean isJsonValueMethod (MethodInfo methodInfo ) {
297
+ return Modifier .isPublic (methodInfo .flags ()) && !Modifier .isStatic (methodInfo .flags ())
298
+ && methodInfo .parametersCount () == 0
299
+ && !methodInfo .returnType ().equals (VoidType .VOID );
300
+ }
301
+
261
302
private boolean isGetterMethod (MethodInfo methodInfo ) {
262
303
String methodName = methodInfo .name ();
263
304
return Modifier .isPublic (methodInfo .flags ()) && !Modifier .isStatic (methodInfo .flags ())
@@ -273,25 +314,36 @@ private void writeField(ClassInfo classInfo, FieldSpecs fieldSpecs, BytecodeCrea
273
314
bytecode = checkInclude (bytecode , ctx , arg );
274
315
275
316
String typeName = fieldSpecs .fieldType .name ().toString ();
317
+ writeFieldValue (fieldSpecs , bytecode , ctx , typeName , arg , pkgName );
318
+ }
319
+
320
+ private void writeFieldValue (FieldSpecs fieldSpecs , BytecodeCreator bytecode , SerializationContext ctx , String typeName ,
321
+ ResultHandle arg , String pkgName ) {
276
322
String primitiveMethodName = writeMethodForPrimitiveFields (typeName );
277
323
278
324
if (primitiveMethodName != null ) {
279
325
BytecodeCreator primitiveBytecode = JacksonSerializationUtils .isBoxedPrimitive (typeName )
280
326
? bytecode .ifNotNull (arg ).trueBranch ()
281
327
: bytecode ;
282
- writeFieldName (fieldSpecs , primitiveBytecode , ctx .jsonGenerator , pkgName );
328
+
329
+ if (pkgName != null ) {
330
+ writeFieldName (fieldSpecs , primitiveBytecode , ctx .jsonGenerator , pkgName );
331
+ }
332
+
283
333
MethodDescriptor primitiveWriter = MethodDescriptor .ofMethod (JSON_GEN_CLASS_NAME , primitiveMethodName , "void" ,
284
334
fieldSpecs .writtenType ());
285
335
primitiveBytecode .invokeVirtualMethod (primitiveWriter , ctx .jsonGenerator , arg );
286
- return ;
287
- }
288
336
289
- registerTypeToBeGenerated (fieldSpecs .fieldType , typeName );
337
+ } else {
338
+ if (pkgName != null ) {
339
+ registerTypeToBeGenerated (fieldSpecs .fieldType , typeName );
340
+ writeFieldName (fieldSpecs , bytecode , ctx .jsonGenerator , pkgName );
341
+ }
290
342
291
- writeFieldName ( fieldSpecs , bytecode , ctx . jsonGenerator , pkgName );
292
- MethodDescriptor writeMethod = MethodDescriptor . ofMethod ( JSON_GEN_CLASS_NAME , "writePOJO" ,
293
- void . class , Object . class );
294
- bytecode . invokeVirtualMethod ( writeMethod , ctx . jsonGenerator , arg );
343
+ MethodDescriptor writeMethod = MethodDescriptor . ofMethod ( JSON_GEN_CLASS_NAME , "writePOJO" ,
344
+ void . class , Object . class );
345
+ bytecode . invokeVirtualMethod ( writeMethod , ctx . jsonGenerator , arg );
346
+ }
295
347
}
296
348
297
349
private static BytecodeCreator checkInclude (BytecodeCreator bytecode , SerializationContext ctx , ResultHandle arg ) {
0 commit comments