|
3 | 3 | import static org.jboss.jandex.AnnotationTarget.Kind.CLASS;
|
4 | 4 | import static org.jboss.jandex.AnnotationTarget.Kind.METHOD;
|
5 | 5 |
|
| 6 | +import java.lang.constant.ClassDesc; |
| 7 | +import java.lang.constant.ConstantDescs; |
| 8 | +import java.lang.constant.MethodTypeDesc; |
6 | 9 | import java.lang.reflect.Field;
|
7 | 10 | import java.util.Arrays;
|
8 | 11 | import java.util.Collection;
|
|
41 | 44 |
|
42 | 45 | import io.quarkus.arc.deployment.AdditionalBeanBuildItem;
|
43 | 46 | import io.quarkus.arc.deployment.GeneratedBeanBuildItem;
|
44 |
| -import io.quarkus.arc.deployment.GeneratedBeanGizmoAdaptor; |
| 47 | +import io.quarkus.arc.deployment.GeneratedBeanGizmo2Adaptor; |
45 | 48 | import io.quarkus.arc.deployment.SyntheticBeanBuildItem;
|
46 | 49 | import io.quarkus.arc.deployment.UnremovableBeanBuildItem;
|
47 | 50 | import io.quarkus.arc.impl.Reflections;
|
|
57 | 60 | import io.quarkus.deployment.builditem.nativeimage.ReflectiveHierarchyBuildItem;
|
58 | 61 | import io.quarkus.deployment.builditem.nativeimage.ReflectiveMethodBuildItem;
|
59 | 62 | import io.quarkus.deployment.pkg.builditem.CurateOutcomeBuildItem;
|
60 |
| -import io.quarkus.gizmo.ClassCreator; |
61 |
| -import io.quarkus.gizmo.ClassOutput; |
62 |
| -import io.quarkus.gizmo.MethodCreator; |
63 |
| -import io.quarkus.gizmo.MethodDescriptor; |
64 |
| -import io.quarkus.gizmo.ResultHandle; |
| 63 | +import io.quarkus.gizmo2.ClassOutput; |
| 64 | +import io.quarkus.gizmo2.Const; |
| 65 | +import io.quarkus.gizmo2.Expr; |
| 66 | +import io.quarkus.gizmo2.Gizmo; |
| 67 | +import io.quarkus.gizmo2.LocalVar; |
| 68 | +import io.quarkus.gizmo2.ParamVar; |
| 69 | +import io.quarkus.gizmo2.Reflection2Gizmo; |
| 70 | +import io.quarkus.gizmo2.desc.ClassMethodDesc; |
| 71 | +import io.quarkus.gizmo2.desc.MethodDesc; |
65 | 72 | import io.quarkus.jackson.JacksonMixin;
|
66 | 73 | import io.quarkus.jackson.ObjectMapperCustomizer;
|
67 | 74 | import io.quarkus.jackson.runtime.ConfigurationCustomizer;
|
@@ -100,6 +107,9 @@ public class JacksonProcessor {
|
100 | 107 | private static final String PARAMETER_NAMES_MODULE = "com.fasterxml.jackson.module.paramnames.ParameterNamesModule";
|
101 | 108 | private static final DotName JACKSON_MIXIN = DotName.createSimple(JacksonMixin.class.getName());
|
102 | 109 |
|
| 110 | + private static final MethodDesc OBJECT_MAPPER_REGISTER_MODULE_METHOD_DESC = MethodDesc.of(ObjectMapper.class, |
| 111 | + "registerModule", ObjectMapper.class, Module.class); |
| 112 | + |
103 | 113 | // this list can probably be enriched with more modules
|
104 | 114 | private static final List<String> MODULES_NAMES_TO_AUTO_REGISTER = Arrays.asList(TIME_MODULE, JDK8_MODULE,
|
105 | 115 | PARAMETER_NAMES_MODULE);
|
@@ -377,79 +387,87 @@ void generateCustomizer(BuildProducer<GeneratedBeanBuildItem> generatedBeans,
|
377 | 387 | return;
|
378 | 388 | }
|
379 | 389 |
|
380 |
| - ClassOutput classOutput = new GeneratedBeanGizmoAdaptor(generatedBeans); |
381 |
| - |
382 |
| - try (ClassCreator classCreator = ClassCreator.builder().classOutput(classOutput) |
383 |
| - .className("io.quarkus.jackson.customizer.RegisterSerializersAndDeserializersCustomizer") |
384 |
| - .interfaces(ObjectMapperCustomizer.class.getName()) |
385 |
| - .build()) { |
386 |
| - classCreator.addAnnotation(Singleton.class); |
387 |
| - |
388 |
| - try (MethodCreator customize = classCreator.getMethodCreator("customize", void.class, ObjectMapper.class)) { |
389 |
| - ResultHandle objectMapper = customize.getMethodParam(0); |
390 |
| - |
391 |
| - for (JacksonModuleBuildItem jacksonModule : jacksonModules) { |
392 |
| - if (jacksonModule.getItems().isEmpty()) { |
393 |
| - continue; |
394 |
| - } |
395 |
| - |
396 |
| - /* |
397 |
| - * Create code similar to the following: |
398 |
| - * |
399 |
| - * SimpleModule module = new SimpleModule("somename"); |
400 |
| - * module.addSerializer(Foo.class, new FooSerializer()); |
401 |
| - * module.addDeserializer(Foo.class, new FooDeserializer()); |
402 |
| - * objectMapper.registerModule(module); |
403 |
| - */ |
404 |
| - ResultHandle module = customize.newInstance( |
405 |
| - MethodDescriptor.ofConstructor(SimpleModule.class, String.class), |
406 |
| - customize.load(jacksonModule.getName())); |
407 |
| - |
408 |
| - for (JacksonModuleBuildItem.Item item : jacksonModule.getItems()) { |
409 |
| - ResultHandle targetClass = customize.loadClassFromTCCL(item.getTargetClassName()); |
410 |
| - |
411 |
| - String serializerClassName = item.getSerializerClassName(); |
412 |
| - if (serializerClassName != null && !serializerClassName.isEmpty()) { |
413 |
| - ResultHandle serializer = customize.newInstance( |
414 |
| - MethodDescriptor.ofConstructor(serializerClassName)); |
415 |
| - customize.invokeVirtualMethod( |
416 |
| - MethodDescriptor.ofMethod(SimpleModule.class, "addSerializer", SimpleModule.class, |
417 |
| - Class.class, JsonSerializer.class), |
418 |
| - module, targetClass, serializer); |
| 390 | + ClassOutput classOutput = new GeneratedBeanGizmo2Adaptor(generatedBeans); |
| 391 | + Gizmo g = Gizmo.create(classOutput); |
| 392 | + g.class_("io.quarkus.jackson.customizer.RegisterSerializersAndDeserializersCustomizer", cc -> { |
| 393 | + cc.implements_(ObjectMapperCustomizer.class); |
| 394 | + cc.defaultConstructor(); |
| 395 | + cc.addAnnotation(Singleton.class); |
| 396 | + cc.method("customize", mc -> { |
| 397 | + ParamVar objectMapperParam = mc.parameter("objectMapper", ObjectMapper.class); |
| 398 | + mc.returning(void.class); |
| 399 | + mc.body(bc -> { |
| 400 | + ClassDesc simpleModuleClassDesc = Reflection2Gizmo.classDescOf(SimpleModule.class); |
| 401 | + for (JacksonModuleBuildItem jacksonModule : jacksonModules) { |
| 402 | + if (jacksonModule.getItems().isEmpty()) { |
| 403 | + continue; |
419 | 404 | }
|
420 | 405 |
|
421 |
| - String deserializerClassName = item.getDeserializerClassName(); |
422 |
| - if (deserializerClassName != null && !deserializerClassName.isEmpty()) { |
423 |
| - ResultHandle deserializer = customize.newInstance( |
424 |
| - MethodDescriptor.ofConstructor(deserializerClassName)); |
425 |
| - customize.invokeVirtualMethod( |
426 |
| - MethodDescriptor.ofMethod(SimpleModule.class, "addDeserializer", SimpleModule.class, |
427 |
| - Class.class, JsonDeserializer.class), |
428 |
| - module, targetClass, deserializer); |
| 406 | + /* |
| 407 | + * Create code similar to the following: |
| 408 | + * |
| 409 | + * SimpleModule module = new SimpleModule("somename"); |
| 410 | + * module.addSerializer(Foo.class, new FooSerializer()); |
| 411 | + * module.addDeserializer(Foo.class, new FooDeserializer()); |
| 412 | + * objectMapper.registerModule(module); |
| 413 | + */ |
| 414 | + |
| 415 | + LocalVar simpleModuleInstance = bc.localVar("simpleModule", |
| 416 | + bc.new_(SimpleModule.class, Const.of(jacksonModule.getName()))); |
| 417 | + |
| 418 | + for (JacksonModuleBuildItem.Item item : jacksonModule.getItems()) { |
| 419 | + |
| 420 | + LocalVar targetClass = bc.localVar("targetClass", |
| 421 | + Const.of(ClassDesc.of(item.getTargetClassName()))); |
| 422 | + String serializerClassName = item.getSerializerClassName(); |
| 423 | + if ((serializerClassName != null) && !serializerClassName.isEmpty()) { |
| 424 | + ClassDesc serializerClassDesc = ClassDesc.of(serializerClassName); |
| 425 | + Expr serializerInstance = bc.new_(serializerClassDesc); |
| 426 | + |
| 427 | + bc.invokeVirtual( |
| 428 | + ClassMethodDesc.of(simpleModuleClassDesc, "addSerializer", |
| 429 | + MethodTypeDesc.of(simpleModuleClassDesc, |
| 430 | + ConstantDescs.CD_Class, Reflection2Gizmo.classDescOf( |
| 431 | + JsonSerializer.class))), |
| 432 | + simpleModuleInstance, targetClass, serializerInstance); |
| 433 | + |
| 434 | + } |
| 435 | + |
| 436 | + String deserializerClassName = item.getDeserializerClassName(); |
| 437 | + if ((deserializerClassName != null) && !deserializerClassName.isEmpty()) { |
| 438 | + ClassDesc deserializerClassDesc = ClassDesc.of(deserializerClassName); |
| 439 | + Expr deserializerInstance = bc.new_(deserializerClassDesc); |
| 440 | + |
| 441 | + bc.invokeVirtual( |
| 442 | + ClassMethodDesc.of(simpleModuleClassDesc, "addDeserializer", |
| 443 | + MethodTypeDesc.of(simpleModuleClassDesc, |
| 444 | + ConstantDescs.CD_Class, Reflection2Gizmo.classDescOf( |
| 445 | + JsonDeserializer.class))), |
| 446 | + simpleModuleInstance, targetClass, deserializerInstance); |
| 447 | + |
| 448 | + } |
429 | 449 | }
|
430 |
| - } |
431 | 450 |
|
432 |
| - customize.invokeVirtualMethod( |
433 |
| - MethodDescriptor.ofMethod(ObjectMapper.class, "registerModule", ObjectMapper.class, Module.class), |
434 |
| - objectMapper, module); |
435 |
| - } |
| 451 | + bc.invokeVirtual( |
| 452 | + OBJECT_MAPPER_REGISTER_MODULE_METHOD_DESC, |
| 453 | + objectMapperParam, simpleModuleInstance); |
436 | 454 |
|
437 |
| - for (ClassPathJacksonModuleBuildItem classPathJacksonModule : classPathJacksonModules) { |
438 |
| - ResultHandle module = customize |
439 |
| - .newInstance(MethodDescriptor.ofConstructor(classPathJacksonModule.getModuleClassName())); |
440 |
| - customize.invokeVirtualMethod( |
441 |
| - MethodDescriptor.ofMethod(ObjectMapper.class, "registerModule", ObjectMapper.class, Module.class), |
442 |
| - objectMapper, module); |
443 |
| - } |
| 455 | + } |
444 | 456 |
|
445 |
| - customize.returnValue(null); |
446 |
| - } |
| 457 | + for (ClassPathJacksonModuleBuildItem classPathJacksonModule : classPathJacksonModules) { |
| 458 | + bc.invokeVirtual( |
| 459 | + OBJECT_MAPPER_REGISTER_MODULE_METHOD_DESC, |
| 460 | + objectMapperParam, bc.new_(ClassDesc.of(classPathJacksonModule.getModuleClassName()))); |
| 461 | + } |
447 | 462 |
|
448 |
| - // ensure that the things we auto-register have the lower priority - this ensures that user registered modules take priority |
449 |
| - try (MethodCreator priority = classCreator.getMethodCreator("priority", int.class)) { |
450 |
| - priority.returnValue(priority.load(ObjectMapperCustomizer.QUARKUS_CUSTOMIZER_PRIORITY)); |
451 |
| - } |
452 |
| - } |
| 463 | + bc.return_(); |
| 464 | + }); |
| 465 | + }); |
| 466 | + cc.method("priority", mc -> { |
| 467 | + mc.returning(int.class); |
| 468 | + mc.body(bc -> bc.return_(ObjectMapperCustomizer.QUARKUS_CUSTOMIZER_PRIORITY)); |
| 469 | + }); |
| 470 | + }); |
453 | 471 | }
|
454 | 472 |
|
455 | 473 | @Record(ExecutionTime.STATIC_INIT)
|
|
0 commit comments