27 Commits

Author SHA1 Message Date
Redkale
bd21644571 Redkale 2.0.0.rc1 结束 2019-10-18 08:42:28 +08:00
Redkale
5f3599d9b8 2019-10-17 18:51:08 +08:00
Redkale
1e4a30bd70 2019-10-16 15:17:04 +08:00
Redkale
e7dc5de9f2 2019-10-15 22:18:44 +08:00
Redkale
ccb9cb28f5 修复JsonByteBufferWriter的utf8问题 2019-10-15 21:55:31 +08:00
Redkale
4d9b72c922 2019-10-15 21:43:45 +08:00
Redkale
a51ae13a39 2019-10-15 18:02:34 +08:00
Redkale
dfca186688 2019-10-15 18:01:34 +08:00
Redkale
fadd229a89 2019-10-14 15:29:28 +08:00
Redkale
7acc69adc4 2019-10-14 12:32:53 +08:00
Redkale
d88e4120a1 2019-10-13 17:29:12 +08:00
Redkale
ef98edd91a Convert.newConvert 增加第2个Function参数 2019-10-13 12:55:00 +08:00
Redkale
f4548bbe34 2019-10-11 11:13:41 +08:00
Redkale
11a5faca1d Utility增加reverseSort方法 2019-10-11 08:59:40 +08:00
Redkale
c37b0e8cb5 Redkale 2.0.0.beta5 结束 2019-10-10 09:21:48 +08:00
Redkale
a20570a6eb 2019-10-10 09:17:42 +08:00
Redkale
5e3edb7e1d 2019-10-09 13:43:11 +08:00
Redkale
ad8f1d2da6 增加util.ResourceInjectLoader功能 2019-10-09 13:42:29 +08:00
Redkale
24b23c894f 修复FileSimpledCoder的instance写错的bug 2019-10-09 13:41:39 +08:00
Redkale
c551d5fb81 2019-09-26 16:32:36 +08:00
Redkale
fba43894c1 2019-09-26 16:27:42 +08:00
Redkale
22cc7e086c RetResult增加Convert属性 2019-09-26 16:22:56 +08:00
Redkale
1791008729 2019-09-25 15:41:19 +08:00
Redkale
90e15dd253 2019-09-25 15:40:47 +08:00
Redkale
7db73c076c 2019-09-25 15:33:18 +08:00
Redkale
95ad6e99d9 2019-09-23 18:57:45 +08:00
Redkale
0b2a5d0f61 2019-09-23 08:59:03 +08:00
24 changed files with 460 additions and 107 deletions

View File

@@ -1 +0,0 @@
<EFBFBD>Լ<EFBFBD><EFBFBD><EFBFBD>ҵ<EFBFBD><EFBFBD>jarĬ<EFBFBD>Ϸ<EFBFBD><EFBFBD>ڴ˴<EFBFBD>

View File

@@ -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>

View File

@@ -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();

View 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);
}
}

View File

@@ -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);
} }

View File

@@ -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值

View File

@@ -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);
} }
}; };
} }

View File

@@ -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));
} }
/** /**

View File

@@ -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) {

View File

@@ -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)));

View File

@@ -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);
} }
}; };
} }

View File

@@ -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(':');
} }

View File

@@ -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) {

View File

@@ -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;
} }

View File

@@ -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;

View File

@@ -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)) {

View File

@@ -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();

View File

@@ -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();
} }

View File

@@ -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() {

View File

@@ -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();

View 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();
}

View File

@@ -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)));

View File

@@ -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,44 +16,53 @@ 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;
} }
public static void main(String[] args) throws Throwable { public static void main(String[] args) throws Throwable {
GamePlayer player1 = new GamePlayer(); GamePlayer player1 = new GamePlayer();
player1.userid= 1; player1.userid = 1;
player1.username="玩家1"; player1.username = "玩家1";
player1.cards = new int[]{11,12,13,14,15}; player1.cards = new int[]{11, 12, 13, 14, 15};
GamePlayer player2 = new GamePlayer(); GamePlayer player2 = new GamePlayer();
player2.userid= 2; player2.userid = 2;
player2.username="玩家2"; player2.username = "玩家2";
player2.cards = new int[]{21,22,23,24,25}; player2.cards = new int[]{21, 22, 23, 24, 25};
GamePlayer player3 = new GamePlayer(); GamePlayer player3 = new GamePlayer();
player3.userid= 3; player3.userid = 3;
player3.username="玩家3"; player3.username = "玩家3";
player3.cards = new int[]{31,32,33,34,35}; player3.cards = new int[]{31, 32, 33, 34, 35};
GameTable table = new GameTable(); GameTable table = new GameTable();
table.tableid=100; table.tableid = 100;
table.players = new GamePlayer[]{player1,player2,player3}; table.players = new GamePlayer[]{player1, player2, player3};
JsonConvert convert1 = JsonConvert.root(); JsonConvert convert1 = JsonConvert.root();
System.out.println(convert1.convertTo(table)); System.out.println(convert1.convertTo(table));
JsonConvert convert2 = convert1.newConvert((Attribute t, Object u) -> { JsonConvert convert2 = convert1.newConvert((Attribute t, Object u) -> {
if(t.field().equals("cards") && u instanceof GamePlayer){ if (t.field().equals("cards") && u instanceof GamePlayer) {
int userid = ((GamePlayer)u).userid; int userid = ((GamePlayer) u).userid;
if(userid == 3) return null; //玩家3的cards不输出 if (userid == 3) return null; //玩家3的cards不输出
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":"扩展字段值"}
} }
} }

View 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();
}
}