blob: a9b688d78c222023e4be4ac6596da92c933a9cde [file] [log] [blame]
/*
* 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;
}
}
}