From e8ba9baff7536fc4565719cbc130ef81995d15bb Mon Sep 17 00:00:00 2001 From: Thomas <> Date: Thu, 1 Feb 2024 13:46:53 +0100 Subject: feat(core): add Jackson Joda module Hint: Modules will be only loaded if it is available on classpath --- eaaf_core/pom.xml | 7 ++- .../eaaf/core/impl/utils/DefaultJsonMapper.java | 68 +++++++++++++++++++++- 2 files changed, 72 insertions(+), 3 deletions(-) (limited to 'eaaf_core') diff --git a/eaaf_core/pom.xml b/eaaf_core/pom.xml index 16184607..1ca6d90e 100644 --- a/eaaf_core/pom.xml +++ b/eaaf_core/pom.xml @@ -66,7 +66,12 @@ com.fasterxml.jackson.module jackson-module-parameter-names provided - + + + com.fasterxml.jackson.datatype + jackson-datatype-joda + provided + org.slf4j diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/utils/DefaultJsonMapper.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/utils/DefaultJsonMapper.java index 8303e860..92bf94d4 100644 --- a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/utils/DefaultJsonMapper.java +++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/utils/DefaultJsonMapper.java @@ -1,6 +1,8 @@ package at.gv.egiz.eaaf.core.impl.utils; import java.io.IOException; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; import com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility; import com.fasterxml.jackson.annotation.PropertyAccessor; @@ -9,10 +11,10 @@ import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.JavaType; import com.fasterxml.jackson.databind.JsonMappingException; +import com.fasterxml.jackson.databind.Module; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.SerializationFeature; import com.fasterxml.jackson.databind.type.TypeFactory; -import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; import at.gv.egiz.eaaf.core.exceptions.EaafJsonMapperException; import lombok.Getter; @@ -27,6 +29,11 @@ import lombok.extern.slf4j.Slf4j; @Slf4j public final class DefaultJsonMapper { + private static final String JAVA_TIME_MODULE_CLASS = "com.fasterxml.jackson.datatype.jsr310.JavaTimeModule"; + private static final String JAVA_TIME_MODULE_CONSTRUCTOR = "JavaTimeModule"; + private static final String JODA_TIME_MODULE_CLASS = "com.fasterxml.jackson.datatype.joda.JodaModule"; + private static final String JODA_TIME_MODULE_CONSTRUCTOR = "JodaModule"; + @Getter private static final ObjectMapper jsonMapper = new ObjectMapper(); @@ -39,7 +46,9 @@ public final class DefaultJsonMapper { jsonMapper.setVisibility(PropertyAccessor.GETTER, Visibility.PUBLIC_ONLY); jsonMapper.setVisibility(PropertyAccessor.IS_GETTER, Visibility.PUBLIC_ONLY); - jsonMapper.registerModule(new JavaTimeModule()); + registerModuleIfAvailable(JAVA_TIME_MODULE_CLASS, JAVA_TIME_MODULE_CONSTRUCTOR); + registerModuleIfAvailable(JODA_TIME_MODULE_CLASS, JODA_TIME_MODULE_CONSTRUCTOR); + jsonMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false); } @@ -101,6 +110,61 @@ public final class DefaultJsonMapper { throw new EaafJsonMapperException(e.getMessage(), e); } + } + + private static void registerModuleIfAvailable(String fullModuleClasspath, String constructorName) { + Module module = checkAndLoadModule(fullModuleClasspath, constructorName); + if (module != null) { + jsonMapper.registerModule(module); + log.info("Register Jackson module: {}", module.getModuleName()); + + } else { + log.debug("Skipping Jackson module not on classpath: {}", fullModuleClasspath); + + } + } + + private static Module checkAndLoadModule(String fullModuleClasspath, String constructorName) { + Class clazz = getModuleClass(fullModuleClasspath); + if (clazz != null) { + return getModuleInstance(clazz, constructorName); + } + + return null; + } + + private static Module getModuleInstance(Class clazz, String constructorName) { + try { + final Method constructor = clazz.getMethod(constructorName, new Class[] {}); + if (constructor != null) { + log.trace("Found method: {} for class:{}. Creating instanze .... ", + constructorName, clazz.getName()); + final Object rawModule = constructor.invoke(clazz); + return rawModule instanceof Module ? (Module) rawModule : null; + } else { + log.warn("Find module:{}, but Constructor:{} looks wrong!", clazz.getName(), constructorName); + + } + + } catch (NoSuchMethodException | SecurityException | IllegalAccessException + | IllegalArgumentException | InvocationTargetException e) { + log.debug("Can not create instanze of Jackson module: {}. Reason: {}", clazz.getName(), e.getMessage()); + log.trace("Detailed error", e); + + } + return null; + + } + + private static Class getModuleClass(String fullClassName) { + try { + return Class.forName(fullClassName); + + } catch (final ClassNotFoundException e1) { + log.debug("No {} implemenation in ClassPath. Jackson module will not be available", fullClassName); + return null; + + } } } -- cgit v1.2.3