Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ Follow those simple steps:
dependencies {
implementation group: 'pl.allegro.tech', name: 'json-cache-jackson', version: '...'
// above module doesn't supply dependent libraries to avoid dependency pollution, so make sure you include them yourself
implementation group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '...'
implementation group: 'tools.jackson.core', name: 'jackson-databind', version: '...'
}
```

Expand Down
4 changes: 2 additions & 2 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ nexus-publish-plugin = "2.0.0"
test-logger = "4.0.0"

# core libs
jackson = "2.22.2"
jackson = "3.2.0"

# test libs
junit = "6.1.3"
Expand All @@ -19,7 +19,7 @@ test-logger = { id = "com.adarshr.test-logger", version.ref = "test-logger" }

[libraries]
# core libs
jackson-databind = { group = "com.fasterxml.jackson.core", name = "jackson-databind", version.ref = "jackson"}
jackson-databind = { group = "tools.jackson.core", name = "jackson-databind", version.ref = "jackson"}
# test libs
junit-dependencies = { group = "org.junit", name = "junit-bom", version.ref = "junit" }
junit-jupiter = { group = "org.junit.jupiter", name = "junit-jupiter" }
Expand Down
2 changes: 1 addition & 1 deletion json-cache-jackson/src/main/java/module-info.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
*/
module json.cache.jackson {
requires transitive json.cache.core;
requires transitive com.fasterxml.jackson.databind;
requires transitive tools.jackson.databind;

exports pl.allegro.tech.jsoncache.jackson;
exports pl.allegro.tech.jsoncache.jackson.keybuilder.strategy;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
package pl.allegro.tech.jsoncache.jackson;

import com.fasterxml.jackson.databind.BeanDescription;
import com.fasterxml.jackson.databind.DeserializationConfig;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.deser.BeanDeserializerModifier;
import tools.jackson.databind.BeanDescription;
import tools.jackson.databind.DeserializationConfig;
import tools.jackson.databind.JsonNode;
import tools.jackson.databind.ValueDeserializer;
import tools.jackson.databind.deser.ValueDeserializerModifier;
import pl.allegro.tech.jsoncache.CacheResolver;
import pl.allegro.tech.jsoncache.CacheableEntity;
import pl.allegro.tech.jsoncache.keybuilder.CacheKeyBuilderFactory;

/**
* Deserializer modifier used to wrap standard {@link com.fasterxml.jackson.databind.deser.BeanDeserializer POJO deserializer}
* Deserializer modifier used to wrap standard {@link ValueDeserializer POJO deserializer}
* and apply caching mechanism based on presence of {@link CacheableEntity} annotation on deserialized type.
*/
public class CacheApplyingDeserializerModifier extends BeanDeserializerModifier {
public class CacheApplyingDeserializerModifier extends ValueDeserializerModifier {

/**
* Key building factory.
Expand All @@ -36,7 +36,7 @@ public CacheApplyingDeserializerModifier(CacheKeyBuilderFactory cacheKeyBuilderF
}

/**
* Conditionally apply caching mechanism to default {@link JsonDeserializer deserializer} depending on the presence
* Conditionally apply caching mechanism to default {@link ValueDeserializer deserializer} depending on the presence
* of {@link CacheableEntity} annotation in metadata of class which instance should be constructed from the JSON payload.
*
* @param config deserialization config
Expand All @@ -47,13 +47,15 @@ public CacheApplyingDeserializerModifier(CacheKeyBuilderFactory cacheKeyBuilderF
* in runtime
*/
@Override
public JsonDeserializer<?> modifyDeserializer(DeserializationConfig config, BeanDescription beanDesc, JsonDeserializer<?> deserializer) {
public ValueDeserializer<?> modifyDeserializer(DeserializationConfig config,
BeanDescription.Supplier beanDesc,
ValueDeserializer<?> deserializer) {
CacheableEntity cacheableEntity = beanDesc.getClassAnnotations().get(CacheableEntity.class);
if (cacheableEntity == null) {
return deserializer;
}
return cacheKeyBuilderFactory.findCacheKeyBuilderFor(cacheableEntity, JsonNode.class)
.<JsonDeserializer<?>>map(cacheKeyBuilder -> new CacheSupportingDeserializer<>(
.<ValueDeserializer<?>>map(cacheKeyBuilder -> new CacheSupportingDeserializer<>(
deserializer,
cacheResolver.resolveCache(cacheableEntity.cacheName()),
cacheKeyBuilder
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,16 @@
package pl.allegro.tech.jsoncache.jackson;

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.ObjectCodec;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.deser.std.DelegatingDeserializer;
import tools.jackson.core.JacksonException;
import tools.jackson.core.JsonParser;
import tools.jackson.core.ObjectReadContext;
import tools.jackson.databind.DeserializationContext;
import tools.jackson.databind.JsonNode;
import tools.jackson.databind.ValueDeserializer;
import tools.jackson.databind.deser.std.DelegatingDeserializer;
import pl.allegro.tech.jsoncache.EntityCache;
import pl.allegro.tech.jsoncache.keybuilder.CacheKeyBuilder;
import pl.allegro.tech.jsoncache.keybuilder.KeyBuildingException;

import java.io.IOException;

/**
* Deserializer that wraps default deserializer and caches created instances in memory by key constructed using
* {@link CacheKeyBuilder key builder}. Key is extracted directly from plain {@link JsonNode} before actual
Expand All @@ -33,11 +32,11 @@ public class CacheSupportingDeserializer<K> extends DelegatingDeserializer {
/**
* Default constructor.
*
* @param originalDeserializer original {@link JsonDeserializer deserializer}
* @param originalDeserializer original {@link ValueDeserializer deserializer}
* @param cache {@link EntityCache cache}
* @param keyBuilder {@link CacheKeyBuilder key builder}
*/
public CacheSupportingDeserializer(JsonDeserializer<?> originalDeserializer,
public CacheSupportingDeserializer(ValueDeserializer<?> originalDeserializer,
EntityCache<K, Object> cache,
CacheKeyBuilder<K, JsonNode> keyBuilder) {
super(originalDeserializer);
Expand All @@ -46,7 +45,7 @@ public CacheSupportingDeserializer(JsonDeserializer<?> originalDeserializer,
}

@Override
protected JsonDeserializer<?> newDelegatingInstance(JsonDeserializer<?> newDelegatee) {
protected ValueDeserializer<?> newDelegatingInstance(ValueDeserializer<?> newDelegatee) {
return new CacheSupportingDeserializer<>(newDelegatee, cache, keyBuilder);
}

Expand All @@ -60,24 +59,24 @@ protected JsonDeserializer<?> newDelegatingInstance(JsonDeserializer<?> newDeleg
* @param ctxt Context that can be used to access information about
* this deserialization activity
* @return deserialized instance
* @throws IOException in case JSON cannot be properly parsed or deserialized
* @throws JacksonException in case JSON cannot be properly parsed or deserialized
*/
@Override
public Object deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
public Object deserialize(JsonParser p, DeserializationContext ctxt) throws JacksonException {
JsonNode parsedJson = ctxt.readTree(p);
try {
return cache.computeIfAbsent(
keyBuilder.buildKey(parsedJson),
key -> deserializeJson(parsedJson, p.getCodec(), ctxt)
key -> deserializeJson(parsedJson, p.objectReadContext(), ctxt)
);
} catch (KeyBuildingException ex) {
return deserializeJson(parsedJson, p.getCodec(), ctxt);
return deserializeJson(parsedJson, p.objectReadContext(), ctxt);
}
}

private Object deserializeJson(JsonNode parsedJson, ObjectCodec originalCodec, DeserializationContext ctxt)
throws IOException {
JsonParser p = parsedJson.traverse(originalCodec);
private Object deserializeJson(JsonNode parsedJson, ObjectReadContext originalReadContext, DeserializationContext ctxt)
throws JacksonException {
JsonParser p = parsedJson.traverse(originalReadContext);
if (p.currentToken() == null) {
p.nextToken();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
package pl.allegro.tech.jsoncache.jackson;

import com.fasterxml.jackson.core.Version;
import com.fasterxml.jackson.databind.Module;
import tools.jackson.core.Version;
import tools.jackson.databind.JacksonModule;

/**
* Jackson module that allows registration of {@link CacheApplyingDeserializerModifier deserializer modifier}.
*/
public class CachedDeserializationModule extends Module {
public class CachedDeserializationModule extends JacksonModule {

private static final String MODULE_NAME = "cached-deserialization";
private static final Version VERSION = new Version(1, 0, 0, null, "pl.allegro.tech", "json-cache-jackson");
Expand All @@ -33,8 +33,8 @@ public Version version() {
}

@Override
public void setupModule(SetupContext context) {
context.addBeanDeserializerModifier(cacheApplyingDeserializerModifier);
public void setupModule(JacksonModule.SetupContext context) {
context.addDeserializerModifier(cacheApplyingDeserializerModifier);
}

}
Original file line number Diff line number Diff line change
@@ -1,21 +1,19 @@
package pl.allegro.tech.jsoncache.jackson.keybuilder.strategy;

import com.fasterxml.jackson.databind.JsonNode;
import tools.jackson.databind.JsonNode;
import pl.allegro.tech.jsoncache.keybuilder.KeyPartMissingException;
import pl.allegro.tech.jsoncache.keybuilder.stategy.KeyComponentBasedStrategy;

import java.util.Optional;

/**
* Strategy for retrieving key parts directly from {@link JsonNode json nodes}.
*/
public class JsonComponentExtractingStrategy extends KeyComponentBasedStrategy<JsonNode> {

@Override
protected String extractKeyPart(JsonNode value, String component) throws KeyPartMissingException {
return Optional.ofNullable(value.get(component))
return value.optional(component)
.filter(JsonNode::isValueNode)
.map(JsonNode::asText)
.map(JsonNode::asString)
.orElseThrow(() -> new KeyPartMissingException(value, component));
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package pl.allegro.tech.jsoncache.jackson.keybuilder.strategy;


import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.JsonNodeFactory;
import tools.jackson.databind.JsonNode;
import tools.jackson.databind.node.JsonNodeFactory;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.function.Executable;
import pl.allegro.tech.jsoncache.CacheableEntity;
Expand Down