Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
Prev Previous commit
Add MessagePackFactory#setExtTypeCustomDesers
  • Loading branch information
komamitsu committed Jan 19, 2017
commit 473268ebbcf08f6824c0f41ffaf1a8e78b78e78d
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
//
// MessagePack for Java
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
package org.msgpack.jackson.dataformat;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;

import java.io.IOException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

public class ExtensionTypeCustomDeserializers
{
private final ObjectMapper objectMapper;
private Map<Byte, Deser> deserTable = new ConcurrentHashMap<Byte, Deser>();

public ExtensionTypeCustomDeserializers()
{
objectMapper = new ObjectMapper(new MessagePackFactory().setReuseResourceInParser(false));
}

public <T> void addTargetClass(byte type, final Class<T> klass)
{
deserTable.put(type, new Deser()
{
@Override
public Object deserialize(byte[] data)
throws IOException
{
return objectMapper.readValue(data, klass);
}
});
}

public void addTargetTypeReference(byte type, final TypeReference typeReference)
{
deserTable.put(type, new Deser()
{
@Override
public Object deserialize(byte[] data)
throws IOException
{
return objectMapper.readValue(data, typeReference);
}
});
}

public void addCustomDeser(byte type, final Deser deser)
{
deserTable.put(type, new Deser()
{
@Override
public Object deserialize(byte[] data)
throws IOException
{
return deser.deserialize(data);
}
});
}

public Deser getDeser(byte type)
{
return deserTable.get(type);
}

public void clearEntries()
{
deserTable.clear();
}

public interface Deser
{
Object deserialize(byte[] data)
throws IOException;
}
}
Original file line number Diff line number Diff line change
@@ -1,20 +1,13 @@
package org.msgpack.jackson.dataformat;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.deser.std.UntypedObjectDeserializer;

import java.io.IOException;
import java.util.Arrays;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

@JsonSerialize(using = MessagePackExtensionType.Serializer.class)
public class MessagePackExtensionType
Expand Down Expand Up @@ -79,83 +72,4 @@ public void serialize(MessagePackExtensionType value, JsonGenerator gen, Seriali
}
}
}

public interface Deser
{
Object deserialize(byte[] data)
throws IOException;
}

public static class TypeBasedDeserializer
extends UntypedObjectDeserializer.Vanilla
{
private final ObjectMapper objectMapper;
private Map<Byte, Deser> deserTable = new ConcurrentHashMap<Byte, Deser>();

public TypeBasedDeserializer()
{
MessagePackFactory messagePackFactory = new MessagePackFactory();
messagePackFactory.setReuseResourceInParser(false);
objectMapper = new ObjectMapper(messagePackFactory);
}

public <T> void addTargetClass(byte type, final Class<T> klass)
{
deserTable.put(type, new Deser() {
@Override
public Object deserialize(byte[] data)
throws IOException
{
return objectMapper.readValue(data, klass);
}
});
}

public void addTargetTypeReference(byte type, final TypeReference typeReference)
{
deserTable.put(type, new Deser() {
@Override
public Object deserialize(byte[] data)
throws IOException
{
return objectMapper.readValue(data, typeReference);
}
});
}

public void addCustomDeser(byte type, final Deser deser)
{
deserTable.put(type, new Deser() {
@Override
public Object deserialize(byte[] data)
throws IOException
{
return deser.deserialize(data);
}
});
}

public void clearEntries()
{
deserTable.clear();
}

@Override
public Object deserialize(JsonParser p, DeserializationContext ctxt)
throws IOException
{
Object obj = super.deserialize(p, ctxt);
if (! (obj instanceof MessagePackExtensionType)) {
return obj;
}

MessagePackExtensionType ext = (MessagePackExtensionType) obj;
Deser deser = deserTable.get(ext.getType());
if (deser == null) {
return obj;
}

return deser.deserialize(ext.getData());
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ public class MessagePackFactory
private final MessagePack.PackerConfig packerConfig;
private boolean reuseResourceInGenerator = true;
private boolean reuseResourceInParser = true;
private ExtensionTypeCustomDeserializers extTypeCustomDesers;

public MessagePackFactory()
{
Expand All @@ -50,14 +51,22 @@ public MessagePackFactory(MessagePack.PackerConfig packerConfig)
this.packerConfig = packerConfig;
}

public void setReuseResourceInGenerator(boolean reuseResourceInGenerator)
public MessagePackFactory setReuseResourceInGenerator(boolean reuseResourceInGenerator)
{
this.reuseResourceInGenerator = reuseResourceInGenerator;
return this;
}

public void setReuseResourceInParser(boolean reuseResourceInParser)
public MessagePackFactory setReuseResourceInParser(boolean reuseResourceInParser)
{
this.reuseResourceInParser = reuseResourceInParser;
return this;
}

public MessagePackFactory setExtTypeCustomDesers(ExtensionTypeCustomDeserializers extTypeCustomDesers)
{
this.extTypeCustomDesers = extTypeCustomDesers;
return this;
}

@Override
Expand Down Expand Up @@ -102,6 +111,9 @@ protected MessagePackParser _createParser(InputStream in, IOContext ctxt)
throws IOException
{
MessagePackParser parser = new MessagePackParser(ctxt, _parserFeatures, _objectCodec, in, reuseResourceInParser);
if (extTypeCustomDesers != null) {
parser.setExtensionTypeCustomDeserializers(extTypeCustomDesers);
}
return parser;
}

Expand All @@ -113,6 +125,9 @@ protected JsonParser _createParser(byte[] data, int offset, int len, IOContext c
data = Arrays.copyOfRange(data, offset, offset + len);
}
MessagePackParser parser = new MessagePackParser(ctxt, _parserFeatures, _objectCodec, data, reuseResourceInParser);
if (extTypeCustomDesers != null) {
parser.setExtensionTypeCustomDeserializers(extTypeCustomDesers);
}
return parser;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ public class MessagePackParser
private long tokenPosition;
private long currentPosition;
private final IOContext ioContext;
private ExtensionTypeCustomDeserializers extTypeCustomDesers;

private enum Type
{
Expand Down Expand Up @@ -191,6 +192,11 @@ private MessagePackParser(IOContext ctxt,
messageUnpackerHolder.set(new Tuple<Object, MessageUnpacker>(src, messageUnpacker));
}

public void setExtensionTypeCustomDeserializers(ExtensionTypeCustomDeserializers extTypeCustomDesers)
{
this.extTypeCustomDesers = extTypeCustomDesers;
}

@Override
public ObjectCodec getCodec()
{
Expand Down Expand Up @@ -551,6 +557,12 @@ public Object getEmbeddedObject()
case BYTES:
return bytesValue;
case EXT:
if (extTypeCustomDesers != null) {
ExtensionTypeCustomDeserializers.Deser deser = extTypeCustomDesers.getDeser(extensionTypeValue.getType());
if (deser != null) {
return deser.deserialize(extensionTypeValue.getData());
}
}
return extensionTypeValue;
default:
throw new IllegalStateException("Invalid type=" + type);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -678,7 +678,7 @@ public Object deserializeKey(String key, DeserializationContext ctxt)
}

@Test
public void typeBasedDeserialize()
public void extensionTypeCustomDeserializers()
throws IOException
{
ByteArrayOutputStream out = new ByteArrayOutputStream();
Expand Down Expand Up @@ -717,12 +717,10 @@ public void typeBasedDeserialize()
}
packer.close();

ObjectMapper objectMapper = new ObjectMapper(new MessagePackFactory());
MessagePackExtensionType.TypeBasedDeserializer typeBasedDeserializer
= new MessagePackExtensionType.TypeBasedDeserializer();
typeBasedDeserializer.addTargetClass((byte) 17, NestedListComplexPojo.class);
typeBasedDeserializer.addTargetTypeReference((byte) 99, new TypeReference<Map<String, Integer>>() {});
typeBasedDeserializer.addCustomDeser((byte) 31, new MessagePackExtensionType.Deser() {
ExtensionTypeCustomDeserializers extTypeCustomDesers = new ExtensionTypeCustomDeserializers();
extTypeCustomDesers.addTargetClass((byte) 17, NestedListComplexPojo.class);
extTypeCustomDesers.addTargetTypeReference((byte) 99, new TypeReference<Map<String, Integer>>() {});
extTypeCustomDesers.addCustomDeser((byte) 31, new ExtensionTypeCustomDeserializers.Deser() {
@Override
public Object deserialize(byte[] data)
throws IOException
Expand All @@ -734,8 +732,8 @@ public Object deserialize(byte[] data)
}
}
);
SimpleModule module = new SimpleModule("MyModule").addDeserializer(Object.class, typeBasedDeserializer);
objectMapper.registerModule(module);
ObjectMapper objectMapper =
new ObjectMapper(new MessagePackFactory().setExtTypeCustomDesers(extTypeCustomDesers));

List<Object> values = objectMapper.readValue(new ByteArrayInputStream(out.toByteArray()), new TypeReference<List<Object>>() {});
assertThat(values.size(), is(5));
Expand Down