package com.feedly.cassandra.entity; import java.io.Serializable; import java.math.BigInteger; import java.nio.ByteBuffer; import java.util.Collections; import java.util.Date; import java.util.HashMap; import java.util.Map; import java.util.Map.Entry; import java.util.UUID; import me.prettyprint.cassandra.serializers.AbstractSerializer; import me.prettyprint.hector.api.Serializer; public class ByteIndicatorSerializer extends AbstractSerializer<Object> { public static final Map<Class<?>, Byte> INDICATOR_BYTES; public static final Map<Byte, Class<?>> INDICATOR_BYTES_REV; private static final ByteIndicatorSerializer _instance = new ByteIndicatorSerializer(); static { //these values cannot change! byte val = 0; Map<Class<?>, Byte> bytes = new HashMap<Class<?>, Byte>(); Map<Byte, Class<?>> bytesRev = new HashMap<Byte, Class<?>>(); bytes.put(byte[].class, val++); bytes.put(BigInteger.class, val++); bytes.put(Boolean.class, val++); bytes.put(Byte.class, val++); bytes.put(ByteBuffer.class, val++); bytes.put(Character.class, val++); bytes.put(Date.class, val++); bytes.put(Double.class, val++); bytes.put(Float.class, val++); bytes.put(Integer.class, val++); bytes.put(Long.class, val++); bytes.put(Short.class, val++); bytes.put(String.class, val++); bytes.put(UUID.class, val++); bytes.put(Serializable.class, val++); for(Entry<Class<?>, Byte> e : bytes.entrySet()) bytesRev.put(e.getValue(), e.getKey()); INDICATOR_BYTES = Collections.unmodifiableMap(bytes); INDICATOR_BYTES_REV = Collections.unmodifiableMap(bytesRev); } public static final ByteIndicatorSerializer get() { return _instance; } @SuppressWarnings({ "unchecked", "rawtypes" }) @Override public ByteBuffer toByteBuffer(Object obj) { if(obj == null) return null; Byte indicator = INDICATOR_BYTES.get(obj.getClass()); //what type is the value? if(indicator == null && obj instanceof Serializable) indicator = INDICATOR_BYTES.get(Serializable.class); if(indicator == null) throw new IllegalArgumentException(obj.getClass() + " not serializable by this class"); byte[] val = ((Serializer) EntityUtils.getSerializer(obj.getClass())).toBytes(obj); ByteBuffer buffer = ByteBuffer.allocate(val.length + 1); buffer.put(indicator); buffer.put(val); buffer.rewind(); return buffer; } @Override public Object fromByteBuffer(ByteBuffer byteBuffer) { if(byteBuffer == null || !byteBuffer.hasRemaining()) return null; Byte indicator = byteBuffer.get(); Class<?> clazz = INDICATOR_BYTES_REV.get(indicator); if(clazz == null) throw new IllegalArgumentException("invalid indicator byte " + indicator); return EntityUtils.getSerializer(clazz).fromByteBuffer(byteBuffer); } }