package redis.clients.jedis.serializable; import com.dyuproject.protostuff.LinkedBuffer; import com.dyuproject.protostuff.ProtostuffIOUtil; import com.dyuproject.protostuff.Schema; import com.dyuproject.protostuff.runtime.RuntimeSchema; import java.util.concurrent.ConcurrentHashMap; /** * Created by yijunzhang on 14-4-10. */ public class ProtostuffSerializer { private static ConcurrentHashMap<Class<?>, Schema<?>> cachedSchema = new ConcurrentHashMap<Class<?>, Schema<?>>(); public <T> byte[] serialize(final T source) { VO<T> vo = new VO<T>(source); final LinkedBuffer buffer = LinkedBuffer.allocate(LinkedBuffer.DEFAULT_BUFFER_SIZE); try { final Schema<VO> schema = getSchema(VO.class); return serializeInternal(vo, schema, buffer); } catch (final Exception e) { throw new IllegalStateException(e.getMessage(), e); } finally { buffer.clear(); } } public <T> T deserialize(final byte[] bytes) { try { Schema<VO> schema = getSchema(VO.class); VO vo = deserializeInternal(bytes, schema.newMessage(), schema); if (vo != null && vo.getValue() != null) { return (T) vo.getValue(); } } catch (final Exception e) { throw new IllegalStateException(e.getMessage(), e); } return null; } private <T> byte[] serializeInternal(final T source, final Schema<T> schema, final LinkedBuffer buffer) { return ProtostuffIOUtil.toByteArray(source, schema, buffer); } private <T> T deserializeInternal(final byte[] bytes, final T result, final Schema<T> schema) { ProtostuffIOUtil.mergeFrom(bytes, result, schema); return result; } private static <T> Schema<T> getSchema(Class<T> clazz) { @SuppressWarnings("unchecked") Schema<T> schema = (Schema<T>) cachedSchema.get(clazz); if (schema == null) { schema = RuntimeSchema.createFrom(clazz); cachedSchema.put(clazz, schema); } return schema; } }