This commit is contained in:
@@ -27,7 +27,7 @@ public final class AnyEncoder<T> implements Encodeable<Writer, T> {
|
||||
if (value == null) {
|
||||
out.writeNull();
|
||||
} else {
|
||||
out.wirteClassName(value.getClass());
|
||||
out.wirteClassName(factory.getEntity(value.getClass()));
|
||||
factory.loadEncoder(value.getClass()).convertTo(out, value);
|
||||
}
|
||||
}
|
||||
|
||||
25
src/com/wentch/redkale/convert/ConvertEntity.java
Normal file
25
src/com/wentch/redkale/convert/ConvertEntity.java
Normal file
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package com.wentch.redkale.convert;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
import static java.lang.annotation.ElementType.TYPE;
|
||||
import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
||||
|
||||
/**
|
||||
* 用于类名的别名, 类似javax.persistence.Table
|
||||
* 该值必须是全局唯一
|
||||
*
|
||||
* @author zhangjx
|
||||
*/
|
||||
@Inherited
|
||||
@Documented
|
||||
@Target({TYPE})
|
||||
@Retention(RUNTIME)
|
||||
public @interface ConvertEntity {
|
||||
|
||||
String value();
|
||||
}
|
||||
@@ -15,6 +15,7 @@ import java.math.BigInteger;
|
||||
import java.net.*;
|
||||
import static com.wentch.redkale.convert.ext.InetAddressSimpledCoder.*;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.*;
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -36,6 +37,8 @@ public abstract class Factory<R extends Reader, W extends Writer> {
|
||||
//-----------------------------------------------------------------------------------
|
||||
private final HashedMap<Class, Creator> creators = new HashedMap();
|
||||
|
||||
private final Map<String, Class> entitys = new ConcurrentHashMap<>();
|
||||
|
||||
private final HashedMap<Type, Decodeable<R, ?>> decoders = new HashedMap();
|
||||
|
||||
private final HashedMap<Type, Encodeable<W, ?>> encoders = new HashedMap();
|
||||
@@ -138,6 +141,21 @@ public abstract class Factory<R extends Reader, W extends Writer> {
|
||||
return null;
|
||||
}
|
||||
|
||||
final String getEntity(Class clazz) {
|
||||
ConvertEntity ce = (ConvertEntity) clazz.getAnnotation(ConvertEntity.class);
|
||||
if (ce != null && entitys.get(ce.value()) == null) entitys.put(ce.value(), clazz);
|
||||
return ce == null ? clazz.getName() : ce.value();
|
||||
}
|
||||
|
||||
final Class getEntity(String name) {
|
||||
Class clazz = entitys.get(name);
|
||||
try {
|
||||
return clazz == null ? Class.forName(name) : clazz;
|
||||
} catch (Exception ex) {
|
||||
throw new ConvertException("convert entity is " + name, ex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 使所有类的所有被声明为ConvertColumn.ignore = true 的字段或方法变为ConvertColumn.ignore = false
|
||||
* <p>
|
||||
|
||||
@@ -107,13 +107,7 @@ public final class ObjectDecoder<R extends Reader, T> implements Decodeable<R, T
|
||||
@Override
|
||||
public final T convertFrom(final R in) {
|
||||
final String clazz = in.readClassName();
|
||||
if (clazz != null && !clazz.isEmpty()) {
|
||||
try {
|
||||
return (T) factory.loadDecoder(Class.forName(clazz)).convertFrom(in);
|
||||
} catch (Exception ex) {
|
||||
throw new ConvertException(ex);
|
||||
}
|
||||
}
|
||||
if (clazz != null && !clazz.isEmpty()) return (T) factory.loadDecoder(factory.getEntity(clazz)).convertFrom(in);
|
||||
if (in.readObjectB() == Reader.SIGN_NULL) return null;
|
||||
final T result = this.creator.create();
|
||||
final AtomicInteger index = new AtomicInteger();
|
||||
|
||||
@@ -189,7 +189,7 @@ public final class ObjectEncoder<W extends Writer, T> implements Encodeable<W, T
|
||||
}
|
||||
if (value != null && value.getClass() != this.typeClass) {
|
||||
final Class clz = value.getClass();
|
||||
out.wirteClassName(clz);
|
||||
out.wirteClassName(factory.getEntity(clz));
|
||||
factory.loadEncoder(clz).convertTo(out, value);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ public interface Writer {
|
||||
*
|
||||
* @param clazz
|
||||
*/
|
||||
public void wirteClassName(Class clazz);
|
||||
public void wirteClassName(String clazz);
|
||||
|
||||
/**
|
||||
* 输出一个对象前的操作
|
||||
|
||||
@@ -10,6 +10,21 @@ import com.wentch.redkale.util.*;
|
||||
import java.lang.reflect.*;
|
||||
|
||||
/**
|
||||
* BSON协议格式:
|
||||
* 1). 基本数据类型: 直接转换成byte[]
|
||||
* 2). String: smallstring(无特殊字符且长度小于256的字符串): length(1 byte) + byte[](utf8); 其他字符串: length(4 bytes) + byte[](utf8);
|
||||
* 3). 数组(长度不能大于65535): length(2 byte) + byte[]...
|
||||
* 4). Object:
|
||||
* 1. realclass (smallstring) (如果指定格式化的class与实体对象的class不一致才会有该值)
|
||||
* 2. 空字符串(smallstring)
|
||||
* 3. SIGN_OBJECTB 标记位,值固定为0xBB (short)
|
||||
* 4. 循环字段值:
|
||||
* 4.1 SIGN_HASNEXT 标记位,值固定为1 (byte)
|
||||
* 4.2 字段类型; 1-9为基本类型&字符串; 101-109为基本类型&字符串的数组; 127为object
|
||||
* 4.3 字段名 (smallstring)
|
||||
* 4.4 字段的值object
|
||||
* 5. SIGN_NONEXT 标记位,值固定为0 (byte)
|
||||
* 6. SIGN_OBJECTE 标记位,值固定为0xEE (short)
|
||||
*
|
||||
* @author zhangjx
|
||||
*/
|
||||
|
||||
@@ -170,7 +170,7 @@ public final class BsonReader implements Reader {
|
||||
*/
|
||||
@Override
|
||||
public int readArrayB() {
|
||||
return readShort();
|
||||
return readShort() & 0xffff;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -151,8 +151,8 @@ public final class BsonWriter implements Writer {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void wirteClassName(Class clazz) {
|
||||
writeSmallString(clazz == null ? "" : clazz.getName());
|
||||
public void wirteClassName(String clazz) {
|
||||
writeSmallString(clazz == null ? "" : clazz);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -224,7 +224,7 @@ public final class JsonWriter implements Writer {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void wirteClassName(Class clazz) {
|
||||
public void wirteClassName(String clazz) {
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
Reference in New Issue
Block a user