View Javadoc
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  }