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
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
Expand Up @@ -7,6 +7,7 @@
import com.fasterxml.jackson.databind.annotation.JsonSerialize;

import java.io.IOException;
import java.util.Arrays;

@JsonSerialize(using = MessagePackExtensionType.Serializer.class)
public class MessagePackExtensionType
Expand All @@ -30,6 +31,32 @@ public byte[] getData()
return data;
}

@Override
public boolean equals(Object o)
{
if (this == o) {
return true;
}
if (!(o instanceof MessagePackExtensionType)) {
return false;
}

MessagePackExtensionType that = (MessagePackExtensionType) o;

if (type != that.type) {
return false;
}
return Arrays.equals(data, that.data);
}

@Override
public int hashCode()
{
int result = (int) type;
result = 31 * result + Arrays.hashCode(data);
return result;
}

public static class Serializer extends JsonSerializer<MessagePackExtensionType>
{
@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ public class MessagePackFactory

private final MessagePack.PackerConfig packerConfig;
private boolean reuseResourceInGenerator = true;
private boolean reuseResourceInParser = true;
private ExtensionTypeCustomDeserializers extTypeCustomDesers;

public MessagePackFactory()
{
Expand All @@ -49,9 +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 MessagePackFactory setReuseResourceInParser(boolean reuseResourceInParser)
{
this.reuseResourceInParser = reuseResourceInParser;
return this;
}

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

@Override
Expand Down Expand Up @@ -95,7 +110,10 @@ public JsonParser createParser(InputStream in)
protected MessagePackParser _createParser(InputStream in, IOContext ctxt)
throws IOException
{
MessagePackParser parser = new MessagePackParser(ctxt, _parserFeatures, _objectCodec, in);
MessagePackParser parser = new MessagePackParser(ctxt, _parserFeatures, _objectCodec, in, reuseResourceInParser);
if (extTypeCustomDesers != null) {
parser.setExtensionTypeCustomDeserializers(extTypeCustomDesers);
}
return parser;
}

Expand All @@ -106,7 +124,10 @@ protected JsonParser _createParser(byte[] data, int offset, int len, IOContext c
if (offset != 0 || len != data.length) {
data = Arrays.copyOfRange(data, offset, offset + len);
}
MessagePackParser parser = new MessagePackParser(ctxt, _parserFeatures, _objectCodec, data);
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 @@ -49,6 +49,7 @@ public class MessagePackParser
{
private static final ThreadLocal<Tuple<Object, MessageUnpacker>> messageUnpackerHolder =
new ThreadLocal<Tuple<Object, MessageUnpacker>>();
private final MessageUnpacker messageUnpacker;

private static final BigInteger LONG_MIN = BigInteger.valueOf((long) Long.MIN_VALUE);
private static final BigInteger LONG_MAX = BigInteger.valueOf((long) Long.MAX_VALUE);
Expand All @@ -61,6 +62,7 @@ public class MessagePackParser
private long tokenPosition;
private long currentPosition;
private final IOContext ioContext;
private ExtensionTypeCustomDeserializers extTypeCustomDesers;

private enum Type
{
Expand All @@ -74,6 +76,7 @@ private enum Type
private String stringValue;
private BigInteger biValue;
private MessagePackExtensionType extensionTypeValue;
private boolean reuseResourceInParser;

private abstract static class StackItem
{
Expand Down Expand Up @@ -116,16 +119,43 @@ private static class StackItemForArray
public MessagePackParser(IOContext ctxt, int features, ObjectCodec objectCodec, InputStream in)
throws IOException
{
this(ctxt, features, new InputStreamBufferInput(in), objectCodec, in);
this(ctxt, features, objectCodec, in, true);
}

public MessagePackParser(
IOContext ctxt,
int features,
ObjectCodec objectCodec,
InputStream in,
boolean reuseResourceInParser)
throws IOException
{
this(ctxt, features, new InputStreamBufferInput(in), objectCodec, in, reuseResourceInParser);
}

public MessagePackParser(IOContext ctxt, int features, ObjectCodec objectCodec, byte[] bytes)
throws IOException
{
this(ctxt, features, new ArrayBufferInput(bytes), objectCodec, bytes);
this(ctxt, features, objectCodec, bytes, true);
}

private MessagePackParser(IOContext ctxt, int features, MessageBufferInput input, ObjectCodec objectCodec, Object src)
public MessagePackParser(
IOContext ctxt,
int features,
ObjectCodec objectCodec,
byte[] bytes,
boolean reuseResourceInParser)
throws IOException
{
this(ctxt, features, new ArrayBufferInput(bytes), objectCodec, bytes, reuseResourceInParser);
}

private MessagePackParser(IOContext ctxt,
int features,
MessageBufferInput input,
ObjectCodec objectCodec,
Object src,
boolean reuseResourceInParser)
throws IOException
{
super(features);
Expand All @@ -135,6 +165,14 @@ private MessagePackParser(IOContext ctxt, int features, MessageBufferInput input
DupDetector dups = Feature.STRICT_DUPLICATE_DETECTION.enabledIn(features)
? DupDetector.rootDetector(this) : null;
parsingContext = JsonReadContext.createRootContext(dups);
this.reuseResourceInParser = reuseResourceInParser;
if (!reuseResourceInParser) {
this.messageUnpacker = MessagePack.newDefaultUnpacker(input);
return;
}
else {
this.messageUnpacker = null;
}

MessageUnpacker messageUnpacker;
Tuple<Object, MessageUnpacker> messageUnpackerTuple = messageUnpackerHolder.get();
Expand All @@ -154,6 +192,11 @@ private MessagePackParser(IOContext ctxt, int features, MessageBufferInput input
messageUnpackerHolder.set(new Tuple<Object, MessageUnpacker>(src, messageUnpacker));
}

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

@Override
public ObjectCodec getCodec()
{
Expand Down Expand Up @@ -514,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 Expand Up @@ -607,6 +656,10 @@ public String getCurrentName()

private MessageUnpacker getMessageUnpacker()
{
if (!reuseResourceInParser) {
return this.messageUnpacker;
}

Tuple<Object, MessageUnpacker> messageUnpackerTuple = messageUnpackerHolder.get();
if (messageUnpackerTuple == null) {
throw new IllegalStateException("messageUnpacker is null");
Expand Down
Loading