1 package top.infra.jackson2;
2
3 import static java.lang.Boolean.FALSE;
4
5 import com.fasterxml.jackson.databind.Module;
6 import com.fasterxml.jackson.databind.ObjectMapper;
7
8 import lombok.extern.slf4j.Slf4j;
9
10 import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
11
12 import java.lang.reflect.Method;
13 import java.util.List;
14 import java.util.Optional;
15
16 import top.infra.common.ClassUtils;
17
18 @Slf4j
19 public class HalJackson2Customizer implements Jackson2Customizer {
20
21 @Override
22 public void customize(final Jackson2Properties properties, final ObjectMapper mapper) {
23 final Optional<Module> jackson2HalModule = this.jackson2HalModule();
24 if (jackson2HalModule.isPresent() && !this.isAlreadyRegisteredIn(mapper, jackson2HalModule.get().getClass())) {
25 mapper.registerModule(jackson2HalModule.get());
26 }
27 }
28
29 @Override
30 public void customize(final Jackson2Properties properties, final Jackson2ObjectMapperBuilder builder) {
31 final Optional<Module> jackson2HalModule = this.jackson2HalModule();
32
33 final List<Module> modules = this.modules(builder);
34 if (jackson2HalModule.isPresent() && modules.stream().noneMatch(
35 module -> jackson2HalModule.get().getClass().isAssignableFrom(module.getClass()))) {
36
37 modules.add(jackson2HalModule.get());
38 builder.modulesToInstall(modules.toArray(new Module[0]));
39 }
40 }
41
42 public Boolean isAlreadyRegisteredIn(final ObjectMapper mapper, final Class<?> jackson2HalModuleClass) {
43 try {
44 final Boolean result;
45 final Method methodIsAlreadyRegisteredIn = jackson2HalModuleClass.getDeclaredMethod(
46 "isAlreadyRegisteredIn", ObjectMapper.class);
47 result = (Boolean) methodIsAlreadyRegisteredIn.invoke(null, mapper);
48 return result;
49 } catch (final ReflectiveOperationException | SecurityException | IllegalArgumentException ex) {
50 log.info("Jackson2HalModule config error", ex);
51 return FALSE;
52 }
53 }
54
55 public Optional<Module> jackson2HalModule() {
56 try {
57 final Optional<Class<?>> moduleClass = ClassUtils.forName(HalJackson2MapperCustomizerFactory.CLASS_JACKSON2_HAL_MODULE);
58 final Object jackson2HalModule;
59 if (moduleClass.isPresent()) {
60 jackson2HalModule = moduleClass.get().newInstance();
61 } else {
62 jackson2HalModule = null;
63 }
64 return Optional.ofNullable((Module) jackson2HalModule);
65 } catch (final ReflectiveOperationException ex) {
66 log.info("Jackson2HalModule config error", ex);
67 return Optional.empty();
68 }
69 }
70 }