Created
          July 14, 2016 12:25 
        
      - 
      
- 
        Save jackeylu/3fa72264ca7de02f7030d0ed7b98a3e4 to your computer and use it in GitHub Desktop. 
Revisions
- 
        jackeylu created this gist Jul 14, 2016 .There are no files selected for viewingThis file contains hidden or 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 charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,34 @@ package example.protostuff; /** * wrapper is needed for interface and abstract modifier * Created by jackeylv on 2016/7/14. */ public class ClassWrapper { private Object wrappedValue; public ClassWrapper(){ wrappedValue = null; } public Object getValue() { return wrappedValue; } public void setValue(Object value) { this.wrappedValue = value; } // public Class getRealClass(){ // if (null == value) // return ClassWrapper.class; // // Class clz = value.getClass(); // if (clz.isInterface() // || Modifier.isAbstract(clz.getModifiers())){ // return ClassWrapper.class; // } // // return clz; // } } This file contains hidden or 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 charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,38 @@ package example.protostuff; import io.protostuff.Input; import io.protostuff.Output; import io.protostuff.Pipe; import io.protostuff.WireFormat; import io.protostuff.runtime.Delegate; import java.io.IOException; import java.sql.Date; /** * Created by jackeylv on 2016/7/14. */ public class Delegates { public static final Delegate<Date> DATE_DELEGATE = new Delegate<Date>() { public WireFormat.FieldType getFieldType() { return WireFormat.FieldType.FIXED64; } public Date readFrom(Input input) throws IOException { return new Date(input.readFixed64()); } public void writeTo(Output output, int number, Date value, boolean repeated) throws IOException { output.writeFixed64(number, value.getTime(), repeated); } public void transfer(Pipe pipe, Input input, Output output, int number, boolean repeated) throws IOException { output.writeFixed64(number, input.readFixed64(), repeated); } public Class<?> typeClass() { return Date.class; } }; } This file contains hidden or 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 charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,69 @@ package example.protostuff; import io.protostuff.LinkedBuffer; import io.protostuff.ProtostuffIOUtil; import io.protostuff.Schema; import io.protostuff.runtime.DefaultIdStrategy; import io.protostuff.runtime.RuntimeSchema; import java.util.concurrent.ConcurrentHashMap; /** * Created by jackeylv on 2016/7/14. */ public class SerializationUtil { private static ConcurrentHashMap<Class<?>, Schema<?>> cachedSchema = new ConcurrentHashMap(256); private static DefaultIdStrategy strategy = new DefaultIdStrategy(); static { strategy.registerDelegate(Delegates.DATE_DELEGATE); } private static ThreadLocal<ClassWrapper> clazzWrapper = new ThreadLocal<ClassWrapper>(){ @Override protected ClassWrapper initialValue() { return new ClassWrapper(); } }; private SerializationUtil(){} private static Schema getSchema(Class clz){ Schema schema = cachedSchema.get(clz); if (null == schema){ schema = RuntimeSchema.getSchema(clz, strategy); if (null != schema){ cachedSchema.put(clz, schema); } else { throw new IllegalStateException("Failed to create schema for class " + clz); } } return schema; } /** * @param obj * @return */ public static byte[] marshall(Object obj){ clazzWrapper.get().setValue(obj); LinkedBuffer buffer = LinkedBuffer.allocate(); try { Schema schema = getSchema(ClassWrapper.class); return ProtostuffIOUtil.toByteArray(clazzWrapper.get(), schema, buffer); }finally { buffer.clear(); } } public static Object unmarshall(byte[] bytes){ if (0 == bytes.length) return null; Schema schema = getSchema(ClassWrapper.class); assert null != schema : "schema is null"; ClassWrapper message = (ClassWrapper) schema.newMessage(); ProtostuffIOUtil.mergeFrom(bytes, message, schema); return message.getValue(); } } This file contains hidden or 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 charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,101 @@ package example.protostuff; import example.protostuff.SerializationUtil; import io.protostuff.LinkedBuffer; import io.protostuff.ProtostuffIOUtil; import io.protostuff.Schema; import io.protostuff.runtime.RuntimeSchema; import org.junit.Assert; import org.junit.Test; import java.util.*; import static org.junit.Assert.*; /** * Created by jackeylv on 2016/7/14. */ public class SerializationUtilTest { private void testHelper(Object obj){ byte[] bytes = SerializationUtil.marshall(obj); System.out.printf("object = %s, object.class = %s, bytes.length = %d, bytes = %s%n", obj, null != obj ? obj.getClass() : null, bytes.length, bytes); Object desr = SerializationUtil.unmarshall(bytes); if (null == obj && null == desr){ return; } if (null == obj && null != desr){ Assert.fail("desc != null"); } if (obj.getClass().isArray()){ System.out.println(Arrays.deepToString((Object[]) obj)); System.out.println(Arrays.deepToString((Object[]) desr)); Assert.assertArrayEquals(((Object[]) obj), ((Object[]) desr)); } else { Assert.assertEquals(obj, desr); } } @Test public void testListWithNullElement() throws Exception { LinkedList lst = new LinkedList(); testHelper(lst); lst.add(1); lst.add("hello"); lst.add("2.456"); testHelper(lst); lst.add(null); lst.add("hi"); testHelper(lst); } @Test public void testSetWithNullElement() throws Exception { HashSet set = null; testHelper(set); set = new HashSet(); testHelper(set); set.add(1); set.add("23"); set.add(null); testHelper(set); } @Test public void testObjectArrayWithNullElements() throws Exception { Object[] objects = new Object[]{ 1, null, "hello", null, 345 }; testHelper(objects); } /** * FIXME We can fix it with {@link ClassWrapper}. Or any other suggestions? * java.lang.RuntimeException: The root object can neither be an abstract class nor interface: "[Ljava.lang.Integer; * @throws Exception */ @Test public void testIntArrayWithRawPS() throws Exception { Integer[] arr = new Integer[]{0,1,2,3}; Schema schema = RuntimeSchema.getSchema(arr.getClass()); LinkedBuffer buffer = LinkedBuffer.allocate(); try { byte[] bytes = ProtostuffIOUtil.toByteArray(arr,schema,buffer); Integer[] ret = (Integer[]) schema.newMessage(); ProtostuffIOUtil.mergeFrom(bytes, ret, schema); Assert.assertArrayEquals(arr, ret); } finally { buffer.clear(); } } }