Compare commits
31 Commits
2.0.0.beta
...
2.0.0.rc2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d373ab7204 | ||
|
|
4f9a563ba7 | ||
|
|
852da19b1e | ||
|
|
ddfc040a53 | ||
|
|
df3ccb763a | ||
|
|
f42561ca93 | ||
|
|
580e28519a | ||
|
|
9ecc1d8f19 | ||
|
|
40629ed7b9 | ||
|
|
5790135add | ||
|
|
fd862ed6c6 | ||
|
|
33763af96c | ||
|
|
7c05df3cfb | ||
|
|
f471e2d4c5 | ||
|
|
d4fd093521 | ||
|
|
40003c7789 | ||
|
|
b94f99f338 | ||
|
|
bd21644571 | ||
|
|
5f3599d9b8 | ||
|
|
1e4a30bd70 | ||
|
|
e7dc5de9f2 | ||
|
|
ccb9cb28f5 | ||
|
|
4d9b72c922 | ||
|
|
a51ae13a39 | ||
|
|
dfca186688 | ||
|
|
fadd229a89 | ||
|
|
7acc69adc4 | ||
|
|
d88e4120a1 | ||
|
|
ef98edd91a | ||
|
|
f4548bbe34 | ||
|
|
11a5faca1d |
@@ -1 +0,0 @@
|
|||||||
<EFBFBD>Լ<EFBFBD><EFBFBD><EFBFBD>ҵ<EFBFBD><EFBFBD>jarĬ<EFBFBD>Ϸ<EFBFBD><EFBFBD>ڴ˴<EFBFBD>
|
|
||||||
@@ -16,10 +16,6 @@
|
|||||||
<directory>${project.basedir}/conf</directory>
|
<directory>${project.basedir}/conf</directory>
|
||||||
<outputDirectory>conf</outputDirectory>
|
<outputDirectory>conf</outputDirectory>
|
||||||
</fileSet>
|
</fileSet>
|
||||||
<fileSet>
|
|
||||||
<directory>${project.basedir}/libs</directory>
|
|
||||||
<outputDirectory>libs</outputDirectory>
|
|
||||||
</fileSet>
|
|
||||||
<fileSet>
|
<fileSet>
|
||||||
<directory>${project.basedir}/logs</directory>
|
<directory>${project.basedir}/logs</directory>
|
||||||
<outputDirectory>logs</outputDirectory>
|
<outputDirectory>logs</outputDirectory>
|
||||||
|
|||||||
@@ -116,7 +116,7 @@
|
|||||||
excludelibs: 排除lib.path与excludes中的正则表达式匹配的路径, 多个正则表达式用分号;隔开
|
excludelibs: 排除lib.path与excludes中的正则表达式匹配的路径, 多个正则表达式用分号;隔开
|
||||||
charset: 文本编码, 默认: UTF-8
|
charset: 文本编码, 默认: UTF-8
|
||||||
backlog: 默认10K
|
backlog: 默认10K
|
||||||
threads: 线程数, 默认: CPU核数*32
|
threads: 线程数, 默认: CPU核数*2,最小8个
|
||||||
maxconns:最大连接数, 小于1表示无限制, 默认: 0
|
maxconns:最大连接数, 小于1表示无限制, 默认: 0
|
||||||
maxbody: request.body最大值, 默认: 64K
|
maxbody: request.body最大值, 默认: 64K
|
||||||
bufferCapacity: ByteBuffer的初始化大小, TCP默认: 32K; (HTTP 2.0、WebSocket,必须要16k以上); UDP默认: 1350B
|
bufferCapacity: ByteBuffer的初始化大小, TCP默认: 32K; (HTTP 2.0、WebSocket,必须要16k以上); UDP默认: 1350B
|
||||||
|
|||||||
@@ -30,5 +30,7 @@ module org.redkale {
|
|||||||
exports org.redkale.util;
|
exports org.redkale.util;
|
||||||
exports org.redkale.watch;
|
exports org.redkale.watch;
|
||||||
|
|
||||||
|
uses org.redkale.source.SourceLoader;
|
||||||
|
uses org.redkale.util.ResourceInjectLoader;
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
@@ -196,7 +196,7 @@ public final class ApiDocsService {
|
|||||||
final FileOutputStream out = new FileOutputStream(new File(app.getHome(), "apidoc.json"));
|
final FileOutputStream out = new FileOutputStream(new File(app.getHome(), "apidoc.json"));
|
||||||
out.write(json.getBytes("UTF-8"));
|
out.write(json.getBytes("UTF-8"));
|
||||||
out.close();
|
out.close();
|
||||||
File doctemplate = new File(app.getConfPath(), "apidoc-template.html");
|
File doctemplate = new File(app.getConfPath().toString(), "apidoc-template.html");
|
||||||
InputStream in = null;
|
InputStream in = null;
|
||||||
if (doctemplate.isFile() && doctemplate.canRead()) {
|
if (doctemplate.isFile() && doctemplate.canRead()) {
|
||||||
in = new FileInputStream(doctemplate);
|
in = new FileInputStream(doctemplate);
|
||||||
|
|||||||
@@ -57,12 +57,12 @@ public final class Application {
|
|||||||
public static final String RESNAME_APP_TIME = "APP_TIME";
|
public static final String RESNAME_APP_TIME = "APP_TIME";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 当前进程的根目录, 类型:String、File、Path
|
* 当前进程的根目录, 类型:String、File、Path、URI
|
||||||
*/
|
*/
|
||||||
public static final String RESNAME_APP_HOME = "APP_HOME";
|
public static final String RESNAME_APP_HOME = "APP_HOME";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 当前进程的配置目录,如果不是绝对路径则视为HOME目录下的相对路径 类型:String、File、Path
|
* 当前进程的配置目录,如果不是绝对路径则视为HOME目录下的相对路径 类型:String、File、Path、URI
|
||||||
*/
|
*/
|
||||||
public static final String RESNAME_APP_CONF = "APP_CONF";
|
public static final String RESNAME_APP_CONF = "APP_CONF";
|
||||||
|
|
||||||
@@ -143,7 +143,7 @@ public final class Application {
|
|||||||
private final File home;
|
private final File home;
|
||||||
|
|
||||||
//配置文件目录
|
//配置文件目录
|
||||||
private final File confPath;
|
private final URI confPath;
|
||||||
|
|
||||||
//日志
|
//日志
|
||||||
private final Logger logger;
|
private final Logger logger;
|
||||||
@@ -176,16 +176,19 @@ public final class Application {
|
|||||||
this.resourceFactory.register(RESNAME_APP_TIME, long.class, this.startTime);
|
this.resourceFactory.register(RESNAME_APP_TIME, long.class, this.startTime);
|
||||||
this.resourceFactory.register(RESNAME_APP_HOME, Path.class, root.toPath());
|
this.resourceFactory.register(RESNAME_APP_HOME, Path.class, root.toPath());
|
||||||
this.resourceFactory.register(RESNAME_APP_HOME, File.class, root);
|
this.resourceFactory.register(RESNAME_APP_HOME, File.class, root);
|
||||||
|
this.resourceFactory.register(RESNAME_APP_HOME, URI.class, root.toURI());
|
||||||
try {
|
try {
|
||||||
this.resourceFactory.register(RESNAME_APP_HOME, root.getCanonicalPath());
|
this.resourceFactory.register(RESNAME_APP_HOME, root.getCanonicalPath());
|
||||||
this.home = root.getCanonicalFile();
|
this.home = root.getCanonicalFile();
|
||||||
String confsubpath = System.getProperty(RESNAME_APP_CONF, "conf");
|
String confsubpath = System.getProperty(RESNAME_APP_CONF, "conf");
|
||||||
if (confsubpath.charAt(0) == '/' || confsubpath.indexOf(':') > 0) {
|
if (confsubpath.contains("://")) {
|
||||||
this.confPath = new File(confsubpath).getCanonicalFile();
|
this.confPath = new URI(confsubpath);
|
||||||
|
} else if (confsubpath.charAt(0) == '/' || confsubpath.indexOf(':') > 0) {
|
||||||
|
this.confPath = new File(confsubpath).getCanonicalFile().toURI();
|
||||||
} else {
|
} else {
|
||||||
this.confPath = new File(this.home, confsubpath).getCanonicalFile();
|
this.confPath = new File(this.home, confsubpath).getCanonicalFile().toURI();
|
||||||
}
|
}
|
||||||
} catch (IOException e) {
|
} catch (Exception e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
String localaddr = config.getValue("address", "").trim();
|
String localaddr = config.getValue("address", "").trim();
|
||||||
@@ -209,11 +212,12 @@ public final class Application {
|
|||||||
System.setProperty(RESNAME_APP_NODE, node);
|
System.setProperty(RESNAME_APP_NODE, node);
|
||||||
}
|
}
|
||||||
//以下是初始化日志配置
|
//以下是初始化日志配置
|
||||||
final File logconf = new File(confPath, "logging.properties");
|
final URI logConfURI = "file".equals(confPath.getScheme()) ? new File(new File(confPath), "logging.properties").toURI()
|
||||||
if (logconf.isFile() && logconf.canRead()) {
|
: URI.create(confPath.toString() + (confPath.toString().endsWith("/") ? "" : "/") + "logging.properties");
|
||||||
|
if (!"file".equals(confPath.getScheme()) || (new File(logConfURI).isFile() && new File(logConfURI).canRead())) {
|
||||||
try {
|
try {
|
||||||
final String rootpath = root.getCanonicalPath().replace('\\', '/');
|
final String rootpath = root.getCanonicalPath().replace('\\', '/');
|
||||||
FileInputStream fin = new FileInputStream(logconf);
|
InputStream fin = logConfURI.toURL().openStream();
|
||||||
Properties properties = new Properties();
|
Properties properties = new Properties();
|
||||||
properties.load(fin);
|
properties.load(fin);
|
||||||
fin.close();
|
fin.close();
|
||||||
@@ -301,7 +305,7 @@ public final class Application {
|
|||||||
transportExec = Executors.newFixedThreadPool(threads, (Runnable r) -> {
|
transportExec = Executors.newFixedThreadPool(threads, (Runnable r) -> {
|
||||||
Thread t = new Thread(r);
|
Thread t = new Thread(r);
|
||||||
t.setDaemon(true);
|
t.setDaemon(true);
|
||||||
t.setName("Transport-Thread-" + counter.incrementAndGet());
|
t.setName("Redkale-Transport-Thread-" + counter.incrementAndGet());
|
||||||
return t;
|
return t;
|
||||||
});
|
});
|
||||||
transportGroup = AsynchronousChannelGroup.withCachedThreadPool(transportExec, 1);
|
transportGroup = AsynchronousChannelGroup.withCachedThreadPool(transportExec, 1);
|
||||||
@@ -316,7 +320,7 @@ public final class Application {
|
|||||||
transportExec = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors() * 8, (Runnable r) -> {
|
transportExec = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors() * 8, (Runnable r) -> {
|
||||||
Thread t = new Thread(r);
|
Thread t = new Thread(r);
|
||||||
t.setDaemon(true);
|
t.setDaemon(true);
|
||||||
t.setName("Transport-Thread-" + counter.incrementAndGet());
|
t.setName("Redkale-Transport-Thread-" + counter.incrementAndGet());
|
||||||
return t;
|
return t;
|
||||||
});
|
});
|
||||||
try {
|
try {
|
||||||
@@ -375,7 +379,7 @@ public final class Application {
|
|||||||
return home;
|
return home;
|
||||||
}
|
}
|
||||||
|
|
||||||
public File getConfPath() {
|
public URI getConfPath() {
|
||||||
return confPath;
|
return confPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -398,10 +402,14 @@ public final class Application {
|
|||||||
System.setProperty("convert.bson.writer.buffer.defsize", "4096");
|
System.setProperty("convert.bson.writer.buffer.defsize", "4096");
|
||||||
System.setProperty("convert.json.writer.buffer.defsize", "4096");
|
System.setProperty("convert.json.writer.buffer.defsize", "4096");
|
||||||
|
|
||||||
File persist = new File(this.confPath, "persistence.xml");
|
final String confpath = this.confPath.toString();
|
||||||
final String homepath = this.home.getCanonicalPath();
|
final String homepath = this.home.getCanonicalPath();
|
||||||
final String confpath = this.confPath.getCanonicalPath();
|
if ("file".equals(this.confPath.getScheme())) {
|
||||||
if (persist.isFile()) System.setProperty(DataSources.DATASOURCE_CONFPATH, persist.getCanonicalPath());
|
File persist = new File(new File(confPath), "persistence.xml");
|
||||||
|
if (persist.isFile()) System.setProperty(DataSources.DATASOURCE_CONFPATH, persist.getCanonicalPath());
|
||||||
|
} else {
|
||||||
|
System.setProperty(DataSources.DATASOURCE_CONFPATH, confpath + (confpath.endsWith("/") ? "" : "/") + "persistence.xml");
|
||||||
|
}
|
||||||
String pidstr = "";
|
String pidstr = "";
|
||||||
try { //JDK 9+
|
try { //JDK 9+
|
||||||
Class phclass = Class.forName("java.lang.ProcessHandle");
|
Class phclass = Class.forName("java.lang.ProcessHandle");
|
||||||
@@ -425,13 +433,17 @@ public final class Application {
|
|||||||
if (dfloads != null) {
|
if (dfloads != null) {
|
||||||
for (String dfload : dfloads.split(";")) {
|
for (String dfload : dfloads.split(";")) {
|
||||||
if (dfload.trim().isEmpty()) continue;
|
if (dfload.trim().isEmpty()) continue;
|
||||||
final File df = (dfload.indexOf('/') < 0) ? new File(confPath, "/" + dfload) : new File(dfload);
|
final URI df = (dfload.indexOf('/') < 0) ? URI.create(confpath + (confpath.endsWith("/") ? "" : "/") + dfload) : new File(dfload).toURI();
|
||||||
if (df.isFile()) {
|
if (!"file".equals(df.getScheme()) || new File(df).isFile()) {
|
||||||
Properties ps = new Properties();
|
Properties ps = new Properties();
|
||||||
InputStream in = new FileInputStream(df);
|
try {
|
||||||
ps.load(in);
|
InputStream in = df.toURL().openStream();
|
||||||
in.close();
|
ps.load(in);
|
||||||
ps.forEach((x, y) -> resourceFactory.register("property." + x, y.toString().replace("${APP_HOME}", homepath)));
|
in.close();
|
||||||
|
ps.forEach((x, y) -> resourceFactory.register("property." + x, y.toString().replace("${APP_HOME}", homepath)));
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.log(Level.WARNING, "load properties(" + dfload + ") error", e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -558,9 +570,10 @@ public final class Application {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void restoreConfig() throws IOException {
|
public void restoreConfig() throws IOException {
|
||||||
|
if (!"file".equals(this.confPath.getScheme())) return;
|
||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
File confFile = new File(this.confPath, "application.xml");
|
File confFile = new File(this.confPath.toString(), "application.xml");
|
||||||
confFile.renameTo(new File(this.confPath, "application_" + String.format("%1$tY%1$tm%1$td%1$tH%1$tM%1$tS", System.currentTimeMillis()) + ".xml"));
|
confFile.renameTo(new File(this.confPath.toString(), "application_" + String.format("%1$tY%1$tm%1$td%1$tH%1$tM%1$tS", System.currentTimeMillis()) + ".xml"));
|
||||||
final PrintStream ps = new PrintStream(new FileOutputStream(confFile));
|
final PrintStream ps = new PrintStream(new FileOutputStream(confFile));
|
||||||
ps.append(config.toXML("application"));
|
ps.append(config.toXML("application"));
|
||||||
ps.close();
|
ps.close();
|
||||||
@@ -571,7 +584,7 @@ public final class Application {
|
|||||||
final Application application = this;
|
final Application application = this;
|
||||||
new Thread() {
|
new Thread() {
|
||||||
{
|
{
|
||||||
setName("Application-Control-Thread");
|
setName("Redkale-Application-SelfServer-Thread");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -742,7 +755,7 @@ public final class Application {
|
|||||||
Thread thread = new Thread() {
|
Thread thread = new Thread() {
|
||||||
{
|
{
|
||||||
String host = serconf.getValue("host", "0.0.0.0").replace("0.0.0.0", "*");
|
String host = serconf.getValue("host", "0.0.0.0").replace("0.0.0.0", "*");
|
||||||
setName(serconf.getValue("protocol", "Server").toUpperCase() + "-" + host + ":" + serconf.getIntValue("port") + "-Thread");
|
setName("Redkale-" + serconf.getValue("protocol", "Server").toUpperCase() + "-" + host + ":" + serconf.getIntValue("port") + "-Thread");
|
||||||
this.setDaemon(true);
|
this.setDaemon(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -843,18 +856,20 @@ public final class Application {
|
|||||||
final String home = new File(System.getProperty(RESNAME_APP_HOME, "")).getCanonicalPath().replace('\\', '/');
|
final String home = new File(System.getProperty(RESNAME_APP_HOME, "")).getCanonicalPath().replace('\\', '/');
|
||||||
System.setProperty(RESNAME_APP_HOME, home);
|
System.setProperty(RESNAME_APP_HOME, home);
|
||||||
String confsubpath = System.getProperty(RESNAME_APP_CONF, "conf");
|
String confsubpath = System.getProperty(RESNAME_APP_CONF, "conf");
|
||||||
File appfile;
|
URI appconf;
|
||||||
if (confsubpath.charAt(0) == '/' || confsubpath.indexOf(':') > 0) {
|
if (confsubpath.contains("://")) {
|
||||||
appfile = new File(confsubpath).getCanonicalFile();
|
appconf = URI.create(confsubpath + (confsubpath.endsWith("/") ? "" : "/") + "application.xml");
|
||||||
|
} else if (confsubpath.charAt(0) == '/' || confsubpath.indexOf(':') > 0) {
|
||||||
|
appconf = new File(confsubpath, "application.xml").toURI();
|
||||||
} else {
|
} else {
|
||||||
appfile = new File(new File(home), confsubpath);
|
appconf = new File(new File(home, confsubpath), "application.xml").toURI();
|
||||||
}
|
}
|
||||||
File appconf = new File(appfile, "application.xml");
|
return new Application(singleton, load(appconf.toURL().openStream()));
|
||||||
return new Application(singleton, load(new FileInputStream(appconf)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void main(String[] args) throws Exception {
|
public static void main(String[] args) throws Exception {
|
||||||
Utility.midnight(); //先初始化一下Utility
|
Utility.midnight(); //先初始化一下Utility
|
||||||
|
Thread.currentThread().setName("Redkale-Application-Main-Thread");
|
||||||
//运行主程序
|
//运行主程序
|
||||||
final Application application = Application.create(false);
|
final Application application = Application.create(false);
|
||||||
if (System.getProperty("CMD") != null) {
|
if (System.getProperty("CMD") != null) {
|
||||||
|
|||||||
@@ -133,7 +133,7 @@ public class LogFileHandler extends Handler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void open() {
|
private void open() {
|
||||||
final String name = "Logging-" + getClass().getSimpleName() + "-Thread";
|
final String name = "Redkale-Logging-" + getClass().getSimpleName() + "-Thread";
|
||||||
new Thread() {
|
new Thread() {
|
||||||
{
|
{
|
||||||
setName(name);
|
setName(name);
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|
||||||
|
|||||||
@@ -133,6 +133,54 @@ public abstract class ConvertFactory<R extends Reader, W extends Writer> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
try {
|
||||||
|
Class sqldateClass = Class.forName("java.sql.Date");
|
||||||
|
this.register(sqldateClass, new SimpledCoder<R, W, java.sql.Date>() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void convertTo(W out, java.sql.Date value) {
|
||||||
|
out.writeSmallString(value == null ? null : value.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public java.sql.Date convertFrom(R in) {
|
||||||
|
String t = in.readSmallString();
|
||||||
|
return t == null ? null : java.sql.Date.valueOf(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
Class sqltimeClass = Class.forName("java.sql.Time");
|
||||||
|
this.register(sqltimeClass, new SimpledCoder<R, W, java.sql.Time>() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void convertTo(W out, java.sql.Time value) {
|
||||||
|
out.writeSmallString(value == null ? null : value.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public java.sql.Time convertFrom(R in) {
|
||||||
|
String t = in.readSmallString();
|
||||||
|
return t == null ? null : java.sql.Time.valueOf(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
Class timestampClass = Class.forName("java.sql.Timestamp");
|
||||||
|
this.register(timestampClass, new SimpledCoder<R, W, java.sql.Timestamp>() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void convertTo(W out, java.sql.Timestamp value) {
|
||||||
|
out.writeSmallString(value == null ? null : value.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public java.sql.Timestamp convertFrom(R in) {
|
||||||
|
String t = in.readSmallString();
|
||||||
|
return t == null ? null : java.sql.Timestamp.valueOf(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
} catch (Throwable t) {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -711,7 +759,8 @@ public abstract class ConvertFactory<R extends Reader, W extends Writer> {
|
|||||||
encoder = new OptionalCoder(this, type);
|
encoder = new OptionalCoder(this, type);
|
||||||
} else if (clazz == Object.class) {
|
} else if (clazz == Object.class) {
|
||||||
return (Encodeable<W, E>) this.anyEncoder;
|
return (Encodeable<W, E>) this.anyEncoder;
|
||||||
} else if (!clazz.getName().startsWith("java.") || java.net.HttpCookie.class == clazz || java.util.AbstractMap.SimpleEntry.class == clazz) {
|
} else if (!clazz.getName().startsWith("java.") || java.net.HttpCookie.class == clazz
|
||||||
|
|| java.util.Map.Entry.class == clazz || java.util.AbstractMap.SimpleEntry.class == clazz) {
|
||||||
Encodeable simpleCoder = null;
|
Encodeable simpleCoder = null;
|
||||||
for (final Method method : clazz.getDeclaredMethods()) {
|
for (final Method method : clazz.getDeclaredMethods()) {
|
||||||
if (!Modifier.isStatic(method.getModifiers())) continue;
|
if (!Modifier.isStatic(method.getModifiers())) continue;
|
||||||
|
|||||||
102
src/org/redkale/convert/ConvertField.java
Normal file
102
src/org/redkale/convert/ConvertField.java
Normal file
@@ -0,0 +1,102 @@
|
|||||||
|
/*
|
||||||
|
* To change this license header, choose License Headers in Project Properties.
|
||||||
|
* To change this template file, choose Tools | Templates
|
||||||
|
* and open the template in the editor.
|
||||||
|
*/
|
||||||
|
package org.redkale.convert;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.lang.reflect.Type;
|
||||||
|
import org.redkale.convert.json.JsonConvert;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* newConvert参数中的Function返回结果的数据类
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* 详情见: https://redkale.org
|
||||||
|
*
|
||||||
|
* @author zhangjx
|
||||||
|
*/
|
||||||
|
public class ConvertField implements Serializable {
|
||||||
|
|
||||||
|
protected String name;
|
||||||
|
|
||||||
|
protected Type type;
|
||||||
|
|
||||||
|
protected int position;
|
||||||
|
|
||||||
|
protected Object value;
|
||||||
|
|
||||||
|
public ConvertField() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public ConvertField(String name, Object value) {
|
||||||
|
this.name = name;
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ConvertField(String name, int position, Object value) {
|
||||||
|
this.name = name;
|
||||||
|
this.position = position;
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ConvertField(String name, Type type, Object value) {
|
||||||
|
this.name = name;
|
||||||
|
this.type = type;
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ConvertField(String name, Type type, int position, Object value) {
|
||||||
|
this.name = name;
|
||||||
|
this.type = type;
|
||||||
|
this.position = position;
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ConvertField[] ofArray(Object... items) {
|
||||||
|
int len = items.length / 2;
|
||||||
|
ConvertField[] rs = new ConvertField[len];
|
||||||
|
for (int i = 0; i < len; i++) {
|
||||||
|
rs[i] = new ConvertField(items[i * 2].toString(), items[i * 2 + 1]);
|
||||||
|
}
|
||||||
|
return rs;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Type getType() {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setType(Type type) {
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getPosition() {
|
||||||
|
return position;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPosition(int position) {
|
||||||
|
this.position = position;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object getValue() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setValue(Object value) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return JsonConvert.root().convertTo(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -164,9 +164,22 @@ public class ObjectEncoder<W extends Writer, T> implements Encodeable<W, T> {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (out.writeObjectB(value) < 0) {
|
if (out.writeObjectB(value) < 0) {
|
||||||
|
int maxPosition = 0;
|
||||||
for (EnMember member : members) {
|
for (EnMember member : members) {
|
||||||
|
maxPosition = member.getPosition();
|
||||||
out.writeObjectField(member, value);
|
out.writeObjectField(member, value);
|
||||||
}
|
}
|
||||||
|
if (out.objExtFunc != null) {
|
||||||
|
ConvertField[] extFields = out.objExtFunc.apply(value);
|
||||||
|
if (extFields != null) {
|
||||||
|
Encodeable<W, ?> anyEncoder = factory.getAnyEncoder();
|
||||||
|
for (ConvertField en : extFields) {
|
||||||
|
if (en == null) continue;
|
||||||
|
maxPosition++;
|
||||||
|
out.writeObjectField(en.getName(), en.getType(), Math.max(en.getPosition(), maxPosition), anyEncoder, en.getValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
out.writeObjectE(value);
|
out.writeObjectE(value);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
package org.redkale.convert;
|
package org.redkale.convert;
|
||||||
|
|
||||||
import java.lang.reflect.*;
|
import java.lang.reflect.*;
|
||||||
import java.util.function.BiFunction;
|
import java.util.function.*;
|
||||||
import org.redkale.util.*;
|
import org.redkale.util.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -26,7 +26,10 @@ public abstract class Writer {
|
|||||||
protected Type specify;
|
protected Type specify;
|
||||||
|
|
||||||
//对某个字段值进行动态处理
|
//对某个字段值进行动态处理
|
||||||
protected BiFunction<Attribute, Object, Object> fieldFunc;
|
protected BiFunction<Attribute, Object, Object> objFieldFunc;
|
||||||
|
|
||||||
|
//对某个对象进行动态扩展字段值处理
|
||||||
|
protected Function<Object, ConvertField[]> objExtFunc;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 设置specify
|
* 设置specify
|
||||||
@@ -44,7 +47,7 @@ public abstract class Writer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected boolean recycle() {
|
protected boolean recycle() {
|
||||||
this.fieldFunc = null;
|
this.objFieldFunc = null;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -116,10 +119,10 @@ public abstract class Writer {
|
|||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public void writeObjectField(final EnMember member, Object obj) {
|
public void writeObjectField(final EnMember member, Object obj) {
|
||||||
Object value;
|
Object value;
|
||||||
if (fieldFunc == null) {
|
if (objFieldFunc == null) {
|
||||||
value = member.attribute.get(obj);
|
value = member.attribute.get(obj);
|
||||||
} else {
|
} else {
|
||||||
value = fieldFunc.apply(member.attribute, obj);
|
value = objFieldFunc.apply(member.attribute, obj);
|
||||||
}
|
}
|
||||||
if (value == null) return;
|
if (value == null) return;
|
||||||
if (tiny()) {
|
if (tiny()) {
|
||||||
@@ -129,11 +132,49 @@ public abstract class Writer {
|
|||||||
if (!((Boolean) value)) return;
|
if (!((Boolean) value)) return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.writeFieldName(member);
|
Attribute attr = member.getAttribute();
|
||||||
|
this.writeFieldName(attr.field(), attr.genericType(), member.getPosition());
|
||||||
member.encoder.convertTo(this, value);
|
member.encoder.convertTo(this, value);
|
||||||
this.comma = true;
|
this.comma = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 输出一个对象的某个扩展字段
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @param fieldName 字段名称
|
||||||
|
* @param fieldType 字段类型
|
||||||
|
* @param fieldPos 字段顺序
|
||||||
|
* @param anyEncoder Encoder
|
||||||
|
* @param value 写入的字段对象
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public void writeObjectField(final String fieldName, Type fieldType, int fieldPos, Encodeable anyEncoder, Object value) {
|
||||||
|
if (value == null) return;
|
||||||
|
if (fieldType == null) fieldType = value.getClass();
|
||||||
|
if (tiny() && fieldType instanceof Class) {
|
||||||
|
Class clazz = (Class) fieldType;
|
||||||
|
if (CharSequence.class.isAssignableFrom(clazz)) {
|
||||||
|
if (((CharSequence) value).length() == 0) return;
|
||||||
|
} else if (clazz == boolean.class || clazz == Boolean.class) {
|
||||||
|
if (!((Boolean) value)) return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.writeFieldName(fieldName, fieldType, fieldPos);
|
||||||
|
anyEncoder.convertTo(this, value);
|
||||||
|
this.comma = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 输出一个字段名
|
||||||
|
*
|
||||||
|
* @param member 字段
|
||||||
|
*/
|
||||||
|
public final void writeFieldName(final EnMember member) {
|
||||||
|
Attribute attr = member.getAttribute();
|
||||||
|
this.writeFieldName(attr.field(), attr.genericType(), member.getPosition());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 输出一个对象后的操作
|
* 输出一个对象后的操作
|
||||||
*
|
*
|
||||||
@@ -191,9 +232,11 @@ public abstract class Writer {
|
|||||||
/**
|
/**
|
||||||
* 输出一个字段名
|
* 输出一个字段名
|
||||||
*
|
*
|
||||||
* @param member 字段的EnMember对象
|
* @param fieldName 字段名称
|
||||||
|
* @param fieldType 字段类型
|
||||||
|
* @param fieldPos 字段顺序
|
||||||
*/
|
*/
|
||||||
public abstract void writeFieldName(EnMember member);
|
public abstract void writeFieldName(String fieldName, Type fieldType, int fieldPos);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 写入一个boolean值
|
* 写入一个boolean值
|
||||||
|
|||||||
@@ -61,10 +61,15 @@ public class BsonConvert extends BinaryConvert<BsonReader, BsonWriter> {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BsonConvert newConvert(final BiFunction<Attribute, Object, Object> fieldFunc) {
|
public BsonConvert newConvert(final BiFunction<Attribute, Object, Object> fieldFunc) {
|
||||||
|
return newConvert(fieldFunc, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BsonConvert newConvert(final BiFunction<Attribute, Object, Object> fieldFunc, Function<Object, ConvertField[]> objExtFunc) {
|
||||||
return new BsonConvert(getFactory(), tiny) {
|
return new BsonConvert(getFactory(), tiny) {
|
||||||
@Override
|
@Override
|
||||||
protected <S extends BsonWriter> S configWrite(S writer) {
|
protected <S extends BsonWriter> S configWrite(S writer) {
|
||||||
return fieldFunc(writer, fieldFunc);
|
return fieldFunc(writer, fieldFunc, objExtFunc);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
*/
|
*/
|
||||||
package org.redkale.convert.bson;
|
package org.redkale.convert.bson;
|
||||||
|
|
||||||
|
import java.lang.reflect.Type;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import org.redkale.convert.*;
|
import org.redkale.convert.*;
|
||||||
import org.redkale.convert.ext.ByteSimpledCoder;
|
import org.redkale.convert.ext.ByteSimpledCoder;
|
||||||
@@ -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));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -115,7 +115,7 @@ public class JsonByteBufferWriter extends JsonWriter {
|
|||||||
int byteLength = quote ? 2 : 0;
|
int byteLength = quote ? 2 : 0;
|
||||||
ByteBuffer bb = null;
|
ByteBuffer bb = null;
|
||||||
if (charset == null) {
|
if (charset == null) {
|
||||||
byteLength += encodeUTF8Length(chs, start, len);
|
byteLength += Utility.encodeUTF8Length(chs, start, len);
|
||||||
} else {
|
} else {
|
||||||
bb = charset.encode(CharBuffer.wrap(chs, start, len));
|
bb = charset.encode(CharBuffer.wrap(chs, start, len));
|
||||||
byteLength += bb.remaining();
|
byteLength += bb.remaining();
|
||||||
@@ -134,6 +134,13 @@ public class JsonByteBufferWriter extends JsonWriter {
|
|||||||
} else if (c < 0x800) {
|
} else if (c < 0x800) {
|
||||||
buffer.put((byte) (0xc0 | (c >> 6)));
|
buffer.put((byte) (0xc0 | (c >> 6)));
|
||||||
buffer.put((byte) (0x80 | (c & 0x3f)));
|
buffer.put((byte) (0x80 | (c & 0x3f)));
|
||||||
|
} else if (Character.isSurrogate(c)) { //连取两个
|
||||||
|
int uc = Character.toCodePoint(c, chs[i + 1]);
|
||||||
|
buffer.put((byte) (0xf0 | ((uc >> 18))));
|
||||||
|
buffer.put((byte) (0x80 | ((uc >> 12) & 0x3f)));
|
||||||
|
buffer.put((byte) (0x80 | ((uc >> 6) & 0x3f)));
|
||||||
|
buffer.put((byte) (0x80 | (uc & 0x3f)));
|
||||||
|
i++;
|
||||||
} else {
|
} else {
|
||||||
buffer.put((byte) (0xe0 | ((c >> 12))));
|
buffer.put((byte) (0xe0 | ((c >> 12))));
|
||||||
buffer.put((byte) (0x80 | ((c >> 6) & 0x3f)));
|
buffer.put((byte) (0x80 | ((c >> 6) & 0x3f)));
|
||||||
@@ -155,7 +162,34 @@ public class JsonByteBufferWriter extends JsonWriter {
|
|||||||
if (charset == null) { //UTF-8
|
if (charset == null) { //UTF-8
|
||||||
final int limit = start + len;
|
final int limit = start + len;
|
||||||
for (int i = start; i < limit; i++) {
|
for (int i = start; i < limit; i++) {
|
||||||
buffer = putUTF8Char(buffer, chs[i]);
|
char c = chs[i];
|
||||||
|
if (c < 0x80) {
|
||||||
|
if (!buffer.hasRemaining()) buffer = nextByteBuffer();
|
||||||
|
buffer.put((byte) c);
|
||||||
|
} else if (c < 0x800) {
|
||||||
|
if (!buffer.hasRemaining()) buffer = nextByteBuffer();
|
||||||
|
buffer.put((byte) (0xc0 | (c >> 6)));
|
||||||
|
if (!buffer.hasRemaining()) buffer = nextByteBuffer();
|
||||||
|
buffer.put((byte) (0x80 | (c & 0x3f)));
|
||||||
|
} else if (Character.isSurrogate(c)) { //连取两个
|
||||||
|
int uc = Character.toCodePoint(c, chs[i + 1]);
|
||||||
|
if (!buffer.hasRemaining()) buffer = nextByteBuffer();
|
||||||
|
buffer.put((byte) (0xf0 | ((uc >> 18))));
|
||||||
|
if (!buffer.hasRemaining()) buffer = nextByteBuffer();
|
||||||
|
buffer.put((byte) (0x80 | ((uc >> 12) & 0x3f)));
|
||||||
|
if (!buffer.hasRemaining()) buffer = nextByteBuffer();
|
||||||
|
buffer.put((byte) (0x80 | ((uc >> 6) & 0x3f)));
|
||||||
|
if (!buffer.hasRemaining()) buffer = nextByteBuffer();
|
||||||
|
buffer.put((byte) (0x80 | (uc & 0x3f)));
|
||||||
|
i++;
|
||||||
|
} else {
|
||||||
|
if (!buffer.hasRemaining()) buffer = nextByteBuffer();
|
||||||
|
buffer.put((byte) (0xe0 | ((c >> 12))));
|
||||||
|
if (!buffer.hasRemaining()) buffer = nextByteBuffer();
|
||||||
|
buffer.put((byte) (0x80 | ((c >> 6) & 0x3f)));
|
||||||
|
if (!buffer.hasRemaining()) buffer = nextByteBuffer();
|
||||||
|
buffer.put((byte) (0x80 | (c & 0x3f)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
while (bb.hasRemaining()) {
|
while (bb.hasRemaining()) {
|
||||||
@@ -169,50 +203,18 @@ public class JsonByteBufferWriter extends JsonWriter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private ByteBuffer putUTF8Char(ByteBuffer buffer, char c) {
|
|
||||||
if (c < 0x80) {
|
|
||||||
if (!buffer.hasRemaining()) buffer = nextByteBuffer();
|
|
||||||
buffer.put((byte) c);
|
|
||||||
} else if (c < 0x800) {
|
|
||||||
if (!buffer.hasRemaining()) buffer = nextByteBuffer();
|
|
||||||
buffer.put((byte) (0xc0 | (c >> 6)));
|
|
||||||
if (!buffer.hasRemaining()) buffer = nextByteBuffer();
|
|
||||||
buffer.put((byte) (0x80 | (c & 0x3f)));
|
|
||||||
} else {
|
|
||||||
if (!buffer.hasRemaining()) buffer = nextByteBuffer();
|
|
||||||
buffer.put((byte) (0xe0 | ((c >> 12))));
|
|
||||||
if (!buffer.hasRemaining()) buffer = nextByteBuffer();
|
|
||||||
buffer.put((byte) (0x80 | ((c >> 6) & 0x3f)));
|
|
||||||
if (!buffer.hasRemaining()) buffer = nextByteBuffer();
|
|
||||||
buffer.put((byte) (0x80 | (c & 0x3f)));
|
|
||||||
}
|
|
||||||
return buffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
private ByteBuffer nextByteBuffer() {
|
private ByteBuffer nextByteBuffer() {
|
||||||
this.buffers[this.index].flip();
|
this.buffers[this.index].flip();
|
||||||
return this.buffers[++this.index];
|
return this.buffers[++this.index];
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static int encodeUTF8Length(final char[] text, final int start, final int len) {
|
|
||||||
char c;
|
|
||||||
int size = 0;
|
|
||||||
final char[] chars = text;
|
|
||||||
final int limit = start + len;
|
|
||||||
for (int i = start; i < limit; i++) {
|
|
||||||
c = chars[i];
|
|
||||||
size += (c < 0x80 ? 1 : (c < 0x800 ? 2 : 3));
|
|
||||||
}
|
|
||||||
return size;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected static int encodeEscapeUTF8Length(final char[] text, final int start, final int len) {
|
protected static int encodeEscapeUTF8Length(final char[] text, final int start, final int len) {
|
||||||
char c;
|
char c;
|
||||||
int size = 0;
|
int size = 0;
|
||||||
final char[] chars = text;
|
final char[] chs = text;
|
||||||
final int limit = start + len;
|
final int limit = start + len;
|
||||||
for (int i = start; i < limit; i++) {
|
for (int i = start; i < limit; i++) {
|
||||||
c = chars[i];
|
c = chs[i];
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case '\n': size += 2;
|
case '\n': size += 2;
|
||||||
break;
|
break;
|
||||||
@@ -225,7 +227,7 @@ public class JsonByteBufferWriter extends JsonWriter {
|
|||||||
case '"': size += 2;
|
case '"': size += 2;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
size += (c < 0x80 ? 1 : (c < 0x800 ? 2 : 3));
|
size += (c < 0x80 ? 1 : (c < 0x800 || Character.isSurrogate(c) ? 2 : 3));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -289,7 +291,8 @@ public class JsonByteBufferWriter extends JsonWriter {
|
|||||||
if (expandsize == 0) { // 只需要一个buffer
|
if (expandsize == 0) { // 只需要一个buffer
|
||||||
final ByteBuffer buffer = this.buffers[index];
|
final ByteBuffer buffer = this.buffers[index];
|
||||||
buffer.put((byte) '"');
|
buffer.put((byte) '"');
|
||||||
for (char c : chs) {
|
for (int i = 0; i < chs.length; i++) {
|
||||||
|
char c = chs[i];
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case '\n': buffer.put((byte) '\\').put((byte) 'n');
|
case '\n': buffer.put((byte) '\\').put((byte) 'n');
|
||||||
break;
|
break;
|
||||||
@@ -307,6 +310,13 @@ public class JsonByteBufferWriter extends JsonWriter {
|
|||||||
} else if (c < 0x800) {
|
} else if (c < 0x800) {
|
||||||
buffer.put((byte) (0xc0 | (c >> 6)));
|
buffer.put((byte) (0xc0 | (c >> 6)));
|
||||||
buffer.put((byte) (0x80 | (c & 0x3f)));
|
buffer.put((byte) (0x80 | (c & 0x3f)));
|
||||||
|
} else if (Character.isSurrogate(c)) { //连取两个
|
||||||
|
int uc = Character.toCodePoint(c, chs[i + 1]);
|
||||||
|
buffer.put((byte) (0xf0 | ((uc >> 18))));
|
||||||
|
buffer.put((byte) (0x80 | ((uc >> 12) & 0x3f)));
|
||||||
|
buffer.put((byte) (0x80 | ((uc >> 6) & 0x3f)));
|
||||||
|
buffer.put((byte) (0x80 | (uc & 0x3f)));
|
||||||
|
i++;
|
||||||
} else {
|
} else {
|
||||||
buffer.put((byte) (0xe0 | ((c >> 12))));
|
buffer.put((byte) (0xe0 | ((c >> 12))));
|
||||||
buffer.put((byte) (0x80 | ((c >> 6) & 0x3f)));
|
buffer.put((byte) (0x80 | ((c >> 6) & 0x3f)));
|
||||||
|
|||||||
@@ -48,10 +48,15 @@ public class JsonConvert extends TextConvert<JsonReader, JsonWriter> {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public JsonConvert newConvert(final BiFunction<Attribute, Object, Object> fieldFunc) {
|
public JsonConvert newConvert(final BiFunction<Attribute, Object, Object> fieldFunc) {
|
||||||
|
return newConvert(fieldFunc, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JsonConvert newConvert(final BiFunction<Attribute, Object, Object> fieldFunc, Function<Object, ConvertField[]> objExtFunc) {
|
||||||
return new JsonConvert(getFactory(), tiny) {
|
return new JsonConvert(getFactory(), tiny) {
|
||||||
@Override
|
@Override
|
||||||
protected <S extends JsonWriter> S configWrite(S writer) {
|
protected <S extends JsonWriter> S configWrite(S writer) {
|
||||||
return fieldFunc(writer, fieldFunc);
|
return fieldFunc(writer, fieldFunc, objExtFunc);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,10 +26,7 @@ public final class JsonFactory extends ConvertFactory<JsonReader, JsonWriter> {
|
|||||||
private static final JsonFactory instance = new JsonFactory(null, Boolean.getBoolean("convert.json.tiny"));
|
private static final JsonFactory instance = new JsonFactory(null, Boolean.getBoolean("convert.json.tiny"));
|
||||||
|
|
||||||
static {
|
static {
|
||||||
instance.register(InetAddress.class, InetAddressSimpledCoder.InetAddressJsonSimpledCoder.instance);
|
|
||||||
instance.register(InetSocketAddress.class, InetAddressSimpledCoder.InetSocketAddressJsonSimpledCoder.instance);
|
|
||||||
instance.register(DLong.class, DLongSimpledCoder.DLongJsonSimpledCoder.instance);
|
|
||||||
instance.register(BigInteger.class, BigIntegerSimpledCoder.BigIntegerJsonSimpledCoder.instance);
|
|
||||||
instance.register(Serializable.class, instance.loadEncoder(Object.class));
|
instance.register(Serializable.class, instance.loadEncoder(Object.class));
|
||||||
|
|
||||||
instance.register(AnyValue.class, instance.loadDecoder(AnyValue.DefaultAnyValue.class));
|
instance.register(AnyValue.class, instance.loadDecoder(AnyValue.DefaultAnyValue.class));
|
||||||
@@ -38,6 +35,12 @@ public final class JsonFactory extends ConvertFactory<JsonReader, JsonWriter> {
|
|||||||
|
|
||||||
private JsonFactory(JsonFactory parent, boolean tiny) {
|
private JsonFactory(JsonFactory parent, boolean tiny) {
|
||||||
super(parent, tiny);
|
super(parent, tiny);
|
||||||
|
if (parent == null) {
|
||||||
|
this.register(InetAddress.class, InetAddressSimpledCoder.InetAddressJsonSimpledCoder.instance);
|
||||||
|
this.register(InetSocketAddress.class, InetAddressSimpledCoder.InetSocketAddressJsonSimpledCoder.instance);
|
||||||
|
this.register(DLong.class, DLongSimpledCoder.DLongJsonSimpledCoder.instance);
|
||||||
|
this.register(BigInteger.class, BigIntegerSimpledCoder.BigIntegerJsonSimpledCoder.instance);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -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.*;
|
||||||
@@ -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(':');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -129,7 +129,7 @@ public abstract class Server<K extends Serializable, C extends Context, R extend
|
|||||||
this.maxbody = parseLenth(config.getValue("maxbody"), 64 * 1024);
|
this.maxbody = parseLenth(config.getValue("maxbody"), 64 * 1024);
|
||||||
int bufCapacity = parseLenth(config.getValue("bufferCapacity"), "UDP".equalsIgnoreCase(protocol) ? 1350 : 32 * 1024);
|
int bufCapacity = parseLenth(config.getValue("bufferCapacity"), "UDP".equalsIgnoreCase(protocol) ? 1350 : 32 * 1024);
|
||||||
this.bufferCapacity = "UDP".equalsIgnoreCase(protocol) ? bufCapacity : (bufCapacity < 8 * 1024 ? 8 * 1024 : bufCapacity);
|
this.bufferCapacity = "UDP".equalsIgnoreCase(protocol) ? bufCapacity : (bufCapacity < 8 * 1024 ? 8 * 1024 : bufCapacity);
|
||||||
this.threads = config.getIntValue("threads", Runtime.getRuntime().availableProcessors() * 32);
|
this.threads = config.getIntValue("threads", Math.max(8, Runtime.getRuntime().availableProcessors() * 2));
|
||||||
this.bufferPoolSize = config.getIntValue("bufferPoolSize", this.threads * 4);
|
this.bufferPoolSize = config.getIntValue("bufferPoolSize", this.threads * 4);
|
||||||
this.responsePoolSize = config.getIntValue("responsePoolSize", this.threads * 2);
|
this.responsePoolSize = config.getIntValue("responsePoolSize", this.threads * 2);
|
||||||
this.name = config.getValue("name", "Server-" + protocol + "-" + this.address.getPort());
|
this.name = config.getValue("name", "Server-" + protocol + "-" + this.address.getPort());
|
||||||
@@ -153,7 +153,7 @@ public abstract class Server<K extends Serializable, C extends Context, R extend
|
|||||||
final String n = name;
|
final String n = name;
|
||||||
this.executor = (ThreadPoolExecutor) Executors.newFixedThreadPool(threads, (Runnable r) -> {
|
this.executor = (ThreadPoolExecutor) Executors.newFixedThreadPool(threads, (Runnable r) -> {
|
||||||
Thread t = new WorkThread(executor, r);
|
Thread t = new WorkThread(executor, r);
|
||||||
t.setName(n + "-ServletThread-" + f.format(counter.incrementAndGet()));
|
t.setName("Redkale-" + n + "-ServletThread-" + f.format(counter.incrementAndGet()));
|
||||||
return t;
|
return t;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -119,7 +119,7 @@ public class TransportFactory {
|
|||||||
if (this.checkinterval < 2) this.checkinterval = 2;
|
if (this.checkinterval < 2) this.checkinterval = 2;
|
||||||
}
|
}
|
||||||
this.scheduler = new ScheduledThreadPoolExecutor(1, (Runnable r) -> {
|
this.scheduler = new ScheduledThreadPoolExecutor(1, (Runnable r) -> {
|
||||||
final Thread t = new Thread(r, this.getClass().getSimpleName() + "-TransportFactoryTask-Thread");
|
final Thread t = new Thread(r, "Redkale-" + this.getClass().getSimpleName() + "-Schedule-Thread");
|
||||||
t.setDaemon(true);
|
t.setDaemon(true);
|
||||||
return t;
|
return t;
|
||||||
});
|
});
|
||||||
@@ -162,7 +162,7 @@ public class TransportFactory {
|
|||||||
ExecutorService transportExec = Executors.newFixedThreadPool(threads, (Runnable r) -> {
|
ExecutorService transportExec = Executors.newFixedThreadPool(threads, (Runnable r) -> {
|
||||||
Thread t = new Thread(r);
|
Thread t = new Thread(r);
|
||||||
t.setDaemon(true);
|
t.setDaemon(true);
|
||||||
t.setName("Transport-Thread-" + counter.incrementAndGet());
|
t.setName("Redkale-Transport-Thread-" + counter.incrementAndGet());
|
||||||
return t;
|
return t;
|
||||||
});
|
});
|
||||||
AsynchronousChannelGroup transportGroup = null;
|
AsynchronousChannelGroup transportGroup = null;
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ public class HttpResourceServlet extends HttpServlet {
|
|||||||
|
|
||||||
public WatchThread(File root) throws IOException {
|
public WatchThread(File root) throws IOException {
|
||||||
this.root = root;
|
this.root = root;
|
||||||
this.setName("HttpResourceServlet-Watch-Thread");
|
this.setName("Redkale-HttpResourceServlet-Watch-Thread");
|
||||||
this.setDaemon(true);
|
this.setDaemon(true);
|
||||||
this.watcher = this.root.toPath().getFileSystem().newWatchService();
|
this.watcher = this.root.toPath().getFileSystem().newWatchService();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -855,7 +855,9 @@ public class HttpResponse extends Response<HttpContext, HttpRequest> {
|
|||||||
}
|
}
|
||||||
this.contentLength = length;
|
this.contentLength = length;
|
||||||
if (filename != null && !filename.isEmpty() && file != null) {
|
if (filename != null && !filename.isEmpty() && file != null) {
|
||||||
addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(filename, "UTF-8"));
|
if (this.header.getValue("Content-Disposition") == null) {
|
||||||
|
addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(filename, "UTF-8"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
this.contentType = MimeType.getByFilename(filename == null || filename.isEmpty() ? file.getName() : filename);
|
this.contentType = MimeType.getByFilename(filename == null || filename.isEmpty() ? file.getName() : filename);
|
||||||
if (this.contentType == null) this.contentType = "application/octet-stream";
|
if (this.contentType == null) this.contentType = "application/octet-stream";
|
||||||
|
|||||||
@@ -595,7 +595,7 @@ 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() : (message instanceof CharSequence ? message : 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)) {
|
||||||
@@ -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)) {
|
||||||
|
|||||||
@@ -70,18 +70,17 @@ public class DataJdbcSource extends DataSqlSource<Connection> {
|
|||||||
}
|
}
|
||||||
c = c1;
|
c = c1;
|
||||||
} catch (SQLException se) {
|
} catch (SQLException se) {
|
||||||
if (info.tableStrategy == null || !info.isTableNotExist(se)) throw se;
|
if (info.getTableStrategy() == null || !info.isTableNotExist(se)) throw se;
|
||||||
synchronized (info.tables) {
|
synchronized (info.disTableLock()) {
|
||||||
final String oldTable = info.table;
|
|
||||||
final String catalog = conn.getCatalog();
|
final String catalog = conn.getCatalog();
|
||||||
final String newTable = info.getTable(entitys[0]);
|
final String newTable = info.getTable(entitys[0]);
|
||||||
final String tablekey = newTable.indexOf('.') > 0 ? newTable : (catalog + '.' + newTable);
|
final String tablekey = newTable.indexOf('.') > 0 ? newTable : (catalog + '.' + newTable);
|
||||||
if (!info.tables.contains(tablekey)) {
|
if (!info.containsDisTable(tablekey)) {
|
||||||
try {
|
try {
|
||||||
Statement st = conn.createStatement();
|
Statement st = conn.createStatement();
|
||||||
st.execute(info.tablecopySQL.replace("${newtable}", newTable).replace("${oldtable}", oldTable));
|
st.execute(info.getTableCopySQL(newTable));
|
||||||
st.close();
|
st.close();
|
||||||
info.tables.add(tablekey);
|
info.addDisTable(tablekey);
|
||||||
} catch (SQLException sqle) { //多进程并发时可能会出现重复建表
|
} catch (SQLException sqle) { //多进程并发时可能会出现重复建表
|
||||||
if (newTable.indexOf('.') > 0 && info.isTableNotExist(se)) {
|
if (newTable.indexOf('.') > 0 && info.isTableNotExist(se)) {
|
||||||
Statement st;
|
Statement st;
|
||||||
@@ -94,14 +93,14 @@ public class DataJdbcSource extends DataSqlSource<Connection> {
|
|||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
st = conn.createStatement();
|
st = conn.createStatement();
|
||||||
st.execute(info.tablecopySQL.replace("${newtable}", newTable).replace("${oldtable}", oldTable));
|
st.execute(info.getTableCopySQL(newTable));
|
||||||
st.close();
|
st.close();
|
||||||
info.tables.add(tablekey);
|
info.addDisTable(tablekey);
|
||||||
} catch (SQLException sqle2) {
|
} catch (SQLException sqle2) {
|
||||||
logger.log(Level.SEVERE, "create table2(" + info.tablecopySQL.replace("${newtable}", newTable).replace("${oldtable}", oldTable) + ") error", sqle2);
|
logger.log(Level.SEVERE, "create table2(" + info.getTableCopySQL(newTable) + ") error", sqle2);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
logger.log(Level.SEVERE, "create table(" + info.tablecopySQL.replace("${newtable}", newTable).replace("${oldtable}", oldTable) + ") error", sqle);
|
logger.log(Level.SEVERE, "create table(" + info.getTableCopySQL(newTable) + ") error", sqle);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -114,7 +113,7 @@ public class DataJdbcSource extends DataSqlSource<Connection> {
|
|||||||
c1 += cc;
|
c1 += cc;
|
||||||
}
|
}
|
||||||
c = c1;
|
c = c1;
|
||||||
}
|
}
|
||||||
prestmt.close();
|
prestmt.close();
|
||||||
//------------------------------------------------------------
|
//------------------------------------------------------------
|
||||||
if (info.isLoggable(logger, Level.FINEST)) { //打印调试信息
|
if (info.isLoggable(logger, Level.FINEST)) { //打印调试信息
|
||||||
@@ -143,7 +142,7 @@ public class DataJdbcSource extends DataSqlSource<Connection> {
|
|||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
CompletableFuture future = new CompletableFuture();
|
CompletableFuture future = new CompletableFuture();
|
||||||
future.completeExceptionally(e);
|
future.completeExceptionally(e);
|
||||||
return future;
|
return future;//return CompletableFuture.failedFuture(e);
|
||||||
} finally {
|
} finally {
|
||||||
if (conn != null) writePool.offerConnection(conn);
|
if (conn != null) writePool.offerConnection(conn);
|
||||||
}
|
}
|
||||||
@@ -201,7 +200,7 @@ public class DataJdbcSource extends DataSqlSource<Connection> {
|
|||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
CompletableFuture future = new CompletableFuture();
|
CompletableFuture future = new CompletableFuture();
|
||||||
future.completeExceptionally(e);
|
future.completeExceptionally(e);
|
||||||
return future;
|
return future;//return CompletableFuture.failedFuture(e);
|
||||||
} finally {
|
} finally {
|
||||||
if (conn != null) writePool.offerConnection(conn);
|
if (conn != null) writePool.offerConnection(conn);
|
||||||
}
|
}
|
||||||
@@ -222,7 +221,7 @@ public class DataJdbcSource extends DataSqlSource<Connection> {
|
|||||||
if (info.isTableNotExist(e)) return CompletableFuture.completedFuture(-1);
|
if (info.isTableNotExist(e)) return CompletableFuture.completedFuture(-1);
|
||||||
CompletableFuture future = new CompletableFuture();
|
CompletableFuture future = new CompletableFuture();
|
||||||
future.completeExceptionally(e);
|
future.completeExceptionally(e);
|
||||||
return future;
|
return future;//return CompletableFuture.failedFuture(e);
|
||||||
} finally {
|
} finally {
|
||||||
if (conn != null) writePool.offerConnection(conn);
|
if (conn != null) writePool.offerConnection(conn);
|
||||||
}
|
}
|
||||||
@@ -243,7 +242,7 @@ public class DataJdbcSource extends DataSqlSource<Connection> {
|
|||||||
if (info.isTableNotExist(e)) return CompletableFuture.completedFuture(-1);
|
if (info.isTableNotExist(e)) return CompletableFuture.completedFuture(-1);
|
||||||
CompletableFuture future = new CompletableFuture();
|
CompletableFuture future = new CompletableFuture();
|
||||||
future.completeExceptionally(e);
|
future.completeExceptionally(e);
|
||||||
return future;
|
return future;//return CompletableFuture.failedFuture(e);
|
||||||
} finally {
|
} finally {
|
||||||
if (conn != null) writePool.offerConnection(conn);
|
if (conn != null) writePool.offerConnection(conn);
|
||||||
}
|
}
|
||||||
@@ -296,7 +295,7 @@ public class DataJdbcSource extends DataSqlSource<Connection> {
|
|||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
CompletableFuture future = new CompletableFuture();
|
CompletableFuture future = new CompletableFuture();
|
||||||
future.completeExceptionally(e);
|
future.completeExceptionally(e);
|
||||||
return future;
|
return future;//return CompletableFuture.failedFuture(e);
|
||||||
} finally {
|
} finally {
|
||||||
if (conn != null) writePool.offerConnection(conn);
|
if (conn != null) writePool.offerConnection(conn);
|
||||||
}
|
}
|
||||||
@@ -330,7 +329,7 @@ public class DataJdbcSource extends DataSqlSource<Connection> {
|
|||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
CompletableFuture future = new CompletableFuture();
|
CompletableFuture future = new CompletableFuture();
|
||||||
future.completeExceptionally(e);
|
future.completeExceptionally(e);
|
||||||
return future;
|
return future;//return CompletableFuture.failedFuture(e);
|
||||||
} finally {
|
} finally {
|
||||||
if (conn != null) writePool.offerConnection(conn);
|
if (conn != null) writePool.offerConnection(conn);
|
||||||
}
|
}
|
||||||
@@ -339,12 +338,12 @@ public class DataJdbcSource extends DataSqlSource<Connection> {
|
|||||||
@Override
|
@Override
|
||||||
protected <T, N extends Number> CompletableFuture<Map<String, N>> getNumberMapDB(EntityInfo<T> info, String sql, FilterFuncColumn... columns) {
|
protected <T, N extends Number> CompletableFuture<Map<String, N>> getNumberMapDB(EntityInfo<T> info, String sql, FilterFuncColumn... columns) {
|
||||||
Connection conn = null;
|
Connection conn = null;
|
||||||
|
final Map map = new HashMap<>();
|
||||||
try {
|
try {
|
||||||
conn = readPool.poll();
|
conn = readPool.poll();
|
||||||
//conn.setReadOnly(true);
|
//conn.setReadOnly(true);
|
||||||
final Statement stmt = conn.createStatement();
|
final Statement stmt = conn.createStatement();
|
||||||
ResultSet set = stmt.executeQuery(sql);
|
ResultSet set = stmt.executeQuery(sql);
|
||||||
final Map map = new HashMap<>();
|
|
||||||
if (set.next()) {
|
if (set.next()) {
|
||||||
int index = 0;
|
int index = 0;
|
||||||
for (FilterFuncColumn ffc : columns) {
|
for (FilterFuncColumn ffc : columns) {
|
||||||
@@ -360,9 +359,10 @@ public class DataJdbcSource extends DataSqlSource<Connection> {
|
|||||||
stmt.close();
|
stmt.close();
|
||||||
return CompletableFuture.completedFuture(map);
|
return CompletableFuture.completedFuture(map);
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
|
if (info.getTableStrategy() != null && info.isTableNotExist(e)) return CompletableFuture.completedFuture(map);
|
||||||
CompletableFuture future = new CompletableFuture();
|
CompletableFuture future = new CompletableFuture();
|
||||||
future.completeExceptionally(e);
|
future.completeExceptionally(e);
|
||||||
return future;
|
return future;//return CompletableFuture.failedFuture(e);
|
||||||
} finally {
|
} finally {
|
||||||
if (conn != null) readPool.offerConnection(conn);
|
if (conn != null) readPool.offerConnection(conn);
|
||||||
}
|
}
|
||||||
@@ -385,9 +385,10 @@ public class DataJdbcSource extends DataSqlSource<Connection> {
|
|||||||
stmt.close();
|
stmt.close();
|
||||||
return CompletableFuture.completedFuture(rs);
|
return CompletableFuture.completedFuture(rs);
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
|
if (info.getTableStrategy() != null && info.isTableNotExist(e)) return CompletableFuture.completedFuture(defVal);
|
||||||
CompletableFuture future = new CompletableFuture();
|
CompletableFuture future = new CompletableFuture();
|
||||||
future.completeExceptionally(e);
|
future.completeExceptionally(e);
|
||||||
return future;
|
return future;//return CompletableFuture.failedFuture(e);
|
||||||
} finally {
|
} finally {
|
||||||
if (conn != null) readPool.offerConnection(conn);
|
if (conn != null) readPool.offerConnection(conn);
|
||||||
}
|
}
|
||||||
@@ -396,11 +397,11 @@ public class DataJdbcSource extends DataSqlSource<Connection> {
|
|||||||
@Override
|
@Override
|
||||||
protected <T, K extends Serializable, N extends Number> CompletableFuture<Map<K, N>> queryColumnMapDB(EntityInfo<T> info, String sql, String keyColumn) {
|
protected <T, K extends Serializable, N extends Number> CompletableFuture<Map<K, N>> queryColumnMapDB(EntityInfo<T> info, String sql, String keyColumn) {
|
||||||
Connection conn = null;
|
Connection conn = null;
|
||||||
|
Map<K, N> rs = new LinkedHashMap<>();
|
||||||
try {
|
try {
|
||||||
conn = readPool.poll();
|
conn = readPool.poll();
|
||||||
//conn.setReadOnly(true);
|
//conn.setReadOnly(true);
|
||||||
final Statement stmt = conn.createStatement();
|
final Statement stmt = conn.createStatement();
|
||||||
Map<K, N> rs = new LinkedHashMap<>();
|
|
||||||
ResultSet set = stmt.executeQuery(sql);
|
ResultSet set = stmt.executeQuery(sql);
|
||||||
ResultSetMetaData rsd = set.getMetaData();
|
ResultSetMetaData rsd = set.getMetaData();
|
||||||
boolean smallint = rsd == null ? false : rsd.getColumnType(1) == Types.SMALLINT;
|
boolean smallint = rsd == null ? false : rsd.getColumnType(1) == Types.SMALLINT;
|
||||||
@@ -411,9 +412,10 @@ public class DataJdbcSource extends DataSqlSource<Connection> {
|
|||||||
stmt.close();
|
stmt.close();
|
||||||
return CompletableFuture.completedFuture(rs);
|
return CompletableFuture.completedFuture(rs);
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
|
if (info.getTableStrategy() != null && info.isTableNotExist(e)) return CompletableFuture.completedFuture(rs);
|
||||||
CompletableFuture future = new CompletableFuture();
|
CompletableFuture future = new CompletableFuture();
|
||||||
future.completeExceptionally(e);
|
future.completeExceptionally(e);
|
||||||
return future;
|
return future;//return CompletableFuture.failedFuture(e);
|
||||||
} finally {
|
} finally {
|
||||||
if (conn != null) readPool.offerConnection(conn);
|
if (conn != null) readPool.offerConnection(conn);
|
||||||
}
|
}
|
||||||
@@ -433,10 +435,10 @@ public class DataJdbcSource extends DataSqlSource<Connection> {
|
|||||||
ps.close();
|
ps.close();
|
||||||
return CompletableFuture.completedFuture(rs);
|
return CompletableFuture.completedFuture(rs);
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
if (info.tableStrategy != null && info.isTableNotExist(e)) return CompletableFuture.completedFuture(null);
|
if (info.getTableStrategy() != null && info.isTableNotExist(e)) return CompletableFuture.completedFuture(null);
|
||||||
CompletableFuture future = new CompletableFuture();
|
CompletableFuture future = new CompletableFuture();
|
||||||
future.completeExceptionally(e);
|
future.completeExceptionally(e);
|
||||||
return future;
|
return future;//return CompletableFuture.failedFuture(e);
|
||||||
} finally {
|
} finally {
|
||||||
if (conn != null) readPool.offerConnection(conn);
|
if (conn != null) readPool.offerConnection(conn);
|
||||||
}
|
}
|
||||||
@@ -460,10 +462,10 @@ public class DataJdbcSource extends DataSqlSource<Connection> {
|
|||||||
ps.close();
|
ps.close();
|
||||||
return CompletableFuture.completedFuture(val == null ? defValue : val);
|
return CompletableFuture.completedFuture(val == null ? defValue : val);
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
if (info.tableStrategy != null && info.isTableNotExist(e)) return CompletableFuture.completedFuture(defValue);
|
if (info.getTableStrategy() != null && info.isTableNotExist(e)) return CompletableFuture.completedFuture(defValue);
|
||||||
CompletableFuture future = new CompletableFuture();
|
CompletableFuture future = new CompletableFuture();
|
||||||
future.completeExceptionally(e);
|
future.completeExceptionally(e);
|
||||||
return future;
|
return future;//return CompletableFuture.failedFuture(e);
|
||||||
} finally {
|
} finally {
|
||||||
if (conn != null) readPool.offerConnection(conn);
|
if (conn != null) readPool.offerConnection(conn);
|
||||||
}
|
}
|
||||||
@@ -483,10 +485,10 @@ public class DataJdbcSource extends DataSqlSource<Connection> {
|
|||||||
if (info.isLoggable(logger, Level.FINEST, sql)) logger.finest(info.getType().getSimpleName() + " exists (" + rs + ") sql=" + sql);
|
if (info.isLoggable(logger, Level.FINEST, sql)) logger.finest(info.getType().getSimpleName() + " exists (" + rs + ") sql=" + sql);
|
||||||
return CompletableFuture.completedFuture(rs);
|
return CompletableFuture.completedFuture(rs);
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
if (info.tableStrategy != null && info.isTableNotExist(e)) return CompletableFuture.completedFuture(false);
|
if (info.getTableStrategy() != null && info.isTableNotExist(e)) return CompletableFuture.completedFuture(false);
|
||||||
CompletableFuture future = new CompletableFuture();
|
CompletableFuture future = new CompletableFuture();
|
||||||
future.completeExceptionally(e);
|
future.completeExceptionally(e);
|
||||||
return future;
|
return future;//return CompletableFuture.failedFuture(e);
|
||||||
} finally {
|
} finally {
|
||||||
if (conn != null) readPool.offerConnection(conn);
|
if (conn != null) readPool.offerConnection(conn);
|
||||||
}
|
}
|
||||||
@@ -557,10 +559,10 @@ public class DataJdbcSource extends DataSqlSource<Connection> {
|
|||||||
ps.close();
|
ps.close();
|
||||||
return CompletableFuture.completedFuture(new Sheet<>(total, list));
|
return CompletableFuture.completedFuture(new Sheet<>(total, list));
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
if (info.tableStrategy != null && info.isTableNotExist(e)) return CompletableFuture.completedFuture(new Sheet<>());
|
if (info.getTableStrategy() != null && info.isTableNotExist(e)) return CompletableFuture.completedFuture(new Sheet<>());
|
||||||
CompletableFuture future = new CompletableFuture();
|
CompletableFuture future = new CompletableFuture();
|
||||||
future.completeExceptionally(e);
|
future.completeExceptionally(e);
|
||||||
return future;
|
return future;//return CompletableFuture.failedFuture(e);
|
||||||
} finally {
|
} finally {
|
||||||
if (conn != null) readPool.offerConnection(conn);
|
if (conn != null) readPool.offerConnection(conn);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ package org.redkale.source;
|
|||||||
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.lang.reflect.Constructor;
|
import java.lang.reflect.Constructor;
|
||||||
import java.net.URL;
|
import java.net.*;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import javax.xml.stream.*;
|
import javax.xml.stream.*;
|
||||||
import org.redkale.util.AnyValue;
|
import org.redkale.util.AnyValue;
|
||||||
@@ -139,7 +139,7 @@ public final class DataSources {
|
|||||||
public static DataSource createDataSource(final String unitName) throws IOException {
|
public static DataSource createDataSource(final String unitName) throws IOException {
|
||||||
return createDataSource(unitName, System.getProperty(DATASOURCE_CONFPATH) == null
|
return createDataSource(unitName, System.getProperty(DATASOURCE_CONFPATH) == null
|
||||||
? DataJdbcSource.class.getResource("/META-INF/persistence.xml")
|
? DataJdbcSource.class.getResource("/META-INF/persistence.xml")
|
||||||
: new File(System.getProperty(DATASOURCE_CONFPATH)).toURI().toURL());
|
: (System.getProperty(DATASOURCE_CONFPATH, "").contains("://") ? URI.create(System.getProperty(DATASOURCE_CONFPATH)).toURL() : new File(System.getProperty(DATASOURCE_CONFPATH)).toURI().toURL()));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static DataSource createDataSource(final String unitName, URL persistxml) throws IOException {
|
public static DataSource createDataSource(final String unitName, URL persistxml) throws IOException {
|
||||||
|
|||||||
@@ -91,7 +91,7 @@ public abstract class DataSqlSource<DBChannel> extends AbstractService implement
|
|||||||
} else if (s.length() == 2) {
|
} else if (s.length() == 2) {
|
||||||
s = "0" + s;
|
s = "0" + s;
|
||||||
}
|
}
|
||||||
t.setName(cname + "-Thread-" + s);
|
t.setName("Redkale-"+cname + "-Thread-" + s);
|
||||||
t.setUncaughtExceptionHandler(ueh);
|
t.setUncaughtExceptionHandler(ueh);
|
||||||
return t;
|
return t;
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -89,16 +89,16 @@ public final class EntityInfo<T> {
|
|||||||
final String notcontainSQL;
|
final String notcontainSQL;
|
||||||
|
|
||||||
//用于判断表不存在的使用, 多个SQLState用;隔开
|
//用于判断表不存在的使用, 多个SQLState用;隔开
|
||||||
final String tablenotexistSqlstates;
|
private final String tablenotexistSqlstates;
|
||||||
|
|
||||||
//用于复制表结构使用
|
//用于复制表结构使用
|
||||||
final String tablecopySQL;
|
private final String tablecopySQL;
|
||||||
|
|
||||||
//用于存在database.table_20160202类似这种分布式表
|
//用于存在database.table_20160202类似这种分布式表
|
||||||
final Set<String> tables = new HashSet<>();
|
private final Set<String> tables = new HashSet<>();
|
||||||
|
|
||||||
//分表 策略
|
//分表 策略
|
||||||
final DistributeTableStrategy<T> tableStrategy;
|
private final DistributeTableStrategy<T> tableStrategy;
|
||||||
|
|
||||||
//根据主键查找单个对象的SQL, 含 ?
|
//根据主键查找单个对象的SQL, 含 ?
|
||||||
private final String queryPrepareSQL;
|
private final String queryPrepareSQL;
|
||||||
@@ -239,7 +239,7 @@ public final class EntityInfo<T> {
|
|||||||
}
|
}
|
||||||
//---------------------------------------------
|
//---------------------------------------------
|
||||||
Table t = type.getAnnotation(Table.class);
|
Table t = type.getAnnotation(Table.class);
|
||||||
if (type.getAnnotation(VirtualEntity.class) != null || "memory".equalsIgnoreCase(source.getType())) {
|
if (type.getAnnotation(VirtualEntity.class) != null || (source == null || "memory".equalsIgnoreCase(source.getType()))) {
|
||||||
this.table = null;
|
this.table = null;
|
||||||
BiFunction<DataSource, Class, List> loader = null;
|
BiFunction<DataSource, Class, List> loader = null;
|
||||||
try {
|
try {
|
||||||
@@ -510,6 +510,18 @@ public final class EntityInfo<T> {
|
|||||||
return tableStrategy;
|
return tableStrategy;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Object disTableLock() {
|
||||||
|
return tables;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean containsDisTable(String tablekey) {
|
||||||
|
return tables.contains(tablekey);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addDisTable(String tablekey) {
|
||||||
|
tables.add(tablekey);
|
||||||
|
}
|
||||||
|
|
||||||
public String getTableNotExistSqlStates2() {
|
public String getTableNotExistSqlStates2() {
|
||||||
return tablenotexistSqlstates;
|
return tablenotexistSqlstates;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -85,6 +85,13 @@ public interface Creator<T> {
|
|||||||
creatorCacheMap.put(Stream.class, (params) -> new ArrayList<>().stream());
|
creatorCacheMap.put(Stream.class, (params) -> new ArrayList<>().stream());
|
||||||
creatorCacheMap.put(ConcurrentHashMap.class, (params) -> new ConcurrentHashMap<>());
|
creatorCacheMap.put(ConcurrentHashMap.class, (params) -> new ConcurrentHashMap<>());
|
||||||
creatorCacheMap.put(CompletableFuture.class, (params) -> new CompletableFuture<>());
|
creatorCacheMap.put(CompletableFuture.class, (params) -> new CompletableFuture<>());
|
||||||
|
creatorCacheMap.put(Map.Entry.class, new Creator<Map.Entry>() {
|
||||||
|
@Override
|
||||||
|
@ConstructorParameters({"key", "value"})
|
||||||
|
public Map.Entry create(Object... params) {
|
||||||
|
return new AbstractMap.SimpleEntry(params[0], params[1]);
|
||||||
|
}
|
||||||
|
});
|
||||||
creatorCacheMap.put(AbstractMap.SimpleEntry.class, new Creator<AbstractMap.SimpleEntry>() {
|
creatorCacheMap.put(AbstractMap.SimpleEntry.class, new Creator<AbstractMap.SimpleEntry>() {
|
||||||
@Override
|
@Override
|
||||||
@ConstructorParameters({"key", "value"})
|
@ConstructorParameters({"key", "value"})
|
||||||
@@ -232,6 +239,8 @@ public interface Creator<T> {
|
|||||||
clazz = (Class<T>) ConcurrentHashMap.class;
|
clazz = (Class<T>) ConcurrentHashMap.class;
|
||||||
} else if (Collection.class.isAssignableFrom(clazz) && clazz.isAssignableFrom(ArrayList.class)) {
|
} else if (Collection.class.isAssignableFrom(clazz) && clazz.isAssignableFrom(ArrayList.class)) {
|
||||||
clazz = (Class<T>) ArrayList.class;
|
clazz = (Class<T>) ArrayList.class;
|
||||||
|
} else if (Map.Entry.class.isAssignableFrom(clazz) && (Modifier.isInterface(clazz.getModifiers()) || Modifier.isAbstract(clazz.getModifiers()) || !Modifier.isPublic(clazz.getModifiers()))) {
|
||||||
|
clazz = (Class<T>) AbstractMap.SimpleEntry.class;
|
||||||
}
|
}
|
||||||
Creator creator = CreatorInner.creatorCacheMap.get(clazz);
|
Creator creator = CreatorInner.creatorCacheMap.get(clazz);
|
||||||
if (creator != null) return creator;
|
if (creator != null) return creator;
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ public final class Redkale {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static String getDotedVersion() {
|
public static String getDotedVersion() {
|
||||||
return "2.0.0-beta5";
|
return "2.0.0-rc2";
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int getMajorVersion() {
|
public static int getMajorVersion() {
|
||||||
|
|||||||
@@ -83,7 +83,8 @@ public abstract class TypeToken<T> {
|
|||||||
if (type instanceof TypeVariable) return null;
|
if (type instanceof TypeVariable) return null;
|
||||||
if (type instanceof GenericArrayType) return Array.newInstance(typeToClass(((GenericArrayType) type).getGenericComponentType()), 0).getClass();
|
if (type instanceof GenericArrayType) return Array.newInstance(typeToClass(((GenericArrayType) type).getGenericComponentType()), 0).getClass();
|
||||||
if (!(type instanceof ParameterizedType)) return null; //只能是null了
|
if (!(type instanceof ParameterizedType)) return null; //只能是null了
|
||||||
return typeToClass(((ParameterizedType) type).getOwnerType());
|
Type owner = ((ParameterizedType) type).getOwnerType();
|
||||||
|
return typeToClass(owner == null ? ((ParameterizedType) type).getRawType() : owner);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Type[] getGenericType(final Type[] types, final Type declaringClass) {
|
public static Type[] getGenericType(final Type[] types, final Type declaringClass) {
|
||||||
|
|||||||
@@ -610,6 +610,30 @@ public final class Utility {
|
|||||||
return news;
|
return news;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将int数组倒序
|
||||||
|
*
|
||||||
|
* @param array 原数组
|
||||||
|
*
|
||||||
|
* @return 新数组
|
||||||
|
*/
|
||||||
|
public static int[] reverseSort(final int[] array) {
|
||||||
|
if (array == null || array.length == 0) return array;
|
||||||
|
return Arrays.stream(array).boxed().sorted(Collections.reverseOrder()).mapToInt(x -> x).toArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将long数组倒序
|
||||||
|
*
|
||||||
|
* @param array 原数组
|
||||||
|
*
|
||||||
|
* @return 新数组
|
||||||
|
*/
|
||||||
|
public static long[] reverseSort(final long[] array) {
|
||||||
|
if (array == null || array.length == 0) return array;
|
||||||
|
return Arrays.stream(array).boxed().sorted(Collections.reverseOrder()).mapToLong(x -> x).toArray();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 将元素从数组中删除
|
* 将元素从数组中删除
|
||||||
*
|
*
|
||||||
@@ -1848,10 +1872,10 @@ public final class Utility {
|
|||||||
public static byte[] encodeUTF8(final char[] text, final int start, final int len) {
|
public static byte[] encodeUTF8(final char[] text, final int start, final int len) {
|
||||||
char c;
|
char c;
|
||||||
int size = 0;
|
int size = 0;
|
||||||
final char[] chars = text;
|
final char[] chs = text;
|
||||||
final int limit = start + len;
|
final int limit = start + len;
|
||||||
for (int i = start; i < limit; i++) {
|
for (int i = start; i < limit; i++) {
|
||||||
c = chars[i];
|
c = chs[i];
|
||||||
if (c < 0x80) {
|
if (c < 0x80) {
|
||||||
size++;
|
size++;
|
||||||
} else if (c < 0x800) {
|
} else if (c < 0x800) {
|
||||||
@@ -1865,14 +1889,14 @@ public final class Utility {
|
|||||||
final byte[] bytes = new byte[size];
|
final byte[] bytes = new byte[size];
|
||||||
size = 0;
|
size = 0;
|
||||||
for (int i = start; i < limit; i++) {
|
for (int i = start; i < limit; i++) {
|
||||||
c = chars[i];
|
c = chs[i];
|
||||||
if (c < 0x80) {
|
if (c < 0x80) {
|
||||||
bytes[size++] = (byte) c;
|
bytes[size++] = (byte) c;
|
||||||
} else if (c < 0x800) {
|
} else if (c < 0x800) {
|
||||||
bytes[size++] = (byte) (0xc0 | (c >> 6));
|
bytes[size++] = (byte) (0xc0 | (c >> 6));
|
||||||
bytes[size++] = (byte) (0x80 | (c & 0x3f));
|
bytes[size++] = (byte) (0x80 | (c & 0x3f));
|
||||||
} else if (Character.isSurrogate(c)) { //连取两个
|
} else if (Character.isSurrogate(c)) { //连取两个
|
||||||
int uc = Character.toCodePoint(c, chars[i + 1]);
|
int uc = Character.toCodePoint(c, chs[i + 1]);
|
||||||
bytes[size++] = (byte) (0xf0 | ((uc >> 18)));
|
bytes[size++] = (byte) (0xf0 | ((uc >> 18)));
|
||||||
bytes[size++] = (byte) (0x80 | ((uc >> 12) & 0x3f));
|
bytes[size++] = (byte) (0x80 | ((uc >> 12) & 0x3f));
|
||||||
bytes[size++] = (byte) (0x80 | ((uc >> 6) & 0x3f));
|
bytes[size++] = (byte) (0x80 | ((uc >> 6) & 0x3f));
|
||||||
@@ -1920,10 +1944,10 @@ public final class Utility {
|
|||||||
public static int encodeUTF8Length(final char[] text, final int start, final int len) {
|
public static int encodeUTF8Length(final char[] text, final int start, final int len) {
|
||||||
char c;
|
char c;
|
||||||
int size = 0;
|
int size = 0;
|
||||||
final char[] chars = text;
|
final char[] chs = text;
|
||||||
final int limit = start + len;
|
final int limit = start + len;
|
||||||
for (int i = start; i < limit; i++) {
|
for (int i = start; i < limit; i++) {
|
||||||
c = chars[i];
|
c = chs[i];
|
||||||
if (c < 0x80) {
|
if (c < 0x80) {
|
||||||
size++;
|
size++;
|
||||||
} else if (c < 0x800) {
|
} else if (c < 0x800) {
|
||||||
@@ -1956,13 +1980,13 @@ public final class Utility {
|
|||||||
//返回的ByteBuffer为扩展buffer,为null表示参数中的buffer足够存储数据
|
//返回的ByteBuffer为扩展buffer,为null表示参数中的buffer足够存储数据
|
||||||
public static ByteBuffer encodeUTF8(final ByteBuffer buffer, int bytesLength, final char[] text, final int start, final int len) {
|
public static ByteBuffer encodeUTF8(final ByteBuffer buffer, int bytesLength, final char[] text, final int start, final int len) {
|
||||||
char c;
|
char c;
|
||||||
char[] chars = text;
|
char[] chs = text;
|
||||||
final int limit = start + len;
|
final int limit = start + len;
|
||||||
int remain = buffer.remaining();
|
int remain = buffer.remaining();
|
||||||
final ByteBuffer buffer2 = remain >= bytesLength ? null : ByteBuffer.allocate(bytesLength - remain + 4); //最差情况buffer最后两byte没有填充
|
final ByteBuffer buffer2 = remain >= bytesLength ? null : ByteBuffer.allocate(bytesLength - remain + 4); //最差情况buffer最后两byte没有填充
|
||||||
ByteBuffer buf = buffer;
|
ByteBuffer buf = buffer;
|
||||||
for (int i = start; i < limit; i++) {
|
for (int i = start; i < limit; i++) {
|
||||||
c = chars[i];
|
c = chs[i];
|
||||||
if (c < 0x80) {
|
if (c < 0x80) {
|
||||||
if (buf.remaining() < 1) buf = buffer2;
|
if (buf.remaining() < 1) buf = buffer2;
|
||||||
buf.put((byte) c);
|
buf.put((byte) c);
|
||||||
@@ -1972,7 +1996,7 @@ public final class Utility {
|
|||||||
buf.put((byte) (0x80 | (c & 0x3f)));
|
buf.put((byte) (0x80 | (c & 0x3f)));
|
||||||
} else if (Character.isSurrogate(c)) { //连取两个
|
} else if (Character.isSurrogate(c)) { //连取两个
|
||||||
if (buf.remaining() < 4) buf = buffer2;
|
if (buf.remaining() < 4) buf = buffer2;
|
||||||
int uc = Character.toCodePoint(c, chars[i + 1]);
|
int uc = Character.toCodePoint(c, chs[i + 1]);
|
||||||
buf.put((byte) (0xf0 | ((uc >> 18))));
|
buf.put((byte) (0xf0 | ((uc >> 18))));
|
||||||
buf.put((byte) (0x80 | ((uc >> 12) & 0x3f)));
|
buf.put((byte) (0x80 | ((uc >> 12) & 0x3f)));
|
||||||
buf.put((byte) (0x80 | ((uc >> 6) & 0x3f)));
|
buf.put((byte) (0x80 | ((uc >> 6) & 0x3f)));
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
*/
|
*/
|
||||||
package org.redkale.test.convert;
|
package org.redkale.test.convert;
|
||||||
|
|
||||||
|
import org.redkale.convert.ConvertField;
|
||||||
import org.redkale.convert.json.JsonConvert;
|
import org.redkale.convert.json.JsonConvert;
|
||||||
import org.redkale.util.Attribute;
|
import org.redkale.util.Attribute;
|
||||||
|
|
||||||
@@ -15,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":"扩展字段值"}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user