package com.dianping.pigeon.remoting.common.codec.protostuff; import java.io.InputStream; import java.io.OutputStream; import java.util.concurrent.ConcurrentHashMap; import org.objenesis.Objenesis; import org.objenesis.ObjenesisStd; import com.dianping.pigeon.remoting.common.codec.AbstractSerializer; import com.dianping.pigeon.remoting.common.exception.SerializationException; import com.dianping.pigeon.remoting.common.util.InvocationUtils; import io.protostuff.LinkedBuffer; import io.protostuff.ProtostuffIOUtil; import io.protostuff.Schema; import io.protostuff.runtime.RuntimeSchema; public class ProtostuffSerializer extends AbstractSerializer { private static ConcurrentHashMap<Class<?>, Schema<?>> cachedSchema = new ConcurrentHashMap<Class<?>, Schema<?>>(); private static Objenesis objenesis = new ObjenesisStd(true); public ProtostuffSerializer() { } private static <T> Schema<T> getSchema(Class<T> cls) { Schema<T> schema = (Schema<T>) cachedSchema.get(cls); if (schema == null) { schema = RuntimeSchema.createFrom(cls); if (schema != null) { cachedSchema.putIfAbsent(cls, schema); } } return schema; } public Object deserializeObject(InputStream is, Class<?> type) throws SerializationException { try { Object message = objenesis.newInstance(type); Schema schema = getSchema(type); ProtostuffIOUtil.mergeFrom(is, message, schema); return message; } catch (Throwable e) { throw new SerializationException(e.getMessage(), e); } } @Override public Object deserializeRequest(InputStream is) throws SerializationException { return deserializeObject(is, InvocationUtils.getRequestClass()); } @Override public void serializeRequest(OutputStream os, Object obj) throws SerializationException { LinkedBuffer buffer = LinkedBuffer.allocate(1024); try { Schema schema = getSchema(obj.getClass()); os.write(ProtostuffIOUtil.toByteArray(obj, schema, buffer)); } catch (Throwable e) { throw new SerializationException(e.getMessage(), e); } finally { buffer.clear(); } } @Override public Object deserializeResponse(InputStream is) throws SerializationException { return deserializeObject(is, InvocationUtils.getResponseClass()); } @Override public void serializeResponse(OutputStream os, Object obj) throws SerializationException { serializeRequest(os, obj); } }