diff --git a/changelog/@unreleased/pr-2221.v2.yml b/changelog/@unreleased/pr-2221.v2.yml new file mode 100644 index 000000000..c3f5e9115 --- /dev/null +++ b/changelog/@unreleased/pr-2221.v2.yml @@ -0,0 +1,5 @@ +type: improvement +improvement: + description: Expose a TypeMarker factory to wrap an arbitrary Type + links: + - https://github.com/palantir/dialogue/pull/2221 diff --git a/dialogue-serde/src/main/java/com/palantir/conjure/java/dialogue/serde/ConjureBodySerDe.java b/dialogue-serde/src/main/java/com/palantir/conjure/java/dialogue/serde/ConjureBodySerDe.java index 90d7df8f1..b738b8529 100644 --- a/dialogue-serde/src/main/java/com/palantir/conjure/java/dialogue/serde/ConjureBodySerDe.java +++ b/dialogue-serde/src/main/java/com/palantir/conjure/java/dialogue/serde/ConjureBodySerDe.java @@ -40,6 +40,7 @@ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; +import java.lang.reflect.Type; import java.util.ArrayList; import java.util.Comparator; import java.util.List; @@ -56,8 +57,8 @@ final class ConjureBodySerDe implements BodySerDe { private final Deserializer<InputStream> binaryInputStreamDeserializer; private final Deserializer<Optional<InputStream>> optionalBinaryInputStreamDeserializer; private final Deserializer<Void> emptyBodyDeserializer; - private final LoadingCache<TypeMarker<?>, Serializer<?>> serializers; - private final LoadingCache<TypeMarker<?>, Deserializer<?>> deserializers; + private final LoadingCache<Type, Serializer<?>> serializers; + private final LoadingCache<Type, Deserializer<?>> deserializers; /** * Selects the first (based on input order) of the provided encodings that @@ -86,11 +87,11 @@ final class ConjureBodySerDe implements BodySerDe { this.emptyBodyDeserializer = new EmptyBodyDeserializer(errorDecoder); // Class unloading: Not supported, Jackson keeps strong references to the types // it sees: https://github.com/FasterXML/jackson-databind/issues/489 - this.serializers = - Caffeine.from(cacheSpec).build(token -> new EncodingSerializerRegistry<>(defaultEncoding, token)); + this.serializers = Caffeine.from(cacheSpec) + .build(type -> new EncodingSerializerRegistry<>(defaultEncoding, TypeMarker.of(type))); this.deserializers = Caffeine.from(cacheSpec) - .build(token -> new EncodingDeserializerRegistry<>( - encodingsSortedByWeight, errorDecoder, emptyContainerDeserializer, token)); + .build(type -> new EncodingDeserializerRegistry<>( + encodingsSortedByWeight, errorDecoder, emptyContainerDeserializer, TypeMarker.of(type))); } private static List<WeightedEncoding> decorateEncodings(List<WeightedEncoding> input) { @@ -112,13 +113,13 @@ private ImmutableList<Encoding> sortByWeight(List<WeightedEncoding> encodings) { @Override @SuppressWarnings("unchecked") public <T> Serializer<T> serializer(TypeMarker<T> token) { - return (Serializer<T>) serializers.get(token); + return (Serializer<T>) serializers.get(token.getType()); } @Override @SuppressWarnings("unchecked") public <T> Deserializer<T> deserializer(TypeMarker<T> token) { - return (Deserializer<T>) deserializers.get(token); + return (Deserializer<T>) deserializers.get(token.getType()); } @Override diff --git a/dialogue-target/src/main/java/com/palantir/dialogue/TypeMarker.java b/dialogue-target/src/main/java/com/palantir/dialogue/TypeMarker.java index ba6d3ccb0..a8a548997 100644 --- a/dialogue-target/src/main/java/com/palantir/dialogue/TypeMarker.java +++ b/dialogue-target/src/main/java/com/palantir/dialogue/TypeMarker.java @@ -16,6 +16,7 @@ package com.palantir.dialogue; +import com.palantir.logsafe.Preconditions; import com.palantir.logsafe.SafeArg; import com.palantir.logsafe.exceptions.SafeIllegalArgumentException; import java.lang.reflect.ParameterizedType; @@ -45,6 +46,10 @@ protected TypeMarker() { } } + private TypeMarker(Type type) { + this.type = Preconditions.checkNotNull(type, "Type is required"); + } + public final Type getType() { return type; } @@ -70,4 +75,15 @@ public final int hashCode() { public final String toString() { return "TypeMarker{type=" + type + '}'; } + + /** Create a new {@link TypeMarker} instance wrapping the provided {@link Type}. */ + public static TypeMarker<?> of(Type type) { + return new WrappingTypeMarker(type); + } + + private static final class WrappingTypeMarker extends TypeMarker<Object> { + private WrappingTypeMarker(Type type) { + super(type); + } + } }