-
-
Save anonymous/dabd7fa2852a51a6d445 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* A utility serializer for data to be backwards compatible with Pelops. Use {@link AnnotatedCompositeSerializer} for all new daos. | |
* Of course, a closer look to the implementation of the AbstractCompositeSerializerPelopsCompatible reveals it is very error prone as it doesn't store | |
* object sizes, so, for example, a Composite key with two String keys will not be able to be deserialized. | |
* @param <T> | |
*/ | |
public class AbstractCompositeSerializerPelopsCompatible<T> extends AnnotatedCompositeSerializer<T> { | |
private static final Integer READ_THE_REST = -1; | |
private final List<ComponentSerializer<?>> components; | |
private final Class<T> clazz; | |
public AbstractCompositeSerializerPelopsCompatible(Class<T> clazz) { | |
super(clazz); | |
this.clazz = clazz; | |
this.components = new ArrayList<ComponentSerializer<?>>(); | |
for (Field field : ReflUtils.getAllDeclaredFields(clazz, true)) { | |
Component annotation = field.getAnnotation(Component.class); | |
if (annotation != null) { | |
Serializer s = SerializerTypeInferer.getSerializer(field.getType()); | |
components.add(makeComponent(field, s, annotation.ordinal())); | |
} | |
} | |
Collections.sort(this.components); | |
} | |
@Override | |
public ByteBuffer toByteBuffer(T obj) { | |
int totalSize = 0; | |
List<ByteBuffer> buffList = new ArrayList<ByteBuffer>(components.size()); | |
for (ComponentSerializer<?> serializer : components) { | |
try { | |
// First, serialize the ByteBuffer for this component | |
ByteBuffer cb = serializer.serialize(obj); | |
if (cb == null) { | |
cb = ByteBuffer.allocate(0); | |
} | |
totalSize += cb.capacity(); | |
buffList.add(cb); | |
} catch (Exception ex) { | |
throw new RuntimeException("Could not convert obj to bytebuffer", ex); | |
} | |
} | |
ByteBuffer bb = ByteBuffer.allocate(totalSize); | |
for (ByteBuffer buff : buffList) { | |
bb.put(buff); | |
} | |
bb.flip(); | |
return bb; | |
} | |
@Override | |
public T fromByteBuffer(ByteBuffer byteBuffer) { | |
byteBuffer = byteBuffer.duplicate(); | |
try { | |
T obj = createContents(clazz); | |
for (ComponentSerializer<?> serializer : components) { | |
int bytesToRead = getByteSizeOf(serializer.getField().getType()); | |
if (READ_THE_REST.equals(bytesToRead)) { | |
bytesToRead = byteBuffer.remaining(); | |
} | |
ByteBuffer data = getBytes(byteBuffer, bytesToRead); | |
if (data != null) { | |
serializer.deserialize(obj, data); | |
} else { | |
throw new RuntimeException("Missing component data in composite type"); | |
} | |
} | |
return obj; | |
} catch (Exception e) { | |
throw new RuntimeException(e); | |
} | |
} | |
private static int getByteSizeOf(final Class<?> clazz) { | |
Class<?> classToCheck = clazz; | |
if (clazz.isPrimitive()) { | |
classToCheck = ClassUtils.primitiveToWrapper(clazz); | |
} | |
if (classToCheck.equals(Integer.class)) { | |
return Integer.SIZE / Byte.SIZE; | |
} else if (classToCheck.equals(Long.class)) { | |
return Long.SIZE / Byte.SIZE; | |
} else if (classToCheck.equals(UUID.class)) { | |
return (Long.SIZE + Long.SIZE) / Byte.SIZE; | |
} else if (classToCheck.equals(Boolean.class)) { | |
return 1; | |
} else if (classToCheck.equals(String.class)) { | |
return READ_THE_REST; | |
} else { | |
throw new RuntimeException("Unsupported conversion type " + clazz); | |
} | |
} | |
private T createContents(Class<T> clazz) throws InstantiationException, IllegalAccessException { | |
return clazz.newInstance(); | |
} | |
private static <P> ComponentSerializer<P> makeComponent(Field field, Serializer<P> serializer, int ordinal) { | |
return new ComponentSerializer<P>(field, serializer, ordinal); | |
} | |
private static int getShortLength(ByteBuffer bb) { | |
int length = (bb.get() & 0xFF) << 8; | |
return length | (bb.get() & 0xFF); | |
} | |
private static ByteBuffer getBytes(ByteBuffer bb, int length) { | |
ByteBuffer copy = bb.duplicate(); | |
copy.limit(copy.position() + length); | |
bb.position(bb.position() + length); | |
return copy; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment