package org.infinispan.server.memcached;
import java.io.IOException;
import org.infinispan.commons.CacheException;
import org.infinispan.commons.marshall.JavaSerializationMarshaller;
import org.infinispan.commons.marshall.Marshaller;
import org.infinispan.compat.TypeConverter;
import org.infinispan.context.Flag;
/**
* Type converter that transforms Memcached data so that it can be accessible
* via other endpoints.
*
* @author Galder ZamarreƱo
* @since 5.3
*/
public class MemcachedTypeConverter implements TypeConverter<String, Object, String, Object> {
// Default marshaller needed in case no custom marshaller is set
// (e.g. not using Spy Memcached client). This is because in compatibility
// mode, data is stored unmarshalled, so when returning data to Memcached
// clients, it needs to be marshalled to fulfill the Memcached protocol.
//
// A generic marshaller using Java Serialization is used by default, since
// that's the safest bet to support alternative Java Memcached clients
private Marshaller marshaller = new JavaSerializationMarshaller();
@Override
public String boxKey(String key) {
return key;
}
@Override
public Object boxValue(Object value) {
return unmarshall(value);
}
@Override
public String unboxKey(String target) {
return target;
}
@Override
public Object unboxValue(Object target) {
return marshall(target);
}
@Override
public boolean supportsInvocation(Flag flag) {
return flag == Flag.OPERATION_MEMCACHED;
}
@Override
public void setMarshaller(Marshaller marshaller) {
this.marshaller = marshaller;
}
private Object unmarshall(Object source) {
if (source instanceof byte[]) {
try {
return marshaller.objectFromByteBuffer((byte[]) source);
} catch (IOException | ClassNotFoundException e) {
throw new CacheException(e);
}
}
return source;
}
private byte[] marshall(Object source) {
if (source != null) {
try {
return marshaller.objectToByteBuffer(source);
} catch (IOException | InterruptedException e) {
throw new CacheException(e);
}
}
return null;
}
}