11 Commits
1.8.2 ... 1.8.3

Author SHA1 Message Date
Redkale
8b3658143a 修复HttpResponse.finishFile传输偶尔异常的BUG 2017-09-25 11:40:49 +08:00
Redkale
6d69ff546b 2017-09-13 11:10:24 +08:00
Redkale
9555e3c9b9 2017-09-13 10:43:34 +08:00
Redkale
744634dbdd ResourceFactory 增加 public <A> List<A> query(final BiPredicate<String, A> predicate) 方法 2017-09-12 19:34:50 +08:00
Redkale
de5ee844c4 Convert 增加 convertMapTo 系列方法, HttpResponse增加 finishMapJson 系列方法 2017-09-09 22:36:35 +08:00
Redkale
ae73cee357 2017-09-09 13:24:19 +08:00
Redkale
d1cf9be8d7 AnyEncoder增加convertMapTo方法 2017-09-09 13:23:35 +08:00
Redkale
43ae77ab33 2017-09-01 11:13:22 +08:00
Redkale
182a75cfad 修复创建RestServlet时方法内含try/catch导致获取方法参数名错位的BUG 2017-09-01 10:51:41 +08:00
Redkale
222dc0edce 2017-08-28 21:54:48 +08:00
Redkale
c7a81513fe Redkale 1.8.3 开始 2017-08-28 19:20:51 +08:00
24 changed files with 236 additions and 30 deletions

View File

@@ -22,6 +22,7 @@ import java.util.logging.Formatter;
*
* @author zhangjx
*/
@SuppressWarnings("unchecked")
public class LogFileHandler extends Handler {
/**

View File

@@ -122,6 +122,7 @@ public class NodeHttpServer extends NodeServer {
}, WebSocketNode.class);
}
@SuppressWarnings("unchecked")
protected void loadHttpFilter(final AnyValue filtersConf, final ClassFilter<? extends Filter> classFilter) throws Exception {
final StringBuilder sb = logger.isLoggable(Level.INFO) ? new StringBuilder() : null;
final String threadName = "[" + Thread.currentThread().getName() + "] ";
@@ -138,6 +139,7 @@ public class NodeHttpServer extends NodeServer {
if (sb != null && sb.length() > 0) logger.log(Level.INFO, sb.toString());
}
@SuppressWarnings("unchecked")
protected void loadHttpServlet(final ClassFilter<? extends Servlet> servletFilter, ClassFilter<? extends WebSocket> webSocketFilter) throws Exception {
final AnyValue servletsConf = this.serverConf.getAnyValue("servlets");
final StringBuilder sb = logger.isLoggable(Level.INFO) ? new StringBuilder() : null;
@@ -195,6 +197,7 @@ public class NodeHttpServer extends NodeServer {
if (sb != null && sb.length() > 0) logger.log(Level.INFO, sb.toString().trim());
}
@SuppressWarnings("unchecked")
protected void loadRestServlet(final ClassFilter<? extends WebSocket> webSocketFilter, final AnyValue restConf, final List<Object> restedObjects, final StringBuilder sb) throws Exception {
if (!rest) return;
if (restConf == null) return; //不存在REST服务

View File

@@ -85,6 +85,7 @@ public class NodeSncpServer extends NodeServer {
if (sncpServer != null) loadSncpFilter(this.serverConf.getAnyValue("fliters"), filterFilter);
}
@SuppressWarnings("unchecked")
protected void loadSncpFilter(final AnyValue servletsConf, final ClassFilter<? extends Filter> classFilter) throws Exception {
final StringBuilder sb = logger.isLoggable(Level.INFO) ? new StringBuilder() : null;
final String threadName = "[" + Thread.currentThread().getName() + "] ";
@@ -106,6 +107,7 @@ public class NodeSncpServer extends NodeServer {
}
@Override
@SuppressWarnings("unchecked")
protected ClassFilter<Filter> createFilterClassFilter() {
return createClassFilter(null, null, SncpFilter.class, new Class[]{org.redkale.watch.WatchFilter.class}, null, "filters", "filter");
}

View File

@@ -35,6 +35,23 @@ public final class AnyEncoder<T> implements Encodeable<Writer, T> {
}
}
@SuppressWarnings("unchecked")
public void convertMapTo(final Writer out, final Object... values) {
if (values == null) {
out.writeNull();
} else {
int count = values.length - values.length % 2;
out.writeMapB(count / 2);
for (int i = 0; i < count; i += 2) {
if (i > 0) out.writeArrayMark();
this.convertTo(out, (T) values[i]);
out.writeMapMark();
this.convertTo(out, (T) values[i + 1]);
}
out.writeMapE();
}
}
@Override
public Type getType() {
return Object.class;

View File

@@ -40,4 +40,7 @@ public abstract class Convert<R extends Reader, W extends Writer> {
public abstract ByteBuffer[] convertTo(final Supplier<ByteBuffer> supplier, final Object value);
public abstract ByteBuffer[] convertTo(final Supplier<ByteBuffer> supplier, final Type type, final Object value);
public abstract ByteBuffer[] convertMapTo(final Supplier<ByteBuffer> supplier, final Object... values);
}

View File

@@ -104,6 +104,7 @@ public final class BsonConvert extends Convert<BsonReader, BsonWriter> {
return convertFrom(type, bytes, 0, bytes.length);
}
@SuppressWarnings("unchecked")
public <T> T convertFrom(final Type type, final byte[] bytes, final int start, final int len) {
if (type == null) return null;
final BsonReader in = readerPool.get();
@@ -114,23 +115,27 @@ public final class BsonConvert extends Convert<BsonReader, BsonWriter> {
return rs;
}
@SuppressWarnings("unchecked")
public <T> T convertFrom(final Type type, final InputStream in) {
if (type == null || in == null) return null;
return (T) factory.loadDecoder(type).convertFrom(new BsonStreamReader(in));
}
@Override
@SuppressWarnings("unchecked")
public <T> T convertFrom(final Type type, final ByteBuffer... buffers) {
if (type == null || buffers.length < 1) return null;
return (T) factory.loadDecoder(type).convertFrom(new BsonByteBufferReader((ConvertMask) null, buffers));
}
@Override
@SuppressWarnings("unchecked")
public <T> T convertFrom(final Type type, final ConvertMask mask, final ByteBuffer... buffers) {
if (type == null || buffers.length < 1) return null;
return (T) factory.loadDecoder(type).convertFrom(new BsonByteBufferReader(mask, buffers));
}
@SuppressWarnings("unchecked")
public <T> T convertFrom(final Type type, final BsonReader reader) {
if (type == null) return null;
@SuppressWarnings("unchecked")
@@ -159,6 +164,15 @@ public final class BsonConvert extends Convert<BsonReader, BsonWriter> {
return result;
}
public byte[] convertMapTo(final Object... values) {
if (values == null) return null;
final BsonWriter out = writerPool.get().tiny(tiny);
((AnyEncoder) factory.getAnyEncoder()).convertMapTo(out, values);
byte[] result = out.toArray();
writerPool.offer(out);
return result;
}
public void convertTo(final OutputStream out, final Object value) {
if (value == null) {
new BsonStreamWriter(tiny, out).writeNull();
@@ -176,6 +190,14 @@ public final class BsonConvert extends Convert<BsonReader, BsonWriter> {
}
}
public void convertMapTo(final OutputStream out, final Object... values) {
if (values == null) {
new BsonStreamWriter(tiny, out).writeNull();
} else {
((AnyEncoder) factory.getAnyEncoder()).convertMapTo(new BsonStreamWriter(tiny, out), values);
}
}
@Override
public ByteBuffer[] convertTo(final Supplier<ByteBuffer> supplier, final Object value) {
if (supplier == null) return null;
@@ -200,6 +222,18 @@ public final class BsonConvert extends Convert<BsonReader, BsonWriter> {
return out.toBuffers();
}
@Override
public ByteBuffer[] convertMapTo(final Supplier<ByteBuffer> supplier, final Object... values) {
if (supplier == null) return null;
BsonByteBufferWriter out = new BsonByteBufferWriter(tiny, supplier);
if (values == null) {
out.writeNull();
} else {
((AnyEncoder) factory.getAnyEncoder()).convertMapTo(out, values);
}
return out.toBuffers();
}
public void convertTo(final BsonWriter writer, final Object value) {
if (value == null) {
writer.writeNull();
@@ -213,6 +247,14 @@ public final class BsonConvert extends Convert<BsonReader, BsonWriter> {
factory.loadEncoder(type).convertTo(writer, value);
}
public void convertMapTo(final BsonWriter writer, final Object... values) {
if (values == null) {
writer.writeNull();
} else {
((AnyEncoder) factory.getAnyEncoder()).convertMapTo(writer, values);
}
}
public BsonWriter convertToWriter(final Object value) {
if (value == null) return null;
return convertToWriter(value.getClass(), value);
@@ -225,4 +267,9 @@ public final class BsonConvert extends Convert<BsonReader, BsonWriter> {
return out;
}
public BsonWriter convertMapToWriter(final Object... values) {
final BsonWriter out = writerPool.get().tiny(tiny);
((AnyEncoder) factory.getAnyEncoder()).convertMapTo(out, values);
return out;
}
}

View File

@@ -87,6 +87,7 @@ public class BsonReader extends Reader {
* 跳过属性的值
*/
@Override
@SuppressWarnings("unchecked")
public final void skipValue() {
if (typeval == 0) return;
final byte val = this.typeval;

View File

@@ -32,7 +32,7 @@ public final class DateSimpledCoder<R extends Reader, W extends Writer> extends
@Override
public Date convertFrom(R in) {
long t = in.readLong();
return t == 0 ? null : new Date();
return t == 0 ? null : new Date(t);
}
}

View File

@@ -20,6 +20,7 @@ import java.net.*;
* @param <R> Reader输入的子类型
* @param <W> Writer输出的子类型
*/
@SuppressWarnings("unchecked")
public final class InetAddressSimpledCoder<R extends Reader, W extends Writer> extends SimpledCoder<R, W, InetAddress> {
public static final InetAddressSimpledCoder instance = new InetAddressSimpledCoder();
@@ -50,6 +51,7 @@ public final class InetAddressSimpledCoder<R extends Reader, W extends Writer> e
* @param <R> Reader输入的子类型
* @param <W> Writer输出的子类型
*/
@SuppressWarnings("unchecked")
public final static class InetSocketAddressSimpledCoder<R extends Reader, W extends Writer> extends SimpledCoder<R, W, InetSocketAddress> {
public static final InetSocketAddressSimpledCoder instance = new InetSocketAddressSimpledCoder();

View File

@@ -149,6 +149,15 @@ public final class JsonConvert extends Convert<JsonReader, JsonWriter> {
return result;
}
public String convertMapTo(final Object... values) {
if (values == null) return "null";
final JsonWriter out = writerPool.get().tiny(tiny);
((AnyEncoder) factory.getAnyEncoder()).convertMapTo(out, values);
String result = out.toString();
writerPool.offer(out);
return result;
}
public void convertTo(final OutputStream out, final Object value) {
if (value == null) {
new JsonStreamWriter(tiny, out).writeNull();
@@ -166,6 +175,14 @@ public final class JsonConvert extends Convert<JsonReader, JsonWriter> {
}
}
public void convertMapTo(final OutputStream out, final Object... values) {
if (values == null) {
new JsonStreamWriter(tiny, out).writeNull();
} else {
((AnyEncoder) factory.getAnyEncoder()).convertMapTo(new JsonStreamWriter(tiny, out), values);
}
}
@Override
public ByteBuffer[] convertTo(final Supplier<ByteBuffer> supplier, final Object value) {
if (supplier == null) return null;
@@ -190,6 +207,18 @@ public final class JsonConvert extends Convert<JsonReader, JsonWriter> {
return out.toBuffers();
}
@Override
public ByteBuffer[] convertMapTo(final Supplier<ByteBuffer> supplier, final Object... values) {
if (supplier == null) return null;
JsonByteBufferWriter out = new JsonByteBufferWriter(tiny, null, supplier);
if (values == null) {
out.writeNull();
} else {
((AnyEncoder) factory.getAnyEncoder()).convertMapTo(out, values);
}
return out.toBuffers();
}
public void convertTo(final JsonWriter writer, final Object value) {
if (value == null) {
writer.writeNull();
@@ -207,6 +236,14 @@ public final class JsonConvert extends Convert<JsonReader, JsonWriter> {
}
}
public void convertMapTo(final JsonWriter writer, final Object... values) {
if (values == null) {
writer.writeNull();
} else {
((AnyEncoder) factory.getAnyEncoder()).convertMapTo(writer, values);
}
}
public JsonWriter convertToWriter(final Object value) {
if (value == null) return null;
return convertToWriter(value.getClass(), value);
@@ -218,4 +255,10 @@ public final class JsonConvert extends Convert<JsonReader, JsonWriter> {
factory.loadEncoder(type).convertTo(out, value);
return out;
}
public JsonWriter convertMapToWriter(final Object... values) {
final JsonWriter out = writerPool.get().tiny(tiny);
((AnyEncoder) factory.getAnyEncoder()).convertMapTo(out, values);
return out;
}
}

View File

@@ -20,6 +20,7 @@ import org.redkale.util.*;
*
* @author zhangjx
*/
@SuppressWarnings("unchecked")
public final class JsonFactory extends ConvertFactory<JsonReader, JsonWriter> {
private static final JsonFactory instance = new JsonFactory(null, Boolean.getBoolean("convert.json.tiny"));

View File

@@ -118,6 +118,7 @@ public abstract class PrepareServlet<K extends Serializable, C extends Context,
}
@Override
@SuppressWarnings("unchecked")
public void init(C context, AnyValue config) {
synchronized (filters) {
if (!filters.isEmpty()) {
@@ -136,6 +137,7 @@ public abstract class PrepareServlet<K extends Serializable, C extends Context,
}
@Override
@SuppressWarnings("unchecked")
public void destroy(C context, AnyValue config) {
synchronized (filters) {
if (!filters.isEmpty()) {
@@ -146,6 +148,7 @@ public abstract class PrepareServlet<K extends Serializable, C extends Context,
}
}
@SuppressWarnings("unchecked")
public void addFilter(Filter<C, R, P> filter, AnyValue conf) {
filter._conf = conf;
synchronized (filters) {
@@ -176,6 +179,7 @@ public abstract class PrepareServlet<K extends Serializable, C extends Context,
return false;
}
@SuppressWarnings("unchecked")
public <T extends Filter<C, R, P>> T removeFilter(Predicate<T> predicate) {
if (this.headFilter == null || predicate == null) return null;
synchronized (filters) {
@@ -198,10 +202,12 @@ public abstract class PrepareServlet<K extends Serializable, C extends Context,
}
}
@SuppressWarnings("unchecked")
public <T extends Filter<C, R, P>> List<T> getFilters() {
return (List) new ArrayList<>(filters);
}
@SuppressWarnings("unchecked")
public abstract void addServlet(S servlet, Object attachment, AnyValue conf, K... mappings);
public final void prepare(final ByteBuffer buffer, final R request, final P response) throws IOException {

View File

@@ -51,6 +51,7 @@ public abstract class Request<C extends Context> {
* 返回值Integer.MIN_VALUE: 帧数据; -1数据不合法 0解析完毕 &gt;0: 需再读取的字节数。
*
* @param buffer ByteBuffer对象
*
* @return 缺少的字节数
*/
protected abstract int readHeader(ByteBuffer buffer);
@@ -59,6 +60,7 @@ public abstract class Request<C extends Context> {
* 读取buffer并返回读取的有效数据长度
*
* @param buffer ByteBuffer对象
*
* @return 有效数据长度
*/
protected abstract int readBody(ByteBuffer buffer);
@@ -82,8 +84,9 @@ public abstract class Request<C extends Context> {
return (T) properties.get(name);
}
@SuppressWarnings("unchecked")
protected <T> T removeProperty(String name) {
return (T)properties.remove(name);
return (T) properties.remove(name);
}
protected Map<String, Object> getProperties() {
@@ -100,8 +103,9 @@ public abstract class Request<C extends Context> {
return (T) attributes.get(name);
}
@SuppressWarnings("unchecked")
public <T> T removeAttribute(String name) {
return (T)attributes.remove(name);
return (T) attributes.remove(name);
}
public Map<String, Object> getAttributes() {

View File

@@ -53,6 +53,7 @@ public class HttpContext extends Context {
return responsePool;
}
@SuppressWarnings("unchecked")
protected <H extends AsyncHandler> Creator<H> loadAsyncHandlerCreator(Class<H> handlerClass) {
Creator<H> creator = asyncHandlerCreators.get(handlerClass);
if (creator == null) {
@@ -62,6 +63,7 @@ public class HttpContext extends Context {
return creator;
}
@SuppressWarnings("unchecked")
private <H extends AsyncHandler> Creator<H> createAsyncHandlerCreator(Class<H> handlerClass) {
//生成规则与SncpAsyncHandler.Factory 很类似
//-------------------------------------------------------------

View File

@@ -186,6 +186,7 @@ public class HttpResponse extends Response<HttpContext, HttpRequest> {
}
@Override
@SuppressWarnings("unchecked")
protected void thenEvent(Servlet servlet) {
this.servlet = servlet;
}
@@ -248,6 +249,7 @@ public class HttpResponse extends Response<HttpContext, HttpRequest> {
*
* @return AsyncHandler AsyncHandler
*/
@SuppressWarnings("unchecked")
public <H extends AsyncHandler> H createAsyncHandler(Class<H> handlerClass) {
if (handlerClass == null || handlerClass == AsyncHandler.class) return (H) createAsyncHandler();
return context.loadAsyncHandlerCreator(handlerClass).create(createAsyncHandler());
@@ -264,6 +266,18 @@ public class HttpResponse extends Response<HttpContext, HttpRequest> {
finish(request.getJsonConvert().convertTo(context.getBufferSupplier(), obj));
}
/**
* 将对象数组用Map的形式以JSON格式输出 <br>
* 例如: finishMap("a",2,"b",3) 输出结果为 {"a":2,"b":3}
*
* @param objs 输出对象
*/
public void finishMapJson(final Object... objs) {
this.contentType = "text/plain; charset=utf-8";
if (this.recycleListener != null) this.output = objs;
finish(request.getJsonConvert().convertMapTo(context.getBufferSupplier(), objs));
}
/**
* 将对象以JSON格式输出
*
@@ -276,6 +290,19 @@ public class HttpResponse extends Response<HttpContext, HttpRequest> {
finish(convert.convertTo(context.getBufferSupplier(), obj));
}
/**
* 将对象数组用Map的形式以JSON格式输出 <br>
* 例如: finishMap("a",2,"b",3) 输出结果为 {"a":2,"b":3}
*
* @param convert 指定的JsonConvert
* @param objs 输出对象
*/
public void finishMapJson(final JsonConvert convert, final Object... objs) {
this.contentType = "text/plain; charset=utf-8";
if (this.recycleListener != null) this.output = objs;
finish(convert.convertMapTo(context.getBufferSupplier(), objs));
}
/**
* 将对象以JSON格式输出
*
@@ -358,6 +385,7 @@ public class HttpResponse extends Response<HttpContext, HttpRequest> {
* @param convert 指定的JsonConvert
* @param future 输出对象的句柄
*/
@SuppressWarnings("unchecked")
public void finishJson(final JsonConvert convert, final CompletableFuture future) {
future.whenComplete((v, e) -> {
if (e != null) {
@@ -382,6 +410,7 @@ public class HttpResponse extends Response<HttpContext, HttpRequest> {
* @param type 指定的类型
* @param future 输出对象的句柄
*/
@SuppressWarnings("unchecked")
public void finishJson(final JsonConvert convert, final Type type, final CompletableFuture future) {
future.whenComplete((v, e) -> {
if (e != null) {
@@ -416,6 +445,7 @@ public class HttpResponse extends Response<HttpContext, HttpRequest> {
* @param convert 指定的JsonConvert
* @param result HttpResult对象
*/
@SuppressWarnings("unchecked")
public void finishJson(final JsonConvert convert, final HttpResult result) {
if (output == null) {
finish("");
@@ -996,54 +1026,59 @@ public class HttpResponse extends Response<HttpContext, HttpRequest> {
private long count;//读取文件的字节数
private long position = 0;
private long readpos = 0;
private boolean next = false;
private boolean hdwrite = true; //写入Header
private boolean read = true;
private boolean read = false;
public TransferFileHandler(File file) throws IOException {
this.file = file;
this.filechannel = AsynchronousFileChannel.open(file.toPath(), options, ((HttpContext) context).getExecutor());
this.position = 0;
this.readpos = 0;
this.max = file.length();
}
public TransferFileHandler(File file, long offset, long len) throws IOException {
this.file = file;
this.filechannel = AsynchronousFileChannel.open(file.toPath(), options, ((HttpContext) context).getExecutor());
this.position = offset <= 0 ? 0 : offset;
this.readpos = offset <= 0 ? 0 : offset;
this.max = len <= 0 ? file.length() : len;
}
@Override
public void completed(Integer result, ByteBuffer attachment) {
//(Thread.currentThread().getName() + "-----------" + file + "-------------------result: " + result + ", max = " + max + ", count = " + count);
//(Utility.now() + "---" + Thread.currentThread().getName() + "-----------" + file + "-------------------result: " + result + ", max = " + max + ", readpos = " + readpos + ", count = " + count + ", " + (hdwrite ? "正在写Header" : (read ? "准备读" : "准备写")));
if (result < 0 || count >= max) {
failed(null, attachment);
return;
}
if (!next && attachment.hasRemaining()) { //Header还没写完
if (hdwrite && attachment.hasRemaining()) { //Header还没写完
channel.write(attachment, attachment, this);
return;
}
if (hdwrite) {
//(Utility.now() + "---" + Thread.currentThread().getName() + "-----------" + file + "-------------------Header写入完毕 准备读取文件.");
hdwrite = false;
read = true;
result = 0;
}
if (read) {
count += result;
} else {
readpos += result;
}
if (read && attachment.hasRemaining()) { //Buffer还没写完
channel.write(attachment, attachment, this);
return;
}
if (next && read && attachment.hasRemaining()) { //Buffer还没写完
channel.write(attachment, attachment, this);
return;
}
if (read) {
read = false;
if (next) {
position += result;
} else {
next = true;
}
attachment.clear();
filechannel.read(attachment, position, attachment, this);
filechannel.read(attachment, readpos, attachment, this);
} else {
read = true;
count += result;
if (count > max) {
attachment.limit((int) (attachment.position() + max - count));
}

View File

@@ -217,6 +217,7 @@ public class HttpServer extends Server<String, HttpContext, HttpRequest, HttpRes
*
* @return RestServlet
*/
@SuppressWarnings("unchecked")
public <S extends Service, T extends HttpServlet> T addRestServlet(final ClassLoader classLoader, final String name, final S service, final Class userType, final Class<T> baseServletType, final String prefix) {
T servlet = null;
final boolean sncp = Sncp.isSncpDyn(service);

View File

@@ -81,6 +81,7 @@ public class HttpServlet extends Servlet<HttpContext, HttpRequest, HttpResponse>
}
};
@SuppressWarnings("unchecked")
void preInit(HttpContext context, AnyValue config) {
String path = _prefix == null ? "" : _prefix;
WebServlet ws = this.getClass().getAnnotation(WebServlet.class);

View File

@@ -92,7 +92,16 @@ public final class Rest {
return new MethodVisitor(Opcodes.ASM5) {
@Override
public void visitLocalVariable(String name, String description, String signature, Label start, Label end, int index) {
if (index > 0) fieldnames.add(name);
if (index < 1) return;
int size = fieldnames.size();
//index并不会按顺序执行的
if (index > size) {
for (int i = size; i < index; i++) {
fieldnames.add(" ");
}
fieldnames.set(index - 1, name);
}
fieldnames.set(index - 1, name);
}
};
}

View File

@@ -112,7 +112,7 @@ public final class WebSocketPacket {
ByteBuffer[] duplicateSendBuffers() {
ByteBuffer[] rs = new ByteBuffer[this.sendBuffers.length];
for (int i = 0; i < this.sendBuffers.length; i++) {
rs[i] = this.sendBuffers[i].duplicate().asReadOnlyBuffer();
rs[i] = this.sendBuffers[i].duplicate().asReadOnlyBuffer(); //必须使用asReadOnlyBuffer 否则会导致ByteBuffer对应的byte[]被ObjectPool回收两次
}
return rs;
}

View File

@@ -106,7 +106,7 @@ public final class DataSources {
}
}
static Map<String, Properties> loadPersistenceXml(final InputStream in0) {
public static Map<String, Properties> loadPersistenceXml(final InputStream in0) {
final Map<String, Properties> map = new LinkedHashMap();
Properties result = new Properties();
boolean flag = false;

View File

@@ -74,6 +74,7 @@ import static jdk.internal.org.objectweb.asm.Opcodes.*;
* @param <T> 字段依附的类
* @param <F> 字段的数据类型
*/
@SuppressWarnings("unchecked")
public interface Attribute<T, F> {
/**

View File

@@ -82,6 +82,7 @@ public interface Creator<T> {
String[] value();
@SuppressWarnings("unchecked")
static class CreatorInner {
static class SimpleClassVisitor extends ClassVisitor {
@@ -108,7 +109,16 @@ public interface Creator<T> {
return new MethodVisitor(Opcodes.ASM5) {
@Override
public void visitLocalVariable(String name, String description, String signature, Label start, Label end, int index) {
if (index > 0) fieldnames.add(name);
if (index < 1) return;
int size = fieldnames.size();
//index不会按顺序执行的
if (index > size) {
for (int i = size; i < index; i++) {
fieldnames.add(" ");
}
fieldnames.set(index - 1, name);
}
fieldnames.set(index - 1, name);
}
};
}

View File

@@ -17,7 +17,7 @@ public final class Redkale {
}
public static String getDotedVersion() {
return "1.8.2";
return "1.8.3";
}
public static int getMajorVersion() {

View File

@@ -9,7 +9,7 @@ import java.lang.ref.WeakReference;
import java.lang.reflect.*;
import java.util.*;
import java.util.concurrent.*;
import java.util.function.BiConsumer;
import java.util.function.*;
import java.util.logging.*;
import javax.annotation.Resource;
@@ -99,7 +99,7 @@ public final class ResourceFactory {
* 1: "$"有特殊含义, 不能表示"$"资源本身
* 2: 只能是字母、数字、(短横)-、(下划线)_、点(.)的组合
* </pre></blockquote>
*
*
* @param name String
*/
public void checkName(String name) {
@@ -471,11 +471,11 @@ public final class ResourceFactory {
}
public <A> List<A> query(Class<? extends A> clazz) {
return query(new ArrayList<A>(), clazz);
return query(new ArrayList<>(), clazz);
}
public <A> List<A> query(Type clazz) {
return query(new ArrayList<A>(), clazz);
return query(new ArrayList<>(), clazz);
}
private <A> List<A> query(final List<A> list, Type clazz) {
@@ -489,6 +489,23 @@ public final class ResourceFactory {
return list;
}
public <A> List<A> query(final BiPredicate<String, Object> predicate) {
return query(new ArrayList<>(), predicate);
}
private <A> List<A> query(final List<A> list, final BiPredicate<String, Object> predicate) {
if (predicate == null) return list;
for (ConcurrentHashMap<String, ResourceEntry> map : this.store.values()) {
for (Map.Entry<String, ResourceEntry> en : map.entrySet()) {
if (predicate.test(en.getKey(), en.getValue().value)) {
list.add((A) en.getValue().value);
}
}
}
if (parent != null) query(list, predicate);
return list;
}
private <A> ResourceEntry<A> findEntry(String name, Class<? extends A> clazz) {
Map<String, ResourceEntry> map = this.store.get(clazz);
if (map != null) {