-
Notifications
You must be signed in to change notification settings - Fork 57
[Guava] Allow Cache serialization
#112
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
guava/src/main/java/com/fasterxml/jackson/datatype/guava/ser/CacheSerializer.java
Show resolved
Hide resolved
guava/src/main/java/com/fasterxml/jackson/datatype/guava/ser/CacheSerializer.java
Outdated
Show resolved
Hide resolved
| continue; | ||
| } | ||
| gen.writeFieldName(key.toString()); | ||
| provider.defaultSerializeValue(value, gen); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This won't support polymorphism and is not as efficient as if serializer was fetched eagerly (like regular Maps will do, if possible; or if not possible, retain (possibly generic) element JavaType) -- but for a minimal implementation it's a clear improvement so that's fine.
guava/src/main/java/com/fasterxml/jackson/datatype/guava/ser/CacheSerializer.java
Outdated
Show resolved
Hide resolved
guava/src/main/java/com/fasterxml/jackson/datatype/guava/ser/CacheSerializer.java
Outdated
Show resolved
Hide resolved
|
Looks good so far. You may want to look at standard I think what I would want to see is at least extracting and passing Now that wrote above, though, I realize that this is not as trivial as thought because But! Have a look at I am ok with not necessarily implementing everything this allows, but at least get type information so handling may be improved. LMK if you need help here, type refinements are pretty advanced functionality. |
Thank you for your detailed feedback on the PR 🙏🏼 I will work on it one by one and get back soon as I can~ |
| Set<String> ignored = (ignorals == null) ? null : ignorals.getIgnored(); | ||
| return new CacheSerializer(type, beanDesc, | ||
| keySerializer, elementTypeSerializer, elementValueSerializer, ignored, filterId); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Identical to that of MultimapSerializer right above.
| import java.util.ArrayList; | ||
| import java.util.List; | ||
|
|
||
| public class CacheSerializationTest extends ModuleTestBase { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have collected and converted most of the tests related to MultiMap for Cache. After implementing the deserialization part, we can further expand the range of tests. For now, we have covered the basic functionality, including:
- Polymorphic type handling
JsonIncludebehavior- Key ordering
Please let me know if there are any additional test cases that should be included! 🙏🏼🙏🏼
| */ | ||
| public class CacheSerializer | ||
| extends ContainerSerializer<Cache<?, ?>> | ||
| implements ContextualSerializer |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since we get Map<?, ?> as the snapshot value of current Cache. I thought it would make sense to use the majority of "battle-hardend" implementations from MultimapSerializer class.
I will write notes on which part here in CacheSerializer is different from MultimapSerializer.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That sounds like a good idea to me.
| */ | ||
|
|
||
| @Override | ||
| public JsonSerializer<?> createContextual(SerializerProvider provider, BeanProperty property) throws JsonMappingException { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This whole method is identical to
Line 144 in ed6416d
| public JsonSerializer<?> createContextual(SerializerProvider provider, |
| // Second, serialize value | ||
| Object vv = entry.getValue(); | ||
| // is this even possible? | ||
| if (vv == null) { | ||
| provider.defaultSerializeNull(gen); | ||
| continue; | ||
| } | ||
| // serialize value | ||
| JsonSerializer<Object> valueSer = _valueSerializer; | ||
| if (valueSer == null) { | ||
| Class<?> cc = vv.getClass(); | ||
| valueSer = serializers.serializerFor(cc); | ||
| if (valueSer == null) { | ||
| valueSer = _findAndAddDynamic(serializers, cc, provider); | ||
| serializers = _dynamicValueSerializers; | ||
| } | ||
| } | ||
| if (_valueTypeSerializer == null) { | ||
| valueSer.serialize(vv, gen, provider); | ||
| } else { | ||
| valueSer.serializeWithType(vv, gen, provider, _valueTypeSerializer); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is no for-loop here unlike Multimap where value is a List ...
Line 328 in ed6416d
| for (Object vv : entry.getValue()) { |
| if ((ignored != null) && ignored.contains(key)) { | ||
| continue; | ||
| } | ||
| Object value = entry.getValue(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This serializeFilteredFields(Map<?, ?>, JsonGenerator, SerializerProvider)method is almost identical to that of MultimapSerializer except current line --no collection, just plain object.
Line 364 in ed6416d
| Collection<?> value = entry.getValue(); |
| */ | ||
|
|
||
| @Override | ||
| public void acceptJsonFormatVisitor(JsonFormatVisitorWrapper visitor, JavaType typeHint) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This method is identical to that of MultimapSerializer
| _dynamicValueSerializers = result.map; | ||
| } | ||
| return result.serializer; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This method is identical to that of MultimapSerializer
| _dynamicValueSerializers = result.map; | ||
| } | ||
| return result.serializer; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This method is identical to that of MultimapSerializer
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also used by many databind-provided serializers.
| provider.reportMappingProblem("Failed to sort Multimap entries due to `NullPointerException`: `null` key?"); | ||
| return null; | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since we are dealing with the standard JDK Map type (unlike Multimap), it seems appropriate to implement full ordering as in MapSerializer._orderEntries.
However, the fact that "Cache itself does not support null keys" makes me think that using MapSerializer might be an overkill from others' perspectives. Therefore, I figured like to hear others' opinions before proceeding 🥹
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah no need to support nulls (i.e. can operate without concern there).
Guava is notoriously null-antagonistic library :)
guava/src/main/java/com/fasterxml/jackson/datatype/guava/ser/CacheSerializer.java
Show resolved
Hide resolved
|
Looks good @JooHyukKim. Is this ready to be merged from your end? (just want to make sure I won't merge too early). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
Yes, it is ~ 🙆🏽♂️🙆🏽♂️ |
|
@cowtowncoder Thank your details reviews as always 👍🏼👍🏼 One question tho, is it reasonable to move on to implementing CacheDeserializer? Or you might have some plan to write some set up code like you did with serializer. |
|
@JooHyukKim I'd guess users would want a deserializer too, yes, so +1 for that. I don't think "empty" implementation would be useful here. |
relates to #90. "Miminal" implementation of
Cacheserialization.