Compare commits
27 Commits
2.0.0.beta
...
2.0.0.rc1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bd21644571 | ||
|
|
5f3599d9b8 | ||
|
|
1e4a30bd70 | ||
|
|
e7dc5de9f2 | ||
|
|
ccb9cb28f5 | ||
|
|
4d9b72c922 | ||
|
|
a51ae13a39 | ||
|
|
dfca186688 | ||
|
|
fadd229a89 | ||
|
|
7acc69adc4 | ||
|
|
d88e4120a1 | ||
|
|
ef98edd91a | ||
|
|
f4548bbe34 | ||
|
|
11a5faca1d | ||
|
|
c37b0e8cb5 | ||
|
|
a20570a6eb | ||
|
|
5e3edb7e1d | ||
|
|
ad8f1d2da6 | ||
|
|
24b23c894f | ||
|
|
c551d5fb81 | ||
|
|
fba43894c1 | ||
|
|
22cc7e086c | ||
|
|
1791008729 | ||
|
|
90e15dd253 | ||
|
|
7db73c076c | ||
|
|
95ad6e99d9 | ||
|
|
0b2a5d0f61 |
@@ -1 +0,0 @@
|
|||||||
<EFBFBD>Լ<EFBFBD><EFBFBD><EFBFBD>ҵ<EFBFBD><EFBFBD>jarĬ<EFBFBD>Ϸ<EFBFBD><EFBFBD>ڴ˴<EFBFBD>
|
|
||||||
@@ -16,10 +16,6 @@
|
|||||||
<directory>${project.basedir}/conf</directory>
|
<directory>${project.basedir}/conf</directory>
|
||||||
<outputDirectory>conf</outputDirectory>
|
<outputDirectory>conf</outputDirectory>
|
||||||
</fileSet>
|
</fileSet>
|
||||||
<fileSet>
|
|
||||||
<directory>${project.basedir}/libs</directory>
|
|
||||||
<outputDirectory>libs</outputDirectory>
|
|
||||||
</fileSet>
|
|
||||||
<fileSet>
|
<fileSet>
|
||||||
<directory>${project.basedir}/logs</directory>
|
<directory>${project.basedir}/logs</directory>
|
||||||
<outputDirectory>logs</outputDirectory>
|
<outputDirectory>logs</outputDirectory>
|
||||||
|
|||||||
@@ -36,12 +36,15 @@ public abstract class Convert<R extends Reader, W extends Writer> {
|
|||||||
return writer;
|
return writer;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected <S extends W> S fieldFunc(S writer, BiFunction<Attribute, Object, Object> fieldFunc) {
|
protected <S extends W> S fieldFunc(S writer, BiFunction<Attribute, Object, Object> objFieldFunc, Function<Object, ConvertField[]> objExtFunc) {
|
||||||
writer.fieldFunc = fieldFunc;
|
writer.objFieldFunc = objFieldFunc;
|
||||||
|
writer.objExtFunc = objExtFunc;
|
||||||
return writer;
|
return writer;
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract Convert<R, W> newConvert(final BiFunction<Attribute, Object, Object> fieldFunc);
|
public abstract Convert<R, W> newConvert(final BiFunction<Attribute, Object, Object> objFieldFunc);
|
||||||
|
|
||||||
|
public abstract Convert<R, W> newConvert(final BiFunction<Attribute, Object, Object> objFieldFunc, Function<Object, ConvertField[]> objExtFunc);
|
||||||
|
|
||||||
public abstract boolean isBinary();
|
public abstract boolean isBinary();
|
||||||
|
|
||||||
|
|||||||
102
src/org/redkale/convert/ConvertField.java
Normal file
102
src/org/redkale/convert/ConvertField.java
Normal file
@@ -0,0 +1,102 @@
|
|||||||
|
/*
|
||||||
|
* 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 org.redkale.convert;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.lang.reflect.Type;
|
||||||
|
import org.redkale.convert.json.JsonConvert;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* newConvert参数中的Function返回结果的数据类
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* 详情见: https://redkale.org
|
||||||
|
*
|
||||||
|
* @author zhangjx
|
||||||
|
*/
|
||||||
|
public class ConvertField implements Serializable {
|
||||||
|
|
||||||
|
protected String name;
|
||||||
|
|
||||||
|
protected Type type;
|
||||||
|
|
||||||
|
protected int position;
|
||||||
|
|
||||||
|
protected Object value;
|
||||||
|
|
||||||
|
public ConvertField() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public ConvertField(String name, Object value) {
|
||||||
|
this.name = name;
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ConvertField(String name, int position, Object value) {
|
||||||
|
this.name = name;
|
||||||
|
this.position = position;
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ConvertField(String name, Type type, Object value) {
|
||||||
|
this.name = name;
|
||||||
|
this.type = type;
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ConvertField(String name, Type type, int position, Object value) {
|
||||||
|
this.name = name;
|
||||||
|
this.type = type;
|
||||||
|
this.position = position;
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ConvertField[] ofArray(Object... items) {
|
||||||
|
int len = items.length / 2;
|
||||||
|
ConvertField[] rs = new ConvertField[len];
|
||||||
|
for (int i = 0; i < len; i++) {
|
||||||
|
rs[i] = new ConvertField(items[i * 2].toString(), items[i * 2 + 1]);
|
||||||
|
}
|
||||||
|
return rs;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Type getType() {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setType(Type type) {
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getPosition() {
|
||||||
|
return position;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPosition(int position) {
|
||||||
|
this.position = position;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object getValue() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setValue(Object value) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return JsonConvert.root().convertTo(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -164,9 +164,22 @@ public class ObjectEncoder<W extends Writer, T> implements Encodeable<W, T> {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (out.writeObjectB(value) < 0) {
|
if (out.writeObjectB(value) < 0) {
|
||||||
|
int maxPosition = 0;
|
||||||
for (EnMember member : members) {
|
for (EnMember member : members) {
|
||||||
|
maxPosition = member.getPosition();
|
||||||
out.writeObjectField(member, value);
|
out.writeObjectField(member, value);
|
||||||
}
|
}
|
||||||
|
if (out.objExtFunc != null) {
|
||||||
|
ConvertField[] extFields = out.objExtFunc.apply(value);
|
||||||
|
if (extFields != null) {
|
||||||
|
Encodeable<W, ?> anyEncoder = factory.getAnyEncoder();
|
||||||
|
for (ConvertField en : extFields) {
|
||||||
|
if (en == null) continue;
|
||||||
|
maxPosition++;
|
||||||
|
out.writeObjectField(en.getName(), en.getType(), Math.max(en.getPosition(), maxPosition), anyEncoder, en.getValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
out.writeObjectE(value);
|
out.writeObjectE(value);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
package org.redkale.convert;
|
package org.redkale.convert;
|
||||||
|
|
||||||
import java.lang.reflect.*;
|
import java.lang.reflect.*;
|
||||||
import java.util.function.BiFunction;
|
import java.util.function.*;
|
||||||
import org.redkale.util.*;
|
import org.redkale.util.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -26,7 +26,10 @@ public abstract class Writer {
|
|||||||
protected Type specify;
|
protected Type specify;
|
||||||
|
|
||||||
//对某个字段值进行动态处理
|
//对某个字段值进行动态处理
|
||||||
protected BiFunction<Attribute, Object, Object> fieldFunc;
|
protected BiFunction<Attribute, Object, Object> objFieldFunc;
|
||||||
|
|
||||||
|
//对某个对象进行动态扩展字段值处理
|
||||||
|
protected Function<Object, ConvertField[]> objExtFunc;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 设置specify
|
* 设置specify
|
||||||
@@ -44,7 +47,7 @@ public abstract class Writer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected boolean recycle() {
|
protected boolean recycle() {
|
||||||
this.fieldFunc = null;
|
this.objFieldFunc = null;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -116,10 +119,10 @@ public abstract class Writer {
|
|||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public void writeObjectField(final EnMember member, Object obj) {
|
public void writeObjectField(final EnMember member, Object obj) {
|
||||||
Object value;
|
Object value;
|
||||||
if (fieldFunc == null) {
|
if (objFieldFunc == null) {
|
||||||
value = member.attribute.get(obj);
|
value = member.attribute.get(obj);
|
||||||
} else {
|
} else {
|
||||||
value = fieldFunc.apply(member.attribute, obj);
|
value = objFieldFunc.apply(member.attribute, obj);
|
||||||
}
|
}
|
||||||
if (value == null) return;
|
if (value == null) return;
|
||||||
if (tiny()) {
|
if (tiny()) {
|
||||||
@@ -129,11 +132,49 @@ public abstract class Writer {
|
|||||||
if (!((Boolean) value)) return;
|
if (!((Boolean) value)) return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.writeFieldName(member);
|
Attribute attr = member.getAttribute();
|
||||||
|
this.writeFieldName(attr.field(), attr.genericType(), member.getPosition());
|
||||||
member.encoder.convertTo(this, value);
|
member.encoder.convertTo(this, value);
|
||||||
this.comma = true;
|
this.comma = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 输出一个对象的某个扩展字段
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @param fieldName 字段名称
|
||||||
|
* @param fieldType 字段类型
|
||||||
|
* @param fieldPos 字段顺序
|
||||||
|
* @param anyEncoder Encoder
|
||||||
|
* @param value 写入的字段对象
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public void writeObjectField(final String fieldName, Type fieldType, int fieldPos, Encodeable anyEncoder, Object value) {
|
||||||
|
if (value == null) return;
|
||||||
|
if (fieldType == null) fieldType = value.getClass();
|
||||||
|
if (tiny() && fieldType instanceof Class) {
|
||||||
|
Class clazz = (Class) fieldType;
|
||||||
|
if (CharSequence.class.isAssignableFrom(clazz)) {
|
||||||
|
if (((CharSequence) value).length() == 0) return;
|
||||||
|
} else if (clazz == boolean.class || clazz == Boolean.class) {
|
||||||
|
if (!((Boolean) value)) return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.writeFieldName(fieldName, fieldType, fieldPos);
|
||||||
|
anyEncoder.convertTo(this, value);
|
||||||
|
this.comma = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 输出一个字段名
|
||||||
|
*
|
||||||
|
* @param member 字段
|
||||||
|
*/
|
||||||
|
public final void writeFieldName(final EnMember member) {
|
||||||
|
Attribute attr = member.getAttribute();
|
||||||
|
this.writeFieldName(attr.field(), attr.genericType(), member.getPosition());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 输出一个对象后的操作
|
* 输出一个对象后的操作
|
||||||
*
|
*
|
||||||
@@ -191,9 +232,11 @@ public abstract class Writer {
|
|||||||
/**
|
/**
|
||||||
* 输出一个字段名
|
* 输出一个字段名
|
||||||
*
|
*
|
||||||
* @param member 字段的EnMember对象
|
* @param fieldName 字段名称
|
||||||
|
* @param fieldType 字段类型
|
||||||
|
* @param fieldPos 字段顺序
|
||||||
*/
|
*/
|
||||||
public abstract void writeFieldName(EnMember member);
|
public abstract void writeFieldName(String fieldName, Type fieldType, int fieldPos);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 写入一个boolean值
|
* 写入一个boolean值
|
||||||
|
|||||||
@@ -61,10 +61,15 @@ public class BsonConvert extends BinaryConvert<BsonReader, BsonWriter> {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BsonConvert newConvert(final BiFunction<Attribute, Object, Object> fieldFunc) {
|
public BsonConvert newConvert(final BiFunction<Attribute, Object, Object> fieldFunc) {
|
||||||
|
return newConvert(fieldFunc, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BsonConvert newConvert(final BiFunction<Attribute, Object, Object> fieldFunc, Function<Object, ConvertField[]> objExtFunc) {
|
||||||
return new BsonConvert(getFactory(), tiny) {
|
return new BsonConvert(getFactory(), tiny) {
|
||||||
@Override
|
@Override
|
||||||
protected <S extends BsonWriter> S configWrite(S writer) {
|
protected <S extends BsonWriter> S configWrite(S writer) {
|
||||||
return fieldFunc(writer, fieldFunc);
|
return fieldFunc(writer, fieldFunc, objExtFunc);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
*/
|
*/
|
||||||
package org.redkale.convert.bson;
|
package org.redkale.convert.bson;
|
||||||
|
|
||||||
|
import java.lang.reflect.Type;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import org.redkale.convert.*;
|
import org.redkale.convert.*;
|
||||||
import org.redkale.convert.ext.ByteSimpledCoder;
|
import org.redkale.convert.ext.ByteSimpledCoder;
|
||||||
@@ -43,7 +44,7 @@ public class BsonWriter extends Writer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected BsonWriter(byte[] bs) {
|
protected BsonWriter(byte[] bs) {
|
||||||
this.content = bs;
|
this.content = bs == null ? new byte[0] : bs;
|
||||||
}
|
}
|
||||||
|
|
||||||
public BsonWriter() {
|
public BsonWriter() {
|
||||||
@@ -102,7 +103,7 @@ public class BsonWriter extends Writer {
|
|||||||
super.recycle();
|
super.recycle();
|
||||||
this.count = 0;
|
this.count = 0;
|
||||||
this.specify = null;
|
this.specify = null;
|
||||||
if (this.content.length > defaultSize) {
|
if (this.content != null && this.content.length > defaultSize) {
|
||||||
this.content = new byte[defaultSize];
|
this.content = new byte[defaultSize];
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@@ -200,11 +201,10 @@ public class BsonWriter extends Writer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final void writeFieldName(EnMember member) {
|
public final void writeFieldName(String fieldName, Type fieldType, int fieldPos) {
|
||||||
Attribute attribute = member.getAttribute();
|
|
||||||
writeByte(BsonReader.SIGN_HASNEXT);
|
writeByte(BsonReader.SIGN_HASNEXT);
|
||||||
writeSmallString(attribute.field());
|
writeSmallString(fieldName);
|
||||||
writeByte(BsonFactory.typeEnum(attribute.type()));
|
writeByte(BsonFactory.typeEnum(fieldType));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ import org.redkale.convert.*;
|
|||||||
*/
|
*/
|
||||||
public class FileSimpledCoder<R extends Reader, W extends Writer> extends SimpledCoder<R, W, File> {
|
public class FileSimpledCoder<R extends Reader, W extends Writer> extends SimpledCoder<R, W, File> {
|
||||||
|
|
||||||
public static final PatternSimpledCoder instance = new PatternSimpledCoder();
|
public static final FileSimpledCoder instance = new FileSimpledCoder();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void convertTo(W out, File value) {
|
public void convertTo(W out, File value) {
|
||||||
|
|||||||
@@ -115,7 +115,7 @@ public class JsonByteBufferWriter extends JsonWriter {
|
|||||||
int byteLength = quote ? 2 : 0;
|
int byteLength = quote ? 2 : 0;
|
||||||
ByteBuffer bb = null;
|
ByteBuffer bb = null;
|
||||||
if (charset == null) {
|
if (charset == null) {
|
||||||
byteLength += encodeUTF8Length(chs, start, len);
|
byteLength += Utility.encodeUTF8Length(chs, start, len);
|
||||||
} else {
|
} else {
|
||||||
bb = charset.encode(CharBuffer.wrap(chs, start, len));
|
bb = charset.encode(CharBuffer.wrap(chs, start, len));
|
||||||
byteLength += bb.remaining();
|
byteLength += bb.remaining();
|
||||||
@@ -134,6 +134,13 @@ public class JsonByteBufferWriter extends JsonWriter {
|
|||||||
} else if (c < 0x800) {
|
} else if (c < 0x800) {
|
||||||
buffer.put((byte) (0xc0 | (c >> 6)));
|
buffer.put((byte) (0xc0 | (c >> 6)));
|
||||||
buffer.put((byte) (0x80 | (c & 0x3f)));
|
buffer.put((byte) (0x80 | (c & 0x3f)));
|
||||||
|
} else if (Character.isSurrogate(c)) { //连取两个
|
||||||
|
int uc = Character.toCodePoint(c, chs[i + 1]);
|
||||||
|
buffer.put((byte) (0xf0 | ((uc >> 18))));
|
||||||
|
buffer.put((byte) (0x80 | ((uc >> 12) & 0x3f)));
|
||||||
|
buffer.put((byte) (0x80 | ((uc >> 6) & 0x3f)));
|
||||||
|
buffer.put((byte) (0x80 | (uc & 0x3f)));
|
||||||
|
i++;
|
||||||
} else {
|
} else {
|
||||||
buffer.put((byte) (0xe0 | ((c >> 12))));
|
buffer.put((byte) (0xe0 | ((c >> 12))));
|
||||||
buffer.put((byte) (0x80 | ((c >> 6) & 0x3f)));
|
buffer.put((byte) (0x80 | ((c >> 6) & 0x3f)));
|
||||||
@@ -155,7 +162,34 @@ public class JsonByteBufferWriter extends JsonWriter {
|
|||||||
if (charset == null) { //UTF-8
|
if (charset == null) { //UTF-8
|
||||||
final int limit = start + len;
|
final int limit = start + len;
|
||||||
for (int i = start; i < limit; i++) {
|
for (int i = start; i < limit; i++) {
|
||||||
buffer = putUTF8Char(buffer, chs[i]);
|
char c = chs[i];
|
||||||
|
if (c < 0x80) {
|
||||||
|
if (!buffer.hasRemaining()) buffer = nextByteBuffer();
|
||||||
|
buffer.put((byte) c);
|
||||||
|
} else if (c < 0x800) {
|
||||||
|
if (!buffer.hasRemaining()) buffer = nextByteBuffer();
|
||||||
|
buffer.put((byte) (0xc0 | (c >> 6)));
|
||||||
|
if (!buffer.hasRemaining()) buffer = nextByteBuffer();
|
||||||
|
buffer.put((byte) (0x80 | (c & 0x3f)));
|
||||||
|
} else if (Character.isSurrogate(c)) { //连取两个
|
||||||
|
int uc = Character.toCodePoint(c, chs[i + 1]);
|
||||||
|
if (!buffer.hasRemaining()) buffer = nextByteBuffer();
|
||||||
|
buffer.put((byte) (0xf0 | ((uc >> 18))));
|
||||||
|
if (!buffer.hasRemaining()) buffer = nextByteBuffer();
|
||||||
|
buffer.put((byte) (0x80 | ((uc >> 12) & 0x3f)));
|
||||||
|
if (!buffer.hasRemaining()) buffer = nextByteBuffer();
|
||||||
|
buffer.put((byte) (0x80 | ((uc >> 6) & 0x3f)));
|
||||||
|
if (!buffer.hasRemaining()) buffer = nextByteBuffer();
|
||||||
|
buffer.put((byte) (0x80 | (uc & 0x3f)));
|
||||||
|
i++;
|
||||||
|
} else {
|
||||||
|
if (!buffer.hasRemaining()) buffer = nextByteBuffer();
|
||||||
|
buffer.put((byte) (0xe0 | ((c >> 12))));
|
||||||
|
if (!buffer.hasRemaining()) buffer = nextByteBuffer();
|
||||||
|
buffer.put((byte) (0x80 | ((c >> 6) & 0x3f)));
|
||||||
|
if (!buffer.hasRemaining()) buffer = nextByteBuffer();
|
||||||
|
buffer.put((byte) (0x80 | (c & 0x3f)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
while (bb.hasRemaining()) {
|
while (bb.hasRemaining()) {
|
||||||
@@ -169,50 +203,18 @@ public class JsonByteBufferWriter extends JsonWriter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private ByteBuffer putUTF8Char(ByteBuffer buffer, char c) {
|
|
||||||
if (c < 0x80) {
|
|
||||||
if (!buffer.hasRemaining()) buffer = nextByteBuffer();
|
|
||||||
buffer.put((byte) c);
|
|
||||||
} else if (c < 0x800) {
|
|
||||||
if (!buffer.hasRemaining()) buffer = nextByteBuffer();
|
|
||||||
buffer.put((byte) (0xc0 | (c >> 6)));
|
|
||||||
if (!buffer.hasRemaining()) buffer = nextByteBuffer();
|
|
||||||
buffer.put((byte) (0x80 | (c & 0x3f)));
|
|
||||||
} else {
|
|
||||||
if (!buffer.hasRemaining()) buffer = nextByteBuffer();
|
|
||||||
buffer.put((byte) (0xe0 | ((c >> 12))));
|
|
||||||
if (!buffer.hasRemaining()) buffer = nextByteBuffer();
|
|
||||||
buffer.put((byte) (0x80 | ((c >> 6) & 0x3f)));
|
|
||||||
if (!buffer.hasRemaining()) buffer = nextByteBuffer();
|
|
||||||
buffer.put((byte) (0x80 | (c & 0x3f)));
|
|
||||||
}
|
|
||||||
return buffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
private ByteBuffer nextByteBuffer() {
|
private ByteBuffer nextByteBuffer() {
|
||||||
this.buffers[this.index].flip();
|
this.buffers[this.index].flip();
|
||||||
return this.buffers[++this.index];
|
return this.buffers[++this.index];
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static int encodeUTF8Length(final char[] text, final int start, final int len) {
|
|
||||||
char c;
|
|
||||||
int size = 0;
|
|
||||||
final char[] chars = text;
|
|
||||||
final int limit = start + len;
|
|
||||||
for (int i = start; i < limit; i++) {
|
|
||||||
c = chars[i];
|
|
||||||
size += (c < 0x80 ? 1 : (c < 0x800 ? 2 : 3));
|
|
||||||
}
|
|
||||||
return size;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected static int encodeEscapeUTF8Length(final char[] text, final int start, final int len) {
|
protected static int encodeEscapeUTF8Length(final char[] text, final int start, final int len) {
|
||||||
char c;
|
char c;
|
||||||
int size = 0;
|
int size = 0;
|
||||||
final char[] chars = text;
|
final char[] chs = text;
|
||||||
final int limit = start + len;
|
final int limit = start + len;
|
||||||
for (int i = start; i < limit; i++) {
|
for (int i = start; i < limit; i++) {
|
||||||
c = chars[i];
|
c = chs[i];
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case '\n': size += 2;
|
case '\n': size += 2;
|
||||||
break;
|
break;
|
||||||
@@ -225,7 +227,7 @@ public class JsonByteBufferWriter extends JsonWriter {
|
|||||||
case '"': size += 2;
|
case '"': size += 2;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
size += (c < 0x80 ? 1 : (c < 0x800 ? 2 : 3));
|
size += (c < 0x80 ? 1 : (c < 0x800 || Character.isSurrogate(c) ? 2 : 3));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -289,7 +291,8 @@ public class JsonByteBufferWriter extends JsonWriter {
|
|||||||
if (expandsize == 0) { // 只需要一个buffer
|
if (expandsize == 0) { // 只需要一个buffer
|
||||||
final ByteBuffer buffer = this.buffers[index];
|
final ByteBuffer buffer = this.buffers[index];
|
||||||
buffer.put((byte) '"');
|
buffer.put((byte) '"');
|
||||||
for (char c : chs) {
|
for (int i = 0; i < chs.length; i++) {
|
||||||
|
char c = chs[i];
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case '\n': buffer.put((byte) '\\').put((byte) 'n');
|
case '\n': buffer.put((byte) '\\').put((byte) 'n');
|
||||||
break;
|
break;
|
||||||
@@ -307,6 +310,13 @@ public class JsonByteBufferWriter extends JsonWriter {
|
|||||||
} else if (c < 0x800) {
|
} else if (c < 0x800) {
|
||||||
buffer.put((byte) (0xc0 | (c >> 6)));
|
buffer.put((byte) (0xc0 | (c >> 6)));
|
||||||
buffer.put((byte) (0x80 | (c & 0x3f)));
|
buffer.put((byte) (0x80 | (c & 0x3f)));
|
||||||
|
} else if (Character.isSurrogate(c)) { //连取两个
|
||||||
|
int uc = Character.toCodePoint(c, chs[i + 1]);
|
||||||
|
buffer.put((byte) (0xf0 | ((uc >> 18))));
|
||||||
|
buffer.put((byte) (0x80 | ((uc >> 12) & 0x3f)));
|
||||||
|
buffer.put((byte) (0x80 | ((uc >> 6) & 0x3f)));
|
||||||
|
buffer.put((byte) (0x80 | (uc & 0x3f)));
|
||||||
|
i++;
|
||||||
} else {
|
} else {
|
||||||
buffer.put((byte) (0xe0 | ((c >> 12))));
|
buffer.put((byte) (0xe0 | ((c >> 12))));
|
||||||
buffer.put((byte) (0x80 | ((c >> 6) & 0x3f)));
|
buffer.put((byte) (0x80 | ((c >> 6) & 0x3f)));
|
||||||
|
|||||||
@@ -48,10 +48,15 @@ public class JsonConvert extends TextConvert<JsonReader, JsonWriter> {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public JsonConvert newConvert(final BiFunction<Attribute, Object, Object> fieldFunc) {
|
public JsonConvert newConvert(final BiFunction<Attribute, Object, Object> fieldFunc) {
|
||||||
|
return newConvert(fieldFunc, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JsonConvert newConvert(final BiFunction<Attribute, Object, Object> fieldFunc, Function<Object, ConvertField[]> objExtFunc) {
|
||||||
return new JsonConvert(getFactory(), tiny) {
|
return new JsonConvert(getFactory(), tiny) {
|
||||||
@Override
|
@Override
|
||||||
protected <S extends JsonWriter> S configWrite(S writer) {
|
protected <S extends JsonWriter> S configWrite(S writer) {
|
||||||
return fieldFunc(writer, fieldFunc);
|
return fieldFunc(writer, fieldFunc, objExtFunc);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
*/
|
*/
|
||||||
package org.redkale.convert.json;
|
package org.redkale.convert.json;
|
||||||
|
|
||||||
|
import java.lang.reflect.Type;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import org.redkale.convert.*;
|
import org.redkale.convert.*;
|
||||||
import org.redkale.util.*;
|
import org.redkale.util.*;
|
||||||
@@ -102,7 +103,7 @@ public class JsonWriter extends Writer {
|
|||||||
super.recycle();
|
super.recycle();
|
||||||
this.count = 0;
|
this.count = 0;
|
||||||
this.specify = null;
|
this.specify = null;
|
||||||
if (this.content.length > defaultSize) {
|
if (this.content != null && this.content.length > defaultSize) {
|
||||||
this.content = new char[defaultSize];
|
this.content = new char[defaultSize];
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@@ -159,9 +160,9 @@ public class JsonWriter extends Writer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final void writeFieldName(EnMember member) {
|
public final void writeFieldName(String fieldName, Type fieldType, int fieldPos) {
|
||||||
if (this.comma) writeTo(',');
|
if (this.comma) writeTo(',');
|
||||||
writeTo(true, member.getAttribute().field());
|
writeTo(true, fieldName);
|
||||||
writeTo(':');
|
writeTo(':');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -390,7 +390,9 @@ public class HttpResponse extends Response<HttpContext, HttpRequest> {
|
|||||||
this.header.addValue("retcode", String.valueOf(ret.getRetcode()));
|
this.header.addValue("retcode", String.valueOf(ret.getRetcode()));
|
||||||
this.header.addValue("retinfo", ret.getRetinfo());
|
this.header.addValue("retinfo", ret.getRetinfo());
|
||||||
}
|
}
|
||||||
finish(request.getJsonConvert().convertTo(getBodyBufferSupplier(), ret));
|
Convert convert = ret == null ? null : ret.convert();
|
||||||
|
if (convert == null || !(convert instanceof TextConvert)) convert = request.getJsonConvert();
|
||||||
|
finish(convert.convertTo(getBodyBufferSupplier(), ret));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -497,6 +499,8 @@ public class HttpResponse extends Response<HttpContext, HttpRequest> {
|
|||||||
context.getLogger().log(Level.WARNING, "HttpServlet finish File occur, force to close channel. request = " + getRequest(), e);
|
context.getLogger().log(Level.WARNING, "HttpServlet finish File occur, force to close channel. request = " + getRequest(), e);
|
||||||
finish(500, null);
|
finish(500, null);
|
||||||
}
|
}
|
||||||
|
} else if (obj instanceof org.redkale.service.RetResult) {
|
||||||
|
finishJson((org.redkale.service.RetResult) obj);
|
||||||
} else if (obj instanceof HttpResult) {
|
} else if (obj instanceof HttpResult) {
|
||||||
HttpResult result = (HttpResult) obj;
|
HttpResult result = (HttpResult) obj;
|
||||||
if (result.getContentType() != null) setContentType(result.getContentType());
|
if (result.getContentType() != null) setContentType(result.getContentType());
|
||||||
@@ -506,7 +510,9 @@ public class HttpResponse extends Response<HttpContext, HttpRequest> {
|
|||||||
} else if (result.getResult() instanceof CharSequence) {
|
} else if (result.getResult() instanceof CharSequence) {
|
||||||
finish(result.getResult().toString());
|
finish(result.getResult().toString());
|
||||||
} else {
|
} else {
|
||||||
finish(result.getConvert() == null ? convert : result.getConvert(), result.getResult());
|
Convert cc = result.convert();
|
||||||
|
if (cc == null || !(cc instanceof TextConvert)) cc = convert;
|
||||||
|
finish(cc, result.getResult());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (hasRender) {
|
if (hasRender) {
|
||||||
|
|||||||
@@ -90,12 +90,11 @@ public class HttpResult<T> {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ConvertDisabled
|
public Convert convert() {
|
||||||
public Convert getConvert() {
|
|
||||||
return convert;
|
return convert;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setConvert(Convert convert) {
|
public void convert(Convert convert) {
|
||||||
this.convert = convert;
|
this.convert = convert;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -860,7 +860,7 @@ public final class Rest {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (defmodulename.isEmpty() || (!pound && entrys.size() <= 6)) {
|
if (defmodulename.isEmpty() || (!pound && entrys.size() <= 2)) {
|
||||||
for (MappingEntry entry : entrys) {
|
for (MappingEntry entry : entrys) {
|
||||||
String suburl = (catalog.isEmpty() ? "/" : ("/" + catalog + "/")) + (defmodulename.isEmpty() ? "" : (defmodulename + "/")) + entry.name;
|
String suburl = (catalog.isEmpty() ? "/" : ("/" + catalog + "/")) + (defmodulename.isEmpty() ? "" : (defmodulename + "/")) + entry.name;
|
||||||
urlpath += "," + suburl;
|
urlpath += "," + suburl;
|
||||||
|
|||||||
@@ -562,7 +562,7 @@ public abstract class WebSocketNode {
|
|||||||
protected CompletableFuture<Integer> sendOneUserMessage(final Object message, final boolean last, final Serializable userid) {
|
protected CompletableFuture<Integer> sendOneUserMessage(final Object message, final boolean last, final Serializable userid) {
|
||||||
if (message instanceof CompletableFuture) return ((CompletableFuture) message).thenApply(msg -> sendOneUserMessage(msg, last, userid));
|
if (message instanceof CompletableFuture) return ((CompletableFuture) message).thenApply(msg -> sendOneUserMessage(msg, last, userid));
|
||||||
if (logger.isLoggable(Level.FINEST)) {
|
if (logger.isLoggable(Level.FINEST)) {
|
||||||
logger.finest("websocket want send message {userid:" + userid + ", content:'" + (message instanceof WebSocketPacket ? ((WebSocketPacket) message).toSimpleString() : JsonConvert.root().convertTo(message)) + "'} from locale node to " + ((this.localEngine != null) ? "locale" : "remote") + " engine");
|
logger.finest("websocket want send message {userid:" + userid + ", content:" + (message instanceof WebSocketPacket ? ((WebSocketPacket) message).toSimpleString() : (message instanceof CharSequence ? message : JsonConvert.root().convertTo(message))) + "} from locale node to " + ((this.localEngine != null) ? "locale" : "remote") + " engine");
|
||||||
}
|
}
|
||||||
CompletableFuture<Integer> localFuture = null;
|
CompletableFuture<Integer> localFuture = null;
|
||||||
if (this.localEngine != null) localFuture = localEngine.sendLocalMessage(message, last, userid);
|
if (this.localEngine != null) localFuture = localEngine.sendLocalMessage(message, last, userid);
|
||||||
@@ -595,8 +595,8 @@ public abstract class WebSocketNode {
|
|||||||
|
|
||||||
protected CompletableFuture<Integer> sendOneAddrMessage(final InetSocketAddress sncpAddr, final Object message, final boolean last, final Serializable... userids) {
|
protected CompletableFuture<Integer> sendOneAddrMessage(final InetSocketAddress sncpAddr, final Object message, final boolean last, final Serializable... userids) {
|
||||||
if (message instanceof CompletableFuture) return ((CompletableFuture) message).thenApply(msg -> sendOneAddrMessage(sncpAddr, msg, last, userids));
|
if (message instanceof CompletableFuture) return ((CompletableFuture) message).thenApply(msg -> sendOneAddrMessage(sncpAddr, msg, last, userids));
|
||||||
if (logger.isLoggable(Level.FINEST)) {
|
if (logger.isLoggable(Level.FINEST) && this.localEngine == null) { //只打印远程模式的
|
||||||
logger.finest("websocket want send message {userids:" + JsonConvert.root().convertTo(userids) + ", sncpaddr:" + sncpAddr + ", content:'" + (message instanceof WebSocketPacket ? ((WebSocketPacket) message).toSimpleString() : JsonConvert.root().convertTo(message)) + "'} from locale node to " + ((this.localEngine != null) ? "locale" : "remote") + " engine");
|
logger.finest("websocket want send message {userids:" + JsonConvert.root().convertTo(userids) + ", sncpaddr:" + sncpAddr + ", content:" + (message instanceof WebSocketPacket ? ((WebSocketPacket) message).toSimpleString() : (message instanceof CharSequence ? message : JsonConvert.root().convertTo(message))) + "} from locale node to " + ((this.localEngine != null) ? "locale" : "remote") + " engine");
|
||||||
}
|
}
|
||||||
if (Objects.equals(sncpAddr, this.localSncpAddress)) {
|
if (Objects.equals(sncpAddr, this.localSncpAddress)) {
|
||||||
return this.localEngine == null ? CompletableFuture.completedFuture(RETCODE_GROUP_EMPTY) : localEngine.sendLocalMessage(message, last, userids);
|
return this.localEngine == null ? CompletableFuture.completedFuture(RETCODE_GROUP_EMPTY) : localEngine.sendLocalMessage(message, last, userids);
|
||||||
@@ -918,7 +918,7 @@ public abstract class WebSocketNode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected CompletableFuture<Integer> sendOneAddrAction(final InetSocketAddress sncpAddr, final WebSocketAction action, final Serializable... userids) {
|
protected CompletableFuture<Integer> sendOneAddrAction(final InetSocketAddress sncpAddr, final WebSocketAction action, final Serializable... userids) {
|
||||||
if (logger.isLoggable(Level.FINEST)) {
|
if (logger.isLoggable(Level.FINEST) && this.localEngine == null) { //只打印远程模式的
|
||||||
logger.finest("websocket want send action {userids:" + JsonConvert.root().convertTo(userids) + ", sncpaddr:" + sncpAddr + ", action:" + action + " from locale node to " + ((this.localEngine != null) ? "locale" : "remote") + " engine");
|
logger.finest("websocket want send action {userids:" + JsonConvert.root().convertTo(userids) + ", sncpaddr:" + sncpAddr + ", action:" + action + " from locale node to " + ((this.localEngine != null) ? "locale" : "remote") + " engine");
|
||||||
}
|
}
|
||||||
if (Objects.equals(sncpAddr, this.localSncpAddress)) {
|
if (Objects.equals(sncpAddr, this.localSncpAddress)) {
|
||||||
|
|||||||
@@ -349,7 +349,12 @@ public final class SncpClient {
|
|||||||
final BsonWriter writer = bsonConvert.pollBsonWriter(transport.getBufferSupplier()); // 将head写入
|
final BsonWriter writer = bsonConvert.pollBsonWriter(transport.getBufferSupplier()); // 将head写入
|
||||||
writer.writeTo(DEFAULT_HEADER);
|
writer.writeTo(DEFAULT_HEADER);
|
||||||
for (int i = 0; i < params.length; i++) { //params 可能包含: 3 个 boolean
|
for (int i = 0; i < params.length; i++) { //params 可能包含: 3 个 boolean
|
||||||
bsonConvert.convertTo(writer, CompletionHandler.class.isAssignableFrom(myparamclass[i]) ? CompletionHandler.class : myparamtypes[i], params[i]);
|
BsonConvert bcc = bsonConvert;
|
||||||
|
if (params[i] instanceof org.redkale.service.RetResult) {
|
||||||
|
org.redkale.convert.Convert cc = ((org.redkale.service.RetResult) params[i]).convert();
|
||||||
|
if (cc instanceof BsonConvert) bcc = (BsonConvert) cc;
|
||||||
|
}
|
||||||
|
bcc.convertTo(writer, CompletionHandler.class.isAssignableFrom(myparamclass[i]) ? CompletionHandler.class : myparamtypes[i], params[i]);
|
||||||
}
|
}
|
||||||
final int reqBodyLength = writer.count() - HEADER_SIZE; //body总长度
|
final int reqBodyLength = writer.count() - HEADER_SIZE; //body总长度
|
||||||
final long seqid = System.nanoTime();
|
final long seqid = System.nanoTime();
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ package org.redkale.service;
|
|||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
import org.redkale.convert.Convert;
|
||||||
import org.redkale.convert.json.*;
|
import org.redkale.convert.json.*;
|
||||||
import org.redkale.util.Utility;
|
import org.redkale.util.Utility;
|
||||||
|
|
||||||
@@ -33,6 +34,8 @@ public class RetResult<T> {
|
|||||||
|
|
||||||
protected Map<String, String> attach;
|
protected Map<String, String> attach;
|
||||||
|
|
||||||
|
protected Convert convert;
|
||||||
|
|
||||||
public RetResult() {
|
public RetResult() {
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -40,6 +43,11 @@ public class RetResult<T> {
|
|||||||
this.result = result;
|
this.result = result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public RetResult(Convert convert, T result) {
|
||||||
|
this.convert = convert;
|
||||||
|
this.result = result;
|
||||||
|
}
|
||||||
|
|
||||||
public RetResult(int retcode) {
|
public RetResult(int retcode) {
|
||||||
this.retcode = retcode;
|
this.retcode = retcode;
|
||||||
}
|
}
|
||||||
@@ -55,6 +63,14 @@ public class RetResult<T> {
|
|||||||
this.result = result;
|
this.result = result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Convert convert() {
|
||||||
|
return convert;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void convert(Convert convert) {
|
||||||
|
this.convert = convert;
|
||||||
|
}
|
||||||
|
|
||||||
public static RetResult success() {
|
public static RetResult success() {
|
||||||
return new RetResult();
|
return new RetResult();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ public final class Redkale {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static String getDotedVersion() {
|
public static String getDotedVersion() {
|
||||||
return "2.0.0-beta4";
|
return "2.0.0-rc1";
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int getMajorVersion() {
|
public static int getMajorVersion() {
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
*/
|
*/
|
||||||
package org.redkale.util;
|
package org.redkale.util;
|
||||||
|
|
||||||
|
import java.lang.annotation.Annotation;
|
||||||
import java.lang.ref.WeakReference;
|
import java.lang.ref.WeakReference;
|
||||||
import java.lang.reflect.*;
|
import java.lang.reflect.*;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
@@ -42,12 +43,22 @@ public final class ResourceFactory {
|
|||||||
|
|
||||||
private final List<WeakReference<ResourceFactory>> chidren = new CopyOnWriteArrayList<>();
|
private final List<WeakReference<ResourceFactory>> chidren = new CopyOnWriteArrayList<>();
|
||||||
|
|
||||||
private final ConcurrentHashMap<Type, ResourceLoader> loadermap = new ConcurrentHashMap();
|
private final ConcurrentHashMap<Type, ResourceInjectLoader> injectLoaderMap = new ConcurrentHashMap();
|
||||||
|
|
||||||
|
private final ConcurrentHashMap<Type, ResourceLoader> resLoaderMap = new ConcurrentHashMap();
|
||||||
|
|
||||||
private final ConcurrentHashMap<Type, ConcurrentHashMap<String, ResourceEntry>> store = new ConcurrentHashMap();
|
private final ConcurrentHashMap<Type, ConcurrentHashMap<String, ResourceEntry>> store = new ConcurrentHashMap();
|
||||||
|
|
||||||
private ResourceFactory(ResourceFactory parent) {
|
private ResourceFactory(ResourceFactory parent) {
|
||||||
this.parent = parent;
|
this.parent = parent;
|
||||||
|
if (parent == null) {
|
||||||
|
ServiceLoader<ResourceInjectLoader> loaders = ServiceLoader.load(ResourceInjectLoader.class);
|
||||||
|
Iterator<ResourceInjectLoader> it = loaders.iterator();
|
||||||
|
while (it.hasNext()) {
|
||||||
|
ResourceInjectLoader ril = it.next();
|
||||||
|
this.injectLoaderMap.put(ril.annotationType(), ril);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -565,6 +576,7 @@ public final class ResourceFactory {
|
|||||||
try {
|
try {
|
||||||
list.add(src);
|
list.add(src);
|
||||||
Class clazz = src.getClass();
|
Class clazz = src.getClass();
|
||||||
|
final boolean diyloaderflag = !instance.injectLoaderMap.isEmpty();
|
||||||
do {
|
do {
|
||||||
if (java.lang.Enum.class.isAssignableFrom(clazz)) break;
|
if (java.lang.Enum.class.isAssignableFrom(clazz)) break;
|
||||||
final String cname = clazz.getName();
|
final String cname = clazz.getName();
|
||||||
@@ -586,6 +598,13 @@ public final class ResourceFactory {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (flag && diyloaderflag) {
|
||||||
|
instance.injectLoaderMap.values().stream().forEach(iloader -> {
|
||||||
|
Annotation ann = field.getAnnotation(iloader.annotationType());
|
||||||
|
if (ann == null) return;
|
||||||
|
iloader.load(this, src, ann, field, attachment);
|
||||||
|
});
|
||||||
|
}
|
||||||
if (ns == null) continue;
|
if (ns == null) continue;
|
||||||
final String nsname = ns.getClass().getName();
|
final String nsname = ns.getClass().getName();
|
||||||
if (ns.getClass().isPrimitive() || ns.getClass().isArray()
|
if (ns.getClass().isPrimitive() || ns.getClass().isArray()
|
||||||
@@ -685,16 +704,21 @@ public final class ResourceFactory {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public <T extends Annotation> void register(final ResourceInjectLoader<T> loader) {
|
||||||
|
if (loader == null) return;
|
||||||
|
instance.injectLoaderMap.put(loader.annotationType(), loader);
|
||||||
|
}
|
||||||
|
|
||||||
public void register(final ResourceLoader rs, final Type... clazzs) {
|
public void register(final ResourceLoader rs, final Type... clazzs) {
|
||||||
if (clazzs == null || rs == null) return;
|
if (clazzs == null || rs == null) return;
|
||||||
for (Type clazz : clazzs) {
|
for (Type clazz : clazzs) {
|
||||||
loadermap.put(clazz, rs);
|
resLoaderMap.put(clazz, rs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private ResourceLoader findMatchLoader(Type ft, Field field) {
|
private ResourceLoader findMatchLoader(Type ft, Field field) {
|
||||||
ResourceLoader it = this.loadermap.get(ft);
|
ResourceLoader it = this.resLoaderMap.get(ft);
|
||||||
if (it == null && field != null) it = this.loadermap.get(field.getType());
|
if (it == null && field != null) it = this.resLoaderMap.get(field.getType());
|
||||||
if (it != null) return it;
|
if (it != null) return it;
|
||||||
return parent == null ? null : parent.findMatchLoader(ft, field);
|
return parent == null ? null : parent.findMatchLoader(ft, field);
|
||||||
}
|
}
|
||||||
@@ -702,7 +726,7 @@ public final class ResourceFactory {
|
|||||||
private ResourceLoader findRegxLoader(Type ft, Field field) {
|
private ResourceLoader findRegxLoader(Type ft, Field field) {
|
||||||
if (field == null) return null;
|
if (field == null) return null;
|
||||||
Class c = field.getType();
|
Class c = field.getType();
|
||||||
for (Map.Entry<Type, ResourceLoader> en : this.loadermap.entrySet()) {
|
for (Map.Entry<Type, ResourceLoader> en : this.resLoaderMap.entrySet()) {
|
||||||
Type t = en.getKey();
|
Type t = en.getKey();
|
||||||
if (t == ft) return en.getValue();
|
if (t == ft) return en.getValue();
|
||||||
if (t instanceof Class && (((Class) t)).isAssignableFrom(c)) return en.getValue();
|
if (t instanceof Class && (((Class) t)).isAssignableFrom(c)) return en.getValue();
|
||||||
|
|||||||
25
src/org/redkale/util/ResourceInjectLoader.java
Normal file
25
src/org/redkale/util/ResourceInjectLoader.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 org.redkale.util;
|
||||||
|
|
||||||
|
import java.lang.annotation.Annotation;
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 自定义注入加载器
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* 详情见: https://redkale.org
|
||||||
|
*
|
||||||
|
* @author zhangjx
|
||||||
|
* @param <T> Annotation
|
||||||
|
*/
|
||||||
|
public interface ResourceInjectLoader<T extends Annotation> {
|
||||||
|
|
||||||
|
public void load(ResourceFactory factory, Object src, T annotation, Field field, Object attachment);
|
||||||
|
|
||||||
|
public Class<T> annotationType();
|
||||||
|
}
|
||||||
@@ -610,6 +610,30 @@ public final class Utility {
|
|||||||
return news;
|
return news;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将int数组倒序
|
||||||
|
*
|
||||||
|
* @param array 原数组
|
||||||
|
*
|
||||||
|
* @return 新数组
|
||||||
|
*/
|
||||||
|
public static int[] reverseSort(final int[] array) {
|
||||||
|
if (array == null || array.length == 0) return array;
|
||||||
|
return Arrays.stream(array).boxed().sorted(Collections.reverseOrder()).mapToInt(x -> x).toArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将long数组倒序
|
||||||
|
*
|
||||||
|
* @param array 原数组
|
||||||
|
*
|
||||||
|
* @return 新数组
|
||||||
|
*/
|
||||||
|
public static long[] reverseSort(final long[] array) {
|
||||||
|
if (array == null || array.length == 0) return array;
|
||||||
|
return Arrays.stream(array).boxed().sorted(Collections.reverseOrder()).mapToLong(x -> x).toArray();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 将元素从数组中删除
|
* 将元素从数组中删除
|
||||||
*
|
*
|
||||||
@@ -1848,10 +1872,10 @@ public final class Utility {
|
|||||||
public static byte[] encodeUTF8(final char[] text, final int start, final int len) {
|
public static byte[] encodeUTF8(final char[] text, final int start, final int len) {
|
||||||
char c;
|
char c;
|
||||||
int size = 0;
|
int size = 0;
|
||||||
final char[] chars = text;
|
final char[] chs = text;
|
||||||
final int limit = start + len;
|
final int limit = start + len;
|
||||||
for (int i = start; i < limit; i++) {
|
for (int i = start; i < limit; i++) {
|
||||||
c = chars[i];
|
c = chs[i];
|
||||||
if (c < 0x80) {
|
if (c < 0x80) {
|
||||||
size++;
|
size++;
|
||||||
} else if (c < 0x800) {
|
} else if (c < 0x800) {
|
||||||
@@ -1865,14 +1889,14 @@ public final class Utility {
|
|||||||
final byte[] bytes = new byte[size];
|
final byte[] bytes = new byte[size];
|
||||||
size = 0;
|
size = 0;
|
||||||
for (int i = start; i < limit; i++) {
|
for (int i = start; i < limit; i++) {
|
||||||
c = chars[i];
|
c = chs[i];
|
||||||
if (c < 0x80) {
|
if (c < 0x80) {
|
||||||
bytes[size++] = (byte) c;
|
bytes[size++] = (byte) c;
|
||||||
} else if (c < 0x800) {
|
} else if (c < 0x800) {
|
||||||
bytes[size++] = (byte) (0xc0 | (c >> 6));
|
bytes[size++] = (byte) (0xc0 | (c >> 6));
|
||||||
bytes[size++] = (byte) (0x80 | (c & 0x3f));
|
bytes[size++] = (byte) (0x80 | (c & 0x3f));
|
||||||
} else if (Character.isSurrogate(c)) { //连取两个
|
} else if (Character.isSurrogate(c)) { //连取两个
|
||||||
int uc = Character.toCodePoint(c, chars[i + 1]);
|
int uc = Character.toCodePoint(c, chs[i + 1]);
|
||||||
bytes[size++] = (byte) (0xf0 | ((uc >> 18)));
|
bytes[size++] = (byte) (0xf0 | ((uc >> 18)));
|
||||||
bytes[size++] = (byte) (0x80 | ((uc >> 12) & 0x3f));
|
bytes[size++] = (byte) (0x80 | ((uc >> 12) & 0x3f));
|
||||||
bytes[size++] = (byte) (0x80 | ((uc >> 6) & 0x3f));
|
bytes[size++] = (byte) (0x80 | ((uc >> 6) & 0x3f));
|
||||||
@@ -1920,10 +1944,10 @@ public final class Utility {
|
|||||||
public static int encodeUTF8Length(final char[] text, final int start, final int len) {
|
public static int encodeUTF8Length(final char[] text, final int start, final int len) {
|
||||||
char c;
|
char c;
|
||||||
int size = 0;
|
int size = 0;
|
||||||
final char[] chars = text;
|
final char[] chs = text;
|
||||||
final int limit = start + len;
|
final int limit = start + len;
|
||||||
for (int i = start; i < limit; i++) {
|
for (int i = start; i < limit; i++) {
|
||||||
c = chars[i];
|
c = chs[i];
|
||||||
if (c < 0x80) {
|
if (c < 0x80) {
|
||||||
size++;
|
size++;
|
||||||
} else if (c < 0x800) {
|
} else if (c < 0x800) {
|
||||||
@@ -1956,13 +1980,13 @@ public final class Utility {
|
|||||||
//返回的ByteBuffer为扩展buffer,为null表示参数中的buffer足够存储数据
|
//返回的ByteBuffer为扩展buffer,为null表示参数中的buffer足够存储数据
|
||||||
public static ByteBuffer encodeUTF8(final ByteBuffer buffer, int bytesLength, final char[] text, final int start, final int len) {
|
public static ByteBuffer encodeUTF8(final ByteBuffer buffer, int bytesLength, final char[] text, final int start, final int len) {
|
||||||
char c;
|
char c;
|
||||||
char[] chars = text;
|
char[] chs = text;
|
||||||
final int limit = start + len;
|
final int limit = start + len;
|
||||||
int remain = buffer.remaining();
|
int remain = buffer.remaining();
|
||||||
final ByteBuffer buffer2 = remain >= bytesLength ? null : ByteBuffer.allocate(bytesLength - remain + 4); //最差情况buffer最后两byte没有填充
|
final ByteBuffer buffer2 = remain >= bytesLength ? null : ByteBuffer.allocate(bytesLength - remain + 4); //最差情况buffer最后两byte没有填充
|
||||||
ByteBuffer buf = buffer;
|
ByteBuffer buf = buffer;
|
||||||
for (int i = start; i < limit; i++) {
|
for (int i = start; i < limit; i++) {
|
||||||
c = chars[i];
|
c = chs[i];
|
||||||
if (c < 0x80) {
|
if (c < 0x80) {
|
||||||
if (buf.remaining() < 1) buf = buffer2;
|
if (buf.remaining() < 1) buf = buffer2;
|
||||||
buf.put((byte) c);
|
buf.put((byte) c);
|
||||||
@@ -1972,7 +1996,7 @@ public final class Utility {
|
|||||||
buf.put((byte) (0x80 | (c & 0x3f)));
|
buf.put((byte) (0x80 | (c & 0x3f)));
|
||||||
} else if (Character.isSurrogate(c)) { //连取两个
|
} else if (Character.isSurrogate(c)) { //连取两个
|
||||||
if (buf.remaining() < 4) buf = buffer2;
|
if (buf.remaining() < 4) buf = buffer2;
|
||||||
int uc = Character.toCodePoint(c, chars[i + 1]);
|
int uc = Character.toCodePoint(c, chs[i + 1]);
|
||||||
buf.put((byte) (0xf0 | ((uc >> 18))));
|
buf.put((byte) (0xf0 | ((uc >> 18))));
|
||||||
buf.put((byte) (0x80 | ((uc >> 12) & 0x3f)));
|
buf.put((byte) (0x80 | ((uc >> 12) & 0x3f)));
|
||||||
buf.put((byte) (0x80 | ((uc >> 6) & 0x3f)));
|
buf.put((byte) (0x80 | ((uc >> 6) & 0x3f)));
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
*/
|
*/
|
||||||
package org.redkale.test.convert;
|
package org.redkale.test.convert;
|
||||||
|
|
||||||
|
import org.redkale.convert.ConvertField;
|
||||||
import org.redkale.convert.json.JsonConvert;
|
import org.redkale.convert.json.JsonConvert;
|
||||||
import org.redkale.util.Attribute;
|
import org.redkale.util.Attribute;
|
||||||
|
|
||||||
@@ -15,13 +16,18 @@ import org.redkale.util.Attribute;
|
|||||||
public class BiFunctionConvertMain {
|
public class BiFunctionConvertMain {
|
||||||
|
|
||||||
public static class GamePlayer {
|
public static class GamePlayer {
|
||||||
|
|
||||||
public int userid;
|
public int userid;
|
||||||
|
|
||||||
public String username;
|
public String username;
|
||||||
|
|
||||||
public int[] cards;
|
public int[] cards;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class GameTable {
|
public static class GameTable {
|
||||||
|
|
||||||
public int tableid;
|
public int tableid;
|
||||||
|
|
||||||
public GamePlayer[] players;
|
public GamePlayer[] players;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -50,9 +56,13 @@ public class BiFunctionConvertMain {
|
|||||||
return t.get(u);
|
return t.get(u);
|
||||||
}
|
}
|
||||||
return t.get(u);
|
return t.get(u);
|
||||||
|
}, (Object u) -> {
|
||||||
|
if (table != u) return null;
|
||||||
|
//return new ConvertField[]{new ConvertField("extcol1", 30), new ConvertField("extcol2", "扩展字段值")};
|
||||||
|
return ConvertField.ofArray("extcol1", 30, "extcol2", "扩展字段值");
|
||||||
});
|
});
|
||||||
System.out.println(convert2.convertTo(table));
|
System.out.println(convert2.convertTo(table));
|
||||||
//{"players":[{"cards":[11,12,13,14,15],"userid":1,"username":"玩家1"},{"cards":[21,22,23,24,25],"userid":2,"username":"玩家2"},{"cards":[31,32,33,34,35],"userid":3,"username":"玩家3"}],"tableid":100}
|
//{"players":[{"cards":[11,12,13,14,15],"userid":1,"username":"玩家1"},{"cards":[21,22,23,24,25],"userid":2,"username":"玩家2"},{"cards":[31,32,33,34,35],"userid":3,"username":"玩家3"}],"tableid":100}
|
||||||
//{"players":[{"cards":[11,12,13,14,15],"userid":1,"username":"玩家1"},{"cards":[21,22,23,24,25],"userid":2,"username":"玩家2"},{"userid":3,"username":"玩家3"}],"tableid":100}
|
//{"players":[{"cards":[11,12,13,14,15],"userid":1,"username":"玩家1"},{"cards":[21,22,23,24,25],"userid":2,"username":"玩家2"},{"userid":3,"username":"玩家3"}],"tableid":100,"extcol1":30,"extcol2":"扩展字段值"}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
67
test/org/redkale/test/util/ResourceInjectMain.java
Normal file
67
test/org/redkale/test/util/ResourceInjectMain.java
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
/*
|
||||||
|
* 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 org.redkale.test.util;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.lang.annotation.*;
|
||||||
|
import static java.lang.annotation.ElementType.FIELD;
|
||||||
|
import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import org.redkale.convert.json.JsonConvert;
|
||||||
|
import org.redkale.util.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author zhangjx
|
||||||
|
*/
|
||||||
|
public class ResourceInjectMain {
|
||||||
|
|
||||||
|
public static void main(String[] args) throws Throwable {
|
||||||
|
ResourceFactory factory = ResourceFactory.root();
|
||||||
|
factory.register(new CustomConfLoader());
|
||||||
|
InjectBean bean = new InjectBean();
|
||||||
|
factory.inject(bean);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class CustomConfLoader implements ResourceInjectLoader<CustomConf> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void load(ResourceFactory factory, Object src, CustomConf annotation, Field field, Object attachment) {
|
||||||
|
try {
|
||||||
|
field.set(src, new File(annotation.path()));
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
System.out.println("对象是 src =" + src + ", path=" + annotation.path());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Class<CustomConf> annotationType() {
|
||||||
|
return CustomConf.class;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class InjectBean {
|
||||||
|
|
||||||
|
@CustomConf(path = "conf/test.xml")
|
||||||
|
public File conf;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return JsonConvert.root().convertTo(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Documented
|
||||||
|
@Target({FIELD})
|
||||||
|
@Retention(RUNTIME)
|
||||||
|
public static @interface CustomConf {
|
||||||
|
|
||||||
|
String path();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user