Compare commits
17 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
735ad0908b | ||
|
|
a080a6a8cc | ||
|
|
2cbc51cfdf | ||
|
|
8631b4bdf5 | ||
|
|
285cb86891 | ||
|
|
bf535a7161 | ||
|
|
34e37471b8 | ||
|
|
e223548b23 | ||
|
|
3a13d242f6 | ||
|
|
204e6ec99f | ||
|
|
7e348782e4 | ||
|
|
a4cbe7db17 | ||
|
|
f8101acb4b | ||
|
|
9ed2d59317 | ||
|
|
0329ad7832 | ||
|
|
53df45456f | ||
|
|
93698bacff |
@@ -126,6 +126,17 @@
|
||||
-->
|
||||
<server protocol="HTTP" host="127.0.0.1" port="6060" root="root" lib="">
|
||||
|
||||
<!--
|
||||
【节点在<server>中唯一】
|
||||
value: 创建SSLContext的实现类, 可自定义,必须是org.redkale.net.SSLCreator的子类
|
||||
clientauth: true/false/want
|
||||
keystorepass: KEY密码
|
||||
keystorefile: KEY文件
|
||||
truststorepass: TRUST密码
|
||||
truststorefile: TRUST文件
|
||||
-->
|
||||
<ssl creator=""/>
|
||||
|
||||
<!--
|
||||
加载所有的Service服务;
|
||||
在同一个进程中同一个name同一类型的Service将共用同一个实例
|
||||
@@ -234,8 +245,7 @@
|
||||
当Server为HTTP协议时,render才有效. 指定输出引擎的实现类
|
||||
value: 输出引擎的实现类, 必须是org.redkale.net.http.HttpRender的子类
|
||||
-->
|
||||
<render value="org.redkalex.htel.HttpTemplateRender">
|
||||
</render>
|
||||
<render value="org.redkalex.htel.HttpTemplateRender"/>
|
||||
<!--
|
||||
【节点在<server>中唯一】
|
||||
当Server为HTTP协议时,ResourceServlet才有效. 默认存在一个有默认属性的resource-servlet节点
|
||||
|
||||
@@ -32,7 +32,7 @@ public class MethodDebugVisitor {
|
||||
System.out.println();
|
||||
}
|
||||
|
||||
private final Map<Label, Integer> labels = new LinkedHashMap();
|
||||
private final Map<Label, Integer> labels = new LinkedHashMap<>();
|
||||
|
||||
private static final String[] opcodes = new String[200]; //0 -18
|
||||
|
||||
|
||||
@@ -275,7 +275,7 @@ public final class Application {
|
||||
try {
|
||||
final String strategyClass = transportConf.getValue("strategy");
|
||||
if (strategyClass != null && !strategyClass.isEmpty()) {
|
||||
strategy = (TransportStrategy) classLoader.loadClass(strategyClass).newInstance();
|
||||
strategy = (TransportStrategy) classLoader.loadClass(strategyClass).getDeclaredConstructor().newInstance();
|
||||
}
|
||||
final AtomicInteger counter = new AtomicInteger();
|
||||
transportExec = Executors.newFixedThreadPool(threads, (Runnable r) -> {
|
||||
@@ -502,7 +502,8 @@ public final class Application {
|
||||
if (listenClass.isEmpty()) continue;
|
||||
Class clazz = classLoader.loadClass(listenClass);
|
||||
if (!ApplicationListener.class.isAssignableFrom(clazz)) continue;
|
||||
ApplicationListener listener = (ApplicationListener) clazz.newInstance();
|
||||
@SuppressWarnings("unchecked")
|
||||
ApplicationListener listener = (ApplicationListener) clazz.getDeclaredConstructor().newInstance();
|
||||
listener.init(config);
|
||||
this.listeners.add(listener);
|
||||
}
|
||||
|
||||
@@ -266,7 +266,7 @@ public class LogFileHandler extends Handler {
|
||||
try {
|
||||
if (filterstr != null) {
|
||||
Class<?> clz = ClassLoader.getSystemClassLoader().loadClass(filterstr);
|
||||
setFilter((Filter) clz.newInstance());
|
||||
setFilter((Filter) clz.getDeclaredConstructor().newInstance());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
}
|
||||
@@ -274,7 +274,7 @@ public class LogFileHandler extends Handler {
|
||||
try {
|
||||
if (formatterstr != null) {
|
||||
Class<?> clz = ClassLoader.getSystemClassLoader().loadClass(formatterstr);
|
||||
setFormatter((Formatter) clz.newInstance());
|
||||
setFormatter((Formatter) clz.getDeclaredConstructor().newInstance());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
}
|
||||
|
||||
@@ -56,16 +56,19 @@ public class NodeHttpServer extends NodeServer {
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
protected ClassFilter<Service> createServiceClassFilter() {
|
||||
return createClassFilter(this.sncpGroup, null, Service.class, new Class[]{org.redkale.watch.WatchService.class}, Annotation.class, "services", "service");
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
protected ClassFilter<Filter> createFilterClassFilter() {
|
||||
return createClassFilter(null, null, HttpFilter.class, new Class[]{WatchFilter.class}, null, "filters", "filter");
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
protected ClassFilter<Servlet> createServletClassFilter() {
|
||||
return createClassFilter(null, WebServlet.class, HttpServlet.class, new Class[]{WatchServlet.class}, null, "servlets", "servlet");
|
||||
}
|
||||
@@ -87,6 +90,7 @@ public class NodeHttpServer extends NodeServer {
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
protected void loadServlet(ClassFilter<? extends Servlet> servletFilter, ClassFilter otherFilter) throws Exception {
|
||||
if (httpServer != null) loadHttpServlet(servletFilter, otherFilter);
|
||||
}
|
||||
@@ -136,7 +140,7 @@ public class NodeHttpServer extends NodeServer {
|
||||
for (FilterEntry<? extends Filter> en : list) {
|
||||
Class<HttpFilter> clazz = (Class<HttpFilter>) en.getType();
|
||||
if (Modifier.isAbstract(clazz.getModifiers())) continue;
|
||||
final HttpFilter filter = clazz.newInstance();
|
||||
final HttpFilter filter = clazz.getDeclaredConstructor().newInstance();
|
||||
resourceFactory.inject(filter, this);
|
||||
DefaultAnyValue filterConf = (DefaultAnyValue) en.getProperty();
|
||||
this.httpServer.addHttpFilter(filter, filterConf);
|
||||
@@ -172,7 +176,7 @@ public class NodeHttpServer extends NodeServer {
|
||||
if (Modifier.isAbstract(clazz.getModifiers())) continue;
|
||||
WebServlet ws = clazz.getAnnotation(WebServlet.class);
|
||||
if (ws == null || ws.value().length == 0) continue;
|
||||
final HttpServlet servlet = clazz.newInstance();
|
||||
final HttpServlet servlet = clazz.getDeclaredConstructor().newInstance();
|
||||
resourceFactory.inject(servlet, this);
|
||||
final String[] mappings = ws.value();
|
||||
String pref = ws.repair() ? prefix : "";
|
||||
|
||||
@@ -149,7 +149,7 @@ public abstract class NodeServer {
|
||||
String interceptorClass = this.serverConf.getValue("interceptor", "");
|
||||
if (!interceptorClass.isEmpty()) {
|
||||
Class clazz = serverClassLoader.loadClass(interceptorClass);
|
||||
this.interceptor = (NodeInterceptor) clazz.newInstance();
|
||||
this.interceptor = (NodeInterceptor) clazz.getDeclaredConstructor().newInstance();
|
||||
}
|
||||
|
||||
ClassFilter<Service> serviceFilter = createServiceClassFilter();
|
||||
|
||||
@@ -93,7 +93,7 @@ public class NodeSncpServer extends NodeServer {
|
||||
for (FilterEntry<? extends Filter> en : list) {
|
||||
Class<SncpFilter> clazz = (Class<SncpFilter>) en.getType();
|
||||
if (Modifier.isAbstract(clazz.getModifiers())) continue;
|
||||
final SncpFilter filter = clazz.newInstance();
|
||||
final SncpFilter filter = clazz.getDeclaredConstructor().newInstance();
|
||||
resourceFactory.inject(filter, this);
|
||||
DefaultAnyValue filterConf = (DefaultAnyValue) en.getProperty();
|
||||
this.sncpServer.addSncpFilter(filter, filterConf);
|
||||
|
||||
@@ -24,16 +24,19 @@ public class NodeWatchServer extends NodeHttpServer {
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
protected ClassFilter<Service> createServiceClassFilter() {
|
||||
return createClassFilter(this.sncpGroup, null, WatchService.class, null, Annotation.class, "services", "service");
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
protected ClassFilter<Filter> createFilterClassFilter() {
|
||||
return createClassFilter(null, null, WatchFilter.class, null, null, "filters", "filter");
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
protected ClassFilter<Servlet> createServletClassFilter() {
|
||||
return createClassFilter(null, WebServlet.class, WatchServlet.class, null, null, "servlets", "servlet");
|
||||
}
|
||||
|
||||
@@ -34,6 +34,7 @@ public class OptionalCoder<R extends Reader, W extends Writer, T> extends Simple
|
||||
|
||||
private final Object lock = new Object();
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public OptionalCoder(final ConvertFactory factory, final Type type) {
|
||||
this.type = type;
|
||||
try {
|
||||
|
||||
@@ -25,6 +25,7 @@ public final class BigIntegerSimpledCoder<R extends Reader, W extends Writer> ex
|
||||
public static final BigIntegerSimpledCoder instance = new BigIntegerSimpledCoder();
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public void convertTo(W out, BigInteger value) {
|
||||
if (value == null) {
|
||||
out.writeNull();
|
||||
@@ -34,6 +35,7 @@ public final class BigIntegerSimpledCoder<R extends Reader, W extends Writer> ex
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public BigInteger convertFrom(R in) {
|
||||
byte[] bytes = ByteArraySimpledCoder.instance.convertFrom(in);
|
||||
return bytes == null ? null : new BigInteger(bytes);
|
||||
|
||||
@@ -27,6 +27,7 @@ public final class DLongSimpledCoder<R extends Reader, W extends Writer> extends
|
||||
public static final DLongSimpledCoder instance = new DLongSimpledCoder();
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public void convertTo(final W out, final DLong value) {
|
||||
if (value == null) {
|
||||
out.writeNull();
|
||||
@@ -36,6 +37,7 @@ public final class DLongSimpledCoder<R extends Reader, W extends Writer> extends
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public DLong convertFrom(R in) {
|
||||
byte[] bs = bsSimpledCoder.convertFrom(in);
|
||||
if (bs == null) return null;
|
||||
|
||||
@@ -74,6 +74,7 @@ public final class DoubleArraySimpledCoder<R extends Reader, W extends Writer> e
|
||||
public static final DoubleStreamSimpledCoder instance = new DoubleStreamSimpledCoder();
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public void convertTo(W out, DoubleStream values) {
|
||||
if (values == null) {
|
||||
out.writeNull();
|
||||
@@ -83,6 +84,7 @@ public final class DoubleArraySimpledCoder<R extends Reader, W extends Writer> e
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public DoubleStream convertFrom(R in) {
|
||||
double[] value = DoubleArraySimpledCoder.instance.convertFrom(in);
|
||||
return value == null ? null : DoubleStream.of(value);
|
||||
|
||||
@@ -74,6 +74,7 @@ public final class IntArraySimpledCoder<R extends Reader, W extends Writer> exte
|
||||
public static final IntStreamSimpledCoder instance = new IntStreamSimpledCoder();
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public void convertTo(W out, IntStream values) {
|
||||
if (values == null) {
|
||||
out.writeNull();
|
||||
@@ -83,6 +84,7 @@ public final class IntArraySimpledCoder<R extends Reader, W extends Writer> exte
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public IntStream convertFrom(R in) {
|
||||
int[] value = IntArraySimpledCoder.instance.convertFrom(in);
|
||||
return value == null ? null : IntStream.of(value);
|
||||
|
||||
@@ -74,6 +74,7 @@ public final class LongArraySimpledCoder<R extends Reader, W extends Writer> ext
|
||||
public static final LongStreamSimpledCoder instance = new LongStreamSimpledCoder();
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public void convertTo(W out, LongStream values) {
|
||||
if (values == null) {
|
||||
out.writeNull();
|
||||
@@ -83,6 +84,7 @@ public final class LongArraySimpledCoder<R extends Reader, W extends Writer> ext
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public LongStream convertFrom(R in) {
|
||||
long[] value = LongArraySimpledCoder.instance.convertFrom(in);
|
||||
return value == null ? null : LongStream.of(value);
|
||||
|
||||
@@ -170,7 +170,7 @@ public abstract class AsyncConnection implements AsynchronousByteChannel, AutoCl
|
||||
*/
|
||||
public static CompletableFuture<AsyncConnection> createTCP(final AsynchronousChannelGroup group, final SSLContext sslContext,
|
||||
final SocketAddress address, final boolean noDelay, final int readTimeoutSecond, final int writeTimeoutSecond) {
|
||||
final CompletableFuture future = new CompletableFuture();
|
||||
final CompletableFuture<AsyncConnection> future = new CompletableFuture<>();
|
||||
try {
|
||||
final AsynchronousSocketChannel channel = AsynchronousSocketChannel.open(group);
|
||||
channel.connect(address, null, new CompletionHandler<Void, Void>() {
|
||||
|
||||
20
src/org/redkale/net/SSLClientAuth.java
Normal file
20
src/org/redkale/net/SSLClientAuth.java
Normal file
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
* 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.net;
|
||||
|
||||
/**
|
||||
*
|
||||
* <p>
|
||||
* 详情见: https://redkale.org
|
||||
*
|
||||
* @author zhangjx
|
||||
*/
|
||||
public enum SSLClientAuth {
|
||||
NONE,
|
||||
NEED,
|
||||
WANT,
|
||||
CLIENT;
|
||||
}
|
||||
65
src/org/redkale/net/SSLCreator.java
Normal file
65
src/org/redkale/net/SSLCreator.java
Normal file
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* 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.net;
|
||||
|
||||
import java.io.*;
|
||||
import java.security.*;
|
||||
import java.security.cert.*;
|
||||
import javax.net.ssl.*;
|
||||
import org.redkale.util.*;
|
||||
|
||||
/**
|
||||
* 根据配置生成SSLContext
|
||||
*
|
||||
* <p>
|
||||
* 详情见: https://redkale.org
|
||||
*
|
||||
* @author zhangjx
|
||||
*/
|
||||
public interface SSLCreator {
|
||||
|
||||
default SSLContext create(Server server, AnyValue sslConf) throws Exception {
|
||||
String keyfile = sslConf.getValue("keystorefile");
|
||||
String keypass = sslConf.getValue("keystorepass", "");
|
||||
KeyManager[] keyManagers = null;
|
||||
if (keyfile != null) {
|
||||
KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
|
||||
KeyStore ks = KeyStore.getInstance("JKS");
|
||||
ks.load(new FileInputStream(keyfile), keypass.toCharArray());
|
||||
kmf.init(ks, keypass.toCharArray());
|
||||
keyManagers = kmf.getKeyManagers();
|
||||
}
|
||||
|
||||
String trustfile = sslConf.getValue("truststorefile");
|
||||
String trustpass = sslConf.getValue("truststorepass", "");
|
||||
TrustManager[] trustManagers;
|
||||
if (trustfile != null) {
|
||||
KeyStore ts = KeyStore.getInstance("JKS");
|
||||
ts.load(new FileInputStream(trustfile), trustpass.toCharArray());
|
||||
TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
|
||||
tmf.init(ts);
|
||||
trustManagers = tmf.getTrustManagers();
|
||||
} else {
|
||||
trustManagers = new TrustManager[]{new X509TrustManager() {
|
||||
@Override
|
||||
public void checkClientTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void checkServerTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
|
||||
}
|
||||
|
||||
@Override
|
||||
public X509Certificate[] getAcceptedIssuers() {
|
||||
return new X509Certificate[0];
|
||||
}
|
||||
}};
|
||||
}
|
||||
SSLContext sslContext = SSLContext.getInstance("TLS");
|
||||
sslContext.init(keyManagers, trustManagers, new SecureRandom());
|
||||
return sslContext;
|
||||
}
|
||||
}
|
||||
@@ -124,6 +124,20 @@ public abstract class Server<K extends Serializable, C extends Context, R extend
|
||||
this.responsePoolSize = config.getIntValue("responsePoolSize", this.threads * 2);
|
||||
this.name = config.getValue("name", "Server-" + protocol + "-" + this.address.getPort());
|
||||
if (!this.name.matches("^[a-zA-Z][\\w_-]{1,64}$")) throw new RuntimeException("server.name (" + this.name + ") is illegal");
|
||||
AnyValue sslConf = config.getAnyValue("ssl");
|
||||
if (sslConf != null) {
|
||||
String creatorClass = sslConf.getValue("creator", SSLCreator.class.getName());
|
||||
SSLCreator creator = null;
|
||||
if (SSLCreator.class.getName().equals(creatorClass) || creatorClass.isEmpty()) {
|
||||
creator = new SSLCreator() {
|
||||
};
|
||||
} else {
|
||||
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
|
||||
creator = ((SSLCreator) classLoader.loadClass(creatorClass).getDeclaredConstructor().newInstance());
|
||||
}
|
||||
this.resourceFactory.inject(creator);
|
||||
this.sslContext = creator.create(this, sslConf);
|
||||
}
|
||||
final AtomicInteger counter = new AtomicInteger();
|
||||
final Format f = createFormat();
|
||||
final String n = name;
|
||||
|
||||
@@ -126,7 +126,7 @@ public class HttpPrepareServlet extends PrepareServlet<String, HttpContext, Http
|
||||
List<HttpServlet> list = removeHttpServlet(predicateEntry, predicateFilter);
|
||||
return list == null || list.isEmpty() ? null : list.get(0);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T extends WebSocket> HttpServlet removeHttpServlet(Class<T> websocketOrServletType) {
|
||||
Predicate<MappingEntry> predicateEntry = (t) -> {
|
||||
Class type = t.servlet.getClass();
|
||||
@@ -144,6 +144,7 @@ public class HttpPrepareServlet extends PrepareServlet<String, HttpContext, Http
|
||||
return list == null || list.isEmpty() ? null : list.get(0);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public boolean addForbidURIReg(final String urlreg) {
|
||||
if (urlreg == null || urlreg.isEmpty()) return false;
|
||||
synchronized (excludeLock) {
|
||||
@@ -169,6 +170,7 @@ public class HttpPrepareServlet extends PrepareServlet<String, HttpContext, Http
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public boolean removeForbidURIReg(final String urlreg) {
|
||||
if (urlreg == null || urlreg.isEmpty()) return false;
|
||||
synchronized (excludeLock) {
|
||||
@@ -198,6 +200,7 @@ public class HttpPrepareServlet extends PrepareServlet<String, HttpContext, Http
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public void init(HttpContext context, AnyValue config) {
|
||||
super.init(context, config); //必须要执行
|
||||
Collection<HttpServlet> servlets = getServlets();
|
||||
@@ -225,7 +228,7 @@ public class HttpPrepareServlet extends PrepareServlet<String, HttpContext, Http
|
||||
}
|
||||
String resServlet = resConfig.getValue("servlet", HttpResourceServlet.class.getName());
|
||||
try {
|
||||
this.resourceHttpServlet = (HttpServlet) Thread.currentThread().getContextClassLoader().loadClass(resServlet).newInstance();
|
||||
this.resourceHttpServlet = (HttpServlet) Thread.currentThread().getContextClassLoader().loadClass(resServlet).getDeclaredConstructor().newInstance();
|
||||
} catch (Throwable e) {
|
||||
this.resourceHttpServlet = new HttpResourceServlet();
|
||||
logger.log(Level.WARNING, "init HttpResourceSerlvet(" + resServlet + ") error", e);
|
||||
@@ -239,7 +242,7 @@ public class HttpPrepareServlet extends PrepareServlet<String, HttpContext, Http
|
||||
for (AnyValue renderConfig : renderConfigs) {
|
||||
String renderType = renderConfig.getValue("value");
|
||||
try {
|
||||
HttpRender render = (HttpRender) Thread.currentThread().getContextClassLoader().loadClass(renderType).newInstance();
|
||||
HttpRender render = (HttpRender) Thread.currentThread().getContextClassLoader().loadClass(renderType).getDeclaredConstructor().newInstance();
|
||||
for (HttpRender one : renders) {
|
||||
if (one.getType().equals(render.getType())) throw new RuntimeException("HttpRender(" + renderType + ") repeat");
|
||||
}
|
||||
|
||||
@@ -134,15 +134,19 @@ public class HttpRequest extends Request<HttpContext> {
|
||||
String value = array.toString(index, array.size() - index, charset).trim();
|
||||
switch (name) {
|
||||
case "Content-Type":
|
||||
case "content-type":
|
||||
this.contentType = value;
|
||||
break;
|
||||
case "Content-Length":
|
||||
case "content-length":
|
||||
this.contentLength = Long.decode(value);
|
||||
break;
|
||||
case "Host":
|
||||
case "host":
|
||||
this.host = value;
|
||||
break;
|
||||
case "Cookie":
|
||||
case "cookie":
|
||||
if (this.cookie == null || this.cookie.isEmpty()) {
|
||||
this.cookie = value;
|
||||
} else {
|
||||
@@ -150,9 +154,13 @@ public class HttpRequest extends Request<HttpContext> {
|
||||
}
|
||||
break;
|
||||
case "Connection":
|
||||
case "connection":
|
||||
this.connection = value;
|
||||
this.setKeepAlive(!"close".equalsIgnoreCase(value));
|
||||
break;
|
||||
case "user-agent":
|
||||
header.addValue("User-Agent", value);
|
||||
break;
|
||||
default:
|
||||
header.addValue(name, value);
|
||||
}
|
||||
|
||||
@@ -59,7 +59,8 @@ public class HttpResourceServlet extends HttpServlet {
|
||||
final String uri = path.toString().substring(rootstr.length()).replace('\\', '/');
|
||||
//logger.log(Level.FINEST, "file(" + uri + ") happen " + event.kind() + " event");
|
||||
if (event.kind() == ENTRY_DELETE) {
|
||||
files.remove(uri);
|
||||
FileEntry en = files.remove(uri);
|
||||
if (en != null) en.remove();
|
||||
} else if (event.kind() == ENTRY_MODIFY) {
|
||||
FileEntry en = files.get(uri);
|
||||
if (en != null && en.file != null) {
|
||||
@@ -317,10 +318,8 @@ public class HttpResourceServlet extends HttpServlet {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void finalize() throws Throwable {
|
||||
public void remove() {
|
||||
if (this.content != null) this.servlet.cachedLength.add(0L - this.content.remaining());
|
||||
super.finalize();
|
||||
}
|
||||
|
||||
public long getCachedLength() {
|
||||
|
||||
@@ -45,13 +45,10 @@ public class HttpResponse extends Response<HttpContext, HttpRequest> {
|
||||
|
||||
private static final Set<OpenOption> options = new HashSet<>();
|
||||
|
||||
private static final DateFormat GMT_DATE_FORMAT = new SimpleDateFormat("EEE, dd-MMM-yyyy HH:mm:ss z", Locale.ENGLISH);
|
||||
|
||||
private static final Map<Integer, String> httpCodes = new HashMap<>();
|
||||
|
||||
static {
|
||||
options.add(StandardOpenOption.READ);
|
||||
GMT_DATE_FORMAT.setTimeZone(TimeZone.getTimeZone("GMT"));
|
||||
|
||||
httpCodes.put(100, "Continue");
|
||||
httpCodes.put(101, "Switching Protocols");
|
||||
@@ -99,6 +96,8 @@ public class HttpResponse extends Response<HttpContext, HttpRequest> {
|
||||
httpCodes.put(505, "HTTP Version Not Supported");
|
||||
}
|
||||
|
||||
private final DateFormat gmtDateFormat = new SimpleDateFormat("EEE, dd-MMM-yyyy HH:mm:ss z", Locale.ENGLISH);
|
||||
|
||||
private int status = 200;
|
||||
|
||||
private String contentType = "text/plain; charset=utf-8";
|
||||
@@ -142,6 +141,7 @@ public class HttpResponse extends Response<HttpContext, HttpRequest> {
|
||||
this.renders = renders;
|
||||
this.hasRender = renders != null && !renders.isEmpty();
|
||||
this.onlyoneHttpRender = renders != null && renders.size() == 1 ? renders.get(0) : null;
|
||||
gmtDateFormat.setTimeZone(TimeZone.getTimeZone("GMT"));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -270,7 +270,7 @@ public class HttpResponse extends Response<HttpContext, HttpRequest> {
|
||||
* @param obj 输出对象
|
||||
*/
|
||||
public void finishJson(final Object obj) {
|
||||
this.contentType = "text/plain; charset=utf-8";
|
||||
this.contentType = "application/json; charset=utf-8";
|
||||
if (this.recycleListener != null) this.output = obj;
|
||||
finish(request.getJsonConvert().convertTo(getBodyBufferSupplier(), obj));
|
||||
}
|
||||
@@ -282,7 +282,7 @@ public class HttpResponse extends Response<HttpContext, HttpRequest> {
|
||||
* @param objs 输出对象
|
||||
*/
|
||||
public void finishMapJson(final Object... objs) {
|
||||
this.contentType = "text/plain; charset=utf-8";
|
||||
this.contentType = "application/json; charset=utf-8";
|
||||
if (this.recycleListener != null) this.output = objs;
|
||||
finish(request.getJsonConvert().convertMapTo(getBodyBufferSupplier(), objs));
|
||||
}
|
||||
@@ -294,7 +294,7 @@ public class HttpResponse extends Response<HttpContext, HttpRequest> {
|
||||
* @param obj 输出对象
|
||||
*/
|
||||
public void finishJson(final JsonConvert convert, final Object obj) {
|
||||
this.contentType = "text/plain; charset=utf-8";
|
||||
this.contentType = "application/json; charset=utf-8";
|
||||
if (this.recycleListener != null) this.output = obj;
|
||||
finish(convert.convertTo(getBodyBufferSupplier(), obj));
|
||||
}
|
||||
@@ -307,7 +307,7 @@ public class HttpResponse extends Response<HttpContext, HttpRequest> {
|
||||
* @param objs 输出对象
|
||||
*/
|
||||
public void finishMapJson(final JsonConvert convert, final Object... objs) {
|
||||
this.contentType = "text/plain; charset=utf-8";
|
||||
this.contentType = "application/json; charset=utf-8";
|
||||
if (this.recycleListener != null) this.output = objs;
|
||||
finish(convert.convertMapTo(getBodyBufferSupplier(), objs));
|
||||
}
|
||||
@@ -319,7 +319,7 @@ public class HttpResponse extends Response<HttpContext, HttpRequest> {
|
||||
* @param obj 输出对象
|
||||
*/
|
||||
public void finishJson(final Type type, final Object obj) {
|
||||
this.contentType = "text/plain; charset=utf-8";
|
||||
this.contentType = "application/json; charset=utf-8";
|
||||
this.output = obj;
|
||||
finish(request.getJsonConvert().convertTo(getBodyBufferSupplier(), type, obj));
|
||||
}
|
||||
@@ -332,7 +332,7 @@ public class HttpResponse extends Response<HttpContext, HttpRequest> {
|
||||
* @param obj 输出对象
|
||||
*/
|
||||
public void finishJson(final JsonConvert convert, final Type type, final Object obj) {
|
||||
this.contentType = "text/plain; charset=utf-8";
|
||||
this.contentType = "application/json; charset=utf-8";
|
||||
if (this.recycleListener != null) this.output = obj;
|
||||
finish(convert.convertTo(getBodyBufferSupplier(), type, obj));
|
||||
}
|
||||
@@ -343,7 +343,7 @@ public class HttpResponse extends Response<HttpContext, HttpRequest> {
|
||||
* @param objs 输出对象
|
||||
*/
|
||||
public void finishJson(final Object... objs) {
|
||||
this.contentType = "text/plain; charset=utf-8";
|
||||
this.contentType = "application/json; charset=utf-8";
|
||||
if (this.recycleListener != null) this.output = objs;
|
||||
finish(request.getJsonConvert().convertTo(getBodyBufferSupplier(), objs));
|
||||
}
|
||||
@@ -354,7 +354,7 @@ public class HttpResponse extends Response<HttpContext, HttpRequest> {
|
||||
* @param ret RetResult输出对象
|
||||
*/
|
||||
public void finishJson(final org.redkale.service.RetResult ret) {
|
||||
this.contentType = "text/plain; charset=utf-8";
|
||||
this.contentType = "application/json; charset=utf-8";
|
||||
if (this.recycleListener != null) this.output = ret;
|
||||
if (ret != null && !ret.isSuccess()) {
|
||||
this.header.addValue("retcode", String.valueOf(ret.getRetcode()));
|
||||
@@ -370,7 +370,7 @@ public class HttpResponse extends Response<HttpContext, HttpRequest> {
|
||||
* @param ret RetResult输出对象
|
||||
*/
|
||||
public void finishJson(final JsonConvert convert, final org.redkale.service.RetResult ret) {
|
||||
this.contentType = "text/plain; charset=utf-8";
|
||||
this.contentType = "application/json; charset=utf-8";
|
||||
if (this.recycleListener != null) this.output = ret;
|
||||
if (ret != null && !ret.isSuccess()) {
|
||||
this.header.addValue("retcode", String.valueOf(ret.getRetcode()));
|
||||
@@ -493,8 +493,11 @@ public class HttpResponse extends Response<HttpContext, HttpRequest> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (convert instanceof TextConvert) this.contentType = "text/plain; charset=utf-8";
|
||||
if (convert instanceof JsonConvert) {
|
||||
this.contentType = "application/json; charset=utf-8";
|
||||
} else if (convert instanceof TextConvert) {
|
||||
this.contentType = "text/plain; charset=utf-8";
|
||||
}
|
||||
if (this.recycleListener != null) this.output = obj;
|
||||
if (obj instanceof org.redkale.service.RetResult) {
|
||||
org.redkale.service.RetResult ret = (org.redkale.service.RetResult) obj;
|
||||
@@ -842,6 +845,7 @@ public class HttpResponse extends Response<HttpContext, HttpRequest> {
|
||||
if (!this.request.isKeepAlive()) {
|
||||
buffer.put("Connection: close\r\n".getBytes());
|
||||
}
|
||||
buffer.put(("Date: " + gmtDateFormat.format(new Date()) + "\r\n").getBytes());
|
||||
buffer.put(serverNameBytes);
|
||||
|
||||
if (this.defaultAddHeaders != null) {
|
||||
@@ -910,9 +914,7 @@ public class HttpResponse extends Response<HttpContext, HttpRequest> {
|
||||
if (cookie.getPortlist() != null) sb.append("; Port=").append(cookie.getPortlist());
|
||||
if (cookie.getMaxAge() > 0) {
|
||||
sb.append("; Max-Age=").append(cookie.getMaxAge());
|
||||
synchronized (GMT_DATE_FORMAT) {
|
||||
sb.append("; Expires=").append(GMT_DATE_FORMAT.format(new Date(System.currentTimeMillis() + cookie.getMaxAge() * 1000)));
|
||||
}
|
||||
sb.append("; Expires=").append(gmtDateFormat.format(new Date(System.currentTimeMillis() + cookie.getMaxAge() * 1000)));
|
||||
}
|
||||
if (cookie.getSecure()) sb.append("; Secure");
|
||||
if (cookie.isHttpOnly()) sb.append("; HttpOnly");
|
||||
|
||||
@@ -59,10 +59,12 @@ public class HttpScope {
|
||||
return this;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> T find(String name) {
|
||||
return this.attributes == null ? null : (T) this.attributes.get(name);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> T find(HttpScope parent, String name) {
|
||||
T rs = this.attributes == null ? null : (T) this.attributes.get(name);
|
||||
if (rs != null) return rs;
|
||||
|
||||
@@ -274,7 +274,7 @@ public class HttpServlet extends Servlet<HttpContext, HttpRequest, HttpResponse>
|
||||
}
|
||||
}.loadClass(newDynName.replace('/', '.'), bytes);
|
||||
try {
|
||||
HttpServlet instance = (HttpServlet) newClazz.newInstance();
|
||||
HttpServlet instance = (HttpServlet) newClazz.getDeclaredConstructor().newInstance();
|
||||
instance.getClass().getField(factfield).set(instance, this);
|
||||
return instance;
|
||||
} catch (Exception ex) {
|
||||
@@ -294,7 +294,7 @@ public class HttpServlet extends Servlet<HttpContext, HttpRequest, HttpResponse>
|
||||
HttpMapping mapping = method.getAnnotation(HttpMapping.class);
|
||||
this.ignore = mapping == null || !mapping.auth();
|
||||
this.cacheseconds = mapping == null ? 0 : mapping.cacheseconds();
|
||||
this.cache = cacheseconds > 0 ? new ConcurrentHashMap() : null;
|
||||
this.cache = cacheseconds > 0 ? new ConcurrentHashMap<>() : null;
|
||||
this.cacheHandler = cacheseconds > 0 ? (HttpResponse response, ByteBuffer[] buffers) -> {
|
||||
int status = response.getStatus();
|
||||
if (status != 200) return null;
|
||||
|
||||
@@ -70,6 +70,7 @@ public class MimeType {
|
||||
contentTypes.put("jpeg", "image/jpeg");
|
||||
contentTypes.put("jpg", "image/jpeg");
|
||||
contentTypes.put("js", "text/javascript");
|
||||
contentTypes.put("json", "application/json");
|
||||
contentTypes.put("kar", "audio/x-midi");
|
||||
contentTypes.put("latex", "application/x-latex");
|
||||
contentTypes.put("log", "text/plain");
|
||||
|
||||
@@ -129,7 +129,7 @@ public final class Rest {
|
||||
|
||||
static JsonConvert createJsonConvert(RestConvert[] converts) {
|
||||
if (converts == null || converts.length < 1) return JsonConvert.root();
|
||||
final JsonFactory childFactory = JsonFactory.root().createChild();
|
||||
final JsonFactory childFactory = JsonFactory.create();
|
||||
List<Class> types = new ArrayList<>();
|
||||
for (RestConvert rc : converts) {
|
||||
if (types.contains(rc.type())) throw new RuntimeException("@RestConvert type(" + rc.type() + ") repeat");
|
||||
@@ -637,7 +637,7 @@ public final class Rest {
|
||||
cw.visitEnd();
|
||||
Class<?> newClazz = newLoader.loadClass(newDynName.replace('/', '.'), cw.toByteArray());
|
||||
try {
|
||||
return (T) newClazz.newInstance();
|
||||
return (T) newClazz.getDeclaredConstructor().newInstance();
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
@@ -1684,7 +1684,7 @@ public final class Rest {
|
||||
cw.visitEnd();
|
||||
Class<?> newClazz = new RestClassLoader(loader).loadClass(newDynName.replace('/', '.'), cw.toByteArray());
|
||||
try {
|
||||
T obj = ((Class<T>) newClazz).newInstance();
|
||||
T obj = ((Class<T>) newClazz).getDeclaredConstructor().newInstance();
|
||||
for (Map.Entry<String, org.redkale.util.Attribute> en : restAttributes.entrySet()) {
|
||||
Field attrField = newClazz.getDeclaredField(en.getKey());
|
||||
attrField.setAccessible(true);
|
||||
|
||||
@@ -754,7 +754,7 @@ public abstract class Sncp {
|
||||
final AnyValue conf) {
|
||||
try {
|
||||
final Class newClazz = createLocalServiceClass(classLoader, name, serviceImplClass);
|
||||
T rs = (T) newClazz.newInstance();
|
||||
T rs = (T) newClazz.getDeclaredConstructor().newInstance();
|
||||
//--------------------------------------
|
||||
Service remoteService = null;
|
||||
{
|
||||
@@ -888,7 +888,7 @@ public abstract class Sncp {
|
||||
String newDynName = supDynName.substring(0, supDynName.lastIndexOf('/') + 1) + REMOTEPREFIX + serviceTypeOrImplClass.getSimpleName();
|
||||
try {
|
||||
Class newClazz = loader.loadClass(newDynName.replace('/', '.'));
|
||||
T rs = (T) newClazz.newInstance();
|
||||
T rs = (T) newClazz.getDeclaredConstructor().newInstance();
|
||||
SncpClient client = new SncpClient(name, serviceTypeOrImplClass, rs, transportFactory, true, realed ? createLocalServiceClass(loader, name, serviceTypeOrImplClass) : serviceTypeOrImplClass, clientAddress);
|
||||
client.setRemoteGroups(groups);
|
||||
client.setRemoteGroupTransport(transportFactory.loadRemoteTransport(clientAddress, groups));
|
||||
@@ -1069,7 +1069,7 @@ public abstract class Sncp {
|
||||
}
|
||||
}.loadClass(newDynName.replace('/', '.'), bytes);
|
||||
try {
|
||||
T rs = (T) newClazz.newInstance();
|
||||
T rs = (T) newClazz.getDeclaredConstructor().newInstance();
|
||||
SncpClient client = new SncpClient(name, serviceTypeOrImplClass, rs, transportFactory, true, realed ? createLocalServiceClass(loader, name, serviceTypeOrImplClass) : serviceTypeOrImplClass, clientAddress);
|
||||
client.setRemoteGroups(groups);
|
||||
client.setRemoteGroupTransport(transportFactory.loadRemoteTransport(clientAddress, groups));
|
||||
|
||||
@@ -441,6 +441,7 @@ public final class SncpClient {
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public void success() {
|
||||
future.complete(this.body);
|
||||
transport.offerBuffer(buffer);
|
||||
@@ -547,6 +548,7 @@ public final class SncpClient {
|
||||
|
||||
protected final Creator<? extends CompletableFuture> futureCreator;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public SncpAction(final Class clazz, Method method, DLong actionid) {
|
||||
this.actionid = actionid == null ? Sncp.hash(method) : actionid;
|
||||
Type rt = TypeToken.getGenericType(method.getGenericReturnType(), clazz);
|
||||
@@ -595,7 +597,7 @@ public final class SncpClient {
|
||||
for (Annotation ann : anns[i]) {
|
||||
if (ann.annotationType() == RpcCall.class) {
|
||||
try {
|
||||
atts[i + 1] = ((RpcCall) ann).value().newInstance();
|
||||
atts[i + 1] = ((RpcCall) ann).value().getDeclaredConstructor().newInstance();
|
||||
hasattr = true;
|
||||
} catch (Exception e) {
|
||||
logger.log(Level.SEVERE, RpcCall.class.getSimpleName() + ".attribute cannot a newInstance for" + method, e);
|
||||
|
||||
@@ -105,6 +105,7 @@ public final class SncpDynServlet extends SncpServlet {
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public void execute(SncpRequest request, SncpResponse response) throws IOException {
|
||||
if (bufferSupplier == null) {
|
||||
bufferSupplier = request.getContext().getBufferSupplier();
|
||||
@@ -586,7 +587,7 @@ public final class SncpDynServlet extends SncpServlet {
|
||||
}
|
||||
}.loadClass(newDynName.replace('/', '.'), bytes);
|
||||
try {
|
||||
SncpServletAction instance = (SncpServletAction) newClazz.newInstance();
|
||||
SncpServletAction instance = (SncpServletAction) newClazz.getDeclaredConstructor().newInstance();
|
||||
instance.method = method;
|
||||
java.lang.reflect.Type[] ptypes = TypeToken.getGenericType(method.getGenericParameterTypes(), serviceClass);
|
||||
java.lang.reflect.Type[] types = new java.lang.reflect.Type[ptypes.length + 1];
|
||||
@@ -606,7 +607,7 @@ public final class SncpDynServlet extends SncpServlet {
|
||||
for (Annotation ann : anns[i]) {
|
||||
if (ann.annotationType() == RpcCall.class) {
|
||||
try {
|
||||
atts[i + 1] = ((RpcCall) ann).value().newInstance();
|
||||
atts[i + 1] = ((RpcCall) ann).value().getDeclaredConstructor().newInstance();
|
||||
hasattr = true;
|
||||
} catch (Exception e) {
|
||||
logger.log(Level.SEVERE, RpcCall.class.getSimpleName() + ".attribute cannot a newInstance for" + method, e);
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
package org.redkale.service;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import org.redkale.convert.json.*;
|
||||
|
||||
/**
|
||||
@@ -57,6 +58,10 @@ public class RetResult<T> {
|
||||
return new RetResult();
|
||||
}
|
||||
|
||||
public static <T> CompletableFuture<RetResult<T>> successFuture() {
|
||||
return CompletableFuture.completedFuture(new RetResult());
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断结果是否成功返回, retcode = 0 视为成功, 否则视为错误码
|
||||
*
|
||||
|
||||
@@ -27,6 +27,7 @@ import org.redkale.util.*;
|
||||
*
|
||||
* @author zhangjx
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
@Local
|
||||
@AutoLoad(false)
|
||||
@ResourceType(CacheSource.class)
|
||||
@@ -85,6 +86,7 @@ public class CacheMemorySource<V extends Object> extends AbstractService impleme
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public void init(AnyValue conf) {
|
||||
if (this.convert == null) this.convert = this.defaultConvert;
|
||||
if (this.convert == null) this.convert = JsonConvert.root();
|
||||
@@ -104,7 +106,7 @@ public class CacheMemorySource<V extends Object> extends AbstractService impleme
|
||||
String expireHandlerClass = prop == null ? null : prop.getValue("expirehandler");
|
||||
if (expireHandlerClass != null) {
|
||||
try {
|
||||
this.expireHandler = (Consumer<CacheEntry>) Thread.currentThread().getContextClassLoader().loadClass(expireHandlerClass).newInstance();
|
||||
this.expireHandler = (Consumer<CacheEntry>) Thread.currentThread().getContextClassLoader().loadClass(expireHandlerClass).getDeclaredConstructor().newInstance();
|
||||
} catch (Throwable e) {
|
||||
logger.log(Level.SEVERE, self.getClass().getSimpleName() + " new expirehandler class (" + expireHandlerClass + ") instance error", e);
|
||||
}
|
||||
@@ -320,6 +322,7 @@ public class CacheMemorySource<V extends Object> extends AbstractService impleme
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public V get(String key) {
|
||||
if (key == null) return null;
|
||||
CacheEntry entry = container.get(key);
|
||||
@@ -362,6 +365,7 @@ public class CacheMemorySource<V extends Object> extends AbstractService impleme
|
||||
|
||||
@Override
|
||||
@RpcMultiRun
|
||||
@SuppressWarnings("unchecked")
|
||||
public V getAndRefresh(String key, final int expireSeconds) {
|
||||
if (key == null) return null;
|
||||
CacheEntry entry = container.get(key);
|
||||
@@ -375,6 +379,7 @@ public class CacheMemorySource<V extends Object> extends AbstractService impleme
|
||||
|
||||
@Override
|
||||
@RpcMultiRun
|
||||
@SuppressWarnings("unchecked")
|
||||
public String getStringAndRefresh(String key, final int expireSeconds) {
|
||||
if (key == null) return null;
|
||||
CacheEntry entry = container.get(key);
|
||||
|
||||
@@ -14,6 +14,11 @@ import org.redkale.convert.json.JsonFactory;
|
||||
import org.redkale.util.ConstructorParameters;
|
||||
|
||||
/**
|
||||
* Redkale中缓存数据源的核心类。 主要供业务开发者使用, 技术开发者提供CacheSource的实现。<br>
|
||||
* CacheSource提供三种数据类型操作: String、Long和泛型指定的数据类型。<br>
|
||||
* String统一用setString、getString等系列方法。<br>
|
||||
* Long统一用setLong、getLong、incr等系列方法。<br>
|
||||
* 其他则供自定义数据类型使用。
|
||||
*
|
||||
* @param <V> value的类型
|
||||
* <p>
|
||||
|
||||
@@ -18,6 +18,7 @@ import org.redkale.util.*;
|
||||
* @param <T> Entity类的类型
|
||||
* @param <F> 字段的类型
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public final class DataCallArrayAttribute<T, F> implements Attribute<T[], F> {
|
||||
|
||||
public static final DataCallArrayAttribute instance = new DataCallArrayAttribute();
|
||||
|
||||
@@ -10,6 +10,7 @@ import java.net.URL;
|
||||
import java.sql.*;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.atomic.*;
|
||||
import java.util.function.*;
|
||||
import java.util.logging.*;
|
||||
import java.util.stream.Stream;
|
||||
@@ -323,6 +324,10 @@ public class DataJdbcSource extends AbstractService implements DataSource, DataC
|
||||
Blob blob = conn.createBlob();
|
||||
blob.setBytes(1, (byte[]) val);
|
||||
prestmt.setObject(++i, blob);
|
||||
} else if (val instanceof AtomicInteger) {
|
||||
prestmt.setObject(++i, ((AtomicInteger) val).get());
|
||||
} else if (val instanceof AtomicLong) {
|
||||
prestmt.setObject(++i, ((AtomicLong) val).get());
|
||||
} else {
|
||||
prestmt.setObject(++i, val);
|
||||
}
|
||||
@@ -599,6 +604,10 @@ public class DataJdbcSource extends AbstractService implements DataSource, DataC
|
||||
Blob blob = conn.createBlob();
|
||||
blob.setBytes(1, (byte[]) val);
|
||||
prestmt.setObject(++k, blob);
|
||||
} else if (val instanceof AtomicInteger) {
|
||||
prestmt.setObject(++k, ((AtomicInteger) val).get());
|
||||
} else if (val instanceof AtomicLong) {
|
||||
prestmt.setObject(++k, ((AtomicLong) val).get());
|
||||
} else {
|
||||
prestmt.setObject(++k, val);
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ import java.io.Serializable;
|
||||
import java.lang.reflect.Array;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.*;
|
||||
import java.util.concurrent.atomic.*;
|
||||
import java.util.function.*;
|
||||
import java.util.logging.*;
|
||||
import java.util.stream.*;
|
||||
@@ -226,6 +227,10 @@ public final class EntityCache<T> {
|
||||
id = ((Number) id).byteValue();
|
||||
} else if (atype == double.class || atype == Double.class) {
|
||||
id = ((Number) id).doubleValue();
|
||||
} else if (atype == AtomicInteger.class) {
|
||||
id = new AtomicInteger(((Number) id).intValue());
|
||||
} else if (atype == AtomicLong.class) {
|
||||
id = new AtomicLong(((Number) id).longValue());
|
||||
}
|
||||
}
|
||||
return this.map.containsKey(id);
|
||||
@@ -299,11 +304,11 @@ public final class EntityCache<T> {
|
||||
if (filter != null) stream = stream.filter(filter);
|
||||
switch (func) {
|
||||
case AVG:
|
||||
if (attr.type() == int.class || attr.type() == Integer.class) {
|
||||
OptionalDouble rs = stream.mapToInt(x -> (Integer) attr.get(x)).average();
|
||||
if (attr.type() == int.class || attr.type() == Integer.class || attr.type() == AtomicInteger.class) {
|
||||
OptionalDouble rs = stream.mapToInt(x -> ((Number) attr.get(x)).intValue()).average();
|
||||
return rs.isPresent() ? (int) rs.getAsDouble() : defResult;
|
||||
} else if (attr.type() == long.class || attr.type() == Long.class) {
|
||||
OptionalDouble rs = stream.mapToLong(x -> (Long) attr.get(x)).average();
|
||||
} else if (attr.type() == long.class || attr.type() == Long.class || attr.type() == AtomicLong.class) {
|
||||
OptionalDouble rs = stream.mapToLong(x -> ((Number) attr.get(x)).longValue()).average();
|
||||
return rs.isPresent() ? (long) rs.getAsDouble() : defResult;
|
||||
} else if (attr.type() == short.class || attr.type() == Short.class) {
|
||||
OptionalDouble rs = stream.mapToInt(x -> ((Short) attr.get(x)).intValue()).average();
|
||||
@@ -322,11 +327,11 @@ public final class EntityCache<T> {
|
||||
return stream.map(x -> attr.get(x)).distinct().count();
|
||||
|
||||
case MAX:
|
||||
if (attr.type() == int.class || attr.type() == Integer.class) {
|
||||
OptionalInt rs = stream.mapToInt(x -> (Integer) attr.get(x)).max();
|
||||
if (attr.type() == int.class || attr.type() == Integer.class || attr.type() == AtomicInteger.class) {
|
||||
OptionalInt rs = stream.mapToInt(x -> ((Number) attr.get(x)).intValue()).max();
|
||||
return rs.isPresent() ? rs.getAsInt() : defResult;
|
||||
} else if (attr.type() == long.class || attr.type() == Long.class) {
|
||||
OptionalLong rs = stream.mapToLong(x -> (Long) attr.get(x)).max();
|
||||
} else if (attr.type() == long.class || attr.type() == Long.class || attr.type() == AtomicLong.class) {
|
||||
OptionalLong rs = stream.mapToLong(x -> ((Number) attr.get(x)).longValue()).max();
|
||||
return rs.isPresent() ? rs.getAsLong() : defResult;
|
||||
} else if (attr.type() == short.class || attr.type() == Short.class) {
|
||||
OptionalInt rs = stream.mapToInt(x -> ((Short) attr.get(x)).intValue()).max();
|
||||
@@ -341,11 +346,11 @@ public final class EntityCache<T> {
|
||||
throw new RuntimeException("getNumberResult error(type:" + type + ", attr.declaringClass: " + attr.declaringClass() + ", attr.field: " + attr.field() + ", attr.type: " + attr.type());
|
||||
|
||||
case MIN:
|
||||
if (attr.type() == int.class || attr.type() == Integer.class) {
|
||||
OptionalInt rs = stream.mapToInt(x -> (Integer) attr.get(x)).min();
|
||||
if (attr.type() == int.class || attr.type() == Integer.class || attr.type() == AtomicInteger.class) {
|
||||
OptionalInt rs = stream.mapToInt(x -> ((Number) attr.get(x)).intValue()).min();
|
||||
return rs.isPresent() ? rs.getAsInt() : defResult;
|
||||
} else if (attr.type() == long.class || attr.type() == Long.class) {
|
||||
OptionalLong rs = stream.mapToLong(x -> (Long) attr.get(x)).min();
|
||||
} else if (attr.type() == long.class || attr.type() == Long.class || attr.type() == AtomicLong.class) {
|
||||
OptionalLong rs = stream.mapToLong(x -> ((Number) attr.get(x)).longValue()).min();
|
||||
return rs.isPresent() ? rs.getAsLong() : defResult;
|
||||
} else if (attr.type() == short.class || attr.type() == Short.class) {
|
||||
OptionalInt rs = stream.mapToInt(x -> ((Short) attr.get(x)).intValue()).min();
|
||||
@@ -360,10 +365,10 @@ public final class EntityCache<T> {
|
||||
throw new RuntimeException("getNumberResult error(type:" + type + ", attr.declaringClass: " + attr.declaringClass() + ", attr.field: " + attr.field() + ", attr.type: " + attr.type());
|
||||
|
||||
case SUM:
|
||||
if (attr.type() == int.class || attr.type() == Integer.class) {
|
||||
return stream.mapToInt(x -> (Integer) attr.get(x)).sum();
|
||||
} else if (attr.type() == long.class || attr.type() == Long.class) {
|
||||
return stream.mapToLong(x -> (Long) attr.get(x)).sum();
|
||||
if (attr.type() == int.class || attr.type() == Integer.class || attr.type() == AtomicInteger.class) {
|
||||
return stream.mapToInt(x -> ((Number) attr.get(x)).intValue()).sum();
|
||||
} else if (attr.type() == long.class || attr.type() == Long.class || attr.type() == AtomicLong.class) {
|
||||
return stream.mapToLong(x -> ((Number) attr.get(x)).longValue()).sum();
|
||||
} else if (attr.type() == short.class || attr.type() == Short.class) {
|
||||
return (short) stream.mapToInt(x -> ((Short) attr.get(x)).intValue()).sum();
|
||||
} else if (attr.type() == float.class || attr.type() == Float.class) {
|
||||
@@ -628,6 +633,16 @@ public final class EntityCache<T> {
|
||||
newval = numb.doubleValue();
|
||||
} else if (ft == byte.class || ft == Byte.class) {
|
||||
newval = numb.byteValue();
|
||||
} else if (ft == AtomicInteger.class) {
|
||||
newval = new AtomicInteger(numb.intValue());
|
||||
} else if (ft == AtomicLong.class) {
|
||||
newval = new AtomicLong(numb.longValue());
|
||||
}
|
||||
} else {
|
||||
if (ft == AtomicInteger.class && newval != null && newval.getClass() != AtomicInteger.class) {
|
||||
newval = new AtomicInteger(((Number) newval).intValue());
|
||||
} else if (ft == AtomicLong.class && newval != null && newval.getClass() != AtomicLong.class) {
|
||||
newval = new AtomicLong(((Number) newval).longValue());
|
||||
}
|
||||
}
|
||||
attr.set(rs, (V) newval);
|
||||
@@ -657,9 +672,9 @@ public final class EntityCache<T> {
|
||||
final String func = sub[0].substring(0, pos);
|
||||
if ("ABS".equalsIgnoreCase(func)) {
|
||||
Function getter = null;
|
||||
if (pattr.type() == int.class || pattr.type() == Integer.class) {
|
||||
if (pattr.type() == int.class || pattr.type() == Integer.class || pattr.type() == AtomicInteger.class) {
|
||||
getter = x -> Math.abs(((Number) pattr.get((T) x)).intValue());
|
||||
} else if (pattr.type() == long.class || pattr.type() == Long.class) {
|
||||
} else if (pattr.type() == long.class || pattr.type() == Long.class || pattr.type() == AtomicLong.class) {
|
||||
getter = x -> Math.abs(((Number) pattr.get((T) x)).longValue());
|
||||
} else if (pattr.type() == float.class || pattr.type() == Float.class) {
|
||||
getter = x -> Math.abs(((Number) pattr.get((T) x)).floatValue());
|
||||
|
||||
@@ -10,6 +10,7 @@ import java.lang.reflect.*;
|
||||
import java.sql.*;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.atomic.*;
|
||||
import java.util.function.*;
|
||||
import java.util.logging.*;
|
||||
import javax.persistence.*;
|
||||
@@ -191,7 +192,7 @@ public final class EntityInfo<T> {
|
||||
this.table = null;
|
||||
BiFunction<DataSource, Class, List> loader = null;
|
||||
try {
|
||||
loader = type.getAnnotation(VirtualEntity.class).loader().newInstance();
|
||||
loader = type.getAnnotation(VirtualEntity.class).loader().getDeclaredConstructor().newInstance();
|
||||
} catch (Exception e) {
|
||||
logger.log(Level.SEVERE, type + " init @VirtualEntity.loader error", e);
|
||||
}
|
||||
@@ -204,7 +205,7 @@ public final class EntityInfo<T> {
|
||||
DistributeTable dt = type.getAnnotation(DistributeTable.class);
|
||||
DistributeTableStrategy dts = null;
|
||||
try {
|
||||
dts = (dt == null) ? null : dt.strategy().newInstance();
|
||||
dts = (dt == null) ? null : dt.strategy().getDeclaredConstructor().newInstance();
|
||||
} catch (Exception e) {
|
||||
logger.log(Level.SEVERE, type + " init DistributeTableStrategy error", e);
|
||||
}
|
||||
@@ -760,6 +761,18 @@ public final class EntityInfo<T> {
|
||||
} else if (t == char.class) {
|
||||
o = (char) 0;
|
||||
}
|
||||
} else if (t == AtomicInteger.class) {
|
||||
if (o != null) {
|
||||
o = new AtomicInteger(((Number) o).intValue());
|
||||
} else {
|
||||
o = new AtomicInteger();
|
||||
}
|
||||
} else if (t == AtomicLong.class) {
|
||||
if (o != null) {
|
||||
o = new AtomicLong(((Number) o).longValue());
|
||||
} else {
|
||||
o = new AtomicLong();
|
||||
}
|
||||
}
|
||||
}
|
||||
return o;
|
||||
|
||||
@@ -154,7 +154,7 @@ public class PoolJdbcSource {
|
||||
}
|
||||
}
|
||||
final Class clazz = Thread.currentThread().getContextClassLoader().loadClass(source);
|
||||
Object pdsource = clazz.newInstance();
|
||||
Object pdsource = clazz.getDeclaredConstructor().newInstance();
|
||||
if (source.contains(".postgresql.")) {
|
||||
Class driver = Thread.currentThread().getContextClassLoader().loadClass("org.postgresql.Driver");
|
||||
Properties properties = (Properties) driver.getMethod("parseURL", String.class, Properties.class).invoke(null, url, new Properties());
|
||||
|
||||
@@ -441,7 +441,7 @@ public interface Attribute<T, F> {
|
||||
+ fieldname.substring(fieldname.indexOf('.') + 1) + "_" + pcolumn.getSimpleName().replace("[]", "Array");
|
||||
}
|
||||
try {
|
||||
return (Attribute) loader.loadClass(newDynName.replace('/', '.')).newInstance();
|
||||
return (Attribute) loader.loadClass(newDynName.replace('/', '.')).getDeclaredConstructor().newInstance();
|
||||
} catch (Throwable ex) {
|
||||
}
|
||||
//---------------------------------------------------
|
||||
@@ -593,7 +593,7 @@ public interface Attribute<T, F> {
|
||||
}
|
||||
}.loadClass(newDynName.replace('/', '.'), bytes);
|
||||
try {
|
||||
return creatorClazz.newInstance();
|
||||
return creatorClazz.getDeclaredConstructor().newInstance();
|
||||
} catch (Exception ex) {
|
||||
throw new RuntimeException(ex);
|
||||
}
|
||||
|
||||
@@ -246,7 +246,7 @@ public interface Creator<T> {
|
||||
newDynName = interName + "_Dyn" + Creator.class.getSimpleName();
|
||||
}
|
||||
try {
|
||||
return (Creator) loader.loadClass(newDynName.replace('/', '.')).newInstance();
|
||||
return (Creator) loader.loadClass(newDynName.replace('/', '.')).getDeclaredConstructor().newInstance();
|
||||
} catch (Throwable ex) {
|
||||
}
|
||||
|
||||
@@ -494,7 +494,7 @@ public interface Creator<T> {
|
||||
return defineClass(name, b, 0, b.length);
|
||||
}
|
||||
}.loadClass(newDynName.replace('/', '.'), bytes);
|
||||
return (Creator) resultClazz.newInstance();
|
||||
return (Creator) resultClazz.getDeclaredConstructor().newInstance();
|
||||
} catch (Exception ex) {
|
||||
throw new RuntimeException(ex);
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ public final class Redkale {
|
||||
}
|
||||
|
||||
public static String getDotedVersion() {
|
||||
return "1.9.0";
|
||||
return "1.9.1";
|
||||
}
|
||||
|
||||
public static int getMajorVersion() {
|
||||
|
||||
@@ -5,7 +5,9 @@
|
||||
*/
|
||||
package org.redkale.util;
|
||||
|
||||
import java.lang.reflect.*;
|
||||
import java.net.*;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.HashSet;
|
||||
|
||||
/**
|
||||
@@ -35,6 +37,15 @@ public class RedkaleClassLoader extends URLClassLoader {
|
||||
public URL[] getAllURLs() {
|
||||
ClassLoader loader = this;
|
||||
HashSet<URL> set = new HashSet<>();
|
||||
String appPath = System.getProperty("java.class.path");
|
||||
if (appPath != null && !appPath.isEmpty()) {
|
||||
for (String path : appPath.replace(":/", "&&").replace(":\\", "##").replace(':', ';').split(";")) {
|
||||
try {
|
||||
set.add(Paths.get(path.replace("&&", ":/").replace("##", ":\\")).toRealPath().toFile().toURI().toURL());
|
||||
} catch (Exception e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
do {
|
||||
String loaderName = loader.getClass().getName();
|
||||
if (loaderName.startsWith("sun.") && loaderName.contains("ExtClassLoader")) continue;
|
||||
@@ -42,6 +53,33 @@ public class RedkaleClassLoader extends URLClassLoader {
|
||||
for (URL url : ((URLClassLoader) loader).getURLs()) {
|
||||
set.add(url);
|
||||
}
|
||||
} else { //可能JDK9及以上
|
||||
loader.getResource("org.redkale"); //必须要运行一次,确保URLClassPath的值被填充完毕
|
||||
Class loaderClazz = loader.getClass();
|
||||
Object ucp = null;
|
||||
do { //读取 java.base/jdk.internal.loader.BuiltinClassLoader的URLClassPath ucp值
|
||||
try {
|
||||
//需要在命令行里加入: --add-opens java.base/jdk.internal.loader=ALL-UNNAMED
|
||||
Field field = loaderClazz.getDeclaredField("ucp");
|
||||
field.setAccessible(true);
|
||||
ucp = field.get(loader);
|
||||
break;
|
||||
} catch (Throwable e) {
|
||||
}
|
||||
} while ((loaderClazz = loaderClazz.getSuperclass()) != Object.class);
|
||||
if (ucp != null) { //URLClassPath
|
||||
URL[] urls = null;
|
||||
try { //读取 java.base/jdk.internal.loader.URLClassPath的urls值
|
||||
Method method = ucp.getClass().getMethod("getURLs");
|
||||
urls = (URL[]) method.invoke(ucp);
|
||||
} catch (Exception e) {
|
||||
}
|
||||
if (urls != null) {
|
||||
for (URL url : urls) {
|
||||
set.add(url);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} while ((loader = loader.getParent()) != null);
|
||||
return set.toArray(new URL[set.size()]);
|
||||
|
||||
@@ -23,11 +23,16 @@ public interface Reproduce<D, S> extends BiFunction<D, S, D> {
|
||||
public D apply(D dest, S src);
|
||||
|
||||
public static <D, S> Reproduce<D, S> create(final Class<D> destClass, final Class<S> srcClass) {
|
||||
return create(destClass, srcClass, null);
|
||||
return create(destClass, srcClass, (BiPredicate) null);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <D, S> Reproduce<D, S> create(final Class<D> destClass, final Class<S> srcClass, final Predicate<String> columnPredicate) {
|
||||
return create(destClass, srcClass, (sc, m) -> columnPredicate.test(m));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <D, S> Reproduce<D, S> create(final Class<D> destClass, final Class<S> srcClass, final BiPredicate<Class<S>, String> columnPredicate) {
|
||||
// ------------------------------------------------------------------------------
|
||||
final String supDynName = Reproduce.class.getName().replace('.', '/');
|
||||
final String destName = destClass.getName().replace('.', '/');
|
||||
@@ -41,7 +46,7 @@ public interface Reproduce<D, S> extends BiFunction<D, S, D> {
|
||||
newDynName = destName + "_Dyn" + Reproduce.class.getSimpleName() + "_" + srcClass.getSimpleName();
|
||||
}
|
||||
try {
|
||||
return (Reproduce) loader.loadClass(newDynName.replace('/', '.')).newInstance();
|
||||
return (Reproduce) loader.loadClass(newDynName.replace('/', '.')).getDeclaredConstructor().newInstance();
|
||||
} catch (Throwable ex) {
|
||||
}
|
||||
// ------------------------------------------------------------------------------
|
||||
@@ -72,7 +77,7 @@ public interface Reproduce<D, S> extends BiFunction<D, S, D> {
|
||||
final String fname = field.getName();
|
||||
try {
|
||||
if (!field.getType().equals(destClass.getField(fname).getType())) continue;
|
||||
if (!columnPredicate.test(fname)) continue;
|
||||
if (!columnPredicate.test(srcClass, fname)) continue;
|
||||
} catch (Exception e) {
|
||||
continue;
|
||||
}
|
||||
@@ -99,7 +104,7 @@ public interface Reproduce<D, S> extends BiFunction<D, S, D> {
|
||||
cs[0] = Character.toLowerCase(cs[0]);
|
||||
col = new String(cs);
|
||||
}
|
||||
if (!columnPredicate.test(col)) continue;
|
||||
if (!columnPredicate.test(srcClass, col)) continue;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
continue;
|
||||
@@ -136,7 +141,7 @@ public interface Reproduce<D, S> extends BiFunction<D, S, D> {
|
||||
}
|
||||
}.loadClass(newDynName.replace('/', '.'), bytes);
|
||||
try {
|
||||
return (Reproduce) creatorClazz.newInstance();
|
||||
return (Reproduce) creatorClazz.getDeclaredConstructor().newInstance();
|
||||
} catch (Exception ex) {
|
||||
throw new RuntimeException(ex);
|
||||
}
|
||||
|
||||
@@ -567,7 +567,11 @@ public final class ResourceFactory {
|
||||
}
|
||||
}
|
||||
if (ns == null) continue;
|
||||
if (ns.getClass().isPrimitive() || ns.getClass().isArray() || ns.getClass().getName().startsWith("java")) continue;
|
||||
if (ns.getClass().isPrimitive() || ns.getClass().isArray()
|
||||
|| ns.getClass().getName().startsWith("java.")
|
||||
|| ns.getClass().getName().startsWith("javax.")
|
||||
|| ns.getClass().getName().startsWith("jdk.")
|
||||
|| ns.getClass().getName().startsWith("sun.")) continue;
|
||||
if (flag) this.inject(ns, attachment, consumer, list);
|
||||
continue;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user