Skip to content

Commit 136f32b

Browse files
committed
Support ext type as map-key
1 parent 5c2be3a commit 136f32b

File tree

2 files changed

+127
-8
lines changed

2 files changed

+127
-8
lines changed

msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackParser.java

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -341,7 +341,13 @@ public JsonToken nextToken()
341341
type = Type.EXT;
342342
ExtensionTypeHeader header = messageUnpacker.unpackExtensionTypeHeader();
343343
extensionTypeValue = new MessagePackExtensionType(header.getType(), messageUnpacker.readPayload(header.getLength()));
344-
nextToken = JsonToken.VALUE_EMBEDDED_OBJECT;
344+
if (parsingContext.inObject() && _currToken != JsonToken.FIELD_NAME) {
345+
parsingContext.setCurrentName(getExtensionTypeValue().toString());
346+
nextToken = JsonToken.FIELD_NAME;
347+
}
348+
else {
349+
nextToken = JsonToken.VALUE_EMBEDDED_OBJECT;
350+
}
345351
break;
346352
default:
347353
throw new IllegalStateException("Shouldn't reach here");
@@ -563,6 +569,18 @@ public BigDecimal getDecimalValue()
563569
}
564570
}
565571

572+
private Object getExtensionTypeValue()
573+
throws IOException
574+
{
575+
if (extTypeCustomDesers != null) {
576+
ExtensionTypeCustomDeserializers.Deser deser = extTypeCustomDesers.getDeser(extensionTypeValue.getType());
577+
if (deser != null) {
578+
return deser.deserialize(extensionTypeValue.getData());
579+
}
580+
}
581+
return extensionTypeValue;
582+
}
583+
566584
@Override
567585
public Object getEmbeddedObject()
568586
throws IOException, JsonParseException
@@ -571,13 +589,7 @@ public Object getEmbeddedObject()
571589
case BYTES:
572590
return bytesValue;
573591
case EXT:
574-
if (extTypeCustomDesers != null) {
575-
ExtensionTypeCustomDeserializers.Deser deser = extTypeCustomDesers.getDeser(extensionTypeValue.getType());
576-
if (deser != null) {
577-
return deser.deserialize(extensionTypeValue.getData());
578-
}
579-
}
580-
return extensionTypeValue;
592+
return getExtensionTypeValue();
581593
default:
582594
throw new IllegalStateException("Invalid type=" + type);
583595
}

msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackParserTest.java

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,20 +15,27 @@
1515
//
1616
package org.msgpack.jackson.dataformat;
1717

18+
import com.fasterxml.jackson.core.JsonGenerator;
1819
import com.fasterxml.jackson.core.JsonParser;
1920
import com.fasterxml.jackson.core.JsonProcessingException;
2021
import com.fasterxml.jackson.core.JsonToken;
2122
import com.fasterxml.jackson.core.io.JsonEOFException;
2223
import com.fasterxml.jackson.core.type.TypeReference;
2324
import com.fasterxml.jackson.databind.DeserializationContext;
2425
import com.fasterxml.jackson.databind.DeserializationFeature;
26+
import com.fasterxml.jackson.databind.JsonDeserializer;
2527
import com.fasterxml.jackson.databind.JsonMappingException;
2628
import com.fasterxml.jackson.databind.KeyDeserializer;
2729
import com.fasterxml.jackson.databind.ObjectMapper;
30+
import com.fasterxml.jackson.databind.SerializerProvider;
2831
import com.fasterxml.jackson.databind.module.SimpleModule;
32+
import com.fasterxml.jackson.databind.ser.std.StdSerializer;
2933
import org.junit.Test;
3034
import org.msgpack.core.MessagePack;
3135
import org.msgpack.core.MessagePacker;
36+
import org.msgpack.value.ExtensionValue;
37+
import org.msgpack.value.MapValue;
38+
import org.msgpack.value.ValueFactory;
3239

3340
import java.io.ByteArrayInputStream;
3441
import java.io.ByteArrayOutputStream;
@@ -44,6 +51,7 @@
4451
import java.util.HashMap;
4552
import java.util.List;
4653
import java.util.Map;
54+
import java.util.UUID;
4755

4856
import static org.hamcrest.MatcherAssert.assertThat;
4957
import static org.hamcrest.core.Is.is;
@@ -775,6 +783,105 @@ public Object deserialize(byte[] data)
775783
assertThat((String) values.get(4), is("Java"));
776784
}
777785

786+
787+
static class UUIDSerializer
788+
extends StdSerializer<UUID>
789+
{
790+
private final byte code;
791+
792+
UUIDSerializer(byte code)
793+
{
794+
super(UUID.class);
795+
this.code = code;
796+
}
797+
798+
public void serialize(UUID value, JsonGenerator jsonGenerator, SerializerProvider provider)
799+
throws IOException
800+
{
801+
if (jsonGenerator instanceof MessagePackGenerator) {
802+
MessagePackGenerator messagePackGenerator = (MessagePackGenerator) jsonGenerator;
803+
messagePackGenerator.writeExtensionType(new MessagePackExtensionType(code, toBytes(value)));
804+
} else {
805+
throw new RuntimeException("Something went wrong with the serialization");
806+
}
807+
}
808+
809+
@SuppressWarnings("WeakerAccess")
810+
static byte[] toBytes(UUID value)
811+
{
812+
return value.toString().getBytes();
813+
}
814+
815+
static UUID fromBytes(byte[] value)
816+
{
817+
return UUID.fromString(new String(value));
818+
}
819+
}
820+
821+
@Test
822+
public void extensionTypeInMap()
823+
throws IOException
824+
{
825+
byte uuidTypeCode = 42;
826+
827+
ExtensionTypeCustomDeserializers extTypeCustomDesers = new ExtensionTypeCustomDeserializers();
828+
extTypeCustomDesers.addCustomDeser(uuidTypeCode, new ExtensionTypeCustomDeserializers.Deser()
829+
{
830+
@Override
831+
public Object deserialize(byte[] value1)
832+
throws IOException
833+
{
834+
return UUIDSerializer.fromBytes(value1);
835+
}
836+
});
837+
838+
ObjectMapper objectMapper = new ObjectMapper(
839+
new MessagePackFactory().setExtTypeCustomDesers(extTypeCustomDesers));
840+
841+
SimpleModule simpleModule = new SimpleModule();
842+
simpleModule.addDeserializer(UUID.class,
843+
new JsonDeserializer<UUID>()
844+
{
845+
@Override
846+
public UUID deserialize(JsonParser p, DeserializationContext ctxt)
847+
throws IOException, JsonProcessingException
848+
{
849+
return UUID.fromString(p.readValueAs(String.class));
850+
}
851+
});
852+
objectMapper.registerModule(simpleModule);
853+
854+
// Prepare serialized data
855+
Map<UUID, UUID> originalMap = new HashMap<>();
856+
byte[] serializedData;
857+
{
858+
ValueFactory.MapBuilder mapBuilder = ValueFactory.newMapBuilder();
859+
for (int i = 0; i < 4; i++) {
860+
UUID uuidKey = UUID.randomUUID();
861+
UUID uuidValue = UUID.randomUUID();
862+
ExtensionValue k = ValueFactory.newExtension(uuidTypeCode, uuidKey.toString().getBytes());
863+
ExtensionValue v = ValueFactory.newExtension(uuidTypeCode, uuidValue.toString().getBytes());
864+
mapBuilder.put(k, v);
865+
originalMap.put(uuidKey, uuidValue);
866+
}
867+
ByteArrayOutputStream output = new ByteArrayOutputStream();
868+
MessagePacker packer = MessagePack.newDefaultPacker(output);
869+
MapValue mapValue = mapBuilder.build();
870+
mapValue.writeTo(packer);
871+
packer.close();
872+
873+
serializedData = output.toByteArray();
874+
}
875+
876+
Map<UUID, UUID> deserializedMap = objectMapper.readValue(serializedData,
877+
new TypeReference<Map<UUID, UUID>>() {});
878+
879+
assertEquals(originalMap.size(), deserializedMap.size());
880+
for (Map.Entry<UUID, UUID> entry : originalMap.entrySet()) {
881+
assertEquals(entry.getValue(), deserializedMap.get(entry.getKey()));
882+
}
883+
}
884+
778885
@Test
779886
public void parserShouldReadStrAsBin()
780887
throws IOException

0 commit comments

Comments
 (0)