| /*
|
| * Copyright 1999-2011 Alibaba Group.
|
| *
|
| * Licensed under the Apache License, Version 2.0 (the "License");
|
| * you may not use this file except in compliance with the License.
|
| * You may obtain a copy of the License at
|
| *
|
| * http://www.apache.org/licenses/LICENSE-2.0
|
| *
|
| * Unless required by applicable law or agreed to in writing, software
|
| * distributed under the License is distributed on an "AS IS" BASIS,
|
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| * See the License for the specific language governing permissions and
|
| * limitations under the License.
|
| */
|
| package com.alibaba.dubbo.common.serialize.dubbo; |
| |
| import static junit.framework.Assert.assertEquals; |
| import static junit.framework.Assert.assertNull; |
| import static junit.framework.Assert.assertTrue; |
| |
| import java.io.Serializable; |
| import java.lang.reflect.Modifier;
|
| import java.sql.Time; |
| import java.util.ArrayList; |
| import java.util.HashMap; |
| import java.util.Map; |
| import java.util.concurrent.ConcurrentHashMap; |
| |
| import org.junit.Assert; |
| import org.junit.Ignore; |
| import org.junit.Test; |
| |
| import com.alibaba.dubbo.common.io.Bytes; |
| import com.alibaba.dubbo.common.io.UnsafeByteArrayOutputStream; |
| import com.alibaba.dubbo.common.serialize.support.dubbo.Builder; |
| |
| public class BuilderTest |
| { |
| @Test |
| public void testPrimaryTypeBuilder() throws Exception |
| { |
| System.out.println((new byte[2]).hashCode()); |
| Builder<String> builder = Builder.register(String.class); |
| UnsafeByteArrayOutputStream os = new UnsafeByteArrayOutputStream(); |
| String v = "123"; |
| builder.writeTo(v, os); |
| byte[] b = os.toByteArray(); |
| System.out.println(b.length+":"+Bytes.bytes2hex(b)); |
| v = builder.parseFrom(b); |
| builder.writeTo(v, os); |
| b = os.toByteArray(); |
| System.out.println(b.length+":"+Bytes.bytes2hex(b)); |
| } |
| |
| @Test |
| public void testEnumBuilder() throws Exception |
| { |
| Builder<Type> builder = Builder.register(Type.class); |
| UnsafeByteArrayOutputStream os = new UnsafeByteArrayOutputStream(); |
| Type v = Type.High; |
| builder.writeTo(v, os); |
| byte[] b = os.toByteArray(); |
| System.out.println(b.length+":"+Bytes.bytes2hex(b)); |
| v = builder.parseFrom(b); |
| } |
| |
| @Test |
| public void testThrowableBuilder() throws Exception |
| { |
| Builder<Throwable> builder = Builder.register(Throwable.class); |
| Throwable th = new Throwable(); |
| UnsafeByteArrayOutputStream os = new UnsafeByteArrayOutputStream(); |
| builder.writeTo(th, os); |
| byte[] b = os.toByteArray(); |
| System.out.println(b.length+":"+Bytes.bytes2hex(b)); |
| |
| th = builder.parseFrom(b); |
| } |
| |
| @Test |
| public void testArrayClassBuilder() throws Exception |
| { |
| UnsafeByteArrayOutputStream os; |
| |
| byte[] b; |
| |
| Builder<Object[]> osb = Builder.register(Object[].class); |
| os = new UnsafeByteArrayOutputStream(); |
| osb.writeTo(new Object[]{ new String[0] }, os); |
| b = os.toByteArray(); |
| |
| Builder<long[]> lsb = Builder.register(long[].class); |
| os = new UnsafeByteArrayOutputStream(); |
| lsb.writeTo(new long[]{ 1,121232,-3,4,-5,61321432413l }, os); |
| lsb.writeTo(new long[]{ 1,121232,-3,4,-5,61321432413l }, os); |
| lsb.writeTo(new long[]{ 1,2,3,12131314,123132313135l,-6 }, os); |
| b = os.toByteArray(); |
| long[] ls = lsb.parseFrom(b); |
| assertEquals(ls.length, 6); |
| |
| Builder<byte[]> bsb = Builder.register(byte[].class); |
| os = new UnsafeByteArrayOutputStream(); |
| bsb.writeTo("i am a string.".getBytes(), os); |
| b = os.toByteArray(); |
| |
| Builder<int[][]> iisb = Builder.register(int[][].class); |
| os = new UnsafeByteArrayOutputStream(); |
| iisb.writeTo(new int[][]{ {1,2,3,4}, {5,6,7,8}, {9,10}, {122,123,444} }, os); |
| b = os.toByteArray(); |
| int[][] iis = iisb.parseFrom(b); |
| assertEquals(iis.length, 4); |
| |
| Builder<int[][][]> iiisb = Builder.register(int[][][].class); |
| os = new UnsafeByteArrayOutputStream(); |
| iiisb.writeTo(new int[][][]{ |
| {{1,2,3,4}}, |
| {{5,6,7,8}}, |
| {{122,123,444}} |
| }, os); |
| b = os.toByteArray(); |
| int[][][] iii = iiisb.parseFrom(b); |
| assertEquals(iii.length, 3); |
| } |
| |
| @Test |
| public void testObjectBuilder() throws Exception |
| { |
| UnsafeByteArrayOutputStream os = new UnsafeByteArrayOutputStream(); |
| Builder<Bean> BeanBuilder = Builder.register(Bean.class); |
| |
| Bean bean = new Bean(); |
| bean.name = "ql"; |
| bean.type = Type.High; |
| bean.types = new Type[]{ Type.High, Type.High }; |
| BeanBuilder.writeTo(bean, os); |
| |
| byte[] b = os.toByteArray(); |
| System.out.println(b.length+":"+Bytes.bytes2hex(b)); |
| |
| bean = BeanBuilder.parseFrom(b); |
| assertNull(bean.time); |
| assertEquals(bean.i, 123123); |
| assertEquals(bean.ni, -12344); |
| assertEquals(bean.d, 12.345); |
| assertEquals(bean.nd, -12.345); |
| assertEquals(bean.l, 1281447759383l); |
| assertEquals(bean.nl, -13445l); |
| assertEquals(bean.vl, 100l); |
| assertEquals(bean.type, Type.High); |
| assertEquals(bean.types.length, 2); |
| assertEquals(bean.types[0], Type.High); |
| assertEquals(bean.types[1], Type.High); |
| assertEquals(bean.list.size(), 3); |
| assertEquals(bean.list.get(0), 1); |
| assertEquals(bean.list.get(1), 2); |
| assertEquals(bean.list.get(2), 1308147); |
| } |
| |
| @Test |
| public void testInterfaceBuilder() throws Exception |
| { |
| UnsafeByteArrayOutputStream os = new UnsafeByteArrayOutputStream(); |
| Builder<TestDO> builder = Builder.register(TestDO.class); |
| TestDO d = new TestDOImpl(); |
| builder.writeTo(d, os); |
| |
| byte[] b = os.toByteArray(); |
| |
| d = builder.parseFrom(b); |
| assertTrue(TestDO.class.isAssignableFrom(d.getClass())); |
| assertEquals("name", d.getName()); |
| assertEquals(28, d.getArg()); |
| assertEquals(Type.High, d.getType()); |
| } |
| |
| @Test |
| public void testGenericBuilder() throws Exception |
| { |
| UnsafeByteArrayOutputStream os = new UnsafeByteArrayOutputStream(); |
| Builder<Object> ob = Builder.register(Object.class); |
| |
| Object o = new Object(); |
| ob.writeTo(o, os); |
| byte[] b = os.toByteArray(); |
| |
| os = new UnsafeByteArrayOutputStream(); |
| Bean bean = new Bean(); |
| bean.name = "ql"; |
| bean.type = Type.High; |
| bean.types = new Type[]{ Type.High, Type.High }; |
| ob.writeTo(bean, os); |
| |
| b = os.toByteArray(); |
| bean = (Bean)ob.parseFrom(b); |
| assertEquals(bean.i, 123123); |
| assertEquals(bean.ni, -12344); |
| assertEquals(bean.d, 12.345); |
| assertEquals(bean.nd, -12.345); |
| assertEquals(bean.l, 1281447759383l); |
| assertEquals(bean.nl, -13445l); |
| assertEquals(bean.vl, 100l); |
| assertEquals(bean.type, Type.High); |
| assertEquals(bean.types.length, 2); |
| assertEquals(bean.types[0], Type.High); |
| assertEquals(bean.types[1], Type.High); |
| assertEquals(bean.list.size(), 3); |
| assertEquals(bean.list.get(0), 1); |
| assertEquals(bean.list.get(1), 2); |
| assertEquals(bean.list.get(2), 1308147); |
| } |
| |
| @Test |
| public void testObjectArrayBuilder() throws Exception |
| { |
| UnsafeByteArrayOutputStream os = new UnsafeByteArrayOutputStream(); |
| Builder<Object[]> builder = Builder.register(Object[].class); |
| |
| Object[] obj = new Object[5]; |
| obj[0] = "1234"; |
| obj[1] = new Double(109.23); |
| obj[2] = "3455"; |
| obj[3] = null; |
| obj[4] = Boolean.TRUE; |
| |
| builder.writeTo(obj, os); |
| byte[] b = os.toByteArray(); |
| System.out.println("Object array:"+b.length+":"+Bytes.bytes2hex(b)); |
| |
| Assert.assertArrayEquals(obj, builder.parseFrom(b)); |
| } |
| |
| // FIXME MyList的从ArrayList中继承来的属性size会在decode时设置好,再Add时就不对了!! |
| @Ignore |
| @Test |
| @SuppressWarnings({ "rawtypes", "unchecked" }) |
| public void testBuilder_MyList() throws Exception |
| { |
| Builder<MyList> b1 = Builder.register(MyList.class); |
| MyList list = new MyList(); |
| list.add(new boolean[]{ true,false }); |
| list.add(new int[]{ 1,2,3,4,5 }); |
| list.add("String"); |
| list.add(4); |
| list.code = 4321; |
| |
| UnsafeByteArrayOutputStream os = new UnsafeByteArrayOutputStream(); |
| b1.writeTo(list, os); |
| byte[] b = os.toByteArray(); |
| System.out.println(b.length+":"+Bytes.bytes2hex(b)); |
| MyList result = b1.parseFrom(b); |
| |
| assertEquals(4, result.size()); |
| assertEquals(result.code, 4321); |
| assertEquals(result.id, "feedback"); |
| } |
| |
| @Test |
| @SuppressWarnings({ "rawtypes", "unchecked" }) |
| public void testBuilder_MyMap() throws Exception |
| { |
| UnsafeByteArrayOutputStream os = new UnsafeByteArrayOutputStream(); |
| Builder<MyMap> b2 = Builder.register(MyMap.class); |
| MyMap map = new MyMap(); |
| map.put("name", "qianlei"); |
| map.put("displayName", "钱磊"); |
| map.code = 4321; |
| b2.writeTo(map, os); |
| byte[] b = os.toByteArray(); |
| System.out.println(b.length+":"+Bytes.bytes2hex(b)); |
| |
| map = b2.parseFrom(b); |
| |
| assertEquals(map.size(), 2); |
| assertEquals(map.code, 4321); |
| assertEquals(map.id, "feedback"); |
| } |
| |
| @Test |
| @SuppressWarnings("unchecked") |
| public void testSerializableBean() throws Exception |
| { |
| System.out.println("testSerializableBean"); |
| UnsafeByteArrayOutputStream os = new UnsafeByteArrayOutputStream(); |
| |
| SerializableBean sb = new SerializableBean(); |
| Builder<SerializableBean> sbb = Builder.register(SerializableBean.class); |
| sbb.writeTo(sb, os); |
| |
| byte[] b = os.toByteArray(); |
| System.out.println(b.length+":"+Bytes.bytes2hex(b)); |
| assertEquals(sbb.parseFrom(os.toByteArray()), sb); |
| } |
| |
| @Test |
| @SuppressWarnings("unchecked") |
| public void testOthers() throws Exception |
| { |
| UnsafeByteArrayOutputStream os = new UnsafeByteArrayOutputStream(); |
| |
| StringBuffer buf = new StringBuffer(); |
| for(int i=0;i<1024*32+32;i++) |
| buf.append('A'); |
| Builder<String> sb = Builder.register(String.class); |
| sb.writeTo(buf.toString(), os); |
| assertEquals(sb.parseFrom(os.toByteArray()), buf.toString()); |
| |
| os = new UnsafeByteArrayOutputStream(); |
| Builder<HashMap> builder = Builder.register(HashMap.class); |
| Map services = new HashMap(); |
| HashMap map = new HashMap(); |
| services.put("test.service", "http://127.0.0.1:9010/test.service"); |
| map.put("name", "qianlei"); |
| map.put("password", "123455"); |
| map.put("services", services); |
| |
| builder.writeTo(map, os); |
| byte[] b = os.toByteArray(); |
| System.out.println(b.length+":"+Bytes.bytes2hex(b)); |
| map = builder.parseFrom(b); |
| assertTrue(map.size() > 0); |
| assertEquals("http://127.0.0.1:9010/test.service", ((Map) map.get("services")).get("test.service")); |
| |
| services = new ConcurrentHashMap(); |
| services.put("test.service", "http://127.0.0.1:9010/test.service"); |
| map.put("services", services); |
| |
| os = new UnsafeByteArrayOutputStream(); |
| builder.writeTo(map, os); |
| b = os.toByteArray(); |
| System.out.println(b.length+":"+Bytes.bytes2hex(b)); |
| map = builder.parseFrom(b); |
| assertTrue(map.size() > 0); |
| assertEquals("http://127.0.0.1:9010/test.service", ((Map) map.get("services")).get("test.service")); |
| |
| Node node1 = new Node(); |
| Node node0 = new Node(); |
| node0.value = "0"; |
| node0.next = node1; |
| node1.value = "1"; |
| node1.prev = node0; |
| // write. |
| Builder<Node> nodebuilder = Builder.register(Node.class); |
| os = new UnsafeByteArrayOutputStream(); |
| nodebuilder.writeTo(node0, os); |
| b = os.toByteArray(); |
| System.out.println("Node:"+b.length+":"+Bytes.bytes2hex(b)); |
| // parse |
| node0 = nodebuilder.parseFrom(b); |
| assertEquals(node0, node0.prev); |
| assertEquals(node0, node0.next.prev); |
| assertEquals(node0.value, "0"); |
| } |
| public static void main(String[] args) {
|
| System.out.println(Modifier.isPublic(String.class.getModifiers()));
|
| } |
| @Test |
| public void testWithFC() throws Exception |
| { |
| Builder<SimpleDO> builder = Builder.register(SimpleDO.class); |
| UnsafeByteArrayOutputStream os = new UnsafeByteArrayOutputStream(); |
| |
| SimpleDO sd = new SimpleDO(); |
| sd.a = 1; |
| sd.b = 2; |
| sd.c = 3; |
| sd.str1 = "12345"; |
| sd.str2 = "54321"; |
| builder.writeTo(sd, os); |
| byte[] b = os.toByteArray(); |
| System.out.println(b.length+":"+Bytes.bytes2hex(b)); |
| |
| sd = builder.parseFrom(b); |
| assertEquals(sd.a, 1); |
| assertEquals(sd.b, 2); |
| assertEquals(sd.c, 3); |
| assertEquals(sd.str1, "124"); |
| System.out.println(sd.str2); |
| } |
| |
| public enum Type |
| { |
| Lower, Normal, High; |
| } |
| |
| static interface TestDO |
| { |
| String getName(); |
| void setName(String name); |
| Type getType(); |
| void setType(Type t); |
| int getArg(); |
| void setArg(int arg); |
| } |
| |
| static class TestDOImpl implements TestDO, Serializable |
| { |
| private static final long serialVersionUID = 1L; |
| public String getName() |
| { |
| return "name"; |
| } |
| public void setName(String name){} |
| public Type getType() |
| { |
| return Type.High; |
| } |
| public void setType(Type t){} |
| public int getArg() |
| { |
| return 28; |
| } |
| public void setArg(int arg){} |
| } |
| |
| static class Bean implements Serializable |
| { |
| private static final long serialVersionUID = 1L; |
| public int vi = 0; |
| public long vl = 100l; |
| |
| boolean b = true; |
| boolean[] bs = {false, true}; |
| |
| String s1 = "1234567890"; |
| String s2 = "1234567890一二三四五六七八九零"; |
| |
| private int i = 123123, ni = -12344, is[] = {1,2,3,4,-1,-2,-3,-4}; |
| private short s = 12, ns = -76; |
| private double d = 12.345, nd = -12.345; |
| private long l = 1281447759383l, nl = -13445l; |
| |
| private Boolean B = Boolean.FALSE; |
| private Integer I = -1234; |
| private Double D = new Double(1.23); |
| private String name = "qianlei"; |
| private Type type = Type.Lower, type1 = Type.Normal; |
| private Type[] types = { Type.Lower, Type.Lower }; |
| |
| private Time time = null; |
| |
| public Type getType() |
| { |
| return type; |
| } |
| |
| public void setType(Type type) |
| { |
| this.type = type; |
| } |
| |
| private ArrayList list = new ArrayList(); |
| { |
| list.add(1); |
| list.add(2); |
| list.add(1308147); |
| } |
| } |
| |
| static class MyList<T> extends ArrayList<T> |
| { |
| private int code = 12345; |
| private String id = "feedback"; |
| } |
| |
| static class MyMap<K, V> extends HashMap<K, V> |
| { |
| private int code = 12345; |
| private String id = "feedback"; |
| } |
| |
| static class Node implements Serializable |
| { |
| private static final long serialVersionUID = 1L; |
| Node prev = this; |
| Node next = this; |
| String value = "value"; |
| |
| @Override |
| public int hashCode() { |
| final int prime = 31; |
| int result = 1; |
| result = prime * result + ((value == null) ? 0 : value.hashCode()); |
| return result; |
| } |
| |
| @Override |
| public boolean equals(Object obj) { |
| if (this == obj) return true; |
| if (obj == null) return false; |
| if (getClass() != obj.getClass()) return false; |
| Node other = (Node) obj; |
| if (value == null) { |
| if (other.value != null) return false; |
| } else if (!value.equals(other.value)) return false; |
| return true; |
| } |
| } |
| |
| static class SerializableBean implements Serializable |
| { |
| private static final long serialVersionUID = -8949681707161463700L; |
| |
| public int a = 0; |
| public long b = 100l; |
| boolean c = true; |
| String s1 = "1234567890"; |
| String s2 = "1234567890一二三四五六七八九零"; |
| |
| public int hashCode() |
| { |
| return s1.hashCode() ^ s2.hashCode(); |
| } |
| |
| public boolean equals(Object obj) |
| { |
| if( obj == null ) return false; |
| if( obj == this ) return true; |
| if( obj instanceof SerializableBean ) |
| { |
| SerializableBean sb = (SerializableBean)obj; |
| return this.a == sb.a && this.b == sb.b && this.c == sb.c && this.s1.equals(sb.s1) && this.s2.equals(sb.s2); |
| } |
| |
| return false; |
| } |
| } |
| } |