diff --git a/src/main/java/META-INF/application-template.xml b/src/main/java/META-INF/application-template.xml deleted file mode 100644 index 8ccaeae47..000000000 --- a/src/main/java/META-INF/application-template.xml +++ /dev/null @@ -1,188 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/main/java/META-INF/logging-template.properties b/src/main/java/META-INF/logging-template.properties deleted file mode 100644 index a66b1e6da..000000000 --- a/src/main/java/META-INF/logging-template.properties +++ /dev/null @@ -1,21 +0,0 @@ - -handlers = java.util.logging.ConsoleHandler,java.util.logging.FileHandler -.handlers = java.util.logging.ConsoleHandler,java.util.logging.FileHandler - -############################################################ -.level = FINE - -org.level = INFO -javax.level = INFO -com.sun.level = INFO -sun.level = INFO - -#java.util.logging.FileHandler.level = FINE -#10M -java.util.logging.FileHandler.limit = 10485760 -java.util.logging.FileHandler.count = 100 -java.util.logging.FileHandler.encoding = UTF-8 -java.util.logging.FileHandler.pattern = ${APP_HOME}/logs-%m/log-%u.log -java.util.logging.FileHandler.append = true - -#java.util.logging.ConsoleHandler.level = FINE diff --git a/src/main/java/javax/persistence/Cacheable.java b/src/main/java/javax/persistence/Cacheable.java deleted file mode 100644 index 9cbd2a749..000000000 --- a/src/main/java/javax/persistence/Cacheable.java +++ /dev/null @@ -1,45 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2008 - 2013 Oracle Corporation. All rights reserved. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0 - * which accompanies this distribution. - * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html - * and the Eclipse Distribution License is available at - * http://www.eclipse.org/org/documents/edl-v10.php. - * - * Contributors: - * Linda DeMichiel - Java Persistence 2.1 - * Linda DeMichiel - Java Persistence 2.0 - * - ******************************************************************************/ -package javax.persistence; - -import static java.lang.annotation.ElementType.TYPE; -import static java.lang.annotation.RetentionPolicy.RUNTIME; -import java.lang.annotation.Retention; -import java.lang.annotation.Target; - -/** - * Specifies whether an entity should be cached if caching is enabled - * when the value of the persistence.xml caching element - * is ENABLE_SELECTIVE or DISABLE_SELECTIVE. - * The value of the Cacheable annotation is inherited by - * subclasses; it can be overridden by specifying - * Cacheable on a subclass. - * - *

Cacheable(false) means that the entity and its state must - * not be cached by the provider. - * - * @since Java Persistence 2.0 - */ -@Target( { TYPE }) -@Retention(RUNTIME) -public @interface Cacheable { - - /** - * (Optional) Whether or not the entity should be cached. - * @return boolean - */ - boolean value() default true; -} diff --git a/src/main/java/javax/persistence/Column.java b/src/main/java/javax/persistence/Column.java deleted file mode 100644 index a4f6e1dc3..000000000 --- a/src/main/java/javax/persistence/Column.java +++ /dev/null @@ -1,143 +0,0 @@ -/** ***************************************************************************** - * Copyright (c) 2008 - 2013 Oracle Corporation. All rights reserved. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0 - * which accompanies this distribution. - * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html - * and the Eclipse Distribution License is available at - * http://www.eclipse.org/org/documents/edl-v10.php. - * - * Contributors: - * Linda DeMichiel - Java Persistence 2.1 - * Linda DeMichiel - Java Persistence 2.0 - * - ***************************************************************************** */ -package javax.persistence; - -import java.lang.annotation.Target; -import java.lang.annotation.Retention; -import static java.lang.annotation.ElementType.METHOD; -import static java.lang.annotation.ElementType.FIELD; -import static java.lang.annotation.RetentionPolicy.RUNTIME; - -/** - * Specifies the mapped column for a persistent property or field. - * If no Column annotation is specified, the default values apply. - * - *

- *    Example 1:
- *
- *    @Column(name="DESC", nullable=false, length=512)
- *    public String getDescription() { return description; }
- *
- *    Example 2:
- *
- *    @Column(name="DESC",
- *            columnDefinition="CLOB NOT NULL",
- *            table="EMP_DETAIL")
- *    @Lob
- *    public String getDescription() { return description; }
- *
- *    Example 3:
- *
- *    @Column(name="ORDER_COST", updatable=false, precision=12, scale=2)
- *    public BigDecimal getCost() { return cost; }
- *
- * 
- * - * - * @since Java Persistence 1.0 - */ -@Target({METHOD, FIELD}) -@Retention(RUNTIME) -public @interface Column { - - /** - * (Optional) The name of the column. Defaults to - * the property or field name. - * - * @return String - */ - String name() default ""; - - /** - * (Optional) Whether the column is a unique key. This is a - * shortcut for the UniqueConstraint annotation at the table - * level and is useful for when the unique key constraint - * corresponds to only a single column. This constraint applies - * in addition to any constraint entailed by primary key mapping and - * to constraints specified at the table level. - * - * @return boolean - */ - boolean unique() default false; - - /** - * (Optional) Whether the database column is nullable. - * - * @return boolean - */ - boolean nullable() default true; - - /** - * (Optional) Whether the column is included in SQL INSERT - * statements generated by the persistence provider. - * - * @return boolean - */ - boolean insertable() default true; - - /** - * (Optional) Whether the column is included in SQL UPDATE - * statements generated by the persistence provider. - * - * @return boolean - */ - boolean updatable() default true; - - /** - * (Optional) The SQL fragment that is used when - * generating the DDL for the column. - *

- * Defaults to the generated SQL to create a - * column of the inferred type. - * - * @return String - */ - String columnDefinition() default ""; - - /** - * (Optional) The name of the table that contains the column. - * If absent the column is assumed to be in the primary table. - * - * @return String - */ - String table() default ""; - - /** - * (Optional) The column length. (Applies only if a - * string-valued column is used.) - * - * @return int - */ - int length() default 255; - - /** - * (Optional) The precision for a decimal (exact numeric) - * column. (Applies only if a decimal column is used.) - * Value must be set by developer if used when generating - * the DDL for the column. - * - * @return int - */ - int precision() default 0; - - /** - * (Optional) The scale for a decimal (exact numeric) column. - * (Applies only if a decimal column is used.) - * - * @return int - */ - int scale() default 0; -} diff --git a/src/main/java/javax/persistence/Entity.java b/src/main/java/javax/persistence/Entity.java deleted file mode 100644 index 024df1bb5..000000000 --- a/src/main/java/javax/persistence/Entity.java +++ /dev/null @@ -1,43 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2008 - 2013 Oracle Corporation. All rights reserved. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0 - * which accompanies this distribution. - * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html - * and the Eclipse Distribution License is available at - * http://www.eclipse.org/org/documents/edl-v10.php. - * - * Contributors: - * Linda DeMichiel - Java Persistence 2.1 - * Linda DeMichiel - Java Persistence 2.0 - * - ******************************************************************************/ -package javax.persistence; - -import java.lang.annotation.Target; -import java.lang.annotation.Retention; -import java.lang.annotation.Documented; -import static java.lang.annotation.ElementType.TYPE; -import static java.lang.annotation.RetentionPolicy.RUNTIME; - -/** - * Specifies that the class is an entity. This annotation is applied to the - * entity class. - * - * @since Java Persistence 1.0 - */ -@Documented -@Target(TYPE) -@Retention(RUNTIME) -public @interface Entity { - - /** - * (Optional) The entity name. Defaults to the unqualified - * name of the entity class. This name is used to refer to the - * entity in queries. The name must not be a reserved literal - * in the Java Persistence query language. - * @return String - */ - String name() default ""; -} diff --git a/src/main/java/javax/persistence/GeneratedValue.java b/src/main/java/javax/persistence/GeneratedValue.java deleted file mode 100644 index 0d66f074a..000000000 --- a/src/main/java/javax/persistence/GeneratedValue.java +++ /dev/null @@ -1,79 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2008 - 2013 Oracle Corporation. All rights reserved. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0 - * which accompanies this distribution. - * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html - * and the Eclipse Distribution License is available at - * http://www.eclipse.org/org/documents/edl-v10.php. - * - * Contributors: - * Linda DeMichiel - Java Persistence 2.1 - * Linda DeMichiel - Java Persistence 2.0 - * - ******************************************************************************/ -package javax.persistence; - -import java.lang.annotation.Target; -import java.lang.annotation.Retention; -import static java.lang.annotation.ElementType.FIELD; -import static java.lang.annotation.ElementType.METHOD; -import static java.lang.annotation.RetentionPolicy.RUNTIME; - -/** - * Provides for the specification of generation strategies for the - * values of primary keys. - * - *

The GeneratedValue annotation - * may be applied to a primary key property or field of an entity or - * mapped superclass in conjunction with the {@link Id} annotation. - * The use of the GeneratedValue annotation is only - * required to be supported for simple primary keys. Use of the - * GeneratedValue annotation is not supported for derived - * primary keys. - * - *

- *
- *     Example 1:
- *
- *     @Id
- *     @GeneratedValue(strategy=SEQUENCE, generator="CUST_SEQ")
- *     @Column(name="CUST_ID")
- *     public Long getId() { return id; }
- *
- *     Example 2:
- *
- *     @Id
- *     @GeneratedValue(strategy=TABLE, generator="CUST_GEN")
- *     @Column(name="CUST_ID")
- *     Long id;
- * 
- * - * @see Id - * - * @since Java Persistence 1.0 - */ -@Target({METHOD, FIELD}) -@Retention(RUNTIME) - -public @interface GeneratedValue { - /** - * (Optional) The primary key generation strategy - * that the persistence provider must use to - * generate the annotated entity primary key. - * @return GenerationType - */ - @Deprecated - GenerationType strategy() default GenerationType.AUTO; - - /** - * (Optional) The name of the primary key generator - * to use as specified in the SequenceGenerator - * or TableGenerator annotation. - *

Defaults to the id generator supplied by persistence provider. - * @return String - */ - @Deprecated - String generator() default ""; -} diff --git a/src/main/java/javax/persistence/GenerationType.java b/src/main/java/javax/persistence/GenerationType.java deleted file mode 100644 index 9d1980e83..000000000 --- a/src/main/java/javax/persistence/GenerationType.java +++ /dev/null @@ -1,56 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2008 - 2013 Oracle Corporation. All rights reserved. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0 - * which accompanies this distribution. - * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html - * and the Eclipse Distribution License is available at - * http://www.eclipse.org/org/documents/edl-v10.php. - * - * Contributors: - * Linda DeMichiel - Java Persistence 2.1 - * Linda DeMichiel - Java Persistence 2.0 - * - ******************************************************************************/ -package javax.persistence; - -/** - * Defines the types of primary key generation strategies. - * - * @see GeneratedValue - * - * @since Java Persistence 1.0 - */ -public enum GenerationType { - - /** - * Indicates that the persistence provider must assign - * primary keys for the entity using an underlying - * database table to ensure uniqueness. - */ - TABLE, - - /** - * Indicates that the persistence provider must assign - * primary keys for the entity using a database sequence. - */ - SEQUENCE, - - /** - * Indicates that the persistence provider must assign - * primary keys for the entity using a database identity column. - */ - IDENTITY, - - /** - * Indicates that the persistence provider should pick an - * appropriate strategy for the particular database. The - * AUTO generation strategy may expect a database - * resource to exist, or it may attempt to create one. A vendor - * may provide documentation on how to create such resources - * in the event that it does not support schema generation - * or cannot create the schema resource at runtime. - */ - AUTO -} diff --git a/src/main/java/javax/persistence/Id.java b/src/main/java/javax/persistence/Id.java deleted file mode 100644 index a201843be..000000000 --- a/src/main/java/javax/persistence/Id.java +++ /dev/null @@ -1,55 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2008 - 2013 Oracle Corporation. All rights reserved. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0 - * which accompanies this distribution. - * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html - * and the Eclipse Distribution License is available at - * http://www.eclipse.org/org/documents/edl-v10.php. - * - * Contributors: - * Linda DeMichiel - Java Persistence 2.1 - * Linda DeMichiel - Java Persistence 2.0 - * - ******************************************************************************/ -package javax.persistence; - -import java.lang.annotation.Target; -import java.lang.annotation.Retention; -import static java.lang.annotation.ElementType.FIELD; -import static java.lang.annotation.ElementType.METHOD; -import static java.lang.annotation.RetentionPolicy.RUNTIME; - -/** - * Specifies the primary key of an entity. - * The field or property to which the Id annotation is applied - * should be one of the following types: any Java primitive type; - * any primitive wrapper type; - * String; - * java.util.Date; - * java.sql.Date; - * java.math.BigDecimal; - * java.math.BigInteger. - * - *

The mapped column for the primary key of the entity is assumed - * to be the primary key of the primary table. If no Column annotation - * is specified, the primary key column name is assumed to be the name - * of the primary key property or field. - * - *

- *   Example:
- *
- *   @Id
- *   public Long getId() { return id; }
- * 
- * - * @see Column - * @see GeneratedValue - * - * @since Java Persistence 1.0 - */ -@Target({METHOD, FIELD}) -@Retention(RUNTIME) - -public @interface Id {} diff --git a/src/main/java/javax/persistence/Table.java b/src/main/java/javax/persistence/Table.java deleted file mode 100644 index dd39e3784..000000000 --- a/src/main/java/javax/persistence/Table.java +++ /dev/null @@ -1,63 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2008 - 2013 Oracle Corporation. All rights reserved. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0 - * which accompanies this distribution. - * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html - * and the Eclipse Distribution License is available at - * http://www.eclipse.org/org/documents/edl-v10.php. - * - * Contributors: - * Linda DeMichiel - Java Persistence 2.1 - * Linda DeMichiel - Java Persistence 2.0 - * - ******************************************************************************/ -package javax.persistence; - -import java.lang.annotation.Target; -import java.lang.annotation.Retention; -import static java.lang.annotation.ElementType.TYPE; -import static java.lang.annotation.RetentionPolicy.RUNTIME; - -/** - * Specifies the primary table for the annotated entity. Additional - * tables may be specified using SecondaryTable or SecondaryTables annotation. - * - *

If no Table annotation is specified for an entity - * class, the default values apply. - * - *

- *    Example:
- *
- *    @Entity
- *    @Table(name="CUST", schema="RECORDS")
- *    public class Customer { ... }
- * 
- * - * @since Java Persistence 1.0 - */ -@Target(TYPE) -@Retention(RUNTIME) -public @interface Table { - - /** - * (Optional) The name of the table. - *

Defaults to the entity name. - * @return String - */ - String name() default ""; - - /** (Optional) The catalog of the table. - *

Defaults to the default catalog. - * @return String - */ - String catalog() default ""; - - /** (Optional) The schema of the table. - *

Defaults to the default schema for user. - * @return String - */ - String schema() default ""; - -} diff --git a/src/main/java/javax/persistence/Transient.java b/src/main/java/javax/persistence/Transient.java deleted file mode 100644 index 81446afd7..000000000 --- a/src/main/java/javax/persistence/Transient.java +++ /dev/null @@ -1,45 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2008 - 2013 Oracle Corporation. All rights reserved. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0 - * which accompanies this distribution. - * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html - * and the Eclipse Distribution License is available at - * http://www.eclipse.org/org/documents/edl-v10.php. - * - * Contributors: - * Linda DeMichiel - Java Persistence 2.1 - * Linda DeMichiel - Java Persistence 2.0 - * - ******************************************************************************/ -package javax.persistence; - -import java.lang.annotation.Target; -import java.lang.annotation.Retention; -import static java.lang.annotation.ElementType.METHOD; -import static java.lang.annotation.ElementType.FIELD; -import static java.lang.annotation.RetentionPolicy.RUNTIME; - -/** - * Specifies that the property or field is not persistent. It is used - * to annotate a property or field of an entity class, mapped - * superclass, or embeddable class. - * - *

- *    Example:
- *
- *    @Entity
- *    public class Employee {
- *        @Id int id;
- *        @Transient User currentUser;
- *        ...
- *    }
- * 
- * - * @since Java Persistence 1.0 - */ -@Target({METHOD, FIELD}) -@Retention(RUNTIME) - -public @interface Transient {} diff --git a/src/main/java/org/redkale/boot/Application.java b/src/main/java/org/redkale/boot/Application.java deleted file mode 100644 index 27142ff15..000000000 --- a/src/main/java/org/redkale/boot/Application.java +++ /dev/null @@ -1,656 +0,0 @@ -/* - * 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.boot; - -import org.redkale.boot.ClassFilter.FilterEntry; -import org.redkale.util.AnyValue.DefaultAnyValue; -import java.io.*; -import java.net.*; -import java.nio.*; -import java.nio.channels.*; -import java.nio.file.*; -import java.util.*; -import java.util.concurrent.*; -import java.util.concurrent.atomic.*; -import java.util.logging.*; -import javax.xml.parsers.*; -import org.redkale.convert.bson.*; -import org.redkale.convert.json.*; -import org.redkale.net.*; -import org.redkale.net.http.*; -import org.redkale.net.sncp.*; -import org.redkale.service.*; -import org.redkale.source.*; -import org.redkale.util.*; -import org.redkale.watch.*; -import org.w3c.dom.*; - -/** - * 编译时需要加入: -XDignore.symbol.file=true - *

- * 进程启动类,程序启动后读取application.xml,进行classpath扫描动态加载Service与Servlet - * 优先加载所有SNCP协议的服务, 再加载其他协议服务, - * 最后进行Service、Servlet与其他资源之间的依赖注入。 - * - * - *

- * 详情见: http://www.redkale.org - * - * @author zhangjx - */ -public final class Application { - - //当前进程启动的时间, 类型: long - public static final String RESNAME_APP_TIME = "APP_TIME"; - - //当前进程的根目录, 类型:String、File、Path - public static final String RESNAME_APP_HOME = "APP_HOME"; - - //application.xml 文件中resources节点的内容, 类型: AnyValue - public static final String RESNAME_APP_GRES = "APP_GRES"; - - //当前进程节点的name, 类型:String - public static final String RESNAME_APP_NODE = "APP_NODE"; - - //当前进程节点的IP地址, 类型:InetAddress、String - public static final String RESNAME_APP_ADDR = "APP_ADDR"; - - //当前Service的IP地址+端口 类型: SocketAddress、InetSocketAddress、String - public static final String RESNAME_SERVER_ADDR = "SERVER_ADDR"; - - //当前SNCP Server所属的组 类型: String - public static final String RESNAME_SERVER_GROUP = "SERVER_GROUP"; - - //当前Server的ROOT目录 类型:String、File、Path - public static final String RESNAME_SERVER_ROOT = Server.RESNAME_SERVER_ROOT; - - final Map globalNodes = new HashMap<>(); - - final Map> globalGroups = new HashMap<>(); - - final Map globalGroupProtocols = new HashMap<>(); - - final InetAddress localAddress; - - final List cacheSources = new CopyOnWriteArrayList<>(); - - final List dataSources = new CopyOnWriteArrayList<>(); - - final List servers = new CopyOnWriteArrayList<>(); - - CountDownLatch servicecdl; //会出现两次赋值 - - final ObjectPool transportBufferPool; - - final ExecutorService transportExecutor; - - final AsynchronousChannelGroup transportChannelGroup; - - final ResourceFactory resourceFactory = ResourceFactory.root(); - - //-------------------------------------------------------------------------------------------- - private final boolean singletonrun; - - private final WatchFactory watchFactory = WatchFactory.root(); - - private final File home; - - private final Logger logger; - - private final AnyValue config; - - private final long startTime = System.currentTimeMillis(); - - private final CountDownLatch serversLatch; - - private Application(final AnyValue config) { - this(false, config); - } - - private Application(final boolean singletonrun, final AnyValue config) { - this.singletonrun = singletonrun; - this.config = config; - - final File root = new File(System.getProperty(RESNAME_APP_HOME)); - 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, File.class, root); - try { - this.resourceFactory.register(RESNAME_APP_HOME, root.getCanonicalPath()); - this.home = root.getCanonicalFile(); - } catch (IOException e) { - throw new RuntimeException(e); - } - String localaddr = config.getValue("address", "").trim(); - this.localAddress = localaddr.isEmpty() ? Utility.localInetAddress() : new InetSocketAddress(localaddr, config.getIntValue("port")).getAddress(); - this.resourceFactory.register(RESNAME_APP_ADDR, this.localAddress.getHostAddress()); - this.resourceFactory.register(RESNAME_APP_ADDR, InetAddress.class, this.localAddress); - { - String node = config.getValue("node", "").trim(); - if (node.isEmpty()) { - StringBuilder sb = new StringBuilder(); - byte[] bs = this.localAddress.getAddress(); - int v1 = bs[bs.length - 2] & 0xff; - int v2 = bs[bs.length - 1] & 0xff; - if (v1 <= 0xf) sb.append('0'); - sb.append(Integer.toHexString(v1)); - if (v2 <= 0xf) sb.append('0'); - sb.append(Integer.toHexString(v2)); - node = sb.toString(); - } - this.resourceFactory.register(RESNAME_APP_NODE, node); - System.setProperty(RESNAME_APP_NODE, node); - } - //以下是初始化日志配置 - final File logconf = new File(root, "conf/logging.properties"); - if (logconf.isFile() && logconf.canRead()) { - try { - final String rootpath = root.getCanonicalPath().replace('\\', '/'); - FileInputStream fin = new FileInputStream(logconf); - Properties properties = new Properties(); - properties.load(fin); - fin.close(); - properties.entrySet().stream().forEach(x -> { - x.setValue(x.getValue().toString().replace("${APP_HOME}", rootpath)); - }); - - if (properties.getProperty("java.util.logging.FileHandler.formatter") == null) { - properties.setProperty("java.util.logging.FileHandler.formatter", LogFileHandler.LoggingFormater.class.getName()); - } - if (properties.getProperty("java.util.logging.ConsoleHandler.formatter") == null) { - properties.setProperty("java.util.logging.ConsoleHandler.formatter", LogFileHandler.LoggingFormater.class.getName()); - } - String fileHandlerPattern = properties.getProperty("java.util.logging.FileHandler.pattern"); - if (fileHandlerPattern != null && fileHandlerPattern.contains("%d")) { - final String fileHandlerClass = LogFileHandler.class.getName(); - Properties prop = new Properties(); - final String handlers = properties.getProperty("handlers"); - if (handlers != null && handlers.contains("java.util.logging.FileHandler")) { - prop.setProperty("handlers", handlers.replace("java.util.logging.FileHandler", fileHandlerClass)); - } - if (!prop.isEmpty()) { - String prefix = fileHandlerClass + "."; - properties.entrySet().stream().forEach(x -> { - if (x.getKey().toString().startsWith("java.util.logging.FileHandler.")) { - prop.put(x.getKey().toString().replace("java.util.logging.FileHandler.", prefix), x.getValue()); - } - }); - prop.entrySet().stream().forEach(x -> { - properties.put(x.getKey(), x.getValue()); - }); - } - properties.put(SncpClient.class.getSimpleName() + ".handlers", LogFileHandler.SncpLogFileHandler.class.getName()); - } - ByteArrayOutputStream out = new ByteArrayOutputStream(); - final PrintStream ps = new PrintStream(out); - properties.forEach((x, y) -> ps.println(x + "=" + y)); - LogManager.getLogManager().readConfiguration(new ByteArrayInputStream(out.toByteArray())); - } catch (Exception e) { - Logger.getLogger(this.getClass().getSimpleName()).log(Level.WARNING, "init logger configuration error", e); - } - } - this.logger = Logger.getLogger(this.getClass().getSimpleName()); - this.serversLatch = new CountDownLatch(config.getAnyValues("server").length + 1); - //------------------配置 节点 ------------------ - ObjectPool transportPool = null; - ExecutorService transportExec = null; - AsynchronousChannelGroup transportGroup = null; - final AnyValue resources = config.getAnyValue("resources"); - if (resources != null) { - AnyValue transportConf = resources.getAnyValue("transport"); - int groupsize = resources.getAnyValues("group").length; - if (groupsize > 0 && transportConf == null) transportConf = new DefaultAnyValue(); - if (transportConf != null) { - //--------------transportBufferPool----------- - AtomicLong createBufferCounter = watchFactory == null ? new AtomicLong() : watchFactory.createWatchNumber(Transport.class.getSimpleName() + ".Buffer.creatCounter"); - AtomicLong cycleBufferCounter = watchFactory == null ? new AtomicLong() : watchFactory.createWatchNumber(Transport.class.getSimpleName() + ".Buffer.cycleCounter"); - final int bufferCapacity = transportConf.getIntValue("bufferCapacity", 8 * 1024); - final int bufferPoolSize = transportConf.getIntValue("bufferPoolSize", groupsize * Runtime.getRuntime().availableProcessors() * 8); - final int threads = transportConf.getIntValue("threads", groupsize * Runtime.getRuntime().availableProcessors() * 8); - transportPool = new ObjectPool<>(createBufferCounter, cycleBufferCounter, bufferPoolSize, - (Object... params) -> ByteBuffer.allocateDirect(bufferCapacity), null, (e) -> { - if (e == null || e.isReadOnly() || e.capacity() != bufferCapacity) return false; - e.clear(); - return true; - }); - //-----------transportChannelGroup-------------- - try { - final AtomicInteger counter = new AtomicInteger(); - transportExec = Executors.newFixedThreadPool(threads, (Runnable r) -> { - Thread t = new Thread(r); - t.setDaemon(true); - t.setName("Transport-Thread-" + counter.incrementAndGet()); - return t; - }); - transportGroup = AsynchronousChannelGroup.withCachedThreadPool(transportExec, 1); - } catch (Exception e) { - throw new RuntimeException(e); - } - logger.log(Level.INFO, Transport.class.getSimpleName() + " configure bufferCapacity = " + bufferCapacity + "; bufferPoolSize = " + bufferPoolSize + "; threads = " + threads + ";"); - } - } - this.transportBufferPool = transportPool; - this.transportExecutor = transportExec; - this.transportChannelGroup = transportGroup; - } - - public ResourceFactory getResourceFactory() { - return resourceFactory; - } - - public WatchFactory getWatchFactory() { - return watchFactory; - } - - public File getHome() { - return home; - } - - public long getStartTime() { - return startTime; - } - - private void initLogging() { - - } - - public void init() throws Exception { - System.setProperty("java.util.concurrent.ForkJoinPool.common.parallelism", "" + Runtime.getRuntime().availableProcessors() * 4); - System.setProperty("convert.bson.tiny", "true"); - System.setProperty("convert.json.tiny", "true"); - System.setProperty("convert.bson.pool.size", "128"); - System.setProperty("convert.json.pool.size", "128"); - System.setProperty("convert.bson.writer.buffer.defsize", "4096"); - System.setProperty("convert.json.writer.buffer.defsize", "4096"); - - File persist = new File(this.home, "conf/persistence.xml"); - final String homepath = this.home.getCanonicalPath(); - if (persist.isFile()) System.setProperty(DataDefaultSource.DATASOURCE_CONFPATH, persist.getCanonicalPath()); - logger.log(Level.INFO, RESNAME_APP_HOME + "= " + homepath + "\r\n" + RESNAME_APP_ADDR + "= " + this.localAddress.getHostAddress()); - String lib = config.getValue("lib", "").trim().replace("${APP_HOME}", homepath); - lib = lib.isEmpty() ? (homepath + "/conf") : (lib + ";" + homepath + "/conf"); - Server.loadLib(logger, lib); - initLogging(); - //------------------------------------------------------------------------ - final AnyValue resources = config.getAnyValue("resources"); - if (resources != null) { - resourceFactory.register(RESNAME_APP_GRES, AnyValue.class, resources); - final AnyValue properties = resources.getAnyValue("properties"); - if (properties != null) { - String dfloads = properties.getValue("load"); - if (dfloads != null) { - for (String dfload : dfloads.split(";")) { - if (dfload.trim().isEmpty()) continue; - dfload = dfload.trim().replace("${APP_HOME}", home.getCanonicalPath()).replace('\\', '/'); - final File df = (dfload.indexOf('/') < 0) ? new File(home, "conf/" + dfload) : new File(dfload); - if (df.isFile()) { - Properties ps = new Properties(); - InputStream in = new FileInputStream(df); - ps.load(in); - in.close(); - ps.forEach((x, y) -> resourceFactory.register("property." + x, y)); - } - } - } - for (AnyValue prop : properties.getAnyValues("property")) { - String name = prop.getValue("name"); - String value = prop.getValue("value"); - if (name == null || value == null) continue; - if (name.startsWith("system.property.")) { - System.setProperty(name.substring("system.property.".length()), value); - } else if (name.startsWith("mimetype.property.")) { - MimeType.add(name.substring("mimetype.property.".length()), value); - } else { - resourceFactory.register("property." + name, value); - } - } - } - } - if (this.localAddress != null && this.resourceFactory.find("property.datasource.nodeid", String.class) == null) { - byte[] bs = this.localAddress.getAddress(); - int v = (0xff & bs[bs.length - 2]) % 10 * 100 + (0xff & bs[bs.length - 1]); - this.resourceFactory.register("property.datasource.nodeid", "" + v); - } - this.resourceFactory.register(BsonFactory.root()); - this.resourceFactory.register(JsonFactory.root()); - this.resourceFactory.register(BsonFactory.root().getConvert()); - this.resourceFactory.register(JsonFactory.root().getConvert()); - initResources(); - } - - private void initResources() throws Exception { - //------------------------------------------------------------------------- - final AnyValue resources = config.getAnyValue("resources"); - if (resources != null) { - //------------------------------------------------------------------------ - - for (AnyValue conf : resources.getAnyValues("group")) { - final String group = conf.getValue("name", ""); - final String protocol = conf.getValue("protocol", Transport.DEFAULT_PROTOCOL).toUpperCase(); - if (!"TCP".equalsIgnoreCase(protocol) && !"UDP".equalsIgnoreCase(protocol)) { - throw new RuntimeException("Not supported Transport Protocol " + conf.getValue("protocol")); - } - Set addrs = globalGroups.get(group); - if (addrs == null) { - addrs = new LinkedHashSet<>(); - globalGroupProtocols.put(group, protocol); - globalGroups.put(group, addrs); - } - for (AnyValue node : conf.getAnyValues("node")) { - final InetSocketAddress addr = new InetSocketAddress(node.getValue("addr"), node.getIntValue("port")); - addrs.add(addr); - String oldgroup = globalNodes.get(addr); - if (oldgroup != null) throw new RuntimeException(addr + " had one more group " + (globalNodes.get(addr))); - globalNodes.put(addr, group); - } - } - } - //------------------------------------------------------------------------ - } - - private void startSelfServer() throws Exception { - final Application application = this; - new Thread() { - { - setName("Application-Control-Thread"); - } - - @Override - public void run() { - try { - final DatagramChannel channel = DatagramChannel.open(); - channel.configureBlocking(true); - channel.socket().setSoTimeout(3000); - channel.bind(new InetSocketAddress(config.getValue("host", "127.0.0.1"), config.getIntValue("port"))); - boolean loop = true; - ByteBuffer buffer = ByteBuffer.allocateDirect(1024); - while (loop) { - buffer.clear(); - SocketAddress address = channel.receive(buffer); - buffer.flip(); - byte[] bytes = new byte[buffer.remaining()]; - buffer.get(bytes); - if ("SHUTDOWN".equalsIgnoreCase(new String(bytes))) { - try { - long s = System.currentTimeMillis(); - logger.info(application.getClass().getSimpleName() + " shutdowning"); - application.shutdown(); - buffer.clear(); - buffer.put("SHUTDOWN OK".getBytes()); - buffer.flip(); - channel.send(buffer, address); - long e = System.currentTimeMillis() - s; - logger.info(application.getClass().getSimpleName() + " shutdown in " + e + " ms"); - application.serversLatch.countDown(); - System.exit(0); - } catch (Exception ex) { - logger.log(Level.INFO, "SHUTDOWN FAIL", ex); - buffer.clear(); - buffer.put("SHUTDOWN FAIL".getBytes()); - buffer.flip(); - channel.send(buffer, address); - } - } - } - } catch (Exception e) { - logger.log(Level.INFO, "Control fail", e); - System.exit(1); - } - } - }.start(); - } - - private void sendShutDown() throws Exception { - final DatagramChannel channel = DatagramChannel.open(); - channel.configureBlocking(true); - channel.connect(new InetSocketAddress(config.getValue("host", "127.0.0.1"), config.getIntValue("port"))); - ByteBuffer buffer = ByteBuffer.allocate(128); - buffer.put("SHUTDOWN".getBytes()); - buffer.flip(); - channel.write(buffer); - buffer.clear(); - channel.configureBlocking(false); - channel.read(buffer); - buffer.flip(); - byte[] bytes = new byte[buffer.remaining()]; - buffer.get(bytes); - channel.close(); - logger.info(new String(bytes)); - Thread.sleep(500); - } - - public void start() throws Exception { - final AnyValue[] entrys = config.getAnyValues("server"); - CountDownLatch timecd = new CountDownLatch(entrys.length); - final List sncps = new ArrayList<>(); - final List others = new ArrayList<>(); - for (final AnyValue entry : entrys) { - if (entry.getValue("protocol", "").toUpperCase().startsWith("SNCP")) { - sncps.add(entry); - } else { - others.add(entry); - } - } - //单向SNCP服务不需要对等group - //if (!sncps.isEmpty() && globalNodes.isEmpty()) throw new RuntimeException("found SNCP Server node but not found node info."); - - runServers(timecd, sncps); //必须确保sncp都启动后再启动其他协议 - runServers(timecd, others); - timecd.await(); - logger.info(this.getClass().getSimpleName() + " started in " + (System.currentTimeMillis() - startTime) + " ms"); - if (!singletonrun) this.serversLatch.await(); - } - - @SuppressWarnings("unchecked") - private void runServers(CountDownLatch timecd, final List serconfs) throws Exception { - this.servicecdl = new CountDownLatch(serconfs.size()); - CountDownLatch sercdl = new CountDownLatch(serconfs.size()); - final AtomicBoolean inited = new AtomicBoolean(false); - final Map> nodeClasses = new HashMap<>(); - for (final AnyValue serconf : serconfs) { - Thread thread = new Thread() { - { - String host = serconf.getValue("host", "").replace("0.0.0.0", "[0]"); - setName(serconf.getValue("protocol", "Server").toUpperCase() + "-" + host + ":" + serconf.getIntValue("port") + "-Thread"); - this.setDaemon(true); - } - - @Override - public void run() { - try { - //Thread ctd = Thread.currentThread(); - //ctd.setContextClassLoader(new URLClassLoader(new URL[0], ctd.getContextClassLoader())); - final String protocol = serconf.getValue("protocol", "").replaceFirst("\\..+", "").toUpperCase(); - NodeServer server = null; - if ("SNCP".equals(protocol)) { - server = new NodeSncpServer(Application.this, serconf); - } else if ("HTTP".equals(protocol)) { - server = new NodeHttpServer(Application.this, serconf); - } else { - if (!inited.get()) { - synchronized (nodeClasses) { - if (!inited.get()) { - inited.set(true); - ClassFilter profilter = new ClassFilter(NodeProtocol.class, NodeServer.class); - ClassFilter.Loader.load(home, profilter); - final Set> entrys = profilter.getFilterEntrys(); - for (FilterEntry entry : entrys) { - final Class type = entry.getType(); - NodeProtocol pros = type.getAnnotation(NodeProtocol.class); - for (String p : pros.value()) { - p = p.toUpperCase(); - if ("SNCP".equals(p) || "HTTP".equals(p)) continue; - final Class old = nodeClasses.get(p); - if (old != null && old != type) throw new RuntimeException("Protocol(" + p + ") had NodeServer-Class(" + old.getName() + ") but repeat NodeServer-Class(" + type.getName() + ")"); - nodeClasses.put(p, type); - } - } - } - } - } - Class nodeClass = nodeClasses.get(protocol); - if (nodeClass != null) server = NodeServer.create(nodeClass, Application.this, serconf); - } - if (server == null) { - logger.log(Level.SEVERE, "Not found Server Class for protocol({0})", serconf.getValue("protocol")); - System.exit(0); - } - servers.add(server); - server.init(serconf); - if (!singletonrun) server.start(); - timecd.countDown(); - sercdl.countDown(); - } catch (Exception ex) { - logger.log(Level.WARNING, serconf + " runServers error", ex); - Application.this.serversLatch.countDown(); - } - } - }; - thread.start(); - } - sercdl.await(); - } - - public static T singleton(Class serviceClass) throws Exception { - return singleton("", serviceClass); - } - - public static T singleton(String name, Class serviceClass) throws Exception { - final Application application = Application.create(true); - application.init(); - application.start(); - for (NodeServer server : application.servers) { - T service = server.resourceFactory.find(name, serviceClass); - if (service != null) return service; - } - return null; - } - - private static Application create(final boolean singleton) throws IOException { - final String home = new File(System.getProperty(RESNAME_APP_HOME, "")).getCanonicalPath(); - System.setProperty(RESNAME_APP_HOME, home); - File appfile = new File(home, "conf/application.xml"); - return new Application(singleton, load(new FileInputStream(appfile))); - } - - public static void main(String[] args) throws Exception { - Utility.midnight(); //先初始化一下Utility - //运行主程序 - final Application application = Application.create(false); - if (System.getProperty("SHUTDOWN") != null) { - application.sendShutDown(); - return; - } - application.init(); - application.startSelfServer(); - try { - application.start(); - } catch (Exception e) { - application.logger.log(Level.SEVERE, "Application start error", e); - System.exit(0); - } - System.exit(0); - } - - Set findSncpGroups(Transport sameGroupTransport, Collection diffGroupTransports) { - Set gs = new HashSet<>(); - if (sameGroupTransport != null) gs.add(sameGroupTransport.getName()); - if (diffGroupTransports != null) { - for (Transport t : diffGroupTransports) { - gs.add(t.getName()); - } - } - return gs; - } - - NodeSncpServer findNodeSncpServer(final InetSocketAddress sncpAddr) { - for (NodeServer node : servers) { - if (node.isSNCP() && sncpAddr.equals(node.getSncpAddress())) { - return (NodeSncpServer) node; - } - } - return null; - } - - String findGroupProtocol(String group) { - if (group == null) return null; - return globalGroupProtocols.get(group); - } - - Set findGlobalGroup(String group) { - if (group == null) return null; - Set set = globalGroups.get(group); - return set == null ? null : new LinkedHashSet<>(set); - } - - private void shutdown() throws Exception { - servers.stream().forEach((server) -> { - try { - server.shutdown(); - } catch (Exception t) { - logger.log(Level.WARNING, " shutdown server(" + server.getSocketAddress() + ") error", t); - } finally { - serversLatch.countDown(); - } - }); - - for (DataSource source : dataSources) { - try { - source.getClass().getMethod("close").invoke(source); - } catch (Exception e) { - logger.log(Level.FINER, "close DataSource erroneous", e); - } - } - for (CacheSource source : cacheSources) { - try { - source.getClass().getMethod("close").invoke(source); - } catch (Exception e) { - logger.log(Level.FINER, "close CacheSource erroneous", e); - } - } - if (this.transportChannelGroup != null) { - try { - this.transportChannelGroup.shutdownNow(); - } catch (Exception e) { - logger.log(Level.FINER, "close transportChannelGroup erroneous", e); - } - } - } - - private static AnyValue load(final InputStream in0) { - final DefaultAnyValue any = new DefaultAnyValue(); - try (final InputStream in = in0) { - DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); - DocumentBuilder builder = factory.newDocumentBuilder(); - Document doc = builder.parse(in); - Element root = doc.getDocumentElement(); - load(any, root); - } catch (Exception ex) { - throw new RuntimeException(ex); - } - return any; - } - - private static void load(final DefaultAnyValue any, final Node root) { - final String home = System.getProperty(RESNAME_APP_HOME); - NamedNodeMap nodes = root.getAttributes(); - if (nodes == null) return; - for (int i = 0; i < nodes.getLength(); i++) { - Node node = nodes.item(i); - any.addValue(node.getNodeName(), node.getNodeValue().replace("${APP_HOME}", home)); - } - NodeList children = root.getChildNodes(); - if (children == null) return; - for (int i = 0; i < children.getLength(); i++) { - Node node = children.item(i); - if (node.getNodeType() != Node.ELEMENT_NODE) continue; - DefaultAnyValue sub = new DefaultAnyValue(); - load(sub, node); - any.addValue(node.getNodeName(), sub); - } - - } -} diff --git a/src/main/java/org/redkale/boot/ClassFilter.java b/src/main/java/org/redkale/boot/ClassFilter.java deleted file mode 100644 index 259daf58b..000000000 --- a/src/main/java/org/redkale/boot/ClassFilter.java +++ /dev/null @@ -1,431 +0,0 @@ -/* - * 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.boot; - -import java.io.*; -import java.lang.annotation.*; -import java.lang.reflect.*; -import java.net.*; -import java.util.*; -import java.util.concurrent.*; -import java.util.jar.*; -import java.util.logging.*; -import java.util.regex.*; -import org.redkale.util.AnyValue; -import org.redkale.util.AnyValue.DefaultAnyValue; -import org.redkale.util.AutoLoad; - -/** - * class过滤器, 符合条件的class会保留下来存入FilterEntry。 - * - *

- * 详情见: http://www.redkale.org - * - * @author zhangjx - * @param 泛型 - */ -@SuppressWarnings("unchecked") -public final class ClassFilter { - - private final Set> entrys = new HashSet<>(); - - private boolean refused; - - private Class superClass; - - private Class annotationClass; - - private Pattern[] includePatterns; - - private Pattern[] excludePatterns; - - private List ors; - - private List ands; - - private AnyValue conf; - - public ClassFilter(Class annotationClass, Class superClass) { - this(annotationClass, superClass, null); - } - - public ClassFilter(Class annotationClass, Class superClass, AnyValue conf) { - this.annotationClass = annotationClass; - this.superClass = superClass; - this.conf = conf; - } - - public ClassFilter or(ClassFilter filter) { - if (ors == null) ors = new ArrayList<>(); - ors.add(filter); - return this; - } - - public ClassFilter and(ClassFilter filter) { - if (ands == null) ands = new ArrayList<>(); - ands.add(filter); - return this; - } - - /** - * 获取符合条件的class集合 - * - * @return Set<FilterEntry<T>> - */ - public final Set> getFilterEntrys() { - return entrys; - } - - /** - * 自动扫描地过滤指定的class - * - * @param property AnyValue - * @param clazzname String - */ - @SuppressWarnings("unchecked") - public final void filter(AnyValue property, String clazzname) { - filter(property, clazzname, true); - } - - /** - * 过滤指定的class - * - * @param property application.xml中对应class节点下的property属性项 - * @param clazzname class名称 - * @param autoscan 为true表示自动扫描的, false表示显著调用filter, AutoLoad的注解将被忽略 - */ - public final void filter(AnyValue property, String clazzname, boolean autoscan) { - boolean r = accept0(property, clazzname); - ClassFilter cf = r ? this : null; - if (r && ands != null) { - for (ClassFilter filter : ands) { - if (!filter.accept(property, clazzname)) return; - } - } - if (!r && ors != null) { - for (ClassFilter filter : ors) { - if (filter.accept(property, clazzname)) { - cf = filter; - break; - } - } - } - if (cf == null) return; - try { - Class clazz = Class.forName(clazzname); - if (!cf.accept(property, clazz, autoscan)) return; - if (cf.conf != null) { - if (property == null) { - property = cf.conf; - } else if (property instanceof DefaultAnyValue) { - ((DefaultAnyValue) property).addAll(cf.conf); - } else { - DefaultAnyValue dav = new DefaultAnyValue(); - dav.addAll(property); - dav.addAll(cf.conf); - property = dav; - } - } - entrys.add(new FilterEntry(clazz, autoscan, property)); - } catch (Throwable cfe) { - } - } - - private static Pattern[] toPattern(String[] regs) { - if (regs == null) return null; - int i = 0; - Pattern[] rs = new Pattern[regs.length]; - for (String reg : regs) { - if (reg == null || reg.trim().isEmpty()) continue; - rs[i++] = Pattern.compile(reg.trim()); - } - if (i == 0) return null; - if (i == rs.length) return rs; - Pattern[] ps = new Pattern[i]; - System.arraycopy(rs, 0, ps, 0, i); - return ps; - } - - /** - * 判断class是否有效 - * - * @param property AnyValue - * @param classname String - * @return boolean - */ - public boolean accept(AnyValue property, String classname) { - boolean r = accept0(property, classname); - if (r && ands != null) { - for (ClassFilter filter : ands) { - if (!filter.accept(property, classname)) return false; - } - } - if (!r && ors != null) { - for (ClassFilter filter : ors) { - if (filter.accept(property, classname)) return true; - } - } - return r; - } - - private boolean accept0(AnyValue property, String classname) { - if (this.refused) return false; - if (classname.startsWith("java.") || classname.startsWith("javax.")) return false; - if (excludePatterns != null) { - for (Pattern reg : excludePatterns) { - if (reg.matcher(classname).matches()) return false; - } - } - if (includePatterns != null) { - for (Pattern reg : includePatterns) { - if (reg.matcher(classname).matches()) return true; - } - } - return includePatterns == null; - } - - /** - * 判断class是否有效 - * - * @param property AnyValue - * @param clazz Class - * @param autoscan boolean - * @return boolean - */ - @SuppressWarnings("unchecked") - public boolean accept(AnyValue property, Class clazz, boolean autoscan) { - if (this.refused || !Modifier.isPublic(clazz.getModifiers())) return false; - if (autoscan) { - AutoLoad auto = (AutoLoad) clazz.getAnnotation(AutoLoad.class); - if (auto != null && !auto.value()) return false; - } - if (annotationClass != null && clazz.getAnnotation(annotationClass) == null) return false; - return superClass == null || (clazz != superClass && superClass.isAssignableFrom(clazz)); - } - - public void setSuperClass(Class superClass) { - this.superClass = superClass; - } - - public void setAnnotationClass(Class annotationClass) { - this.annotationClass = annotationClass; - } - - public Pattern[] getIncludePatterns() { - return includePatterns; - } - - public void setIncludePatterns(String[] includePatterns) { - this.includePatterns = toPattern(includePatterns); - } - - public Pattern[] getExcludePatterns() { - return excludePatterns; - } - - public void setExcludePatterns(String[] excludePatterns) { - this.excludePatterns = toPattern(excludePatterns); - } - - public Class getAnnotationClass() { - return annotationClass; - } - - public Class getSuperClass() { - return superClass; - } - - public boolean isRefused() { - return refused; - } - - public void setRefused(boolean refused) { - this.refused = refused; - } - - /** - * 存放符合条件的class与class指定的属性项 - * - * @param 泛型 - */ - public static final class FilterEntry { - - private final HashSet groups = new LinkedHashSet<>(); - - private final String name; - - private final Class type; - - private final AnyValue property; - - private final boolean autoload; - - public FilterEntry(Class type, AnyValue property) { - this(type, false, property); - } - - public FilterEntry(Class type, final boolean autoload, AnyValue property) { - this.type = type; - String str = property == null ? null : property.getValue("groups"); - if (str != null) { - str = str.trim(); - if (str.endsWith(";")) str = str.substring(0, str.length() - 1); - } - if (str != null) groups.addAll(Arrays.asList(str.split(";"))); - this.property = property; - this.autoload = autoload; - this.name = property == null ? "" : property.getValue("name", ""); - } - - @Override - public String toString() { - return this.getClass().getSimpleName() + "[thread=" + Thread.currentThread().getName() - + ", type=" + this.type.getSimpleName() + ", name=" + name + ", groups=" + groups + "]"; - } - - @Override - public int hashCode() { - return this.type.hashCode(); - } - - @Override - public boolean equals(Object obj) { - if (obj == null) return false; - if (getClass() != obj.getClass()) return false; - return (this.type == ((FilterEntry) obj).type && this.groups.equals(((FilterEntry) obj).groups) && this.name.equals(((FilterEntry) obj).name)); - } - - public Class getType() { - return type; - } - - public String getName() { - return name; - } - - public AnyValue getProperty() { - return property; - } - - public boolean isEmptyGroups() { - return groups == null || groups.isEmpty(); - } - - public HashSet getGroups() { - return groups; - } - - public boolean isAutoload() { - return autoload; - } - - } - - /** - * class加载类 - */ - public static class Loader { - - protected static final Logger logger = Logger.getLogger(Loader.class.getName()); - - protected static final ConcurrentMap> cache = new ConcurrentHashMap<>(); - - public static void close() { - cache.clear(); - } - - /** - * 加载当前线程的classpath扫描所有class进行过滤 - * - * @param exclude 不需要扫描的文件夹, 可以为null - * @param filters 过滤器 - * @throws IOException 异常 - */ - public static void load(final File exclude, final ClassFilter... filters) throws IOException { - URLClassLoader loader = (URLClassLoader) Thread.currentThread().getContextClassLoader(); - List urlfiles = new ArrayList<>(2); - List urljares = new ArrayList<>(2); - final URL exurl = exclude != null ? exclude.toURI().toURL() : null; - for (URL url : loader.getURLs()) { - if (exurl != null && exurl.sameFile(url)) continue; - if (url.getPath().endsWith(".jar")) { - urljares.add(url); - } else { - urlfiles.add(url); - } - } - List files = new ArrayList<>(); - boolean debug = logger.isLoggable(Level.FINEST); - StringBuilder debugstr = new StringBuilder(); - for (final URL url : urljares) { - Set classes = cache.get(url); - if (classes == null) { - classes = new LinkedHashSet<>(); - try (JarFile jar = new JarFile(URLDecoder.decode(url.getFile(), "UTF-8"))) { - Enumeration it = jar.entries(); - while (it.hasMoreElements()) { - String entryname = it.nextElement().getName().replace('/', '.'); - if (entryname.endsWith(".class") && entryname.indexOf('$') < 0) { - String classname = entryname.substring(0, entryname.length() - 6); - if (classname.startsWith("javax.") || classname.startsWith("com.sun.")) continue; - classes.add(classname); - if (debug) debugstr.append(classname).append("\r\n"); - for (final ClassFilter filter : filters) { - if (filter != null) filter.filter(null, classname); - } - } - } - } - cache.put(url, classes); - } else { - for (String classname : classes) { - for (final ClassFilter filter : filters) { - if (filter != null) filter.filter(null, classname); - } - } - } - } - for (final URL url : urlfiles) { - Set classes = cache.get(url); - if (classes == null) { - classes = new LinkedHashSet<>(); - files.clear(); - File root = new File(url.getFile()); - String rootpath = root.getPath(); - loadClassFiles(exclude, root, files); - for (File f : files) { - String classname = f.getPath().substring(rootpath.length() + 1, f.getPath().length() - 6).replace(File.separatorChar, '.'); - if (classname.startsWith("javax.") || classname.startsWith("com.sun.")) continue; - classes.add(classname); - if (debug) debugstr.append(classname).append("\r\n"); - for (final ClassFilter filter : filters) { - if (filter != null) filter.filter(null, classname); - } - } - cache.put(url, classes); - } else { - for (String classname : classes) { - for (final ClassFilter filter : filters) { - if (filter != null) filter.filter(null, classname); - } - } - } - } - //if (debug) logger.log(Level.INFO, "scan classes: \r\n{0}", debugstr); - } - - private static void loadClassFiles(File exclude, File root, List files) { - if (root.isFile() && root.getName().endsWith(".class")) { - files.add(root); - } else if (root.isDirectory()) { - if (exclude != null && exclude.equals(root)) return; - for (File f : root.listFiles()) { - loadClassFiles(exclude, f, files); - } - } - } - } -} diff --git a/src/main/java/org/redkale/boot/LogFileHandler.java b/src/main/java/org/redkale/boot/LogFileHandler.java deleted file mode 100644 index 0039890d0..000000000 --- a/src/main/java/org/redkale/boot/LogFileHandler.java +++ /dev/null @@ -1,276 +0,0 @@ -/* - * 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.boot; - -import java.io.*; -import java.nio.file.*; -import static java.nio.file.StandardCopyOption.*; -import java.time.*; -import java.util.*; -import java.util.concurrent.*; -import java.util.concurrent.atomic.*; -import java.util.logging.*; -import java.util.logging.Formatter; - -/** - * 自定义的日志输出类 - *

- * 详情见: http://www.redkale.org - * - * @author zhangjx - */ -public class LogFileHandler extends Handler { - - /** - * SNCP的日志输出Handler - */ - public static class SncpLogFileHandler extends LogFileHandler { - - @Override - public String getPrefix() { - return "sncp-"; - } - } - - /** - * 默认的日志时间格式化类 - * - */ - public static class LoggingFormater extends Formatter { - - private static final String format = "%1$tY-%1$tm-%1$td %1$tH:%1$tM:%1$tS.%tL %4$s %2$s\r\n%5$s%6$s\r\n"; - - @Override - public String format(LogRecord record) { - String source; - if (record.getSourceClassName() != null) { - source = record.getSourceClassName(); - if (record.getSourceMethodName() != null) { - source += " " + record.getSourceMethodName(); - } - } else { - source = record.getLoggerName(); - } - String message = formatMessage(record); - String throwable = ""; - if (record.getThrown() != null) { - StringWriter sw = new StringWriter(); - PrintWriter pw = new PrintWriter(sw) { - @Override - public void println() { - super.print("\r\n"); - } - }; - pw.println(); - record.getThrown().printStackTrace(pw); - pw.close(); - throwable = sw.toString(); - } - return String.format(format, - System.currentTimeMillis(), - source, - record.getLoggerName(), - record.getLevel().getName(), - message, - throwable); - } - - } - - protected final LinkedBlockingQueue records = new LinkedBlockingQueue(); - - private String pattern; - - private int limit; //文件大小限制 - - private final AtomicInteger index = new AtomicInteger(); - - private int count = 1; //文件限制 - - private long tomorrow; - - private boolean append; - - private final AtomicLong length = new AtomicLong(); - - private File logfile; - - private OutputStream stream; - - public LogFileHandler() { - updateTomorrow(); - configure(); - open(); - } - - private void updateTomorrow() { - Calendar cal = Calendar.getInstance(); - cal.set(Calendar.HOUR_OF_DAY, 0); - cal.set(Calendar.MINUTE, 0); - cal.set(Calendar.SECOND, 0); - cal.set(Calendar.MILLISECOND, 0); - cal.add(Calendar.DAY_OF_YEAR, 1); - long t = cal.getTimeInMillis(); - if (this.tomorrow != t) index.set(0); - this.tomorrow = t; - } - - private void open() { - final String name = "Logging-" + getClass().getSimpleName() + "-Thread"; - new Thread() { - { - setName(name); - setDaemon(true); - } - - @Override - public void run() { - while (true) { - try { - LogRecord record = records.take(); - final boolean bigger = (limit > 0 && limit <= length.get()); - if (bigger || tomorrow <= record.getMillis()) { - updateTomorrow(); - if (stream != null) { - stream.close(); - if (bigger) { - for (int i = Math.min(count - 2, index.get() - 1); i > 0; i--) { - File greater = new File(logfile.getPath() + "." + i); - if (greater.exists()) Files.move(greater.toPath(), new File(logfile.getPath() + "." + (i + 1)).toPath(), REPLACE_EXISTING, ATOMIC_MOVE); - } - Files.move(logfile.toPath(), new File(logfile.getPath() + ".1").toPath(), REPLACE_EXISTING, ATOMIC_MOVE); - } - stream = null; - } - } - if (stream == null) { - index.incrementAndGet(); - java.time.LocalDate date = LocalDate.now(); - logfile = new File(pattern.replace("%m", String.valueOf((date.getYear() * 100 + date.getMonthValue()))).replace("%d", String.valueOf((date.getYear() * 10000 + date.getMonthValue() * 100 + date.getDayOfMonth())))); - logfile.getParentFile().mkdirs(); - length.set(logfile.length()); - stream = new FileOutputStream(logfile, append); - } - //----------------------写日志------------------------- - String message = getFormatter().format(record); - String encoding = getEncoding(); - byte[] bytes = encoding == null ? message.getBytes() : message.getBytes(encoding); - stream.write(bytes); - length.addAndGet(bytes.length); - } catch (Exception e) { - ErrorManager err = getErrorManager(); - if (err != null) err.error(null, e, ErrorManager.WRITE_FAILURE); - } - } - - } - }.start(); - } - - public String getPrefix() { - return ""; - } - - private void configure() { - LogManager manager = LogManager.getLogManager(); - String cname = LogFileHandler.class.getName(); - pattern = manager.getProperty(cname + ".pattern"); - if (pattern == null) { - pattern = "logs-%m/" + getPrefix() + "log-%d.log"; - } else { - int pos = pattern.lastIndexOf('/'); - if (pos > 0) { - pattern = pattern.substring(0, pos + 1) + getPrefix() + pattern.substring(pos + 1); - } else { - pattern = getPrefix() + pattern; - } - } - String limitstr = manager.getProperty(cname + ".limit"); - try { - if (limitstr != null) limit = Math.abs(Integer.decode(limitstr)); - } catch (Exception e) { - } - String countstr = manager.getProperty(cname + ".count"); - try { - if (countstr != null) count = Math.max(1, Math.abs(Integer.decode(countstr))); - } catch (Exception e) { - } - String appendstr = manager.getProperty(cname + ".append"); - try { - if (appendstr != null) append = "true".equalsIgnoreCase(appendstr) || "1".equals(appendstr); - } catch (Exception e) { - } - String levelstr = manager.getProperty(cname + ".level"); - try { - if (levelstr != null) { - Level l = Level.parse(levelstr); - setLevel(l != null ? l : Level.ALL); - } - } catch (Exception e) { - } - String filterstr = manager.getProperty(cname + ".filter"); - try { - if (filterstr != null) { - Class clz = ClassLoader.getSystemClassLoader().loadClass(filterstr); - setFilter((Filter) clz.newInstance()); - } - } catch (Exception e) { - } - String formatterstr = manager.getProperty(cname + ".formatter"); - try { - if (formatterstr != null) { - Class clz = ClassLoader.getSystemClassLoader().loadClass(formatterstr); - setFormatter((Formatter) clz.newInstance()); - } - } catch (Exception e) { - } - if (getFormatter() == null) setFormatter(new SimpleFormatter()); - - String encodingstr = manager.getProperty(cname + ".encoding"); - try { - if (encodingstr != null) setEncoding(encodingstr); - } catch (Exception e) { - } - } - - @Override - public void publish(LogRecord record) { - final String sourceClassName = record.getSourceClassName(); - if (sourceClassName == null || true) { - StackTraceElement[] ses = new Throwable().getStackTrace(); - for (int i = 2; i < ses.length; i++) { - if (ses[i].getClassName().startsWith("java.util.logging")) continue; - record.setSourceClassName('[' + Thread.currentThread().getName() + "] " + ses[i].getClassName()); - record.setSourceMethodName(ses[i].getMethodName()); - break; - } - } else { - record.setSourceClassName('[' + Thread.currentThread().getName() + "] " + sourceClassName); - } - records.offer(record); - } - - @Override - public void flush() { - try { - if (stream != null) stream.flush(); - } catch (Exception e) { - ErrorManager err = getErrorManager(); - if (err != null) err.error(null, e, ErrorManager.FLUSH_FAILURE); - } - } - - @Override - public void close() throws SecurityException { - try { - if (stream != null) stream.close(); - } catch (Exception e) { - ErrorManager err = getErrorManager(); - if (err != null) err.error(null, e, ErrorManager.CLOSE_FAILURE); - } - } - -} diff --git a/src/main/java/org/redkale/boot/NodeHttpServer.java b/src/main/java/org/redkale/boot/NodeHttpServer.java deleted file mode 100644 index f81af74c9..000000000 --- a/src/main/java/org/redkale/boot/NodeHttpServer.java +++ /dev/null @@ -1,145 +0,0 @@ -/* - * 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.boot; - -import org.redkale.net.http.WebServlet; -import org.redkale.net.http.HttpServer; -import org.redkale.net.http.HttpServlet; -import org.redkale.util.AnyValue; -import org.redkale.boot.ClassFilter.FilterEntry; -import org.redkale.util.AnyValue.DefaultAnyValue; -import java.lang.reflect.*; -import java.net.InetSocketAddress; -import java.util.*; -import java.util.logging.*; -import javax.annotation.*; -import org.redkale.net.*; -import org.redkale.net.http.*; -import org.redkale.net.sncp.*; -import org.redkale.service.*; -import org.redkale.util.*; - -/** - * HTTP Server节点的配置Server - * - *

- * 详情见: http://www.redkale.org - * - * @author zhangjx - */ -@NodeProtocol({"HTTP"}) -public final class NodeHttpServer extends NodeServer { - - private final HttpServer httpServer; - - public NodeHttpServer(Application application, AnyValue serconf) { - super(application, createServer(application, serconf)); - this.httpServer = (HttpServer) server; - } - - private static Server createServer(Application application, AnyValue serconf) { - return new HttpServer(application.getStartTime(), application.getWatchFactory()); - } - - @Override - public InetSocketAddress getSocketAddress() { - return httpServer == null ? null : httpServer.getSocketAddress(); - } - - @Override - protected ClassFilter createServletClassFilter() { - return createClassFilter(null, WebServlet.class, HttpServlet.class, null, "servlets", "servlet"); - } - - @Override - protected void loadServlet(ClassFilter servletFilter) throws Exception { - if (httpServer != null) loadHttpServlet(this.serverConf.getAnyValue("servlets"), servletFilter); - } - - @Override - protected void loadService(ClassFilter serviceFilter) throws Exception { - super.loadService(serviceFilter); - initWebSocketService(); - } - - private void initWebSocketService() { - final NodeServer self = this; - final ResourceFactory regFactory = application.getResourceFactory(); - resourceFactory.add(WebSocketNode.class, (ResourceFactory rf, final Object src, final String resourceName, Field field, Object attachment) -> { //主要用于单点的服务 - try { - if (field.getAnnotation(Resource.class) == null) return; - if (!(src instanceof WebSocketServlet)) return; - synchronized (regFactory) { - Service nodeService = (Service) rf.find(resourceName, WebSocketNode.class); - if (nodeService == null) { - nodeService = Sncp.createLocalService(resourceName, getExecutor(), application.getResourceFactory(), WebSocketNodeService.class, (InetSocketAddress) null, (Transport) null, (Collection) null); - regFactory.register(resourceName, WebSocketNode.class, nodeService); - resourceFactory.inject(nodeService, self); - logger.fine("[" + Thread.currentThread().getName() + "] Load Service " + nodeService); - } - field.set(src, nodeService); - } - } catch (Exception e) { - logger.log(Level.SEVERE, "WebSocketNode inject error", e); - } - }); - } - - protected void loadHttpServlet(final AnyValue conf, final ClassFilter filter) throws Exception { - final StringBuilder sb = logger.isLoggable(Level.FINE) ? new StringBuilder() : null; - final String prefix = conf == null ? "" : conf.getValue("path", ""); - final String threadName = "[" + Thread.currentThread().getName() + "] "; - List> list = new ArrayList(filter.getFilterEntrys()); - list.sort((FilterEntry o1, FilterEntry o2) -> { //必须保证WebSocketServlet优先加载, 因为要确保其他的HttpServlet可以注入本地模式的WebSocketNode - boolean ws1 = WebSocketServlet.class.isAssignableFrom(o1.getType()); - boolean ws2 = WebSocketServlet.class.isAssignableFrom(o2.getType()); - if (ws1 == ws2) return o1.getType().getName().compareTo(o2.getType().getName()); - return ws1 ? -1 : 1; - }); - final List> ss = sb == null ? null : new ArrayList<>(); - for (FilterEntry en : list) { - Class clazz = (Class) en.getType(); - 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(); - resourceFactory.inject(servlet, this); - final String[] mappings = ws.value(); - String pref = ws.repair() ? prefix : ""; - DefaultAnyValue servletConf = (DefaultAnyValue) en.getProperty(); - WebInitParam[] webparams = ws.initParams(); - if (webparams.length > 0) { - if (servletConf == null) servletConf = new DefaultAnyValue(); - for (WebInitParam webparam : webparams) { - servletConf.addValue(webparam.name(), webparam.value()); - } - } - this.httpServer.addHttpServlet(servlet, pref, servletConf, mappings); - if (ss != null) { - for (int i = 0; i < mappings.length; i++) { - mappings[i] = pref + mappings[i]; - } - ss.add(new AbstractMap.SimpleEntry<>(clazz.getName(), mappings)); - } - } - if (ss != null) { - Collections.sort(ss, (AbstractMap.SimpleEntry o1, AbstractMap.SimpleEntry o2) -> o1.getKey().compareTo(o2.getKey())); - int max = 0; - for (AbstractMap.SimpleEntry as : ss) { - if (as.getKey().length() > max) max = as.getKey().length(); - } - for (AbstractMap.SimpleEntry as : ss) { - sb.append(threadName).append(" Loaded ").append(as.getKey()); - for (int i = 0; i < max - as.getKey().length(); i++) { - sb.append(' '); - } - sb.append(" mapping to ").append(Arrays.toString(as.getValue())).append(LINE_SEPARATOR); - } - } - if (sb != null && sb.length() > 0) logger.log(Level.FINE, sb.toString()); - } - -} diff --git a/src/main/java/org/redkale/boot/NodeProtocol.java b/src/main/java/org/redkale/boot/NodeProtocol.java deleted file mode 100644 index 76c03dff9..000000000 --- a/src/main/java/org/redkale/boot/NodeProtocol.java +++ /dev/null @@ -1,24 +0,0 @@ -/* - * 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.boot; - -import java.lang.annotation.*; - -/** - * 根据application.xml中的server节点中的protocol值来适配Server的加载逻辑 - * - *

- * 详情见: http://www.redkale.org - * - * @author zhangjx - */ -@Target({ElementType.TYPE}) -@Retention(RetentionPolicy.RUNTIME) -@Documented -public @interface NodeProtocol { - - String[] value(); -} diff --git a/src/main/java/org/redkale/boot/NodeServer.java b/src/main/java/org/redkale/boot/NodeServer.java deleted file mode 100644 index 600d1f517..000000000 --- a/src/main/java/org/redkale/boot/NodeServer.java +++ /dev/null @@ -1,493 +0,0 @@ -/* - * 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.boot; - -import java.io.*; -import java.lang.annotation.Annotation; -import java.lang.reflect.*; -import java.net.InetSocketAddress; -import java.nio.file.Path; -import java.util.*; -import java.util.concurrent.CopyOnWriteArrayList; -import java.util.function.Consumer; -import java.util.logging.*; -import java.util.stream.Collectors; -import javax.annotation.Resource; -import javax.persistence.Transient; -import static org.redkale.boot.Application.*; -import org.redkale.boot.ClassFilter.FilterEntry; -import org.redkale.net.*; -import org.redkale.net.sncp.*; -import org.redkale.service.*; -import org.redkale.source.*; -import org.redkale.util.AnyValue.DefaultAnyValue; -import org.redkale.util.*; - -/** - * - *

- * 详情见: http://www.redkale.org - * - * @author zhangjx - */ -@SuppressWarnings("unchecked") -public abstract class NodeServer { - - //INFO日志的换行符 - public static final String LINE_SEPARATOR = "\r\n"; - - //日志输出对象 - protected final Logger logger; - - //日志是否为FINE级别 - protected final boolean fine; - - //日志是否为FINE级别 - protected final boolean finer; - - //进程主类 - protected final Application application; - - //依赖注入工厂类 - protected final ResourceFactory resourceFactory; - - //当前Server对象 - protected final Server server; - - private String sncpGroup = null; //当前Server的SNCP协议的组 - - private InetSocketAddress sncpAddress; //SNCP服务的地址, 非SNCP为null - - protected Consumer consumer; - - protected AnyValue serverConf; - - protected final Set localServiceWrappers = new LinkedHashSet<>(); - - protected final Set remoteServiceWrappers = new LinkedHashSet<>(); - - public NodeServer(Application application, Server server) { - this.application = application; - this.resourceFactory = application.getResourceFactory().createChild(); - this.server = server; - this.logger = Logger.getLogger(this.getClass().getSimpleName()); - this.fine = logger.isLoggable(Level.FINE); - this.finer = logger.isLoggable(Level.FINER); - } - - protected Consumer getExecutor() throws Exception { - if (server == null) return null; - final Field field = Server.class.getDeclaredField("context"); - field.setAccessible(true); - return new Consumer() { - - private Context context; - - @Override - public void accept(Runnable t) { - if (context == null && server != null) { - try { - this.context = (Context) field.get(server); - } catch (Exception e) { - logger.log(Level.SEVERE, "Server (" + server.getSocketAddress() + ") cannot find Context", e); - } - } - context.submit(t); - } - - }; - } - - public static NodeServer create(Class clazz, Application application, AnyValue serconf) { - try { - return clazz.getConstructor(Application.class, AnyValue.class).newInstance(application, serconf); - } catch (Exception e) { - throw new RuntimeException(e); - } - } - - public void init(AnyValue config) throws Exception { - this.serverConf = config == null ? AnyValue.create() : config; - if (isSNCP()) { // SNCP协议 - String host = this.serverConf.getValue("host", "0.0.0.0").replace("0.0.0.0", ""); - this.sncpAddress = new InetSocketAddress(host.isEmpty() ? application.localAddress.getHostAddress() : host, this.serverConf.getIntValue("port")); - this.sncpGroup = application.globalNodes.get(this.sncpAddress); - //单向SNCP服务不需要对等group - //if (this.sncpGroup == null) throw new RuntimeException("Server (" + String.valueOf(config).replaceAll("\\s+", " ") + ") not found info"); - } - - if (this.sncpAddress != null) this.resourceFactory.register(RESNAME_SERVER_ADDR, this.sncpAddress); //单点服务不会有 sncpAddress、sncpGroup - if (this.sncpGroup != null) this.resourceFactory.register(RESNAME_SERVER_GROUP, this.sncpGroup); - { - //设置root文件夹 - String webroot = config.getValue("root", "root"); - File myroot = new File(webroot); - if (!webroot.contains(":") && !webroot.startsWith("/")) { - myroot = new File(System.getProperty(Application.RESNAME_APP_HOME), webroot); - } - - resourceFactory.register(Server.RESNAME_SERVER_ROOT, String.class, myroot.getCanonicalPath()); - resourceFactory.register(Server.RESNAME_SERVER_ROOT, File.class, myroot.getCanonicalFile()); - resourceFactory.register(Server.RESNAME_SERVER_ROOT, Path.class, myroot.toPath()); - - final String homepath = myroot.getCanonicalPath(); - Server.loadLib(logger, config.getValue("lib", "").replace("${APP_HOME}", homepath) + ";" + homepath + "/lib/*;" + homepath + "/classes"); - if (server != null) server.init(config); - } - - initResource(); //给 DataSource、CacheSource 注册依赖注入时的监听回调事件。 - - ClassFilter servletFilter = createServletClassFilter(); - ClassFilter serviceFilter = createServiceClassFilter(); - long s = System.currentTimeMillis(); - if (servletFilter == null) { - ClassFilter.Loader.load(application.getHome(), serviceFilter); - } else { - ClassFilter.Loader.load(application.getHome(), serviceFilter, servletFilter); - } - long e = System.currentTimeMillis() - s; - logger.info(this.getClass().getSimpleName() + " load filter class in " + e + " ms"); - loadService(serviceFilter); //必须在servlet之前 - loadServlet(servletFilter); - } - - protected abstract void loadServlet(ClassFilter servletFilter) throws Exception; - - private void initResource() { - final NodeServer self = this; - //--------------------------------------------------------------------------------------------- - final ResourceFactory appResFactory = application.getResourceFactory(); - resourceFactory.add(DataSource.class, (ResourceFactory rf, final Object src, String resourceName, Field field, final Object attachment) -> { - try { - if (field.getAnnotation(Resource.class) == null) return; - if ((src instanceof Service) && Sncp.isRemote((Service) src)) return; //远程模式不得注入 DataSource - DataSource source = new DataDefaultSource(resourceName); - application.dataSources.add(source); - appResFactory.register(resourceName, DataSource.class, source); - - SncpClient client = null; - Transport sameGroupTransport = null; - List diffGroupTransports = null; - try { - Field ts = src.getClass().getDeclaredField("_sameGroupTransport"); - ts.setAccessible(true); - sameGroupTransport = (Transport) ts.get(src); - - ts = src.getClass().getDeclaredField("_diffGroupTransports"); - ts.setAccessible(true); - diffGroupTransports = Arrays.asList((Transport[]) ts.get(src)); - - ts = src.getClass().getDeclaredField("_client"); - ts.setAccessible(true); - client = (SncpClient) ts.get(src); - } catch (Exception e) { - throw new RuntimeException(src.getClass().getName() + " not found _sameGroupTransport or _diffGroupTransports at " + field, e); - } - final InetSocketAddress sncpAddr = client == null ? null : client.getClientAddress(); - if ((src instanceof DataSource) && sncpAddr != null && resourceFactory.find(resourceName, DataCacheListener.class) == null) { //只有DataSourceService 才能赋值 DataCacheListener - Service cacheListenerService = Sncp.createLocalService(resourceName, getExecutor(), appResFactory, DataCacheListenerService.class, sncpAddr, sameGroupTransport, diffGroupTransports); - appResFactory.register(resourceName, DataCacheListener.class, cacheListenerService); - final NodeSncpServer sncpServer = application.findNodeSncpServer(sncpAddr); - Set gs = application.findSncpGroups(sameGroupTransport, diffGroupTransports); - ServiceWrapper wrapper = new ServiceWrapper(DataCacheListenerService.class, cacheListenerService, resourceName, sncpServer.getSncpGroup(), gs, null); - localServiceWrappers.add(wrapper); - sncpServer.consumerAccept(wrapper); - rf.inject(cacheListenerService, self); - if (fine) logger.fine("[" + Thread.currentThread().getName() + "] Load Service " + wrapper.getService()); - } - field.set(src, source); - rf.inject(source, self); // 给 "datasource.nodeid" 赋值; - } catch (Exception e) { - logger.log(Level.SEVERE, "DataSource inject error", e); - } - }); - resourceFactory.add(CacheSource.class, (ResourceFactory rf, final Object src, final String resourceName, Field field, final Object attachment) -> { - try { - if (field.getAnnotation(Resource.class) == null) return; - if ((src instanceof Service) && Sncp.isRemote((Service) src)) return; //远程模式不得注入 CacheSource - - SncpClient client = null; - Transport sameGroupTransport = null; - List diffGroupTransports = null; - try { - Field ts = src.getClass().getDeclaredField("_sameGroupTransport"); - ts.setAccessible(true); - sameGroupTransport = (Transport) ts.get(src); - - ts = src.getClass().getDeclaredField("_diffGroupTransports"); - ts.setAccessible(true); - Transport[] dts = (Transport[]) ts.get(src); - if (dts != null) diffGroupTransports = Arrays.asList(dts); - - ts = src.getClass().getDeclaredField("_client"); - ts.setAccessible(true); - client = (SncpClient) ts.get(src); - } catch (Exception e) { - throw new RuntimeException(src.getClass().getName() + " not found _sameGroupTransport or _diffGroupTransports at " + field, e); - } - final InetSocketAddress sncpAddr = client == null ? null : client.getClientAddress(); - final CacheSourceService source = Sncp.createLocalService(resourceName, getExecutor(), appResFactory, CacheSourceService.class, sncpAddr, sameGroupTransport, diffGroupTransports); - Type genericType = field.getGenericType(); - ParameterizedType pt = (genericType instanceof ParameterizedType) ? (ParameterizedType) genericType : null; - Type valType = pt == null ? null : pt.getActualTypeArguments()[1]; - source.setStoreType(pt == null ? Serializable.class : (Class) pt.getActualTypeArguments()[0], valType instanceof Class ? (Class) valType : Object.class); - if (field.getAnnotation(Transient.class) != null) source.setNeedStore(false); //必须在setStoreType之后 - application.cacheSources.add(source); - appResFactory.register(resourceName, CacheSource.class, source); - field.set(src, source); - rf.inject(source, self); // - ((Service) source).init(null); - - if ((src instanceof WebSocketNodeService) && sncpAddr != null) { //只有WebSocketNodeService的服务才需要给SNCP服务注入CacheSourceService - NodeSncpServer sncpServer = application.findNodeSncpServer(sncpAddr); - Set gs = application.findSncpGroups(sameGroupTransport, diffGroupTransports); - ServiceWrapper wrapper = new ServiceWrapper(CacheSourceService.class, (Service) source, resourceName, sncpServer.getSncpGroup(), gs, null); - sncpServer.getSncpServer().addService(wrapper); - if (finer) logger.finer("[" + Thread.currentThread().getName() + "] Load Service " + wrapper.getService()); - } - logger.finer("[" + Thread.currentThread().getName() + "] Load Source " + source); - } catch (Exception e) { - logger.log(Level.SEVERE, "DataSource inject error", e); - } - }); - } - - @SuppressWarnings("unchecked") - protected void loadService(ClassFilter serviceFilter) throws Exception { - if (serviceFilter == null) return; - final String threadName = "[" + Thread.currentThread().getName() + "] "; - final Set> entrys = serviceFilter.getFilterEntrys(); - ResourceFactory regFactory = isSNCP() ? application.getResourceFactory() : resourceFactory; - - for (FilterEntry entry : entrys) { //service实现类 - final Class type = entry.getType(); - if (Modifier.isFinal(type.getModifiers())) continue; //修饰final的类跳过 - if (!Modifier.isPublic(type.getModifiers())) continue; - if (entry.getName().contains("$")) throw new RuntimeException(" value cannot contains '$' in " + entry.getProperty()); - if (resourceFactory.find(entry.getName(), type) != null) continue; //Server加载Service时需要判断是否已经加载过了。 - final HashSet groups = entry.getGroups(); //groups.isEmpty()表示没有配置groups属性。 - if (groups.isEmpty() && isSNCP() && this.sncpGroup != null) groups.add(this.sncpGroup); - - final boolean localed = (this.sncpAddress == null && entry.isEmptyGroups() && !type.isInterface() && !Modifier.isAbstract(type.getModifiers())) //非SNCP的Server,通常是单点服务 - || groups.contains(this.sncpGroup) //本地IP含在内的 - || (this.sncpGroup == null && entry.isEmptyGroups()) //空的SNCP配置 - || type.getAnnotation(LocalService.class) != null;//本地模式 - if (localed && (type.isInterface() || Modifier.isAbstract(type.getModifiers()))) continue; //本地模式不能实例化接口和抽象类的Service类 - - Service service; - if (localed) { //本地模式 - service = Sncp.createLocalService(entry.getName(), getExecutor(), application.getResourceFactory(), type, this.sncpAddress, loadTransport(this.sncpGroup), loadTransports(groups)); - } else { - service = Sncp.createRemoteService(entry.getName(), getExecutor(), type, this.sncpAddress, loadTransport(groups)); - } - if(SncpClient.parseMethod(type).isEmpty()) continue; //class没有可用的方法, 通常为BaseService - final ServiceWrapper wrapper = new ServiceWrapper(type, service, entry.getName(), localed ? this.sncpGroup : null, groups, entry.getProperty()); - for (final Class restype : wrapper.getTypes()) { - if (resourceFactory.find(wrapper.getName(), restype) == null) { - regFactory.register(wrapper.getName(), restype, wrapper.getService()); - } else if (isSNCP() && !entry.isAutoload()) { - throw new RuntimeException(ServiceWrapper.class.getSimpleName() + "(class:" + type.getName() + ", name:" + entry.getName() + ", group:" + groups + ") is repeat."); - } - } - if (wrapper.isRemote()) { - remoteServiceWrappers.add(wrapper); - } else { - localServiceWrappers.add(wrapper); - if (consumer != null) consumer.accept(wrapper); - } - } - application.servicecdl.countDown(); - application.servicecdl.await(); - - final StringBuilder sb = logger.isLoggable(Level.INFO) ? new StringBuilder() : null; - //---------------- inject ---------------- - new ArrayList<>(localServiceWrappers).forEach(y -> { - resourceFactory.inject(y.getService(), NodeServer.this); - }); - remoteServiceWrappers.forEach(y -> { - resourceFactory.inject(y.getService(), NodeServer.this); - if (sb != null) { - sb.append(threadName).append(y.toSimpleString()).append(" loaded and injected").append(LINE_SEPARATOR); - } - }); - //----------------- init ----------------- - List swlist = new ArrayList<>(localServiceWrappers); - Collections.sort(swlist); - localServiceWrappers.clear(); - localServiceWrappers.addAll(swlist); - final List slist = sb == null ? null : new CopyOnWriteArrayList<>(); - localServiceWrappers.parallelStream().forEach(y -> { - long s = System.currentTimeMillis(); - y.getService().init(y.getConf()); - long e = System.currentTimeMillis() - s; - if (slist != null) slist.add(new StringBuilder().append(threadName).append(y.toSimpleString()).append(" loaded and init ").append(e).append(" ms").append(LINE_SEPARATOR).toString()); - }); - Collections.sort(slist); - if (slist != null && sb != null) { - for (String s : slist) { - sb.append(s); - } - } - if (sb != null && sb.length() > 0) logger.log(Level.INFO, sb.toString()); - } - - protected List loadTransports(final HashSet groups) { - if (groups == null) return null; - final List transports = new ArrayList<>(); - for (String group : groups) { - if (this.sncpGroup == null || !this.sncpGroup.equals(group)) { - transports.add(loadTransport(group)); - } - } - return transports; - } - - protected Transport loadTransport(final HashSet groups) { - if (groups == null || groups.isEmpty()) return null; - List tmpgroup = new ArrayList<>(groups); - Collections.sort(tmpgroup); //按字母排列顺序 - final String groupid = tmpgroup.stream().collect(Collectors.joining(";")); - Transport transport = application.resourceFactory.find(groupid, Transport.class); - if (transport != null) return transport; - final List transports = new ArrayList<>(); - for (String group : groups) { - transports.add(loadTransport(group)); - } - Set addrs = new HashSet(); - transports.forEach(t -> addrs.addAll(Arrays.asList(t.getRemoteAddresses()))); - Transport first = transports.get(0); - Transport newTransport = new Transport(groupid, application.findGroupProtocol(first.getName()), application.getWatchFactory(), - application.transportBufferPool, application.transportChannelGroup, this.sncpAddress, addrs); - synchronized (application.resourceFactory) { - transport = application.resourceFactory.find(groupid, Transport.class); - if (transport == null) { - transport = newTransport; - application.resourceFactory.register(groupid, transport); - } - } - return transport; - } - - protected Transport loadTransport(final String group) { - if (group == null) return null; - Transport transport; - synchronized (application.resourceFactory) { - transport = application.resourceFactory.find(group, Transport.class); - if (transport != null) { - if (this.sncpAddress != null && !this.sncpAddress.equals(transport.getClientAddress())) { - throw new RuntimeException(transport + "repeat create on newClientAddress = " + this.sncpAddress + ", oldClientAddress = " + transport.getClientAddress()); - } - return transport; - } - Set addrs = application.findGlobalGroup(group); - if (addrs == null) throw new RuntimeException("Not found = " + group + " on "); - transport = new Transport(group, application.findGroupProtocol(group), application.getWatchFactory(), - application.transportBufferPool, application.transportChannelGroup, this.sncpAddress, addrs); - application.resourceFactory.register(group, transport); - } - return transport; - } - - protected abstract ClassFilter createServletClassFilter(); - - protected ClassFilter createServiceClassFilter() { - return createClassFilter(this.sncpGroup, null, Service.class, Annotation.class, "services", "service"); - } - - protected ClassFilter createClassFilter(final String localGroup, Class ref, - Class inter, Class ref2, String properties, String property) { - ClassFilter cf = new ClassFilter(ref, inter, null); - if (properties == null && properties == null) return cf; - if (this.serverConf == null) return cf; - AnyValue[] proplist = this.serverConf.getAnyValues(properties); - if (proplist == null || proplist.length < 1) return cf; - cf = null; - for (AnyValue list : proplist) { - DefaultAnyValue prop = null; - String sc = list.getValue("groups"); - if (sc != null) { - sc = sc.trim(); - if (sc.endsWith(";")) sc = sc.substring(0, sc.length() - 1); - } - if (sc == null) sc = localGroup; - if (sc != null) { - prop = new AnyValue.DefaultAnyValue(); - prop.addValue("groups", sc); - } - ClassFilter filter = new ClassFilter(ref, inter, prop); - for (AnyValue av : list.getAnyValues(property)) { - final AnyValue[] items = av.getAnyValues("property"); - if (av instanceof DefaultAnyValue && items.length > 0) { - DefaultAnyValue dav = DefaultAnyValue.create(); - final AnyValue.Entry[] strings = av.getStringEntrys(); - if (strings != null) { - for (AnyValue.Entry en : strings) { - dav.addValue(en.name, en.getValue()); - } - } - final AnyValue.Entry[] anys = av.getAnyEntrys(); - if (anys != null) { - for (AnyValue.Entry en : anys) { - if (!"property".equals(en.name)) dav.addValue(en.name, en.getValue()); - } - } - DefaultAnyValue ps = DefaultAnyValue.create(); - for (AnyValue item : items) { - ps.addValue(item.getValue("name"), item.getValue("value")); - } - dav.addValue("property", ps); - av = dav; - } - filter.filter(av, av.getValue("value"), false); - } - if (list.getBoolValue("autoload", true)) { - String includes = list.getValue("includes", ""); - String excludes = list.getValue("excludes", ""); - filter.setIncludePatterns(includes.split(";")); - filter.setExcludePatterns(excludes.split(";")); - } else if (ref2 == null || ref2 == Annotation.class) { //service如果是autoload=false则不需要加载 - filter.setRefused(true); - } else if (ref2 != Annotation.class) { - filter.setAnnotationClass(ref2); - } - cf = (cf == null) ? filter : cf.or(filter); - } - return cf; - } - - public abstract InetSocketAddress getSocketAddress(); - - public boolean isSNCP() { - return false; - } - - public InetSocketAddress getSncpAddress() { - return sncpAddress; - } - - public String getSncpGroup() { - return sncpGroup; - } - - public void start() throws IOException { - server.start(); - } - - public void shutdown() throws IOException { - final StringBuilder sb = logger.isLoggable(Level.INFO) ? new StringBuilder() : null; - localServiceWrappers.forEach(y -> { - long s = System.currentTimeMillis(); - y.getService().destroy(y.getConf()); - long e = System.currentTimeMillis() - s; - if (e > 2 && sb != null) { - sb.append(y.toSimpleString()).append(" destroy ").append(e).append("ms").append(LINE_SEPARATOR); - } - }); - if (sb != null && sb.length() > 0) logger.log(Level.INFO, sb.toString()); - server.shutdown(); - } - -} diff --git a/src/main/java/org/redkale/boot/NodeSncpServer.java b/src/main/java/org/redkale/boot/NodeSncpServer.java deleted file mode 100644 index 538f3394e..000000000 --- a/src/main/java/org/redkale/boot/NodeSncpServer.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * 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.boot; - -import java.net.*; -import java.util.*; -import java.util.logging.*; -import org.redkale.net.*; -import org.redkale.net.sncp.*; -import org.redkale.util.*; - -/** - * - *

- * 详情见: http://www.redkale.org - * - * @author zhangjx - */ -@NodeProtocol({"SNCP"}) -public final class NodeSncpServer extends NodeServer { - - private final SncpServer sncpServer; - - public NodeSncpServer(Application application, AnyValue serconf) { - super(application, createServer(application, serconf)); - this.sncpServer = (SncpServer) this.server; - this.consumer = sncpServer == null ? null : x -> sncpServer.addService(x); - } - - private static Server createServer(Application application, AnyValue serconf) { - return new SncpServer(application.getStartTime(), application.getWatchFactory()); - } - - @Override - public InetSocketAddress getSocketAddress() { - return sncpServer == null ? null : sncpServer.getSocketAddress(); - } - - public void consumerAccept(ServiceWrapper wrapper) { - if (this.consumer != null) this.consumer.accept(wrapper); - } - - @Override - public void init(AnyValue config) throws Exception { - super.init(config); - //------------------------------------------------------------------- - if (sncpServer == null) return; //调试时server才可能为null - final StringBuilder sb = logger.isLoggable(Level.FINE) ? new StringBuilder() : null; - final String threadName = "[" + Thread.currentThread().getName() + "] "; - List servlets = sncpServer.getSncpServlets(); - Collections.sort(servlets); - for (SncpServlet en : servlets) { - if (sb != null) sb.append(threadName).append(" Loaded ").append(en).append(LINE_SEPARATOR); - } - if (sb != null && sb.length() > 0) logger.log(Level.FINE, sb.toString()); - } - - @Override - public boolean isSNCP() { - return true; - } - - public SncpServer getSncpServer() { - return sncpServer; - } - - @Override - protected void loadServlet(ClassFilter servletFilter) throws Exception { - } - - @Override - protected ClassFilter createServletClassFilter() { - return null; - } - -} diff --git a/src/main/java/org/redkale/boot/package-info.java b/src/main/java/org/redkale/boot/package-info.java deleted file mode 100644 index 569d4b0ee..000000000 --- a/src/main/java/org/redkale/boot/package-info.java +++ /dev/null @@ -1,4 +0,0 @@ -/** - * 提供RedKale服务器的启动、初始化和加载功能 - */ -package org.redkale.boot; diff --git a/src/main/java/org/redkale/convert/AnyEncoder.java b/src/main/java/org/redkale/convert/AnyEncoder.java deleted file mode 100644 index 9a2ff74fb..000000000 --- a/src/main/java/org/redkale/convert/AnyEncoder.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * 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.lang.reflect.Type; - -/** - * 对不明类型的对象进行序列化; BSON序列化时将对象的类名写入Writer,JSON则不写入。 - * - *

详情见: http://www.redkale.org - * @author zhangjx - * @param 序列化的泛型类型 - */ -public final class AnyEncoder implements Encodeable { - - final ConvertFactory factory; - - AnyEncoder(ConvertFactory factory) { - this.factory = factory; - } - - @Override - @SuppressWarnings("unchecked") - public void convertTo(final Writer out, final T value) { - if (value == null) { - out.wirteClassName(null); - out.writeNull(); - } else { - out.wirteClassName(factory.getEntity(value.getClass())); - factory.loadEncoder(value.getClass()).convertTo(out, value); - } - } - - @Override - public Type getType() { - return Object.class; - } - -} diff --git a/src/main/java/org/redkale/convert/ArrayDecoder.java b/src/main/java/org/redkale/convert/ArrayDecoder.java deleted file mode 100644 index 3aa1c5e31..000000000 --- a/src/main/java/org/redkale/convert/ArrayDecoder.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * 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.lang.reflect.*; -import java.util.*; - -/** - * 对象数组的序列化,不包含int[]、long[]这样的primitive class数组. - * 数组长度不能超过 32767。 在BSON中数组长度设定的是short,对于大于32767长度的数组传输会影响性能,所以没有采用int存储。 - * 支持一定程度的泛型。 - * - *

- * 详情见: http://www.redkale.org - * - * @author zhangjx - * @param 反解析的数组元素类型 - */ -@SuppressWarnings("unchecked") -public final class ArrayDecoder implements Decodeable { - - private final Type type; - - private final Type componentType; - - private final Class componentClass; - - private final Decodeable decoder; - - public ArrayDecoder(final ConvertFactory factory, final Type type) { - this.type = type; - if (type instanceof GenericArrayType) { - Type t = ((GenericArrayType) type).getGenericComponentType(); - this.componentType = t instanceof TypeVariable ? Object.class : t; - } else if ((type instanceof Class) && ((Class) type).isArray()) { - this.componentType = ((Class) type).getComponentType(); - } else { - throw new ConvertException("(" + type + ") is not a array type"); - } - if (this.componentType instanceof ParameterizedType) { - this.componentClass = (Class) ((ParameterizedType) this.componentType).getRawType(); - } else { - this.componentClass = (Class) this.componentType; - } - factory.register(type, this); - this.decoder = factory.loadDecoder(this.componentType); - } - - @Override - public T[] convertFrom(Reader in) { - final int len = in.readArrayB(); - if (len == Reader.SIGN_NULL) return null; - final Decodeable localdecoder = this.decoder; - final List result = new ArrayList(); - if (len == Reader.SIGN_NOLENGTH) { - while (in.hasNext()) { - result.add(localdecoder.convertFrom(in)); - } - } else { - for (int i = 0; i < len; i++) { - result.add(localdecoder.convertFrom(in)); - } - } - in.readArrayE(); - T[] rs = (T[]) Array.newInstance((Class) this.componentClass, result.size()); - return result.toArray(rs); - } - - @Override - public String toString() { - return this.getClass().getSimpleName() + "{componentType:" + this.componentType + ", decoder:" + this.decoder + "}"; - } - - @Override - public Type getType() { - return type; - } - -} diff --git a/src/main/java/org/redkale/convert/ArrayEncoder.java b/src/main/java/org/redkale/convert/ArrayEncoder.java deleted file mode 100644 index 1cc5c4b18..000000000 --- a/src/main/java/org/redkale/convert/ArrayEncoder.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * 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.lang.reflect.*; - -/** - * 对象数组的反序列化,不包含int[]、long[]这样的primitive class数组. - * 数组长度不能超过 32767。 在BSON中数组长度设定的是short,对于大于32767长度的数组传输会影响性能,所以没有必要采用int存储。 - * 支持一定程度的泛型。 - * - *

- * 详情见: http://www.redkale.org - * - * @author zhangjx - * @param 序列化的数组元素类型 - */ -@SuppressWarnings("unchecked") -public final class ArrayEncoder implements Encodeable { - - private final Type type; - - private final Type componentType; - - private final Encodeable anyEncoder; - - private final Encodeable encoder; - - public ArrayEncoder(final ConvertFactory factory, final Type type) { - this.type = type; - if (type instanceof GenericArrayType) { - Type t = ((GenericArrayType) type).getGenericComponentType(); - this.componentType = t instanceof TypeVariable ? Object.class : t; - } else if ((type instanceof Class) && ((Class) type).isArray()) { - this.componentType = ((Class) type).getComponentType(); - } else { - throw new ConvertException("(" + type + ") is not a array type"); - } - factory.register(type, this); - this.encoder = factory.loadEncoder(this.componentType); - this.anyEncoder = factory.getAnyEncoder(); - } - - @Override - public void convertTo(Writer out, T[] value) { - if (value == null) { - out.writeNull(); - return; - } - if (value.length == 0) { - out.writeArrayB(0); - out.writeArrayE(); - return; - } - out.writeArrayB(value.length); - final Type comp = this.componentType; - boolean first = true; - for (Object v : value) { - if (!first) out.writeArrayMark(); - ((v != null && v.getClass() == comp) ? encoder : anyEncoder).convertTo(out, v); - if (first) first = false; - } - out.writeArrayE(); - } - - @Override - public String toString() { - return this.getClass().getSimpleName() + "{componentType:" + this.componentType + ", encoder:" + this.encoder + "}"; - } - - @Override - public Type getType() { - return type; - } -} diff --git a/src/main/java/org/redkale/convert/CollectionDecoder.java b/src/main/java/org/redkale/convert/CollectionDecoder.java deleted file mode 100644 index 8c9ed24b8..000000000 --- a/src/main/java/org/redkale/convert/CollectionDecoder.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * 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 org.redkale.util.Creator; -import java.lang.reflect.ParameterizedType; -import java.lang.reflect.Type; -import java.util.Collection; - -/** - * 对象集合的反序列化. - * 集合大小不能超过 32767。 在BSON中集合大小设定的是short,对于大于32767长度的集合传输会影响性能,所以没有采用int存储。 - * 支持一定程度的泛型。 - * - *

- * 详情见: http://www.redkale.org - * - * @author zhangjx - * @param 反解析的集合元素类型 - */ -@SuppressWarnings("unchecked") -public final class CollectionDecoder implements Decodeable> { - - private final Type type; - - private final Type componentType; - - protected Creator> creator; - - private final Decodeable decoder; - - public CollectionDecoder(final ConvertFactory factory, final Type type) { - this.type = type; - if (type instanceof ParameterizedType) { - final ParameterizedType pt = (ParameterizedType) type; - this.componentType = pt.getActualTypeArguments()[0]; - this.creator = factory.loadCreator((Class) pt.getRawType()); - factory.register(type, this); - this.decoder = factory.loadDecoder(this.componentType); - } else { - throw new ConvertException("collectiondecoder not support the type (" + type + ")"); - } - } - - @Override - public Collection convertFrom(Reader in) { - final int len = in.readArrayB(); - if (len == Reader.SIGN_NULL) return null; - final Decodeable localdecoder = this.decoder; - final Collection result = this.creator.create(); - if (len == Reader.SIGN_NOLENGTH) { - while (in.hasNext()) { - result.add(localdecoder.convertFrom(in)); - } - } else { - for (int i = 0; i < len; i++) { - result.add(localdecoder.convertFrom(in)); - } - } - in.readArrayE(); - return result; - } - - @Override - public Type getType() { - return type; - } - -} diff --git a/src/main/java/org/redkale/convert/CollectionEncoder.java b/src/main/java/org/redkale/convert/CollectionEncoder.java deleted file mode 100644 index ebf3b211b..000000000 --- a/src/main/java/org/redkale/convert/CollectionEncoder.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * 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.lang.reflect.*; -import java.util.Collection; - -/** - * 对象集合的序列化. - * 集合大小不能超过 32767。 在BSON中集合大小设定的是short,对于大于32767长度的集合传输会影响性能,所以没有采用int存储。 - * 支持一定程度的泛型。 - * - *

详情见: http://www.redkale.org - * @author zhangjx - * @param 序列化的集合元素类型 - */ -@SuppressWarnings("unchecked") -public final class CollectionEncoder implements Encodeable> { - - private final Type type; - - private final Encodeable encoder; - - public CollectionEncoder(final ConvertFactory factory, final Type type) { - this.type = type; - if (type instanceof ParameterizedType) { - Type t = ((ParameterizedType) type).getActualTypeArguments()[0]; - if (t instanceof TypeVariable) { - this.encoder = factory.getAnyEncoder(); - } else { - this.encoder = factory.loadEncoder(t); - } - } else { - this.encoder = factory.getAnyEncoder(); - } - } - - @Override - public void convertTo(Writer out, Collection value) { - if (value == null) { - out.writeNull(); - return; - } - if (value.isEmpty()) { - out.writeArrayB(0); - out.writeArrayE(); - return; - } - out.writeArrayB(value.size()); - boolean first = true; - for (Object v : value) { - if (!first) out.writeArrayMark(); - encoder.convertTo(out, v); - if (first) first = false; - } - out.writeArrayE(); - } - - @Override - public Type getType() { - return type; - } -} diff --git a/src/main/java/org/redkale/convert/Convert.java b/src/main/java/org/redkale/convert/Convert.java deleted file mode 100644 index 19b7ab5bf..000000000 --- a/src/main/java/org/redkale/convert/Convert.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * 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; - -/** - * 序列化操作类 - * - *

- * 详情见: http://www.redkale.org - * - * @author zhangjx - * @param Reader输入的子类 - * @param Writer输出的子类 - */ -public abstract class Convert { - - protected final ConvertFactory factory; - - protected Convert(ConvertFactory factory) { - this.factory = factory; - } - - public ConvertFactory getFactory() { - return this.factory; - } -} diff --git a/src/main/java/org/redkale/convert/ConvertColumn.java b/src/main/java/org/redkale/convert/ConvertColumn.java deleted file mode 100644 index 53d91f62c..000000000 --- a/src/main/java/org/redkale/convert/ConvertColumn.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * 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.lang.annotation.*; -import static java.lang.annotation.ElementType.*; -import static java.lang.annotation.RetentionPolicy.*; - -/** - * 依附在setter、getter方法、字段进行简单的配置 - * - *

- * 详情见: http://www.redkale.org - * - * @author zhangjx - */ -@Inherited -@Documented -@Target({METHOD, FIELD}) -@Retention(RUNTIME) -@Repeatable(ConvertColumns.class) -public @interface ConvertColumn { - - /** - * 给字段取个别名 - * - * @return 字段别名 - */ - String name() default ""; - - /** - * 解析/序列化时是否屏蔽该字段 - * - * @return 是否屏蔽该字段 - */ - boolean ignore() default false; - - /** - * 解析/序列化定制化的TYPE - * - * @return JSON or BSON or ALL - */ - ConvertType type() default ConvertType.ALL; -} diff --git a/src/main/java/org/redkale/convert/ConvertColumnEntry.java b/src/main/java/org/redkale/convert/ConvertColumnEntry.java deleted file mode 100644 index a4e341481..000000000 --- a/src/main/java/org/redkale/convert/ConvertColumnEntry.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * 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; - -/** - * ConvertColumn 对应的实体类 - * - *

详情见: http://www.redkale.org - * @author zhangjx - */ -public final class ConvertColumnEntry { - - private String name = ""; - - private boolean ignore; - - private ConvertType convertType; - - public ConvertColumnEntry() { - } - - public ConvertColumnEntry(ConvertColumn column) { - if (column == null) return; - this.name = column.name(); - this.ignore = column.ignore(); - this.convertType = column.type(); - } - - public ConvertColumnEntry(String name, boolean ignore) { - this.name = name; - this.ignore = ignore; - this.convertType = ConvertType.ALL; - } - - public ConvertColumnEntry(String name, boolean ignore, ConvertType convertType) { - this.name = name; - this.ignore = ignore; - this.convertType = convertType; - } - - public String name() { - return name == null ? "" : name; - } - - public void setName(String name) { - this.name = name; - } - - public boolean ignore() { - return ignore; - } - - public void setIgnore(boolean ignore) { - this.ignore = ignore; - } - - public ConvertType type() { - return convertType == null ? ConvertType.ALL : convertType; - } - - public void setConvertType(ConvertType convertType) { - this.convertType = convertType; - } - -} diff --git a/src/main/java/org/redkale/convert/ConvertColumns.java b/src/main/java/org/redkale/convert/ConvertColumns.java deleted file mode 100644 index 4173069a4..000000000 --- a/src/main/java/org/redkale/convert/ConvertColumns.java +++ /dev/null @@ -1,25 +0,0 @@ -/* - * 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.lang.annotation.*; -import static java.lang.annotation.ElementType.*; -import static java.lang.annotation.RetentionPolicy.*; - -/** - * ConvertColumn 的多用类 - * - *

详情见: http://www.redkale.org - * @author zhangjx - */ -@Inherited -@Documented -@Target({METHOD, FIELD}) -@Retention(RUNTIME) -public @interface ConvertColumns { - - ConvertColumn[] value(); -} diff --git a/src/main/java/org/redkale/convert/ConvertEntity.java b/src/main/java/org/redkale/convert/ConvertEntity.java deleted file mode 100644 index 9adb71cd2..000000000 --- a/src/main/java/org/redkale/convert/ConvertEntity.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * 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.lang.annotation.*; -import static java.lang.annotation.ElementType.TYPE; -import static java.lang.annotation.RetentionPolicy.RUNTIME; - -/** - * 用于类名的别名, 类似javax.persistence.Table - * 该值必须是全局唯一 - * 使用场景: 当BSON序列化为了不指定class可以使用@ConvertEntity来取个别名。关联方法: Reader.readClassName() 和 Writer.wirteClassName(String value) 。 - * - *

详情见: http://www.redkale.org - * @author zhangjx - */ -@Inherited -@Documented -@Target({TYPE}) -@Retention(RUNTIME) -public @interface ConvertEntity { - - String value(); -} diff --git a/src/main/java/org/redkale/convert/ConvertException.java b/src/main/java/org/redkale/convert/ConvertException.java deleted file mode 100644 index 7898ad319..000000000 --- a/src/main/java/org/redkale/convert/ConvertException.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * To change this template, choose Tools | Templates - * and open the template in the editor. - */ -package org.redkale.convert; - -/** - * - *

详情见: http://www.redkale.org - * @author zhangjx - */ -public class ConvertException extends RuntimeException { - - public ConvertException() { - super(); - } - - public ConvertException(String s) { - super(s); - } - - public ConvertException(String message, Throwable cause) { - super(message, cause); - } - - public ConvertException(Throwable cause) { - super(cause); - } -} diff --git a/src/main/java/org/redkale/convert/ConvertFactory.java b/src/main/java/org/redkale/convert/ConvertFactory.java deleted file mode 100644 index a9a568db2..000000000 --- a/src/main/java/org/redkale/convert/ConvertFactory.java +++ /dev/null @@ -1,486 +0,0 @@ -/* - * 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.lang.reflect.Type; -import java.util.Collection; -import java.util.Map; -import java.lang.reflect.*; -import java.math.BigInteger; -import java.net.*; -import java.nio.channels.*; -import static org.redkale.convert.ext.InetAddressSimpledCoder.*; -import java.util.*; -import java.util.concurrent.*; -import java.util.regex.*; -import org.redkale.convert.ext.*; -import org.redkale.util.*; - -/** - * - *

- * 详情见: http://www.redkale.org - * - * @author zhangjx - * @param Reader输入的子类 - * @param Writer输出的子类 - */ -@SuppressWarnings("unchecked") -public abstract class ConvertFactory { - - private final ConvertFactory parent; - - protected Convert convert; - - protected boolean tiny; - - private final Encodeable anyEncoder = new AnyEncoder(this); - - //----------------------------------------------------------------------------------- - private final ConcurrentHashMap creators = new ConcurrentHashMap(); - - private final ConcurrentHashMap entitys = new ConcurrentHashMap(); - - private final ConcurrentHashMap> decoders = new ConcurrentHashMap(); - - private final ConcurrentHashMap> encoders = new ConcurrentHashMap(); - - private final ConcurrentHashMap columnEntrys = new ConcurrentHashMap(); - - private final Set skipIgnores = new HashSet(); - - private boolean skipAllIgnore = false; - - protected ConvertFactory(ConvertFactory parent, boolean tiny) { - this.tiny = tiny; - this.parent = parent; - if (parent == null) { - //--------------------------------------------------------- - this.register(boolean.class, BoolSimpledCoder.instance); - this.register(Boolean.class, BoolSimpledCoder.instance); - - this.register(byte.class, ByteSimpledCoder.instance); - this.register(Byte.class, ByteSimpledCoder.instance); - - this.register(short.class, ShortSimpledCoder.instance); - this.register(Short.class, ShortSimpledCoder.instance); - - this.register(char.class, CharSimpledCoder.instance); - this.register(Character.class, CharSimpledCoder.instance); - - this.register(int.class, IntSimpledCoder.instance); - this.register(Integer.class, IntSimpledCoder.instance); - - this.register(long.class, LongSimpledCoder.instance); - this.register(Long.class, LongSimpledCoder.instance); - - this.register(float.class, FloatSimpledCoder.instance); - this.register(Float.class, FloatSimpledCoder.instance); - - this.register(double.class, DoubleSimpledCoder.instance); - this.register(Double.class, DoubleSimpledCoder.instance); - - this.register(Number.class, NumberSimpledCoder.instance); - this.register(String.class, StringSimpledCoder.instance); - this.register(CharSequence.class, CharSequenceSimpledCoder.instance); - this.register(java.util.Date.class, DateSimpledCoder.instance); - this.register(BigInteger.class, BigIntegerSimpledCoder.instance); - this.register(InetAddress.class, InetAddressSimpledCoder.instance); - this.register(DLong.class, DLongSimpledCoder.instance); - this.register(Class.class, TypeSimpledCoder.instance); - this.register(InetSocketAddress.class, InetSocketAddressSimpledCoder.instance); - this.register(Pattern.class, PatternSimpledCoder.instance); - this.register(CompletionHandler.class, CompletionHandlerSimpledCoder.instance); - this.register(URL.class, URLSimpledCoder.instance); - this.register(URI.class, URISimpledCoder.instance); - //--------------------------------------------------------- - this.register(boolean[].class, BoolArraySimpledCoder.instance); - this.register(byte[].class, ByteArraySimpledCoder.instance); - this.register(short[].class, ShortArraySimpledCoder.instance); - this.register(char[].class, CharArraySimpledCoder.instance); - this.register(int[].class, IntArraySimpledCoder.instance); - this.register(long[].class, LongArraySimpledCoder.instance); - this.register(float[].class, FloatArraySimpledCoder.instance); - this.register(double[].class, DoubleArraySimpledCoder.instance); - this.register(String[].class, StringArraySimpledCoder.instance); - //--------------------------------------------------------- - } - } - - public ConvertFactory parent() { - return this.parent; - } - - public abstract ConvertType getConvertType(); - - public abstract boolean isReversible(); - - public abstract ConvertFactory createChild(); - - public abstract ConvertFactory createChild(boolean tiny); - - public Convert getConvert() { - return convert; - } - - public ConvertFactory tiny(boolean tiny) { - this.tiny = tiny; - return this; - } - - public ConvertColumnEntry findRef(AccessibleObject element) { - if (element == null) return null; - ConvertColumnEntry en = this.columnEntrys.get(element); - if (en != null) return en; - final ConvertType ct = this.getConvertType(); - ConvertColumn[] ccs = element.getAnnotationsByType(ConvertColumn.class); - if (ccs.length == 0 && element instanceof Method) { - final Method method = (Method) element; - String fieldName = readGetSetFieldName(method); - if (fieldName != null) { - try { - ccs = method.getDeclaringClass().getDeclaredField(fieldName).getAnnotationsByType(ConvertColumn.class); - } catch (Exception e) { //说明没有该字段,忽略异常 - } - } - } - for (ConvertColumn ref : ccs) { - if (ref.type().contains(ct)) { - ConvertColumnEntry entry = new ConvertColumnEntry(ref); - if (skipAllIgnore) { - entry.setIgnore(false); - return entry; - } - if (skipIgnores.isEmpty()) return entry; - if (skipIgnores.contains(((Member) element).getDeclaringClass())) entry.setIgnore(false); - return entry; - } - } - return null; - } - - static String readGetSetFieldName(Method method) { - if (method == null) return null; - String fname = method.getName(); - if (!fname.startsWith("is") && !fname.startsWith("get") && !fname.startsWith("set")) return fname; - fname = fname.substring(fname.startsWith("is") ? 2 : 3); - if (fname.length() > 1 && !(fname.charAt(1) >= 'A' && fname.charAt(1) <= 'Z')) { - fname = Character.toLowerCase(fname.charAt(0)) + fname.substring(1); - } else if (fname.length() == 1) { - fname = "" + Character.toLowerCase(fname.charAt(0)); - } - return fname; - } - - final String getEntity(Class clazz) { - ConvertEntity ce = (ConvertEntity) clazz.getAnnotation(ConvertEntity.class); - if (ce != null && findEntity(ce.value()) == null) entitys.put(ce.value(), clazz); - return ce == null ? clazz.getName() : ce.value(); - } - - private Class findEntity(String name) { - Class clazz = entitys.get(name); - return parent == null ? clazz : parent.findEntity(name); - } - - final Class getEntity(String name) { - Class clazz = findEntity(name); - try { - return clazz == null ? Class.forName(name) : clazz; - } catch (Exception ex) { - throw new ConvertException("convert entity is " + name, ex); - } - } - - /** - * 使所有类的所有被声明为ConvertColumn.ignore = true 的字段或方法变为ConvertColumn.ignore = false - * - * @param skipIgnore 是否忽略Ignore注解 - */ - public final void registerSkipAllIgnore(final boolean skipIgnore) { - this.skipAllIgnore = skipIgnore; - } - - /** - * 使该类所有被声明为ConvertColumn.ignore = true 的字段或方法变为ConvertColumn.ignore = false - * - * @param type 指定的类 - */ - public final void registerSkipIgnore(final Class type) { - skipIgnores.add(type); - } - - public final void register(final Class type, boolean ignore, String... columns) { - for (String column : columns) { - register(type, column, new ConvertColumnEntry(column, ignore)); - } - } - - public final boolean register(final Class type, String column, ConvertColumnEntry entry) { - if (type == null || column == null || entry == null) return false; - try { - final Field field = type.getDeclaredField(column); - String get = "get"; - if (field.getType() == boolean.class || field.getType() == Boolean.class) get = "is"; - char[] cols = column.toCharArray(); - cols[0] = Character.toUpperCase(cols[0]); - String col2 = new String(cols); - try { - register(type.getMethod(get + col2), entry); - } catch (Exception ex) { - } - try { - register(type.getMethod("set" + col2, field.getType()), entry); - } catch (Exception ex) { - } - return register(field, entry); - } catch (Exception e) { - return false; - } - } - - public final boolean register(final AccessibleObject field, final ConvertColumnEntry entry) { - if (field == null || entry == null) return false; - this.columnEntrys.put(field, entry); - return true; - } - - public final void reloadCoder(final Type type) { - this.register(type, this.createDecoder(type)); - this.register(type, this.createEncoder(type)); - } - - public final void reloadCoder(final Type type, final Class clazz) { - this.register(type, this.createDecoder(type, clazz)); - this.register(type, this.createEncoder(type, clazz)); - } - - public final void register(final Class clazz, final Creator creator) { - creators.put(clazz, creator); - } - - public final Creator findCreator(Class type) { - Creator creator = creators.get(type); - if (creator != null) return creator; - return this.parent == null ? null : this.parent.findCreator(type); - } - - public final Creator loadCreator(Class type) { - Creator result = findCreator(type); - if (result == null) { - result = Creator.create(type); - if (result != null) creators.put(type, result); - } - return result; - } - - //---------------------------------------------------------------------- - public final Encodeable getAnyEncoder() { - return (Encodeable) anyEncoder; - } - - public final void register(final Type clazz, final SimpledCoder coder) { - decoders.put(clazz, coder); - encoders.put(clazz, coder); - } - - public final void register(final Type clazz, final Decodeable decoder) { - decoders.put(clazz, decoder); - } - - public final void register(final Type clazz, final Encodeable printer) { - encoders.put(clazz, printer); - } - - public final Decodeable findDecoder(final Type type) { - Decodeable rs = (Decodeable) decoders.get(type); - if (rs != null) return rs; - return this.parent == null ? null : this.parent.findDecoder(type); - } - - public final Encodeable findEncoder(final Type type) { - Encodeable rs = (Encodeable) encoders.get(type); - if (rs != null) return rs; - return this.parent == null ? null : this.parent.findEncoder(type); - } - - public final Decodeable loadDecoder(final Type type) { - Decodeable decoder = findDecoder(type); - if (decoder != null) return decoder; - if (type instanceof GenericArrayType) return new ArrayDecoder(this, type); - Class clazz; - if (type instanceof ParameterizedType) { - final ParameterizedType pts = (ParameterizedType) type; - clazz = (Class) (pts).getRawType(); - } else if (type instanceof TypeVariable) { // e.g. - final TypeVariable tv = (TypeVariable) type; - Class cz = tv.getBounds().length == 0 ? Object.class : null; - for (Type f : tv.getBounds()) { - if (f instanceof Class) { - cz = (Class) f; - break; - } - } - clazz = cz; - if (cz == null) throw new ConvertException("not support the type (" + type + ")"); - } else if (type instanceof WildcardType) { // e.g. - final WildcardType wt = (WildcardType) type; - Class cz = null; - for (Type f : wt.getUpperBounds()) { - if (f instanceof Class) { - cz = (Class) f; - break; - } - } - clazz = cz; - if (cz == null) throw new ConvertException("not support the type (" + type + ")"); - } else if (type instanceof Class) { - clazz = (Class) type; - } else { - throw new ConvertException("not support the type (" + type + ")"); - } - decoder = findDecoder(clazz); - if (decoder != null) return decoder; - return createDecoder(type, clazz); - } - - public final Decodeable createDecoder(final Type type) { - Class clazz; - if (type instanceof ParameterizedType) { - final ParameterizedType pts = (ParameterizedType) type; - clazz = (Class) (pts).getRawType(); - } else if (type instanceof Class) { - clazz = (Class) type; - } else { - throw new ConvertException("not support the type (" + type + ")"); - } - return createDecoder(type, clazz); - } - - private Decodeable createDecoder(final Type type, final Class clazz) { - Decodeable decoder = null; - ObjectDecoder od = null; - if (clazz.isEnum()) { - decoder = new EnumSimpledCoder(clazz); - } else if (clazz.isArray()) { - decoder = new ArrayDecoder(this, type); - } else if (Collection.class.isAssignableFrom(clazz)) { - decoder = new CollectionDecoder(this, type); - } else if (Map.class.isAssignableFrom(clazz)) { - decoder = new MapDecoder(this, type); - } else if (clazz == Object.class) { - od = new ObjectDecoder(type); - decoder = od; - } else if (!clazz.getName().startsWith("java.")) { - Decodeable simpleCoder = null; - for (final Method method : clazz.getDeclaredMethods()) { - if (!Modifier.isStatic(method.getModifiers())) continue; - Class[] paramTypes = method.getParameterTypes(); - if (paramTypes.length != 1) continue; - if (paramTypes[0] != ConvertFactory.class && paramTypes[0] != this.getClass()) continue; - if (!Decodeable.class.isAssignableFrom(method.getReturnType())) continue; - try { - method.setAccessible(true); - simpleCoder = (Decodeable) method.invoke(null, this); - break; - } catch (Exception e) { - } - } - if (simpleCoder == null) { - od = new ObjectDecoder(type); - decoder = od; - } else { - decoder = simpleCoder; - } - } - if (decoder == null) throw new ConvertException("not support the type (" + type + ")"); - register(type, decoder); - if (od != null) od.init(this); - return decoder; - } - - public final Encodeable loadEncoder(final Type type) { - Encodeable encoder = findEncoder(type); - if (encoder != null) return encoder; - if (type instanceof GenericArrayType) return new ArrayEncoder(this, type); - Class clazz; - if (type instanceof ParameterizedType) { - final ParameterizedType pts = (ParameterizedType) type; - clazz = (Class) (pts).getRawType(); - } else if (type instanceof TypeVariable) { - TypeVariable tv = (TypeVariable) type; - Type t = Object.class; - if (tv.getBounds().length == 1) { - t = tv.getBounds()[0]; - } - if (!(t instanceof Class)) t = Object.class; - clazz = (Class) t; - } else if (type instanceof Class) { - clazz = (Class) type; - } else { - throw new ConvertException("not support the type (" + type + ")"); - } - encoder = findEncoder(clazz); - if (encoder != null) return encoder; - return createEncoder(type, clazz); - } - - public final Encodeable createEncoder(final Type type) { - Class clazz; - if (type instanceof ParameterizedType) { - final ParameterizedType pts = (ParameterizedType) type; - clazz = (Class) (pts).getRawType(); - } else if (type instanceof Class) { - clazz = (Class) type; - } else { - throw new ConvertException("not support the type (" + type + ")"); - } - return createEncoder(type, clazz); - } - - private Encodeable createEncoder(final Type type, final Class clazz) { - Encodeable encoder = null; - ObjectEncoder oe = null; - if (clazz.isEnum()) { - encoder = new EnumSimpledCoder(clazz); - } else if (clazz.isArray()) { - encoder = new ArrayEncoder(this, type); - } else if (Collection.class.isAssignableFrom(clazz)) { - encoder = new CollectionEncoder(this, type); - } else if (Map.class.isAssignableFrom(clazz)) { - encoder = new MapEncoder(this, type); - } else if (clazz == Object.class) { - return (Encodeable) this.anyEncoder; - } else if (!clazz.getName().startsWith("java.")) { - Encodeable simpleCoder = null; - for (final Method method : clazz.getDeclaredMethods()) { - if (!Modifier.isStatic(method.getModifiers())) continue; - Class[] paramTypes = method.getParameterTypes(); - if (paramTypes.length != 1) continue; - if (paramTypes[0] != ConvertFactory.class && paramTypes[0] != this.getClass()) continue; - if (!Encodeable.class.isAssignableFrom(method.getReturnType())) continue; - try { - method.setAccessible(true); - simpleCoder = (Encodeable) method.invoke(null, this); - break; - } catch (Exception e) { - } - } - if (simpleCoder == null) { - oe = new ObjectEncoder(type); - encoder = oe; - } else { - encoder = simpleCoder; - } - } - if (encoder == null) throw new ConvertException("not support the type (" + type + ")"); - register(type, encoder); - if (oe != null) oe.init(this); - return encoder; - - } - -} diff --git a/src/main/java/org/redkale/convert/ConvertType.java b/src/main/java/org/redkale/convert/ConvertType.java deleted file mode 100644 index 070ac5a86..000000000 --- a/src/main/java/org/redkale/convert/ConvertType.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * 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; - -/** - * - *

详情见: http://www.redkale.org - * @author zhangjx - */ -public enum ConvertType { - - JSON(1), - BSON(2), - ALL(127); - - private final int value; - - private ConvertType(int v) { - this.value = v; - } - - public boolean contains(ConvertType type) { - if (type == null) return false; - return this.value >= type.value && (this.value & type.value) > 0; - } -} diff --git a/src/main/java/org/redkale/convert/DeMember.java b/src/main/java/org/redkale/convert/DeMember.java deleted file mode 100644 index 3278c5618..000000000 --- a/src/main/java/org/redkale/convert/DeMember.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * 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.lang.reflect.*; -import org.redkale.util.Attribute; - -/** - * - *

- * 详情见: http://www.redkale.org - * - * @author zhangjx - * @param Reader输入的子类 - * @param 字段依附的类 - * @param 字段的数据类型 - */ -@SuppressWarnings("unchecked") -public final class DeMember implements Comparable> { - - protected final Attribute attribute; - - protected Decodeable decoder; - - public DeMember(final Attribute attribute) { - this.attribute = attribute; - } - - public DeMember(Attribute attribute, Decodeable decoder) { - this(attribute); - this.decoder = decoder; - } - - public static DeMember create(final ConvertFactory factory, final Class clazz, final String fieldname) { - try { - Field field = clazz.getDeclaredField(fieldname); - return new DeMember<>(Attribute.create(field), factory.loadDecoder(field.getGenericType())); - } catch (Exception e) { - throw new RuntimeException(e); - } - } - - public final boolean match(String name) { - return attribute.field().equals(name); - } - - public final void read(R in, T obj) { - this.attribute.set(obj, decoder.convertFrom(in)); - } - - public final F read(R in) { - return decoder.convertFrom(in); - } - - public Attribute getAttribute() { - return this.attribute; - } - - @Override - public final int compareTo(DeMember o) { - if (o == null) return 1; - return this.attribute.field().compareTo(o.attribute.field()); - } - - @Override - public boolean equals(Object obj) { - if (this == obj) return true; - if (!(obj instanceof DeMember)) return false; - DeMember other = (DeMember) obj; - return compareTo(other) == 0; - } - - @Override - public int hashCode() { - return this.attribute.field().hashCode(); - } - - @Override - public String toString() { - return "DeMember{" + "attribute=" + attribute.field() + ", decoder=" + decoder + '}'; - } -} diff --git a/src/main/java/org/redkale/convert/Decodeable.java b/src/main/java/org/redkale/convert/Decodeable.java deleted file mode 100644 index c4f1a6767..000000000 --- a/src/main/java/org/redkale/convert/Decodeable.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * 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.lang.reflect.Type; - -/** - * - *

- * 详情见: http://www.redkale.org - * - * @author zhangjx - * @param Reader输入的子类 - * @param 反解析的数据类型 - */ -public interface Decodeable { - - public T convertFrom(final R in); - - /** - * 泛型映射接口 - * - * @return 反解析的数据类型 - */ - public Type getType(); - -} diff --git a/src/main/java/org/redkale/convert/EnMember.java b/src/main/java/org/redkale/convert/EnMember.java deleted file mode 100644 index e31dcf2bb..000000000 --- a/src/main/java/org/redkale/convert/EnMember.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * 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.lang.reflect.*; -import org.redkale.util.Attribute; - -/** - * - *

- * 详情见: http://www.redkale.org - * - * @author zhangjx - * @param Writer输出的子类 - * @param 字段依附的类 - * @param 字段的数据类型 - */ -@SuppressWarnings("unchecked") -public final class EnMember implements Comparable> { - - final Attribute attribute; - - final Encodeable encoder; - - final boolean istring; - - //final boolean isnumber; - final boolean isbool; - - public EnMember(Attribute attribute, Encodeable encoder) { - this.attribute = attribute; - this.encoder = encoder; - Class t = attribute.type(); - this.istring = CharSequence.class.isAssignableFrom(t); - this.isbool = t == Boolean.class || t == boolean.class; - //this.isnumber = Number.class.isAssignableFrom(t) || (!this.isbool && t.isPrimitive()); - } - - public static EnMember create(final ConvertFactory factory, final Class clazz, final String fieldname) { - try { - Field field = clazz.getDeclaredField(fieldname); - return new EnMember<>(Attribute.create(field), factory.loadEncoder(field.getGenericType())); - } catch (Exception e) { - throw new RuntimeException(e); - } - } - - public final boolean match(String name) { - return attribute.field().equals(name); - } - - @Override - public final int compareTo(EnMember o) { - if (o == null) return 1; - return this.attribute.field().compareTo(o.attribute.field()); - } - - @Override - public boolean equals(Object obj) { - if (this == obj) return true; - if (!(obj instanceof EnMember)) return false; - EnMember other = (EnMember) obj; - return compareTo(other) == 0; - } - - @Override - public int hashCode() { - return this.attribute.field().hashCode(); - } - - @Override - public String toString() { - return "EnMember{" + "attribute=" + attribute.field() + ", encoder=" + encoder + '}'; - } -} diff --git a/src/main/java/org/redkale/convert/Encodeable.java b/src/main/java/org/redkale/convert/Encodeable.java deleted file mode 100644 index 9a2a96191..000000000 --- a/src/main/java/org/redkale/convert/Encodeable.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * 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.lang.reflect.Type; - -/** - * - *

- * 详情见: http://www.redkale.org - * - * @author zhangjx - * @param Writer输出的子类 - * @param 序列化的数据类型 - */ -public interface Encodeable { - - public void convertTo(final W out, T value); - - /** - * 泛型映射接口 - * - * @return 返回序列化对象类的数据类型 - */ - public Type getType(); - -} diff --git a/src/main/java/org/redkale/convert/MapDecoder.java b/src/main/java/org/redkale/convert/MapDecoder.java deleted file mode 100644 index 22fb3a3c8..000000000 --- a/src/main/java/org/redkale/convert/MapDecoder.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * 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 org.redkale.util.Creator; -import java.lang.reflect.ParameterizedType; -import java.lang.reflect.Type; -import java.util.Map; - -/** - * - *

详情见: http://www.redkale.org - * @author zhangjx - * @param Map key的数据类型 - * @param Map value的数据类型 - */ -@SuppressWarnings("unchecked") -public final class MapDecoder implements Decodeable> { - - private final Type type; - - private final Type keyType; - - private final Type valueType; - - protected Creator> creator; - - private final Decodeable keyDecoder; - - private final Decodeable valueDecoder; - - public MapDecoder(final ConvertFactory factory, final Type type) { - this.type = type; - if (type instanceof ParameterizedType) { - final ParameterizedType pt = (ParameterizedType) type; - this.keyType = pt.getActualTypeArguments()[0]; - this.valueType = pt.getActualTypeArguments()[1]; - this.creator = factory.loadCreator((Class) pt.getRawType()); - factory.register(type, this); - this.keyDecoder = factory.loadDecoder(this.keyType); - this.valueDecoder = factory.loadDecoder(this.valueType); - } else { - throw new ConvertException("mapdecoder not support the type (" + type + ")"); - } - } - - @Override - public Map convertFrom(Reader in) { - final int len = in.readMapB(); - if (len == Reader.SIGN_NULL) return null; - final Map result = this.creator.create(); - if (len == Reader.SIGN_NOLENGTH) { - while (in.hasNext()) { - K key = keyDecoder.convertFrom(in); - in.readBlank(); - V value = valueDecoder.convertFrom(in); - result.put(key, value); - } - } else { - for (int i = 0; i < len; i++) { - K key = keyDecoder.convertFrom(in); - in.readBlank(); - V value = valueDecoder.convertFrom(in); - result.put(key, value); - } - } - in.readMapE(); - return result; - } - - @Override - public Type getType() { - return this.type; - } - -} diff --git a/src/main/java/org/redkale/convert/MapEncoder.java b/src/main/java/org/redkale/convert/MapEncoder.java deleted file mode 100644 index 1b1f2a264..000000000 --- a/src/main/java/org/redkale/convert/MapEncoder.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * 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.lang.reflect.ParameterizedType; -import java.lang.reflect.Type; -import java.util.Map; - -/** - * - *

- * 详情见: http://www.redkale.org - * - * @author zhangjx - * @param Map key的数据类型 - * @param Map value的数据类型 - */ -@SuppressWarnings("unchecked") -public final class MapEncoder implements Encodeable> { - - private final Type type; - - private final Encodeable keyencoder; - - private final Encodeable valencoder; - - public MapEncoder(final ConvertFactory factory, final Type type) { - this.type = type; - if (type instanceof ParameterizedType) { - final Type[] pt = ((ParameterizedType) type).getActualTypeArguments(); - this.keyencoder = factory.loadEncoder(pt[0]); - this.valencoder = factory.loadEncoder(pt[1]); - } else { - this.keyencoder = factory.getAnyEncoder(); - this.valencoder = factory.getAnyEncoder(); - } - } - - @Override - public void convertTo(Writer out, Map value) { - final Map values = value; - if (values == null) { - out.writeNull(); - return; - } - out.writeMapB(values.size()); - boolean first = true; - for (Map.Entry en : values.entrySet()) { - if (!first) out.writeArrayMark(); - this.keyencoder.convertTo(out, en.getKey()); - out.writeMapMark(); - this.valencoder.convertTo(out, en.getValue()); - if (first) first = false; - } - out.writeMapE(); - } - - @Override - public Type getType() { - return type; - } -} diff --git a/src/main/java/org/redkale/convert/ObjectDecoder.java b/src/main/java/org/redkale/convert/ObjectDecoder.java deleted file mode 100644 index 8bd7d5c12..000000000 --- a/src/main/java/org/redkale/convert/ObjectDecoder.java +++ /dev/null @@ -1,234 +0,0 @@ -/* - * 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 org.redkale.util.Creator; -import java.lang.reflect.*; -import java.util.Arrays; -import java.util.HashSet; -import java.util.Set; -import org.redkale.util.*; - -/** - * - *

- * 详情见: http://www.redkale.org - * - * @author zhangjx - * @param Reader输入的子类 - * @param 反解析的数据类型 - */ -@SuppressWarnings("unchecked") -public final class ObjectDecoder implements Decodeable { - - protected final Type type; - - protected final Class typeClass; - - protected Creator creator; - - protected DeMember[] creatorConstructorMembers; - - protected DeMember[] members; - - protected ConvertFactory factory; - - private boolean inited = false; - - private final Object lock = new Object(); - - protected ObjectDecoder(Type type) { - this.type = ((type instanceof Class) && ((Class) type).isInterface()) ? Object.class : type; - if (type instanceof ParameterizedType) { - final ParameterizedType pt = (ParameterizedType) type; - this.typeClass = (Class) pt.getRawType(); - } else { - this.typeClass = (Class) type; - } - this.members = new DeMember[0]; - } - - public void init(final ConvertFactory factory) { - this.factory = factory; - try { - if (type == Object.class) return; - - Class clazz = null; - if (type instanceof ParameterizedType) { - final ParameterizedType pts = (ParameterizedType) type; - clazz = (Class) (pts).getRawType(); - } else if (!(type instanceof Class)) { - throw new ConvertException("[" + type + "] is no a class"); - } else { - clazz = (Class) type; - } - this.creator = factory.loadCreator(clazz); - - final Set list = new HashSet(); - final String[] cps = ObjectEncoder.findConstructorProperties(this.creator); - try { - ConvertColumnEntry ref; - for (final Field field : clazz.getFields()) { - if (Modifier.isStatic(field.getModifiers())) continue; - ref = factory.findRef(field); - if (ref != null && ref.ignore()) continue; - Type t = ObjectEncoder.createClassType(field.getGenericType(), this.type); - list.add(new DeMember(ObjectEncoder.createAttribute(factory, clazz, field, null, null), factory.loadDecoder(t))); - } - final boolean reversible = factory.isReversible(); - for (final Method method : clazz.getMethods()) { - if (Modifier.isStatic(method.getModifiers())) continue; - if (Modifier.isAbstract(method.getModifiers())) continue; - if (method.isSynthetic()) continue; - if (method.getName().length() < 4) continue; - if (!method.getName().startsWith("set")) continue; - if (method.getParameterTypes().length != 1) continue; - if (method.getReturnType() != void.class) continue; - if (reversible && (cps == null || !ObjectEncoder.contains(cps, ConvertFactory.readGetSetFieldName(method)))) { - boolean is = method.getParameterTypes()[0] == boolean.class || method.getParameterTypes()[0] == Boolean.class; - try { - clazz.getMethod(method.getName().replaceFirst("set", is ? "is" : "get")); - } catch (Exception e) { - continue; - } - } - ref = factory.findRef(method); - if (ref != null && ref.ignore()) continue; - Type t = ObjectEncoder.createClassType(method.getGenericParameterTypes()[0], this.type); - list.add(new DeMember(ObjectEncoder.createAttribute(factory, clazz, null, null, method), factory.loadDecoder(t))); - } - if (cps != null) { //可能存在某些构造函数中的字段名不存在setter方法 - for (final String constructorField : cps) { - boolean flag = false; - for (DeMember m : list) { - if (m.attribute.field().equals(constructorField)) { - flag = true; - break; - } - } - if (flag) continue; - //不存在setter方法 - try { - Field f = clazz.getDeclaredField(constructorField); - Type t = ObjectEncoder.createClassType(f.getGenericType(), this.type); - list.add(new DeMember(ObjectEncoder.createAttribute(factory, clazz, f, null, null), factory.loadDecoder(t))); - } catch (NoSuchFieldException nsfe) { //不存在field, 可能存在getter方法 - char[] fs = constructorField.toCharArray(); - fs[0] = Character.toUpperCase(fs[0]); - String mn = new String(fs); - Method getter; - try { - getter = clazz.getMethod("get" + mn); - } catch (NoSuchMethodException ex) { - getter = clazz.getMethod("is" + mn); - } - Type t = ObjectEncoder.createClassType(getter.getGenericParameterTypes()[0], this.type); - list.add(new DeMember(ObjectEncoder.createAttribute(factory, clazz, null, getter, null), factory.loadDecoder(t))); - } - } - } - this.members = list.toArray(new DeMember[list.size()]); - Arrays.sort(this.members); - - if (cps != null) { - final String[] fields = cps; - final DeMember[] ms = new DeMember[fields.length]; - for (int i = 0; i < fields.length; i++) { - for (DeMember m : this.members) { - if (m.attribute.field().equals(fields[i])) { - ms[i] = m; - break; - } - } - } - this.creatorConstructorMembers = ms; - } - } catch (Exception ex) { - throw new ConvertException(ex); - } - } finally { - inited = true; - synchronized (lock) { - lock.notifyAll(); - } - } - } - - /** - * 对象格式: [0x1][short字段个数][字段名][字段值]...[0x2] - * - * @param in 输入流 - * @return 反解析后的对象结果 - */ - @Override - public final T convertFrom(final R in) { - final String clazz = in.readObjectB(typeClass); - if (clazz == null) return null; - if (!clazz.isEmpty()) return (T) factory.loadDecoder(factory.getEntity(clazz)).convertFrom(in); - if (!this.inited) { - synchronized (lock) { - try { - lock.wait(); - } catch (Exception e) { - e.printStackTrace(); - } - } - } - if (this.creatorConstructorMembers == null) { //空构造函数 - final T result = this.creator.create(); - while (in.hasNext()) { - DeMember member = in.readFieldName(members); - in.readBlank(); - if (member == null) { - in.skipValue(); //跳过不存在的属性的值 - } else { - member.read(in, result); - } - } - in.readObjectE(typeClass); - return result; - } else { //带参数的构造函数 - final DeMember[] fields = this.creatorConstructorMembers; - final Object[] constructorParams = new Object[fields.length]; - final Object[][] otherParams = new Object[this.members.length][2]; - int oc = 0; - while (in.hasNext()) { - DeMember member = in.readFieldName(members); - in.readBlank(); - if (member == null) { - in.skipValue(); //跳过不存在的属性的值 - } else { - Object val = member.read(in); - boolean flag = true; - for (int i = 0; i < fields.length; i++) { - if (member == fields[i]) { - constructorParams[i] = val; - flag = false; - break; - } - } - if (flag) otherParams[oc++] = new Object[]{member.attribute, val}; - } - } - in.readObjectE(typeClass); - final T result = this.creator.create(constructorParams); - for (int i = 0; i < oc; i++) { - ((Attribute) otherParams[i][0]).set(result, otherParams[i][1]); - } - return result; - } - } - - @Override - public final Type getType() { - return this.type; - } - - @Override - public String toString() { - return "ObjectDecoder{" + "type=" + type + ", members=" + Arrays.toString(members) + '}'; - } -} diff --git a/src/main/java/org/redkale/convert/ObjectEncoder.java b/src/main/java/org/redkale/convert/ObjectEncoder.java deleted file mode 100644 index 0e3a94281..000000000 --- a/src/main/java/org/redkale/convert/ObjectEncoder.java +++ /dev/null @@ -1,278 +0,0 @@ -/* - * 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 org.redkale.util.Attribute; -import java.lang.reflect.*; -import java.util.*; -import org.redkale.util.*; - -/** - * - *

- * 详情见: http://www.redkale.org - * - * @author zhangjx - * @param Writer输出的子类 - * @param 序列化的数据类型 - */ -@SuppressWarnings("unchecked") -public final class ObjectEncoder implements Encodeable { - - static final Type[] TYPEZERO = new Type[0]; - - protected final Type type; - - protected final Class typeClass; - - protected EnMember[] members; - - protected ConvertFactory factory; - - private boolean inited = false; - - private final Object lock = new Object(); - - protected ObjectEncoder(Type type) { - this.type = type; - if (type instanceof ParameterizedType) { - final ParameterizedType pt = (ParameterizedType) type; - this.typeClass = (Class) pt.getRawType(); - } else { - this.typeClass = (Class) type; - } - this.members = new EnMember[0]; - } - - public void init(final ConvertFactory factory) { - this.factory = factory; - try { - if (type == Object.class) return; - //if (!(type instanceof Class)) throw new ConvertException("[" + type + "] is no a class"); - final Class clazz = this.typeClass; - final Set list = new HashSet(); - final boolean reversible = factory.isReversible(); - Creator creator = null; - try { - creator = factory.loadCreator(this.typeClass); - } catch (RuntimeException e) { - if (reversible) throw e; - } - final String[] cps = creator == null ? null : ObjectEncoder.findConstructorProperties(creator); - try { - ConvertColumnEntry ref; - for (final Field field : clazz.getFields()) { - if (Modifier.isStatic(field.getModifiers())) continue; - ref = factory.findRef(field); - if (ref != null && ref.ignore()) continue; - Type t = createClassType(field.getGenericType(), this.type); - list.add(new EnMember(createAttribute(factory, clazz, field, null, null), factory.loadEncoder(t))); - } - for (final Method method : clazz.getMethods()) { - if (Modifier.isStatic(method.getModifiers())) continue; - if (Modifier.isAbstract(method.getModifiers())) continue; - if (method.isSynthetic()) continue; - if (method.getName().length() < 3) continue; - if (method.getName().equals("getClass")) continue; - if (!method.getName().startsWith("is") && !method.getName().startsWith("get")) continue; - if (method.getParameterTypes().length != 0) continue; - if (method.getReturnType() == void.class) continue; - if (reversible && (cps == null || !contains(cps, ConvertFactory.readGetSetFieldName(method)))) { - boolean is = method.getName().startsWith("is"); - try { - clazz.getMethod(method.getName().replaceFirst(is ? "is" : "get", "set"), method.getReturnType()); - } catch (Exception e) { - continue; - } - } - ref = factory.findRef(method); - if (ref != null && ref.ignore()) continue; - Type t = createClassType(method.getGenericReturnType(), this.type); - list.add(new EnMember(createAttribute(factory, clazz, null, method, null), factory.loadEncoder(t))); - } - this.members = list.toArray(new EnMember[list.size()]); - Arrays.sort(this.members); - - } catch (Exception ex) { - throw new ConvertException(ex); - } - } finally { - inited = true; - synchronized (lock) { - lock.notifyAll(); - } - } - } - - @Override - public final void convertTo(W out, T value) { - if (value == null) { - out.writeObjectNull(null); - return; - } - if (!this.inited) { - synchronized (lock) { - try { - lock.wait(); - } catch (Exception e) { - e.printStackTrace(); - } - } - } - if (value != null && value.getClass() != this.typeClass) { - final Class clz = value.getClass(); - out.wirteClassName(factory.getEntity(clz)); - factory.loadEncoder(clz).convertTo(out, value); - return; - } - out.writeObjectB(value); - for (EnMember member : members) { - out.writeObjectField(member, value); - } - out.writeObjectE(value); - } - - @Override - public final Type getType() { - return this.type; - } - - @Override - public String toString() { - return "ObjectEncoder{" + "type=" + type + ", members=" + Arrays.toString(members) + '}'; - } - - static Type createClassType(final Type type, final Type declaringType0) { - if (TypeToken.isClassType(type)) return type; - if (type instanceof ParameterizedType) { // e.g. Map - final ParameterizedType pt = (ParameterizedType) type; - final Type[] paramTypes = pt.getActualTypeArguments(); - for (int i = 0; i < paramTypes.length; i++) { - paramTypes[i] = createClassType(paramTypes[i], declaringType0); - } - return TypeToken.createParameterizedType(pt.getOwnerType(), pt.getRawType(), paramTypes); - } - Type declaringType = declaringType0; - if (declaringType instanceof Class) { - do { - declaringType = ((Class) declaringType).getGenericSuperclass(); - if (declaringType == Object.class) return Object.class; - } while (declaringType instanceof Class); - } - //存在通配符则declaringType 必须是 ParameterizedType - if (!(declaringType instanceof ParameterizedType)) return Object.class; - final ParameterizedType declaringPType = (ParameterizedType) declaringType; - final Type[] virTypes = ((Class) declaringPType.getRawType()).getTypeParameters(); - final Type[] desTypes = declaringPType.getActualTypeArguments(); - if (type instanceof WildcardType) { // e.g. - final WildcardType wt = (WildcardType) type; - for (Type f : wt.getUpperBounds()) { - for (int i = 0; i < virTypes.length; i++) { - if (virTypes[i].equals(f)) return desTypes.length <= i ? Object.class : desTypes[i]; - } - } - } else if (type instanceof TypeVariable) { // e.g. - for (int i = 0; i < virTypes.length; i++) { - if (virTypes[i].equals(type)) return desTypes.length <= i ? Object.class : desTypes[i]; - } - } - return type; - } -// -// static Type makeGenericType(final Type type, final Type[] virGenericTypes, final Type[] realGenericTypes) { -// if (type instanceof Class) { //e.g. String -// return type; -// } else if (type instanceof ParameterizedType) { //e.g. Map -// final ParameterizedType pt = (ParameterizedType) type; -// Type[] paramTypes = pt.getActualTypeArguments(); -// final Type[] newTypes = new Type[paramTypes.length]; -// int count = 0; -// for (int i = 0; i < newTypes.length; i++) { -// newTypes[i] = makeGenericType(paramTypes[i], virGenericTypes, realGenericTypes); -// if (paramTypes[i] == newTypes[i]) count++; -// } -// if (count == paramTypes.length) return pt; -// return new ParameterizedType() { -// -// @Override -// public Type[] getActualTypeArguments() { -// return newTypes; -// } -// -// @Override -// public Type getRawType() { -// return pt.getRawType(); -// } -// -// @Override -// public Type getOwnerType() { -// return pt.getOwnerType(); -// } -// -// }; -// } -// if (realGenericTypes == null) return type; -// if (type instanceof WildcardType) { // e.g. -// final WildcardType wt = (WildcardType) type; -// for (Type f : wt.getUpperBounds()) { -// for (int i = 0; i < virGenericTypes.length; i++) { -// if (virGenericTypes[i] == f) return realGenericTypes.length == 0 ? Object.class : realGenericTypes[i]; -// } -// } -// } else if (type instanceof TypeVariable) { // e.g. -// for (int i = 0; i < virGenericTypes.length; i++) { -// if (virGenericTypes[i] == type) return i >= realGenericTypes.length ? Object.class : realGenericTypes[i]; -// } -// } -// return type; -// } - - static boolean contains(String[] values, String value) { - for (String str : values) { - if (str.equals(value)) return true; - } - return false; - } - - static String[] findConstructorProperties(Creator creator) { - try { - Creator.ConstructorParameters cps = creator.getClass().getMethod("create", Object[].class).getAnnotation(Creator.ConstructorParameters.class); - return cps == null ? null : cps.value(); - } catch (Exception e) { - return null; - } - } - - static Attribute createAttribute(final ConvertFactory factory, Class clazz, final Field field, final Method getter, final Method setter) { - String fieldalias; - if (field != null) { // public field - ConvertColumnEntry ref = factory.findRef(field); - fieldalias = ref == null || ref.name().isEmpty() ? field.getName() : ref.name(); - } else if (getter != null) { - ConvertColumnEntry ref = factory.findRef(getter); - String mfieldname = ConvertFactory.readGetSetFieldName(getter); - if (ref == null) { - try { - ref = factory.findRef(clazz.getDeclaredField(mfieldname)); - } catch (Exception e) { - } - } - fieldalias = ref == null || ref.name().isEmpty() ? mfieldname : ref.name(); - } else { // setter != null - ConvertColumnEntry ref = factory.findRef(setter); - String mfieldname = ConvertFactory.readGetSetFieldName(setter); - if (ref == null) { - try { - ref = factory.findRef(clazz.getDeclaredField(mfieldname)); - } catch (Exception e) { - } - } - fieldalias = ref == null || ref.name().isEmpty() ? mfieldname : ref.name(); - } - return Attribute.create(clazz, fieldalias, field, getter, setter); - } - -} diff --git a/src/main/java/org/redkale/convert/Reader.java b/src/main/java/org/redkale/convert/Reader.java deleted file mode 100644 index 5afc6ebe3..000000000 --- a/src/main/java/org/redkale/convert/Reader.java +++ /dev/null @@ -1,170 +0,0 @@ -/* - * 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; - -/** - * - *

- * 详情见: http://www.redkale.org - * - * @author zhangjx - */ -public abstract class Reader { - - //当前对象字段名的游标 - protected int fieldIndex; - - public static final short SIGN_NULL = -1; - - public static final short SIGN_NOLENGTH = -2; - - /** - * 是否还存在下个元素或字段 - * - * @return 是否还存在下个元素或字段 - */ - public abstract boolean hasNext(); - - /** - * 跳过值(不包含值前面的字段) - */ - public abstract void skipValue(); - - /** - * /跳过字段与值之间的多余内容, json就是跳过:符, map跳过: - */ - public abstract void readBlank(); - - /** - * 读取对象的类名, 返回 null 表示对象为null, 返回空字符串表示当前class与返回的class一致,返回非空字符串表示class是当前class的子类。 - * - * @param clazz 类名 - * @return 返回字段数 - */ - public String readObjectB(final Class clazz) { - this.fieldIndex = 0; - return null; - } - - /** - * 读取对象的尾端 - * - * @param clazz 类名 - */ - public abstract void readObjectE(final Class clazz); - - /** - * 读取数组的开头并返回数组的长度 - * - * @return 返回数组的长度 - */ - public abstract int readArrayB(); - - /** - * 读取数组的尾端 - * - */ - public abstract void readArrayE(); - - /** - * 读取map的开头并返回map的size - * - * @return 返回map的size - */ - public abstract int readMapB(); - - /** - * 读取数组的尾端 - * - */ - public abstract void readMapE(); - - /** - * 根据字段读取字段对应的DeMember - * - * @param members DeMember的全量集合 - * @return 匹配的DeMember - */ - public abstract DeMember readFieldName(final DeMember[] members); - - /** - * 读取一个boolean值 - * - * @return boolean值 - */ - public abstract boolean readBoolean(); - - /** - * 读取一个byte值 - * - * @return byte值 - */ - public abstract byte readByte(); - - /** - * 读取一个char值 - * - * @return char值 - */ - public abstract char readChar(); - - /** - * 读取一个short值 - * - * @return short值 - */ - public abstract short readShort(); - - /** - * 读取一个int值 - * - * @return int值 - */ - public abstract int readInt(); - - /** - * 读取一个long值 - * - * @return long值 - */ - public abstract long readLong(); - - /** - * 读取一个float值 - * - * @return float值 - */ - public abstract float readFloat(); - - /** - * 读取一个double值 - * - * @return double值 - */ - public abstract double readDouble(); - - /** - * 读取无转义字符长度不超过255的字符串, 例如枚举值、字段名、类名字符串等 - * - * @return String值 - */ - public abstract String readSmallString(); - - /** - * 读取反解析对象的类名 - * - * @return 类名 - */ - public abstract String readClassName(); - - /** - * 读取一个String值 - * - * @return String值 - */ - public abstract String readString(); - -} diff --git a/src/main/java/org/redkale/convert/SimpledCoder.java b/src/main/java/org/redkale/convert/SimpledCoder.java deleted file mode 100644 index 35ae99813..000000000 --- a/src/main/java/org/redkale/convert/SimpledCoder.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * 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.lang.reflect.ParameterizedType; -import java.lang.reflect.Type; - -/** - * - *

- * 详情见: http://www.redkale.org - * - * @author zhangjx - * @param Reader输入的子类 - * @param Writer输出的子类 - * @param 序列化/反解析的数据类型 - */ -public abstract class SimpledCoder implements Decodeable, Encodeable { - - private Type type; - - @Override - public abstract void convertTo(final W out, final T value); - - @Override - public abstract T convertFrom(final R in); - - @Override - @SuppressWarnings("unchecked") - public Class getType() { - if (type == null) { - Type[] ts = ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments(); - type = ts[ts.length - 1]; - } - return (Class) type; - } - - @Override - public String toString() { - return this.getClass().getSimpleName(); - } -} diff --git a/src/main/java/org/redkale/convert/Writer.java b/src/main/java/org/redkale/convert/Writer.java deleted file mode 100644 index 190201a8e..000000000 --- a/src/main/java/org/redkale/convert/Writer.java +++ /dev/null @@ -1,205 +0,0 @@ -/* - * 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 org.redkale.util.Attribute; - -/** - * - *

- * 详情见: http://www.redkale.org - * - * @author zhangjx - */ -public abstract class Writer { - - //当前对象输出字段名之前是否需要分隔符, JSON字段间的分隔符为,逗号 - protected boolean comma; - - /** - * 当tiny=true时, 字符串为空、boolean为false的字段值都会被跳过, 不会输出。 - * - * @return 是否简化 - */ - public abstract boolean tiny(); - - /** - * 输出null值 - */ - public abstract void writeNull(); - - /** - * 写入类名 - * - * @param clazz 类名 - */ - public abstract void wirteClassName(String clazz); - - /** - * 输出一个对象前的操作 - * 注: 覆盖此方法必须要先调用父方法 super.writeObjectB(obj); - * - * @param obj 写入的对象 - */ - public void writeObjectB(Object obj) { - this.comma = false; - } - - /** - * 输出一个为null的对象 - * - * @param clazz 对象的类名 - */ - public final void writeObjectNull(final Class clazz) { - wirteClassName(null); - writeNull(); - } - - /** - * 输出一个对象的某个字段 - * - * @param member 字段 - * - * @param obj 写入的对象 - */ - @SuppressWarnings("unchecked") - public final void writeObjectField(final EnMember member, Object obj) { - Object value = member.attribute.get(obj); - if (value == null) return; - if (tiny()) { - if (member.istring) { - if (((CharSequence) value).length() == 0) return; - } else if (member.isbool) { - if (!((Boolean) value)) return; - } - } - this.writeFieldName(member.attribute); - member.encoder.convertTo(this, value); - this.comma = true; - } - - /** - * 输出一个对象后的操作 - * - * @param obj 写入的对象 - */ - public abstract void writeObjectE(Object obj); - - /** - * 输出一个数组前的操作 - * - * @param size 数组长度 - */ - public abstract void writeArrayB(int size); - - /** - * 输出数组元素间的间隔符 - * - */ - public abstract void writeArrayMark(); - - /** - * 输出一个数组后的操作 - * - */ - public abstract void writeArrayE(); - - /** - * 输出一个Map前的操作 - * - * @param size map大小 - */ - public abstract void writeMapB(int size); - - /** - * 输出一个Map中key与value间的间隔符 - * - */ - public abstract void writeMapMark(); - - /** - * 输出一个Map后的操作 - * - */ - public abstract void writeMapE(); - - /** - * 输出一个字段名 - * - * @param attribute 字段的Attribute对象 - */ - public abstract void writeFieldName(Attribute attribute); - - /** - * 写入一个boolean值 - * - * @param value boolean值 - */ - public abstract void writeBoolean(boolean value); - - /** - * 写入一个byte值 - * - * @param value byte值 - */ - public abstract void writeByte(byte value); - - /** - * 写入一个char值 - * - * @param value char值 - */ - public abstract void writeChar(char value); - - /** - * 写入一个short值 - * - * @param value short值 - */ - public abstract void writeShort(short value); - - /** - * 写入一个int值 - * - * @param value int值 - */ - public abstract void writeInt(int value); - - /** - * 写入一个long值 - * - * @param value long值 - */ - public abstract void writeLong(long value); - - /** - * 写入一个float值 - * - * @param value float值 - */ - public abstract void writeFloat(float value); - - /** - * 写入一个double值 - * - * @param value double值 - */ - public abstract void writeDouble(double value); - - /** - * 写入无转义字符长度不超过255的字符串, 例如枚举值、字段名、类名字符串等 * - * - * @param value 非空且不含需要转义的字符的String值 - */ - public abstract void writeSmallString(String value); - - /** - * 写入一个String值 - * - * @param value String值 - */ - public abstract void writeString(String value); -} diff --git a/src/main/java/org/redkale/convert/bson/BsonByteBufferReader.java b/src/main/java/org/redkale/convert/bson/BsonByteBufferReader.java deleted file mode 100644 index f9ecc131a..000000000 --- a/src/main/java/org/redkale/convert/bson/BsonByteBufferReader.java +++ /dev/null @@ -1,172 +0,0 @@ -/* - * 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.bson; - -import java.nio.*; -import org.redkale.convert.*; -import static org.redkale.convert.Reader.SIGN_NULL; -import org.redkale.util.*; - -/** - * - * @author zhangjx - */ -public class BsonByteBufferReader extends BsonReader { - - private ByteBuffer[] buffers; - - private int currentIndex = 0; - - private ByteBuffer currentBuffer; - - protected BsonByteBufferReader(ByteBuffer... buffers) { - this.buffers = buffers; - if (buffers != null && buffers.length > 0) this.currentBuffer = buffers[currentIndex]; - } - - @Override - protected boolean recycle() { - super.recycle(); // this.position 初始化值为-1 - this.currentIndex = 0; - this.currentBuffer = null; - this.buffers = null; - return false; - } - - @Override - protected byte currentByte() { - return currentBuffer.get(currentBuffer.position()); - } - - /** - * 判断下一个非空白字节是否为[ - * - * @return 数组长度或 SIGN_NULL - */ - @Override - public final int readArrayB() { - short bt = readShort(); - if (bt == Reader.SIGN_NULL) return bt; - short lt = readShort(); - return (bt & 0xffff) << 16 | (lt & 0xffff); - } -//------------------------------------------------------------ - - @Override - public final boolean readBoolean() { - return readByte() == 1; - } - - @Override - public byte readByte() { - if (this.currentBuffer.hasRemaining()) { - this.position++; - return this.currentBuffer.get(); - } - for (;;) { - this.currentBuffer = this.buffers[++this.currentIndex]; - if (this.currentBuffer.hasRemaining()) { - this.position++; - return this.currentBuffer.get(); - } - } - } - - @Override - public final char readChar() { - if (this.currentBuffer != null) { - int remain = this.currentBuffer.remaining(); - if (remain >= 2) { - this.position += 2; - return this.currentBuffer.getChar(); - } - } - return (char) ((0xff00 & (readByte() << 8)) | (0xff & readByte())); - } - - @Override - public final short readShort() { - if (this.currentBuffer != null) { - int remain = this.currentBuffer.remaining(); - if (remain >= 2) { - this.position += 2; - return this.currentBuffer.getShort(); - } - } - return (short) ((0xff00 & (readByte() << 8)) | (0xff & readByte())); - } - - @Override - public final int readInt() { - if (this.currentBuffer != null) { - int remain = this.currentBuffer.remaining(); - if (remain >= 4) { - this.position += 4; - return this.currentBuffer.getInt(); - } - } - return ((readByte() & 0xff) << 24) | ((readByte() & 0xff) << 16) | ((readByte() & 0xff) << 8) | (readByte() & 0xff); - } - - @Override - public final long readLong() { - if (this.currentBuffer != null) { - int remain = this.currentBuffer.remaining(); - if (remain >= 8) { - this.position += 8; - return this.currentBuffer.getLong(); - } - } - return ((((long) readByte() & 0xff) << 56) - | (((long) readByte() & 0xff) << 48) - | (((long) readByte() & 0xff) << 40) - | (((long) readByte() & 0xff) << 32) - | (((long) readByte() & 0xff) << 24) - | (((long) readByte() & 0xff) << 16) - | (((long) readByte() & 0xff) << 8) - | (((long) readByte() & 0xff))); - } - - protected byte[] read(final int len) { - byte[] bs = new byte[len]; - read(bs, 0); - return bs; - } - - private void read(final byte[] bs, final int pos) { - int remain = this.currentBuffer.remaining(); - if (remain < 1) { - this.currentBuffer = this.buffers[++this.currentIndex]; - read(bs, pos); - return; - } - int len = bs.length - pos; - if (remain >= len) { - this.position += len; - this.currentBuffer.get(bs, pos, len); - return; - } - this.currentBuffer.get(bs, pos, remain); - this.position += remain; - this.currentBuffer = this.buffers[++this.currentIndex]; - read(bs, pos + remain); - } - - @Override - public final String readSmallString() { - int len = 0xff & readByte(); - if (len == 0) return ""; - return new String(read(len)); - } - - @Override - public final String readString() { - int len = readInt(); - if (len == SIGN_NULL) return null; - if (len == 0) return ""; - return new String(Utility.decodeUTF8(read(len))); - } -} diff --git a/src/main/java/org/redkale/convert/bson/BsonByteBufferWriter.java b/src/main/java/org/redkale/convert/bson/BsonByteBufferWriter.java deleted file mode 100644 index 5bf18f4d2..000000000 --- a/src/main/java/org/redkale/convert/bson/BsonByteBufferWriter.java +++ /dev/null @@ -1,142 +0,0 @@ -/* - * 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.bson; - -import java.nio.*; -import java.util.function.*; - -/** - * - *

- * 详情见: http://www.redkale.org - * - * @author zhangjx - */ -public class BsonByteBufferWriter extends BsonWriter { - - private final Supplier supplier; - - private ByteBuffer[] buffers; - - private int index; - - public BsonByteBufferWriter(Supplier supplier) { - this(false, supplier); - } - - protected BsonByteBufferWriter(boolean tiny, Supplier supplier) { - super((byte[]) null); - this.tiny = tiny; - this.supplier = supplier; - } - - @Override - public ByteBuffer[] toBuffers() { - if (buffers == null) return new ByteBuffer[0]; - for (int i = index; i < this.buffers.length; i++) { - ByteBuffer buf = this.buffers[i]; - if (buf.position() != 0) buf.flip(); - } - return this.buffers; - } - - @Override - public byte[] toArray() { - if (buffers == null) return new byte[0]; - int pos = 0; - byte[] bytes = new byte[this.count]; - for (ByteBuffer buf : toBuffers()) { - int r = buf.remaining(); - buf.get(bytes, pos, r); - buf.flip(); - pos += r; - } - return bytes; - } - - @Override - public String toString() { - return this.getClass().getSimpleName() + "[count=" + this.count + "]"; - } - - @Override - public BsonByteBufferWriter tiny(boolean tiny) { - this.tiny = tiny; - return this; - } - - @Override - protected int expand(final int byteLength) { - if (this.buffers == null) { - this.index = 0; - this.buffers = new ByteBuffer[]{supplier.get()}; - } - ByteBuffer buffer = this.buffers[index]; - if (!buffer.hasRemaining()) { - buffer.flip(); - buffer = supplier.get(); - ByteBuffer[] bufs = new ByteBuffer[this.buffers.length + 1]; - System.arraycopy(this.buffers, 0, bufs, 0, this.buffers.length); - bufs[this.buffers.length] = buffer; - this.buffers = bufs; - this.index++; - } - int len = buffer.remaining(); - int size = 0; - while (len < byteLength) { - buffer = supplier.get(); - ByteBuffer[] bufs = new ByteBuffer[this.buffers.length + 1]; - System.arraycopy(this.buffers, 0, bufs, 0, this.buffers.length); - bufs[this.buffers.length] = buffer; - this.buffers = bufs; - len += buffer.remaining(); - size++; - } - return size; - } - - @Override - public void writeTo(final byte[] chs, final int start, final int len) { - if (expand(len) == 0) { - this.buffers[index].put(chs, start, len); - } else { - ByteBuffer buffer = this.buffers[index]; - final int end = start + len; - int remain = len; //还剩多少没有写 - while (remain > 0) { - final int br = buffer.remaining(); - if (remain > br) { //一个buffer写不完 - buffer.put(chs, end - remain, br); - buffer = nextByteBuffer(); - remain -= br; - } else { - buffer.put(chs, end - remain, remain); - remain = 0; - } - } - } - this.count += len; - } - - private ByteBuffer nextByteBuffer() { - this.buffers[this.index].flip(); - return this.buffers[++this.index]; - } - - @Override - public void writeTo(final byte ch) { - expand(1); - this.buffers[index].put(ch); - count++; - } - - @Override - protected boolean recycle() { - this.index = 0; - this.buffers = null; - return false; - } -} diff --git a/src/main/java/org/redkale/convert/bson/BsonConvert.java b/src/main/java/org/redkale/convert/bson/BsonConvert.java deleted file mode 100644 index 2d77dc0f5..000000000 --- a/src/main/java/org/redkale/convert/bson/BsonConvert.java +++ /dev/null @@ -1,214 +0,0 @@ -/* - * 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.bson; - -import java.io.*; -import java.lang.reflect.*; -import java.nio.*; -import java.util.function.*; -import org.redkale.convert.*; -import org.redkale.util.*; - -/** - *

- * BSON协议格式:
- *  1). 基本数据类型: 直接转换成byte[]
- *  2). SmallString(无特殊字符且长度小于256的字符串): length(1 byte) + byte[](utf8); 通常用于类名、字段名、枚举。
- *  3). String: length(4 bytes) + byte[](utf8);
- *  4). 数组: length(4 bytes) + byte[]...
- *  5). Object:
- *      1. realclass (SmallString) (如果指定格式化的class与实体对象的class不一致才会有该值, 该值可以使用@ConvertEntity给其取个别名)
- *      2. 空字符串(SmallString)
- *      3. SIGN_OBJECTB 标记位,值固定为0xBB (short)
- *      4. 循环字段值:
- *          4.1 SIGN_HASNEXT 标记位,值固定为1 (byte)
- *          4.2 字段类型; 1-9为基本类型和字符串; 101-109为基本类型和字符串的数组; 127为Object
- *          4.3 字段名 (SmallString)
- *          4.4 字段的值Object
- *      5. SIGN_NONEXT 标记位,值固定为0 (byte)
- *      6. SIGN_OBJECTE 标记位,值固定为0xEE (short)
- *
- * 
- *

- * 详情见: http://www.redkale.org - * - * @author zhangjx - */ -public final class BsonConvert extends Convert { - - private static final ObjectPool readerPool = BsonReader.createPool(Integer.getInteger("convert.bson.pool.size", 16)); - - private static final ObjectPool writerPool = BsonWriter.createPool(Integer.getInteger("convert.bson.pool.size", 16)); - - private final boolean tiny; - - protected BsonConvert(ConvertFactory factory, boolean tiny) { - super(factory); - this.tiny = tiny; - } - - @Override - public BsonFactory getFactory() { - return (BsonFactory) factory; - } - - public static BsonConvert root() { - return BsonFactory.root().getConvert(); - } - - //------------------------------ reader ----------------------------------------------------------- - public BsonReader pollBsonReader(final ByteBuffer... buffers) { - return new BsonByteBufferReader(buffers); - } - - public BsonReader pollBsonReader(final InputStream in) { - return new BsonStreamReader(in); - } - - public BsonReader pollBsonReader() { - return readerPool.get(); - } - - public void offerBsonReader(final BsonReader in) { - if (in != null) readerPool.offer(in); - } - - //------------------------------ writer ----------------------------------------------------------- - public BsonByteBufferWriter pollBsonWriter(final Supplier supplier) { - return new BsonByteBufferWriter(tiny, supplier); - } - - public BsonWriter pollBsonWriter(final OutputStream out) { - return new BsonStreamWriter(tiny, out); - } - - public BsonWriter pollBsonWriter() { - return writerPool.get().tiny(tiny); - } - - public void offerBsonWriter(final BsonWriter out) { - if (out != null) writerPool.offer(out); - } - - //------------------------------ convertFrom ----------------------------------------------------------- - public T convertFrom(final Type type, final byte[] bytes) { - if (bytes == null) return null; - return convertFrom(type, bytes, 0, bytes.length); - } - - public T convertFrom(final Type type, final byte[] bytes, final int start, final int len) { - if (type == null) return null; - final BsonReader in = readerPool.get(); - in.setBytes(bytes, start, len); - @SuppressWarnings("unchecked") - T rs = (T) factory.loadDecoder(type).convertFrom(in); - readerPool.offer(in); - return rs; - } - - public T convertFrom(final Type type, final InputStream in) { - if (type == null || in == null) return null; - return (T) factory.loadDecoder(type).convertFrom(new BsonStreamReader(in)); - } - - public T convertFrom(final Type type, final ByteBuffer... buffers) { - if (type == null || buffers.length < 1) return null; - return (T) factory.loadDecoder(type).convertFrom(new BsonByteBufferReader(buffers)); - } - - public T convertFrom(final Type type, final BsonReader reader) { - if (type == null) return null; - @SuppressWarnings("unchecked") - T rs = (T) factory.loadDecoder(type).convertFrom(reader); - return rs; - } - - //------------------------------ convertTo ----------------------------------------------------------- - public byte[] convertTo(final Object value) { - if (value == null) { - final BsonWriter out = writerPool.get().tiny(tiny); - out.writeNull(); - byte[] result = out.toArray(); - writerPool.offer(out); - return result; - } - return convertTo(value.getClass(), value); - } - - public byte[] convertTo(final Type type, final Object value) { - if (type == null) return null; - final BsonWriter out = writerPool.get().tiny(tiny); - factory.loadEncoder(type).convertTo(out, value); - byte[] result = out.toArray(); - writerPool.offer(out); - return result; - } - - public void convertTo(final OutputStream out, final Object value) { - if (value == null) { - new BsonStreamWriter(tiny, out).writeNull(); - } else { - factory.loadEncoder(value.getClass()).convertTo(new BsonStreamWriter(tiny, out), value); - } - } - - public void convertTo(final OutputStream out, final Type type, final Object value) { - if (type == null) return; - if (value == null) { - new BsonStreamWriter(tiny, out).writeNull(); - } else { - factory.loadEncoder(type).convertTo(new BsonStreamWriter(tiny, out), value); - } - } - - public ByteBuffer[] convertTo(final Supplier supplier, final Type type, final Object value) { - if (supplier == null || type == null) return null; - BsonByteBufferWriter out = new BsonByteBufferWriter(tiny, supplier); - if (value == null) { - out.writeNull(); - } else { - factory.loadEncoder(type).convertTo(out, value); - } - return out.toBuffers(); - } - - public ByteBuffer[] convertTo(final Supplier supplier, final Object value) { - if (supplier == null) return null; - BsonByteBufferWriter out = new BsonByteBufferWriter(tiny, supplier); - if (value == null) { - out.writeNull(); - } else { - factory.loadEncoder(value.getClass()).convertTo(out, value); - } - return out.toBuffers(); - } - - public void convertTo(final BsonWriter writer, final Object value) { - if (value == null) { - writer.writeNull(); - } else { - factory.loadEncoder(value.getClass()).convertTo(writer, value); - } - } - - public void convertTo(final BsonWriter writer, final Type type, final Object value) { - if (type == null) return; - factory.loadEncoder(type).convertTo(writer, value); - } - - public BsonWriter convertToWriter(final Object value) { - if (value == null) return null; - return convertToWriter(value.getClass(), value); - } - - public BsonWriter convertToWriter(final Type type, final Object value) { - if (type == null) return null; - final BsonWriter out = writerPool.get().tiny(tiny); - factory.loadEncoder(type).convertTo(out, value); - return out; - } - -} diff --git a/src/main/java/org/redkale/convert/bson/BsonFactory.java b/src/main/java/org/redkale/convert/bson/BsonFactory.java deleted file mode 100644 index 67c6a2af7..000000000 --- a/src/main/java/org/redkale/convert/bson/BsonFactory.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * 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.bson; - -import java.io.Serializable; -import org.redkale.convert.*; - -/** - * - *

- * 详情见: http://www.redkale.org - * - * @author zhangjx - */ -@SuppressWarnings("unchecked") -public final class BsonFactory extends ConvertFactory { - - private static final BsonFactory instance = new BsonFactory(null, Boolean.getBoolean("convert.bson.tiny")); - - static final Decodeable objectDecoder = instance.loadDecoder(Object.class); - - static final Encodeable objectEncoder = instance.loadEncoder(Object.class); - - static { - instance.register(Serializable.class, objectDecoder); - instance.register(Serializable.class, objectEncoder); - } - - private BsonFactory(BsonFactory parent, boolean tiny) { - super(parent, tiny); - } - - @Override - public BsonFactory tiny(boolean tiny) { - this.tiny = tiny; - return this; - } - - public static BsonFactory root() { - return instance; - } - - @Override - public final BsonConvert getConvert() { - if (convert == null) convert = new BsonConvert(this, tiny); - return (BsonConvert) convert; - } - - @Override - public BsonFactory createChild() { - return new BsonFactory(this, this.tiny); - } - - @Override - public BsonFactory createChild(boolean tiny) { - return new BsonFactory(this, tiny); - } - - @Override - public ConvertType getConvertType() { - return ConvertType.BSON; - } - - @Override - public boolean isReversible() { - return true; - } - -} diff --git a/src/main/java/org/redkale/convert/bson/BsonReader.java b/src/main/java/org/redkale/convert/bson/BsonReader.java deleted file mode 100644 index 9759032ff..000000000 --- a/src/main/java/org/redkale/convert/bson/BsonReader.java +++ /dev/null @@ -1,324 +0,0 @@ -/* - * 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.bson; - -import java.util.function.*; -import org.redkale.convert.*; -import static org.redkale.convert.Reader.SIGN_NULL; -import org.redkale.convert.ext.*; -import org.redkale.util.*; - -/** - * - *

- * 详情见: http://www.redkale.org - * - * @author zhangjx - */ -public class BsonReader extends Reader { - - public static final short SIGN_OBJECTB = (short) 0xBB; - - public static final short SIGN_OBJECTE = (short) 0xEE; - - public static final byte SIGN_HASNEXT = 1; - - public static final byte SIGN_NONEXT = 0; - - public static final byte VERBOSE_NO = 1; - - public static final byte VERBOSE_YES = 2; - - protected byte typeval; //字段的类型值 对应 BsonWriter.writeField - - protected int position = -1; - - private byte[] content; - - public BsonReader() { - } - - public static ObjectPool createPool(int max) { - return new ObjectPool(max, new Creator() { - - @Override - public BsonReader create(Object... params) { - return new BsonReader(); - } - }, null, new Predicate() { - - @Override - public boolean test(BsonReader t) { - return t.recycle(); - } - }); - } - - public BsonReader(byte[] bytes) { - setBytes(bytes, 0, bytes.length); - } - - public BsonReader(byte[] bytes, int start, int len) { - setBytes(bytes, start, len); - } - - public final void setBytes(byte[] bytes) { - if (bytes == null) { - this.position = 0; - } else { - setBytes(bytes, 0, bytes.length); - } - } - - public final void setBytes(byte[] bytes, int start, int len) { - if (bytes == null) { - this.position = 0; - } else { - this.content = bytes; - this.position = start - 1; - //this.limit = start + len - 1; - } - } - - protected boolean recycle() { - this.position = -1; - this.typeval = 0; - //this.limit = -1; - this.content = null; - return true; - } - - public void close() { - this.recycle(); - } - - /** - * 跳过属性的值 - */ - @Override - public final void skipValue() { - if (typeval == 0) return; - final byte val = this.typeval; - this.typeval = 0; - switch (val) { - case 1: readBoolean(); - break; - case 2: readByte(); - break; - case 3: readShort(); - break; - case 4: readChar(); - break; - case 5: readInt(); - break; - case 6: readLong(); - break; - case 7: readFloat(); - break; - case 8: readDouble(); - break; - case 9: readString(); - break; - case 101: - BoolArraySimpledCoder.instance.convertFrom(this); - break; - case 102: - ByteArraySimpledCoder.instance.convertFrom(this); - break; - case 103: - ShortArraySimpledCoder.instance.convertFrom(this); - break; - case 104: - CharArraySimpledCoder.instance.convertFrom(this); - break; - case 105: - IntArraySimpledCoder.instance.convertFrom(this); - break; - case 106: - LongArraySimpledCoder.instance.convertFrom(this); - break; - case 107: - FloatArraySimpledCoder.instance.convertFrom(this); - break; - case 108: - DoubleArraySimpledCoder.instance.convertFrom(this); - break; - case 109: - StringArraySimpledCoder.instance.convertFrom(this); - break; - case 127: - BsonFactory.objectDecoder.convertFrom(this); - break; - } - } - - @Override - public final String readObjectB(final Class clazz) { - this.fieldIndex = 0; //必须要重置为0 - final String newcls = readClassName(); - if (newcls != null && !newcls.isEmpty()) return newcls; - short bt = readShort(); - if (bt == Reader.SIGN_NULL) return null; - if (bt != SIGN_OBJECTB) { - throw new ConvertException("a bson object must begin with " + (SIGN_OBJECTB) - + " (position = " + position + ") but '" + currentByte() + "'"); - } - return ""; - } - - @Override - public final void readObjectE(final Class clazz) { - if (readShort() != SIGN_OBJECTE) { - throw new ConvertException("a bson object must end with " + (SIGN_OBJECTE) - + " (position = " + position + ") but '" + currentByte() + "'"); - } - } - - protected byte currentByte() { - return this.content[this.position]; - } - - @Override - public final int readMapB() { - return readArrayB(); - } - - @Override - public final void readMapE() { - } - - /** - * 判断下一个非空白字节是否为[ - * - * @return 数组长度或SIGN_NULL - */ - @Override - public int readArrayB() { - short bt = readShort(); - if (bt == Reader.SIGN_NULL) return bt; - return (bt & 0xffff) << 16 | ((content[++this.position] & 0xff) << 8) | (content[++this.position] & 0xff); - } - - @Override - public final void readArrayE() { - } - - /** - * 判断下一个非空白字节是否: - */ - @Override - public final void readBlank() { - } - - /** - * 判断对象是否存在下一个属性或者数组是否存在下一个元素 - * - * @return 是否存在 - */ - @Override - public final boolean hasNext() { - byte b = readByte(); - if (b == SIGN_HASNEXT) return true; - if (b != SIGN_NONEXT) throw new ConvertException("hasNext option must be (" + (SIGN_HASNEXT) - + " or " + (SIGN_NONEXT) + ") but '" + b + "' at position(" + this.position + ")"); - return false; - } - - @Override - public final DeMember readFieldName(final DeMember[] members) { - final String exceptedfield = readSmallString(); - this.typeval = readByte(); - final int len = members.length; - if (this.fieldIndex >= len) this.fieldIndex = 0; - for (int k = this.fieldIndex; k < len; k++) { - if (exceptedfield.equals(members[k].getAttribute().field())) { - this.fieldIndex = k; - return members[k]; - } - } - for (int k = 0; k < this.fieldIndex; k++) { - if (exceptedfield.equals(members[k].getAttribute().field())) { - this.fieldIndex = k; - return members[k]; - } - } - return null; - } - - //------------------------------------------------------------ - @Override - public boolean readBoolean() { - return content[++this.position] == 1; - } - - @Override - public byte readByte() { - return content[++this.position]; - } - - @Override - public char readChar() { - return (char) ((0xff00 & (content[++this.position] << 8)) | (0xff & content[++this.position])); - } - - @Override - public short readShort() { - return (short) ((0xff00 & (content[++this.position] << 8)) | (0xff & content[++this.position])); - } - - @Override - public int readInt() { - return ((content[++this.position] & 0xff) << 24) | ((content[++this.position] & 0xff) << 16) - | ((content[++this.position] & 0xff) << 8) | (content[++this.position] & 0xff); - } - - @Override - public long readLong() { - return ((((long) content[++this.position] & 0xff) << 56) - | (((long) content[++this.position] & 0xff) << 48) - | (((long) content[++this.position] & 0xff) << 40) - | (((long) content[++this.position] & 0xff) << 32) - | (((long) content[++this.position] & 0xff) << 24) - | (((long) content[++this.position] & 0xff) << 16) - | (((long) content[++this.position] & 0xff) << 8) - | (((long) content[++this.position] & 0xff))); - } - - @Override - public final float readFloat() { - return Float.intBitsToFloat(readInt()); - } - - @Override - public final double readDouble() { - return Double.longBitsToDouble(readLong()); - } - - @Override - public final String readClassName() { - return readSmallString(); - } - - @Override - public String readSmallString() { - int len = 0xff & readByte(); - if (len == 0) return ""; - String value = new String(content, ++this.position, len); - this.position += len - 1; //上一行已经++this.position,所以此处要-1 - return value; - } - - @Override - public String readString() { - int len = readInt(); - if (len == SIGN_NULL) return null; - if (len == 0) return ""; - String value = new String(Utility.decodeUTF8(content, ++this.position, len)); - this.position += len - 1;//上一行已经++this.position,所以此处要-1 - return value; - } - -} diff --git a/src/main/java/org/redkale/convert/bson/BsonSimpledCoder.java b/src/main/java/org/redkale/convert/bson/BsonSimpledCoder.java deleted file mode 100644 index d5b497d51..000000000 --- a/src/main/java/org/redkale/convert/bson/BsonSimpledCoder.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * 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.bson; - -import org.redkale.convert.SimpledCoder; - -/** - * - *

- * 详情见: http://www.redkale.org - * - * @author zhangjx - * @param 序列化/反解析的数据类型 - */ -public abstract class BsonSimpledCoder extends SimpledCoder { - -} diff --git a/src/main/java/org/redkale/convert/bson/BsonStreamReader.java b/src/main/java/org/redkale/convert/bson/BsonStreamReader.java deleted file mode 100644 index cd314d3dc..000000000 --- a/src/main/java/org/redkale/convert/bson/BsonStreamReader.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * 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.bson; - -import java.io.*; -import org.redkale.convert.*; - -/** - * - * @author zhangjx - */ -class BsonStreamReader extends BsonByteBufferReader { - - private InputStream in; - - private byte currByte; - - protected BsonStreamReader(InputStream in) { - this.in = in; - } - - @Override - protected boolean recycle() { - super.recycle(); // this.position 初始化值为-1 - this.in = null; - this.currByte = 0; - return false; - } - - @Override - public byte readByte() { - try { - byte b = (currByte = (byte) in.read()); - this.position++; - return b; - } catch (IOException e) { - throw new ConvertException(e); - } - } - - @Override - protected byte currentByte() { - return currByte; - } - - @Override - protected byte[] read(final int len) { - byte[] bs = new byte[len]; - try { - in.read(bs); - this.position += len; - } catch (IOException e) { - throw new ConvertException(e); - } - return bs; - } -} diff --git a/src/main/java/org/redkale/convert/bson/BsonStreamWriter.java b/src/main/java/org/redkale/convert/bson/BsonStreamWriter.java deleted file mode 100644 index c0c22fd10..000000000 --- a/src/main/java/org/redkale/convert/bson/BsonStreamWriter.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * 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.bson; - -import java.io.*; -import org.redkale.convert.*; - -/** - * - * @author zhangjx - */ -class BsonStreamWriter extends BsonByteBufferWriter { - - private OutputStream out; - - protected BsonStreamWriter(boolean tiny, OutputStream out) { - super(tiny, null); - this.out = out; - } - - @Override - protected boolean recycle() { - super.recycle(); - this.out = null; - return false; - } - - @Override - public void writeTo(final byte[] chs, final int start, final int len) { - try { - out.write(chs, start, len); - } catch (IOException e) { - throw new ConvertException(e); - } - } - - @Override - public void writeTo(final byte ch) { - try { - out.write((byte) ch); - } catch (IOException e) { - throw new ConvertException(e); - } - } -} diff --git a/src/main/java/org/redkale/convert/bson/BsonWriter.java b/src/main/java/org/redkale/convert/bson/BsonWriter.java deleted file mode 100644 index 40c1925d3..000000000 --- a/src/main/java/org/redkale/convert/bson/BsonWriter.java +++ /dev/null @@ -1,301 +0,0 @@ -/* - * 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.bson; - -import java.nio.*; -import java.util.function.*; -import org.redkale.convert.*; -import org.redkale.util.*; - -/** - * - *

- * 详情见: http://www.redkale.org - * - * @author zhangjx - */ -public class BsonWriter extends Writer { - - private static final int defaultSize = Integer.getInteger("convert.bson.writer.buffer.defsize", 1024); - - private byte[] content; - - protected int count; - - protected boolean tiny; - - public static ObjectPool createPool(int max) { - return new ObjectPool(max, new Creator() { - - @Override - public BsonWriter create(Object... params) { - return new BsonWriter(); - } - }, null, new Predicate() { - - @Override - public boolean test(BsonWriter t) { - return t.recycle(); - } - }); - } - - public byte[] toArray() { - if (count == content.length) return content; - byte[] newdata = new byte[count]; - System.arraycopy(content, 0, newdata, 0, count); - return newdata; - } - - public ByteBuffer[] toBuffers() { - return new ByteBuffer[]{ByteBuffer.wrap(content, 0, count)}; - } - - protected BsonWriter(byte[] bs) { - this.content = bs; - } - - public BsonWriter() { - this(defaultSize); - } - - public BsonWriter(int size) { - this.content = new byte[size > 128 ? size : 128]; - } - - @Override - public final boolean tiny() { - return tiny; - } - - public BsonWriter tiny(boolean tiny) { - this.tiny = tiny; - return this; - } - - //----------------------------------------------------------------------- - //----------------------------------------------------------------------- - /** - * 扩充指定长度的缓冲区 - * - * @param len 扩容长度 - * @return 固定0 - */ - protected int expand(int len) { - int newcount = count + len; - if (newcount <= content.length) return 0; - byte[] newdata = new byte[Math.max(content.length * 3 / 2, newcount)]; - System.arraycopy(content, 0, newdata, 0, count); - this.content = newdata; - return 0; - } - - public void writeTo(final byte ch) { - expand(1); - content[count++] = ch; - } - - public final void writeTo(final byte... chs) { - writeTo(chs, 0, chs.length); - } - - public void writeTo(final byte[] chs, final int start, final int len) { - expand(len); - System.arraycopy(chs, start, content, count, len); - count += len; - } - - protected boolean recycle() { - this.count = 0; - if (this.content.length > defaultSize) { - this.content = new byte[defaultSize]; - } - return true; - } - - @Override - public String toString() { - return this.getClass().getSimpleName() + "[count=" + this.count + "]"; - } - - //------------------------------------------------------------------------ - public final int count() { - return this.count; - } - - @Override - public final void writeBoolean(boolean value) { - writeTo(value ? (byte) 1 : (byte) 0); - } - - @Override - public final void writeByte(byte value) { - writeTo(value); - } - - @Override - public final void writeChar(final char value) { - writeTo((byte) ((value & 0xFF00) >> 8), (byte) (value & 0xFF)); - } - - @Override - public final void writeShort(short value) { - writeTo((byte) (value >> 8), (byte) value); - } - - @Override - public final void writeInt(int value) { - writeTo((byte) (value >> 24), (byte) (value >> 16), (byte) (value >> 8), (byte) value); - } - - @Override - public final void writeLong(long value) { - writeTo((byte) (value >> 56), (byte) (value >> 48), (byte) (value >> 40), (byte) (value >> 32), - (byte) (value >> 24), (byte) (value >> 16), (byte) (value >> 8), (byte) value); - } - - @Override - public final void writeFloat(float value) { - writeInt(Float.floatToIntBits(value)); - } - - @Override - public final void writeDouble(double value) { - writeLong(Double.doubleToLongBits(value)); - } - - @Override - public final void wirteClassName(String clazz) { - writeSmallString(clazz == null ? "" : clazz); - } - - @Override - public final void writeObjectB(Object obj) { - super.writeObjectB(obj); - writeSmallString(""); - writeShort(BsonReader.SIGN_OBJECTB); - } - - @Override - public final void writeObjectE(Object obj) { - writeByte(BsonReader.SIGN_NONEXT); - writeShort(BsonReader.SIGN_OBJECTE); - } - - @Override - public final void writeFieldName( Attribute attribute) { - writeByte(BsonReader.SIGN_HASNEXT); - writeSmallString(attribute.field()); - byte typeval = 127; //字段的类型值 - final Class type = attribute.type(); - if (type == boolean.class || type == Boolean.class) { - typeval = 1; - } else if (type == byte.class || type == Byte.class) { - typeval = 2; - } else if (type == short.class || type == Short.class) { - typeval = 3; - } else if (type == char.class || type == Character.class) { - typeval = 4; - } else if (type == int.class || type == Integer.class) { - typeval = 5; - } else if (type == long.class || type == Long.class) { - typeval = 6; - } else if (type == float.class || type == Float.class) { - typeval = 7; - } else if (type == double.class || type == Double.class) { - typeval = 8; - } else if (type == String.class) { - typeval = 9; - } else if (type == boolean[].class || type == Boolean[].class) { - typeval = 101; - } else if (type == byte[].class || type == Byte[].class) { - typeval = 102; - } else if (type == short[].class || type == Short[].class) { - typeval = 103; - } else if (type == char[].class || type == Character[].class) { - typeval = 104; - } else if (type == int[].class || type == Integer[].class) { - typeval = 105; - } else if (type == long[].class || type == Long[].class) { - typeval = 106; - } else if (type == float[].class || type == Float[].class) { - typeval = 107; - } else if (type == double[].class || type == Double[].class) { - typeval = 108; - } else if (type == String[].class) { - typeval = 109; - } - writeByte(typeval); - } - - /** - * 对于类的字段名、枚举值这些长度一般不超过255且不会出现双字节字符的字符串采用writeSmallString处理, readSmallString用于读取 - * - * @param value String值 - */ - @Override - public final void writeSmallString(String value) { - if (value.isEmpty()) { - writeTo((byte) 0); - return; - } - char[] chars = Utility.charArray(value); - if (chars.length > 255) throw new ConvertException("'" + value + "' has very long length"); - byte[] bytes = new byte[chars.length + 1]; - bytes[0] = (byte) chars.length; - for (int i = 0; i < chars.length; i++) { - if (chars[i] > Byte.MAX_VALUE) throw new ConvertException("'" + value + "' has double-word"); - bytes[i + 1] = (byte) chars[i]; - } - writeTo(bytes); - } - - @Override - public final void writeString(String value) { - if (value == null) { - writeInt(Reader.SIGN_NULL); - return; - } else if (value.isEmpty()) { - writeInt(0); - return; - } - byte[] bytes = Utility.encodeUTF8(value); - writeInt(bytes.length); - writeTo(bytes); - } - - @Override - public final void writeNull() { - writeShort(Reader.SIGN_NULL); - } - - @Override - public final void writeArrayB(int size) { - writeInt(size); - } - - @Override - public final void writeArrayMark() { - } - - @Override - public final void writeArrayE() { - } - - @Override - public void writeMapB(int size) { - writeArrayB(size); - } - - @Override - public final void writeMapMark() { - } - - @Override - public final void writeMapE() { - } - -} diff --git a/src/main/java/org/redkale/convert/bson/package-info.java b/src/main/java/org/redkale/convert/bson/package-info.java deleted file mode 100644 index 6518406c1..000000000 --- a/src/main/java/org/redkale/convert/bson/package-info.java +++ /dev/null @@ -1,4 +0,0 @@ -/** - * 提供BSON的序列化和反解析功能 - */ -package org.redkale.convert.bson; diff --git a/src/main/java/org/redkale/convert/ext/BigIntegerSimpledCoder.java b/src/main/java/org/redkale/convert/ext/BigIntegerSimpledCoder.java deleted file mode 100644 index 4723235e8..000000000 --- a/src/main/java/org/redkale/convert/ext/BigIntegerSimpledCoder.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * 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.ext; - -import org.redkale.convert.SimpledCoder; -import org.redkale.convert.Writer; -import org.redkale.convert.Reader; -import java.math.BigInteger; - -/** - * BigInteger 的SimpledCoder实现 - * - *

- * 详情见: http://www.redkale.org - * - * @author zhangjx - * @param Reader输入的子类型 - * @param Writer输出的子类型 - */ -public final class BigIntegerSimpledCoder extends SimpledCoder { - - public static final BigIntegerSimpledCoder instance = new BigIntegerSimpledCoder(); - - @Override - public void convertTo(W out, BigInteger value) { - if (value == null) { - out.writeNull(); - return; - } - ByteArraySimpledCoder.instance.convertTo(out, value.toByteArray()); - } - - @Override - public BigInteger convertFrom(R in) { - byte[] bytes = ByteArraySimpledCoder.instance.convertFrom(in); - return bytes == null ? null : new BigInteger(bytes); - } - - /** - * BigInteger 的JsonSimpledCoder实现 - * - * @param Reader输入的子类型 - * @param Writer输出的子类型 - */ - public static class BigIntegerJsonSimpledCoder extends SimpledCoder { - - public static final BigIntegerJsonSimpledCoder instance = new BigIntegerJsonSimpledCoder(); - - @Override - public void convertTo(final Writer out, final BigInteger value) { - if (value == null) { - out.writeNull(); - } else { - out.writeString(value.toString()); - } - } - - @Override - public BigInteger convertFrom(Reader in) { - final String str = in.readString(); - if (str == null) return null; - return new BigInteger(str); - } - } -} diff --git a/src/main/java/org/redkale/convert/ext/BoolArraySimpledCoder.java b/src/main/java/org/redkale/convert/ext/BoolArraySimpledCoder.java deleted file mode 100644 index 2af5397bf..000000000 --- a/src/main/java/org/redkale/convert/ext/BoolArraySimpledCoder.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * 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.ext; - -import org.redkale.convert.Reader; -import org.redkale.convert.SimpledCoder; -import org.redkale.convert.Writer; - -/** - * boolean[] 的SimpledCoder实现 - * - *

- * 详情见: http://www.redkale.org - * - * @author zhangjx - * @param Reader输入的子类型 - * @param Writer输出的子类型 - */ -public final class BoolArraySimpledCoder extends SimpledCoder { - - public static final BoolArraySimpledCoder instance = new BoolArraySimpledCoder(); - - @Override - public void convertTo(W out, boolean[] values) { - if (values == null) { - out.writeNull(); - return; - } - out.writeArrayB(values.length); - boolean flag = false; - for (boolean v : values) { - if (flag) out.writeArrayMark(); - out.writeBoolean(v); - flag = true; - } - out.writeArrayE(); - } - - @Override - public boolean[] convertFrom(R in) { - int len = in.readArrayB(); - if (len == Reader.SIGN_NULL) return null; - if (len == Reader.SIGN_NOLENGTH) { - int size = 0; - boolean[] data = new boolean[8]; - while (in.hasNext()) { - if (size >= data.length) { - boolean[] newdata = new boolean[data.length + 4]; - System.arraycopy(data, 0, newdata, 0, size); - data = newdata; - } - data[size++] = in.readBoolean(); - } - in.readArrayE(); - boolean[] newdata = new boolean[size]; - System.arraycopy(data, 0, newdata, 0, size); - return newdata; - } else { - boolean[] values = new boolean[len]; - for (int i = 0; i < values.length; i++) { - values[i] = in.readBoolean(); - } - in.readArrayE(); - return values; - } - } - -} diff --git a/src/main/java/org/redkale/convert/ext/BoolSimpledCoder.java b/src/main/java/org/redkale/convert/ext/BoolSimpledCoder.java deleted file mode 100644 index 5f7905bec..000000000 --- a/src/main/java/org/redkale/convert/ext/BoolSimpledCoder.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * 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.ext; - -import org.redkale.convert.Reader; -import org.redkale.convert.SimpledCoder; -import org.redkale.convert.Writer; - -/** - * boolean 的SimpledCoder实现 - * - *

- * 详情见: http://www.redkale.org - * - * @author zhangjx - * @param Reader输入的子类型 - * @param Writer输出的子类型 - */ -public final class BoolSimpledCoder extends SimpledCoder { - - public static final BoolSimpledCoder instance = new BoolSimpledCoder(); - - @Override - public void convertTo(W out, Boolean value) { - out.writeBoolean(value); - } - - @Override - public Boolean convertFrom(R in) { - return in.readBoolean(); - } - -} diff --git a/src/main/java/org/redkale/convert/ext/ByteArraySimpledCoder.java b/src/main/java/org/redkale/convert/ext/ByteArraySimpledCoder.java deleted file mode 100644 index 6c6b21b06..000000000 --- a/src/main/java/org/redkale/convert/ext/ByteArraySimpledCoder.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * 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.ext; - -import org.redkale.convert.Reader; -import org.redkale.convert.SimpledCoder; -import org.redkale.convert.Writer; - -/** - * byte[] 的SimpledCoder实现 - * - *

- * 详情见: http://www.redkale.org - * - * @author zhangjx - * @param Reader输入的子类型 - * @param Writer输出的子类型 - */ -public final class ByteArraySimpledCoder extends SimpledCoder { - - public static final ByteArraySimpledCoder instance = new ByteArraySimpledCoder(); - - @Override - public void convertTo(W out, byte[] values) { - if (values == null) { - out.writeNull(); - return; - } - out.writeArrayB(values.length); - boolean flag = false; - for (byte v : values) { - if (flag) out.writeArrayMark(); - out.writeByte(v); - flag = true; - } - out.writeArrayE(); - } - - @Override - public byte[] convertFrom(R in) { - int len = in.readArrayB(); - if (len == Reader.SIGN_NULL) return null; - if (len == Reader.SIGN_NOLENGTH) { - int size = 0; - byte[] data = new byte[8]; - while (in.hasNext()) { - if (size >= data.length) { - byte[] newdata = new byte[data.length + 4]; - System.arraycopy(data, 0, newdata, 0, size); - data = newdata; - } - data[size++] = in.readByte(); - } - in.readArrayE(); - byte[] newdata = new byte[size]; - System.arraycopy(data, 0, newdata, 0, size); - return newdata; - } else { - byte[] values = new byte[len]; - for (int i = 0; i < values.length; i++) { - values[i] = in.readByte(); - } - in.readArrayE(); - return values; - } - } - -} diff --git a/src/main/java/org/redkale/convert/ext/ByteSimpledCoder.java b/src/main/java/org/redkale/convert/ext/ByteSimpledCoder.java deleted file mode 100644 index 041b7c804..000000000 --- a/src/main/java/org/redkale/convert/ext/ByteSimpledCoder.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * 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.ext; - -import org.redkale.convert.Reader; -import org.redkale.convert.SimpledCoder; -import org.redkale.convert.Writer; - -/** - * byte 的SimpledCoder实现 - * - *

- * 详情见: http://www.redkale.org - * - * @author zhangjx - * @param Reader输入的子类型 - * @param Writer输出的子类型 - */ -public final class ByteSimpledCoder extends SimpledCoder { - - public static final ByteSimpledCoder instance = new ByteSimpledCoder(); - - @Override - public void convertTo(W out, Byte value) { - out.writeByte(value); - } - - @Override - public Byte convertFrom(R in) { - return in.readByte(); - } - -} diff --git a/src/main/java/org/redkale/convert/ext/CharArraySimpledCoder.java b/src/main/java/org/redkale/convert/ext/CharArraySimpledCoder.java deleted file mode 100644 index 4a8589dd9..000000000 --- a/src/main/java/org/redkale/convert/ext/CharArraySimpledCoder.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * 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.ext; - -import org.redkale.convert.Reader; -import org.redkale.convert.SimpledCoder; -import org.redkale.convert.Writer; - -/** - * char[] 的SimpledCoder实现 - * - *

详情见: http://www.redkale.org - * @author zhangjx - * @param Reader输入的子类型 - * @param Writer输出的子类型 - */ -public final class CharArraySimpledCoder extends SimpledCoder { - - public static final CharArraySimpledCoder instance = new CharArraySimpledCoder(); - - @Override - public void convertTo(W out, char[] values) { - if (values == null) { - out.writeNull(); - return; - } - out.writeArrayB(values.length); - boolean flag = false; - for (char v : values) { - if (flag) out.writeArrayMark(); - out.writeChar(v); - flag = true; - } - out.writeArrayE(); - } - - @Override - public char[] convertFrom(R in) { - int len = in.readArrayB(); - if (len == Reader.SIGN_NULL) return null; - if (len == Reader.SIGN_NOLENGTH) { - int size = 0; - char[] data = new char[8]; - while (in.hasNext()) { - if (size >= data.length) { - char[] newdata = new char[data.length + 4]; - System.arraycopy(data, 0, newdata, 0, size); - data = newdata; - } - data[size++] = in.readChar(); - } - in.readArrayE(); - char[] newdata = new char[size]; - System.arraycopy(data, 0, newdata, 0, size); - return newdata; - } else { - char[] values = new char[len]; - for (int i = 0; i < values.length; i++) { - values[i] = in.readChar(); - } - in.readArrayE(); - return values; - } - } - -} diff --git a/src/main/java/org/redkale/convert/ext/CharSequenceSimpledCoder.java b/src/main/java/org/redkale/convert/ext/CharSequenceSimpledCoder.java deleted file mode 100644 index 0fcf32e98..000000000 --- a/src/main/java/org/redkale/convert/ext/CharSequenceSimpledCoder.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * 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.ext; - -import org.redkale.convert.*; - -/** - * CharSequence 的SimpledCoder实现 - * - *

详情见: http://www.redkale.org - * @author zhangjx - * @param Reader输入的子类型 - * @param Writer输出的子类型 - */ -public class CharSequenceSimpledCoder extends SimpledCoder { - - public static final CharSequenceSimpledCoder instance = new CharSequenceSimpledCoder(); - - @Override - public void convertTo(W out, CharSequence value) { - out.writeString(value == null ? null : value.toString()); - } - - @Override - public CharSequence convertFrom(R in) { - return in.readString(); - } -} diff --git a/src/main/java/org/redkale/convert/ext/CharSimpledCoder.java b/src/main/java/org/redkale/convert/ext/CharSimpledCoder.java deleted file mode 100644 index edea0bfd1..000000000 --- a/src/main/java/org/redkale/convert/ext/CharSimpledCoder.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * 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.ext; - -import org.redkale.convert.Reader; -import org.redkale.convert.SimpledCoder; -import org.redkale.convert.Writer; - -/** - * char 的SimpledCoder实现 - * - *

详情见: http://www.redkale.org - * @author zhangjx - * @param Reader输入的子类型 - * @param Writer输出的子类型 - */ -public final class CharSimpledCoder extends SimpledCoder { - - public static final CharSimpledCoder instance = new CharSimpledCoder(); - - @Override - public void convertTo(W out, Character value) { - out.writeChar(value); - } - - @Override - public Character convertFrom(R in) { - return in.readChar(); - } - -} diff --git a/src/main/java/org/redkale/convert/ext/CompletionHandlerSimpledCoder.java b/src/main/java/org/redkale/convert/ext/CompletionHandlerSimpledCoder.java deleted file mode 100644 index b4882a8a5..000000000 --- a/src/main/java/org/redkale/convert/ext/CompletionHandlerSimpledCoder.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * 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.ext; - -import java.nio.channels.*; -import org.redkale.convert.*; - -/** - * java.nio.channels.CompletionHandler 的SimpledCoder实现, 只输出null - * - *

- * 详情见: http://www.redkale.org - * - * @author zhangjx - * @param Reader输入的子类型 - * @param Writer输出的子类型 - */ -public final class CompletionHandlerSimpledCoder extends SimpledCoder { - - public static final CompletionHandlerSimpledCoder instance = new CompletionHandlerSimpledCoder(); - - @Override - public void convertTo(W out, CompletionHandler value) { - out.writeObjectNull(CompletionHandler.class); - } - - @Override - public CompletionHandler convertFrom(R in) { - in.readObjectB(CompletionHandler.class); - return null; - } - -} diff --git a/src/main/java/org/redkale/convert/ext/DLongSimpledCoder.java b/src/main/java/org/redkale/convert/ext/DLongSimpledCoder.java deleted file mode 100644 index 9dbd7eb22..000000000 --- a/src/main/java/org/redkale/convert/ext/DLongSimpledCoder.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * 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.ext; - -import org.redkale.convert.Reader; -import org.redkale.convert.Writer; -import org.redkale.convert.SimpledCoder; -import org.redkale.util.*; - -/** - * Dlong 的SimpledCoder实现 - * - *

- * 详情见: http://www.redkale.org - * - * @author zhangjx - * @param Reader输入的子类型 - * @param Writer输出的子类型 - */ -public final class DLongSimpledCoder extends SimpledCoder { - - private static final ByteArraySimpledCoder bsSimpledCoder = ByteArraySimpledCoder.instance; - - public static final DLongSimpledCoder instance = new DLongSimpledCoder(); - - @Override - public void convertTo(final W out, final DLong value) { - if (value == null) { - out.writeNull(); - } else { - bsSimpledCoder.convertTo(out, value.directBytes()); - } - } - - @Override - public DLong convertFrom(R in) { - byte[] bs = bsSimpledCoder.convertFrom(in); - if (bs == null) return null; - return DLong.create(bs); - } - - /** - * DLong 的JsonSimpledCoder实现 - * - * @param Reader输入的子类型 - * @param Writer输出的子类型 - */ - public static class DLongJsonSimpledCoder extends SimpledCoder { - - public static final DLongJsonSimpledCoder instance = new DLongJsonSimpledCoder(); - - @Override - public void convertTo(final Writer out, final DLong value) { - if (value == null) { - out.writeNull(); - } else { - out.writeSmallString(value.toString()); - } - } - - @Override - public DLong convertFrom(Reader in) { - final String str = in.readSmallString(); - if (str == null) return null; - return DLong.create(Utility.hexToBin(str)); - } - } -} diff --git a/src/main/java/org/redkale/convert/ext/DateSimpledCoder.java b/src/main/java/org/redkale/convert/ext/DateSimpledCoder.java deleted file mode 100644 index 79aa269ff..000000000 --- a/src/main/java/org/redkale/convert/ext/DateSimpledCoder.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * 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.ext; - -import org.redkale.convert.Reader; -import org.redkale.convert.SimpledCoder; -import org.redkale.convert.Writer; -import java.util.Date; - -/** - * Date 的SimpledCoder实现 - * - *

详情见: http://www.redkale.org - * @author zhangjx - * @param Reader输入的子类型 - * @param Writer输出的子类型 - */ -public final class DateSimpledCoder extends SimpledCoder { - - public static final DateSimpledCoder instance = new DateSimpledCoder(); - - @Override - public void convertTo(W out, Date value) { - out.writeLong(value.getTime()); - } - - @Override - public Date convertFrom(R in) { - return new Date(in.readLong()); - } - -} diff --git a/src/main/java/org/redkale/convert/ext/DoubleArraySimpledCoder.java b/src/main/java/org/redkale/convert/ext/DoubleArraySimpledCoder.java deleted file mode 100644 index ddc5cf259..000000000 --- a/src/main/java/org/redkale/convert/ext/DoubleArraySimpledCoder.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * 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.ext; - -import org.redkale.convert.Reader; -import org.redkale.convert.SimpledCoder; -import org.redkale.convert.Writer; - -/** - * double[] 的SimpledCoder实现 - * - *

详情见: http://www.redkale.org - * @author zhangjx - * @param Reader输入的子类型 - * @param Writer输出的子类型 - */ -public final class DoubleArraySimpledCoder extends SimpledCoder { - - public static final DoubleArraySimpledCoder instance = new DoubleArraySimpledCoder(); - - @Override - public void convertTo(W out, double[] values) { - if (values == null) { - out.writeNull(); - return; - } - out.writeArrayB(values.length); - boolean flag = false; - for (double v : values) { - if (flag) out.writeArrayMark(); - out.writeDouble(v); - flag = true; - } - out.writeArrayE(); - } - - @Override - public double[] convertFrom(R in) { - int len = in.readArrayB(); - if (len == Reader.SIGN_NULL) return null; - if (len == Reader.SIGN_NOLENGTH) { - int size = 0; - double[] data = new double[8]; - while (in.hasNext()) { - if (size >= data.length) { - double[] newdata = new double[data.length + 4]; - System.arraycopy(data, 0, newdata, 0, size); - data = newdata; - } - data[size++] = in.readDouble(); - } - in.readArrayE(); - double[] newdata = new double[size]; - System.arraycopy(data, 0, newdata, 0, size); - return newdata; - } else { - double[] values = new double[len]; - for (int i = 0; i < values.length; i++) { - values[i] = in.readDouble(); - } - in.readArrayE(); - return values; - } - } - -} diff --git a/src/main/java/org/redkale/convert/ext/DoubleSimpledCoder.java b/src/main/java/org/redkale/convert/ext/DoubleSimpledCoder.java deleted file mode 100644 index 346864533..000000000 --- a/src/main/java/org/redkale/convert/ext/DoubleSimpledCoder.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * 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.ext; - -import org.redkale.convert.Reader; -import org.redkale.convert.SimpledCoder; -import org.redkale.convert.Writer; - -/** - * double 的SimpledCoder实现 - * - *

详情见: http://www.redkale.org - * @author zhangjx - * @param Reader输入的子类型 - * @param Writer输出的子类型 - */ -public final class DoubleSimpledCoder extends SimpledCoder { - - public static final DoubleSimpledCoder instance = new DoubleSimpledCoder(); - - @Override - public void convertTo(W out, Double value) { - out.writeDouble(value); - } - - @Override - public Double convertFrom(R in) { - return in.readDouble(); - } - -} diff --git a/src/main/java/org/redkale/convert/ext/EnumSimpledCoder.java b/src/main/java/org/redkale/convert/ext/EnumSimpledCoder.java deleted file mode 100644 index 53ea7739a..000000000 --- a/src/main/java/org/redkale/convert/ext/EnumSimpledCoder.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * 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.ext; - -import org.redkale.convert.Reader; -import org.redkale.convert.SimpledCoder; -import org.redkale.convert.Writer; - -/** - * 枚举 的SimpledCoder实现 - * - *

- * 详情见: http://www.redkale.org - * - * @author zhangjx - * @param Reader输入的子类型 - * @param Writer输出的子类型 - * @param Enum的子类 - */ -public final class EnumSimpledCoder extends SimpledCoder { - - private final Class type; - - public EnumSimpledCoder(Class type) { - this.type = type; - } - - @Override - public void convertTo(final W out, final E value) { - if (value == null) { - out.writeNull(); - } else { - out.writeSmallString(value.toString()); - } - } - - @Override - @SuppressWarnings("unchecked") - public E convertFrom(final R in) { - String value = in.readSmallString(); - if (value == null) return null; - return (E) Enum.valueOf(type, value); - } - -} diff --git a/src/main/java/org/redkale/convert/ext/FloatArraySimpledCoder.java b/src/main/java/org/redkale/convert/ext/FloatArraySimpledCoder.java deleted file mode 100644 index b3d85dbdc..000000000 --- a/src/main/java/org/redkale/convert/ext/FloatArraySimpledCoder.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * 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.ext; - -import org.redkale.convert.Reader; -import org.redkale.convert.SimpledCoder; -import org.redkale.convert.Writer; - -/** - * float[] 的SimpledCoder实现 - * - *

详情见: http://www.redkale.org - * @author zhangjx - * @param Reader输入的子类型 - * @param Writer输出的子类型 - */ -public final class FloatArraySimpledCoder extends SimpledCoder { - - public static final FloatArraySimpledCoder instance = new FloatArraySimpledCoder(); - - @Override - public void convertTo(W out, float[] values) { - if (values == null) { - out.writeNull(); - return; - } - out.writeArrayB(values.length); - boolean flag = false; - for (float v : values) { - if (flag) out.writeArrayMark(); - out.writeFloat(v); - flag = true; - } - out.writeArrayE(); - } - - @Override - public float[] convertFrom(R in) { - int len = in.readArrayB(); - if (len == Reader.SIGN_NULL) return null; - if (len == Reader.SIGN_NOLENGTH) { - int size = 0; - float[] data = new float[8]; - while (in.hasNext()) { - if (size >= data.length) { - float[] newdata = new float[data.length + 4]; - System.arraycopy(data, 0, newdata, 0, size); - data = newdata; - } - data[size++] = in.readFloat(); - } - in.readArrayE(); - float[] newdata = new float[size]; - System.arraycopy(data, 0, newdata, 0, size); - return newdata; - } else { - float[] values = new float[len]; - for (int i = 0; i < values.length; i++) { - values[i] = in.readFloat(); - } - in.readArrayE(); - return values; - } - } - -} diff --git a/src/main/java/org/redkale/convert/ext/FloatSimpledCoder.java b/src/main/java/org/redkale/convert/ext/FloatSimpledCoder.java deleted file mode 100644 index 3c81e1d23..000000000 --- a/src/main/java/org/redkale/convert/ext/FloatSimpledCoder.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * 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.ext; - -import org.redkale.convert.Reader; -import org.redkale.convert.SimpledCoder; -import org.redkale.convert.Writer; - -/** - * float 的SimpledCoder实现 - * - *

详情见: http://www.redkale.org - * @author zhangjx - * @param Reader输入的子类型 - * @param Writer输出的子类型 - */ -public final class FloatSimpledCoder extends SimpledCoder { - - public static final FloatSimpledCoder instance = new FloatSimpledCoder(); - - @Override - public void convertTo(W out, Float value) { - out.writeFloat(value); - } - - @Override - public Float convertFrom(R in) { - return in.readFloat(); - } - -} diff --git a/src/main/java/org/redkale/convert/ext/InetAddressSimpledCoder.java b/src/main/java/org/redkale/convert/ext/InetAddressSimpledCoder.java deleted file mode 100644 index 4a31c9f37..000000000 --- a/src/main/java/org/redkale/convert/ext/InetAddressSimpledCoder.java +++ /dev/null @@ -1,145 +0,0 @@ -/* - * 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.ext; - -import org.redkale.convert.SimpledCoder; -import org.redkale.convert.Writer; -import org.redkale.convert.Reader; -import java.net.*; - -/** - * InetAddress 的SimpledCoder实现 - * - *

- * 详情见: http://www.redkale.org - * - * @author zhangjx - * @param Reader输入的子类型 - * @param Writer输出的子类型 - */ -public final class InetAddressSimpledCoder extends SimpledCoder { - - public static final InetAddressSimpledCoder instance = new InetAddressSimpledCoder(); - - @Override - public void convertTo(W out, InetAddress value) { - if (value == null) { - out.writeNull(); - return; - } - ByteArraySimpledCoder.instance.convertTo(out, value.getAddress()); - } - - @Override - public InetAddress convertFrom(R in) { - byte[] bytes = ByteArraySimpledCoder.instance.convertFrom(in); - if (bytes == null) return null; - try { - return InetAddress.getByAddress(bytes); - } catch (Exception ex) { - return null; - } - } - - /** - * InetSocketAddress 的SimpledCoder实现 - * - * @param Reader输入的子类型 - * @param Writer输出的子类型 - */ - public final static class InetSocketAddressSimpledCoder extends SimpledCoder { - - public static final InetSocketAddressSimpledCoder instance = new InetSocketAddressSimpledCoder(); - - @Override - public void convertTo(W out, InetSocketAddress value) { - if (value == null) { - out.writeNull(); - return; - } - ByteArraySimpledCoder.instance.convertTo(out, value.getAddress().getAddress()); - out.writeInt(value.getPort()); - } - - @Override - public InetSocketAddress convertFrom(R in) { - byte[] bytes = ByteArraySimpledCoder.instance.convertFrom(in); - if (bytes == null) return null; - int port = in.readInt(); - try { - return new InetSocketAddress(InetAddress.getByAddress(bytes), port); - } catch (Exception ex) { - return null; - } - } - - } - - /** - * InetAddress 的JsonSimpledCoder实现 - * - * @param Reader输入的子类型 - * @param Writer输出的子类型 - */ - public final static class InetAddressJsonSimpledCoder extends SimpledCoder { - - public static final InetAddressJsonSimpledCoder instance = new InetAddressJsonSimpledCoder(); - - @Override - public void convertTo(W out, InetAddress value) { - if (value == null) { - out.writeNull(); - return; - } - StringSimpledCoder.instance.convertTo(out, value.getHostAddress()); - } - - @Override - public InetAddress convertFrom(R in) { - String str = StringSimpledCoder.instance.convertFrom(in); - if (str == null) return null; - try { - return InetAddress.getByName(str); - } catch (Exception ex) { - return null; - } - } - - } - - /** - * InetSocketAddress 的JsonSimpledCoder实现 - * - * @param Reader输入的子类型 - * @param Writer输出的子类型 - */ - public final static class InetSocketAddressJsonSimpledCoder extends SimpledCoder { - - public static final InetSocketAddressJsonSimpledCoder instance = new InetSocketAddressJsonSimpledCoder(); - - @Override - public void convertTo(W out, InetSocketAddress value) { - if (value == null) { - out.writeNull(); - return; - } - StringSimpledCoder.instance.convertTo(out, value.getHostString() + ":" + value.getPort()); - } - - @Override - public InetSocketAddress convertFrom(R in) { - String str = StringSimpledCoder.instance.convertFrom(in); - if (str == null) return null; - try { - int pos = str.indexOf(':'); - return new InetSocketAddress(str.substring(0, pos), Integer.parseInt(str.substring(pos + 1))); - } catch (Exception ex) { - return null; - } - } - - } -} diff --git a/src/main/java/org/redkale/convert/ext/IntArraySimpledCoder.java b/src/main/java/org/redkale/convert/ext/IntArraySimpledCoder.java deleted file mode 100644 index 9b60bbc2d..000000000 --- a/src/main/java/org/redkale/convert/ext/IntArraySimpledCoder.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * 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.ext; - -import org.redkale.convert.Reader; -import org.redkale.convert.SimpledCoder; -import org.redkale.convert.Writer; - -/** - * int[] 的SimpledCoder实现 - * - *

详情见: http://www.redkale.org - * @author zhangjx - * @param Reader输入的子类型 - * @param Writer输出的子类型 - */ -public final class IntArraySimpledCoder extends SimpledCoder { - - public static final IntArraySimpledCoder instance = new IntArraySimpledCoder(); - - @Override - public void convertTo(W out, int[] values) { - if (values == null) { - out.writeNull(); - return; - } - out.writeArrayB(values.length); - boolean flag = false; - for (int v : values) { - if (flag) out.writeArrayMark(); - out.writeInt(v); - flag = true; - } - out.writeArrayE(); - } - - @Override - public int[] convertFrom(R in) { - int len = in.readArrayB(); - if (len == Reader.SIGN_NULL) return null; - if (len == Reader.SIGN_NOLENGTH) { - int size = 0; - int[] data = new int[8]; - while (in.hasNext()) { - if (size >= data.length) { - int[] newdata = new int[data.length + 4]; - System.arraycopy(data, 0, newdata, 0, size); - data = newdata; - } - data[size++] = in.readInt(); - } - in.readArrayE(); - int[] newdata = new int[size]; - System.arraycopy(data, 0, newdata, 0, size); - return newdata; - } else { - int[] values = new int[len]; - for (int i = 0; i < values.length; i++) { - values[i] = in.readInt(); - } - in.readArrayE(); - return values; - } - } - -} diff --git a/src/main/java/org/redkale/convert/ext/IntSimpledCoder.java b/src/main/java/org/redkale/convert/ext/IntSimpledCoder.java deleted file mode 100644 index 2028a409a..000000000 --- a/src/main/java/org/redkale/convert/ext/IntSimpledCoder.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * 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.ext; - -import org.redkale.convert.Reader; -import org.redkale.convert.SimpledCoder; -import org.redkale.convert.Writer; - -/** - * int 的SimpledCoder实现 - * - *

详情见: http://www.redkale.org - * @author zhangjx - * @param Reader输入的子类型 - * @param Writer输出的子类型 - */ -public final class IntSimpledCoder extends SimpledCoder { - - public static final IntSimpledCoder instance = new IntSimpledCoder(); - - @Override - public void convertTo(W out, Integer value) { - out.writeInt(value); - } - - @Override - public Integer convertFrom(R in) { - return in.readInt(); - } - -} diff --git a/src/main/java/org/redkale/convert/ext/LongArraySimpledCoder.java b/src/main/java/org/redkale/convert/ext/LongArraySimpledCoder.java deleted file mode 100644 index c9d906106..000000000 --- a/src/main/java/org/redkale/convert/ext/LongArraySimpledCoder.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * 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.ext; - -import org.redkale.convert.Reader; -import org.redkale.convert.SimpledCoder; -import org.redkale.convert.Writer; - -/** - * long[] 的SimpledCoder实现 - * - *

- * 详情见: http://www.redkale.org - * - * @author zhangjx - * @param Reader输入的子类型 - * @param Writer输出的子类型 - */ -public final class LongArraySimpledCoder extends SimpledCoder { - - public static final LongArraySimpledCoder instance = new LongArraySimpledCoder(); - - @Override - public void convertTo(W out, long[] values) { - if (values == null) { - out.writeNull(); - return; - } - out.writeArrayB(values.length); - boolean flag = false; - for (long v : values) { - if (flag) out.writeArrayMark(); - out.writeLong(v); - flag = true; - } - out.writeArrayE(); - } - - @Override - public long[] convertFrom(R in) { - int len = in.readArrayB(); - if (len == Reader.SIGN_NULL) return null; - if (len == Reader.SIGN_NOLENGTH) { - int size = 0; - long[] data = new long[8]; - while (in.hasNext()) { - if (size >= data.length) { - long[] newdata = new long[data.length + 4]; - System.arraycopy(data, 0, newdata, 0, size); - data = newdata; - } - data[size++] = in.readLong(); - } - in.readArrayE(); - long[] newdata = new long[size]; - System.arraycopy(data, 0, newdata, 0, size); - return newdata; - } else { - long[] values = new long[len]; - for (int i = 0; i < values.length; i++) { - values[i] = in.readLong(); - } - in.readArrayE(); - return values; - } - } - -} diff --git a/src/main/java/org/redkale/convert/ext/LongSimpledCoder.java b/src/main/java/org/redkale/convert/ext/LongSimpledCoder.java deleted file mode 100644 index 09a635881..000000000 --- a/src/main/java/org/redkale/convert/ext/LongSimpledCoder.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * 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.ext; - -import org.redkale.convert.Reader; -import org.redkale.convert.SimpledCoder; -import org.redkale.convert.Writer; - -/** - * long 的SimpledCoder实现 - * - *

详情见: http://www.redkale.org - * @author zhangjx - * @param Reader输入的子类型 - * @param Writer输出的子类型 - */ -public final class LongSimpledCoder extends SimpledCoder { - - public static final LongSimpledCoder instance = new LongSimpledCoder(); - - @Override - public void convertTo(W out, Long value) { - out.writeLong(value); - } - - @Override - public Long convertFrom(R in) { - return in.readLong(); - } - -} diff --git a/src/main/java/org/redkale/convert/ext/NumberSimpledCoder.java b/src/main/java/org/redkale/convert/ext/NumberSimpledCoder.java deleted file mode 100644 index 9569dd2ba..000000000 --- a/src/main/java/org/redkale/convert/ext/NumberSimpledCoder.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * 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.ext; - -import org.redkale.convert.Reader; -import org.redkale.convert.SimpledCoder; -import org.redkale.convert.Writer; - -/** - * Number 的SimpledCoder实现 - * - *

- * 详情见: http://www.redkale.org - * - * @author zhangjx - * @param Reader输入的子类型 - * @param Writer输出的子类型 - */ -public final class NumberSimpledCoder extends SimpledCoder { - - public static final NumberSimpledCoder instance = new NumberSimpledCoder(); - - @Override - public void convertTo(W out, Number value) { - out.writeLong(value == null ? 0L : value.longValue()); - } - - @Override - public Number convertFrom(R in) { - return in.readLong(); - } - -} diff --git a/src/main/java/org/redkale/convert/ext/PatternSimpledCoder.java b/src/main/java/org/redkale/convert/ext/PatternSimpledCoder.java deleted file mode 100644 index a0787c077..000000000 --- a/src/main/java/org/redkale/convert/ext/PatternSimpledCoder.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * 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.ext; - -import java.util.regex.*; -import org.redkale.convert.*; - -/** - * Pattern 的SimpledCoder实现 - * - *

详情见: http://www.redkale.org - * @author zhangjx - * @param Reader输入的子类型 - * @param Writer输出的子类型 - */ -public class PatternSimpledCoder extends SimpledCoder { - - public static final PatternSimpledCoder instance = new PatternSimpledCoder(); - - @Override - public void convertTo(W out, Pattern value) { - if (value == null) { - out.writeNull(); - } else { - out.writeString(value.flags() + "," + value.pattern()); - } - } - - @Override - public Pattern convertFrom(R in) { - String value = in.readString(); - if (value == null) return null; - int pos = value.indexOf(','); - return Pattern.compile(value.substring(pos + 1), Integer.parseInt(value.substring(0, pos))); - } - -} diff --git a/src/main/java/org/redkale/convert/ext/ShortArraySimpledCoder.java b/src/main/java/org/redkale/convert/ext/ShortArraySimpledCoder.java deleted file mode 100644 index a86817bee..000000000 --- a/src/main/java/org/redkale/convert/ext/ShortArraySimpledCoder.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * 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.ext; - -import org.redkale.convert.Reader; -import org.redkale.convert.SimpledCoder; -import org.redkale.convert.Writer; - -/** - * short[] 的SimpledCoder实现 - * - *

详情见: http://www.redkale.org - * @author zhangjx - * @param Reader输入的子类型 - * @param Writer输出的子类型 - */ -public final class ShortArraySimpledCoder extends SimpledCoder { - - public static final ShortArraySimpledCoder instance = new ShortArraySimpledCoder(); - - @Override - public void convertTo(W out, short[] values) { - if (values == null) { - out.writeNull(); - return; - } - out.writeArrayB(values.length); - boolean flag = false; - for (short v : values) { - if (flag) out.writeArrayMark(); - out.writeShort(v); - flag = true; - } - out.writeArrayE(); - } - - @Override - public short[] convertFrom(R in) { - int len = in.readArrayB(); - if (len == Reader.SIGN_NULL) return null; - if (len == Reader.SIGN_NOLENGTH) { - int size = 0; - short[] data = new short[8]; - while (in.hasNext()) { - if (size >= data.length) { - short[] newdata = new short[data.length + 4]; - System.arraycopy(data, 0, newdata, 0, size); - data = newdata; - } - data[size++] = in.readShort(); - } - in.readArrayE(); - short[] newdata = new short[size]; - System.arraycopy(data, 0, newdata, 0, size); - return newdata; - } else { - short[] values = new short[len]; - for (int i = 0; i < values.length; i++) { - values[i] = in.readShort(); - } - in.readArrayE(); - return values; - } - } - -} diff --git a/src/main/java/org/redkale/convert/ext/ShortSimpledCoder.java b/src/main/java/org/redkale/convert/ext/ShortSimpledCoder.java deleted file mode 100644 index d761540fd..000000000 --- a/src/main/java/org/redkale/convert/ext/ShortSimpledCoder.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * 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.ext; - -import org.redkale.convert.Reader; -import org.redkale.convert.SimpledCoder; -import org.redkale.convert.Writer; - -/** - * short 的SimpledCoder实现 - * - *

详情见: http://www.redkale.org - * @author zhangjx - * @param Reader输入的子类型 - * @param Writer输出的子类型 - */ -public final class ShortSimpledCoder extends SimpledCoder { - - public static final ShortSimpledCoder instance = new ShortSimpledCoder(); - - @Override - public void convertTo(W out, Short value) { - out.writeShort(value); - } - - @Override - public Short convertFrom(R in) { - return in.readShort(); - } - -} diff --git a/src/main/java/org/redkale/convert/ext/StringArraySimpledCoder.java b/src/main/java/org/redkale/convert/ext/StringArraySimpledCoder.java deleted file mode 100644 index 76e39156a..000000000 --- a/src/main/java/org/redkale/convert/ext/StringArraySimpledCoder.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * 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.ext; - -import org.redkale.convert.Reader; -import org.redkale.convert.SimpledCoder; -import org.redkale.convert.Writer; - -/** - * String[] 的SimpledCoder实现 - * - *

详情见: http://www.redkale.org - * @author zhangjx - * @param Reader输入的子类型 - * @param Writer输出的子类型 - */ -public final class StringArraySimpledCoder extends SimpledCoder { - - public static final StringArraySimpledCoder instance = new StringArraySimpledCoder(); - - @Override - public void convertTo(W out, String[] values) { - if (values == null) { - out.writeNull(); - return; - } - out.writeArrayB(values.length); - boolean flag = false; - for (String v : values) { - if (flag) out.writeArrayMark(); - out.writeString(v); - flag = true; - } - out.writeArrayE(); - } - - @Override - public String[] convertFrom(R in) { - int len = in.readArrayB(); - if (len == Reader.SIGN_NULL) return null; - if (len == Reader.SIGN_NOLENGTH) { - int size = 0; - String[] data = new String[8]; - while (in.hasNext()) { - if (size >= data.length) { - String[] newdata = new String[data.length + 4]; - System.arraycopy(data, 0, newdata, 0, size); - data = newdata; - } - data[size++] = in.readString(); - } - in.readArrayE(); - String[] newdata = new String[size]; - System.arraycopy(data, 0, newdata, 0, size); - return newdata; - } else { - String[] values = new String[len]; - for (int i = 0; i < values.length; i++) { - values[i] = in.readString(); - } - in.readArrayE(); - return values; - } - } - -} diff --git a/src/main/java/org/redkale/convert/ext/StringSimpledCoder.java b/src/main/java/org/redkale/convert/ext/StringSimpledCoder.java deleted file mode 100644 index e5e61bbf7..000000000 --- a/src/main/java/org/redkale/convert/ext/StringSimpledCoder.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * 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.ext; - -import org.redkale.convert.Reader; -import org.redkale.convert.SimpledCoder; -import org.redkale.convert.Writer; - -/** - * String 的SimpledCoder实现 - * - *

详情见: http://www.redkale.org - * @author zhangjx - * @param Reader输入的子类型 - * @param Writer输出的子类型 - */ -public final class StringSimpledCoder extends SimpledCoder { - - public static final StringSimpledCoder instance = new StringSimpledCoder(); - - @Override - public void convertTo(W out, String value) { - out.writeString(value); - } - - @Override - public String convertFrom(R in) { - return in.readString(); - } - -} diff --git a/src/main/java/org/redkale/convert/ext/TypeSimpledCoder.java b/src/main/java/org/redkale/convert/ext/TypeSimpledCoder.java deleted file mode 100644 index 2bbe852c4..000000000 --- a/src/main/java/org/redkale/convert/ext/TypeSimpledCoder.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * 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.ext; - -import org.redkale.convert.Reader; -import org.redkale.convert.Writer; -import org.redkale.convert.SimpledCoder; - -/** - * Type 的SimpledCoder实现 只支持Type的子类Class - * - *

- * 详情见: http://www.redkale.org - * - * @author zhangjx - * @param Reader输入的子类型 - * @param Writer输出的子类型 - */ -public class TypeSimpledCoder extends SimpledCoder { - - public static final TypeSimpledCoder instance = new TypeSimpledCoder(); - - @Override - public void convertTo(final W out, final Class value) { - if (value == null) { - out.writeNull(); - } else { - out.writeSmallString(value.getName()); - } - } - - @Override - public Class convertFrom(R in) { - String str = in.readSmallString(); - if (str == null) return null; - try { - return Class.forName(str); - } catch (Exception e) { - return null; - } - } - -} diff --git a/src/main/java/org/redkale/convert/ext/URISimpledCoder.java b/src/main/java/org/redkale/convert/ext/URISimpledCoder.java deleted file mode 100644 index 05daf0f74..000000000 --- a/src/main/java/org/redkale/convert/ext/URISimpledCoder.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * 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.ext; - -import java.net.*; -import org.redkale.convert.*; - -/** - * - * @author zhangjx - */ -public class URISimpledCoder extends SimpledCoder { - - public static final URLSimpledCoder instance = new URLSimpledCoder(); - - @Override - public void convertTo(final Writer out, final URI value) { - if (value == null) { - out.writeNull(); - } else { - out.writeString(value.toString()); - } - } - - @Override - public URI convertFrom(Reader in) { - final String str = in.readString(); - if (str == null) return null; - try { - return new URI(str); - } catch (Exception e) { - e.printStackTrace(); - return null; - } - } -} diff --git a/src/main/java/org/redkale/convert/ext/URLSimpledCoder.java b/src/main/java/org/redkale/convert/ext/URLSimpledCoder.java deleted file mode 100644 index 431424efe..000000000 --- a/src/main/java/org/redkale/convert/ext/URLSimpledCoder.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * 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.ext; - -import java.net.*; -import org.redkale.convert.*; - -/** - * - * @author zhangjx - */ -public class URLSimpledCoder extends SimpledCoder { - - public static final URLSimpledCoder instance = new URLSimpledCoder(); - - @Override - public void convertTo(final Writer out, final URL value) { - if (value == null) { - out.writeNull(); - } else { - out.writeString(value.toString()); - } - } - - @Override - public URL convertFrom(Reader in) { - final String str = in.readString(); - if (str == null) return null; - try { - return new URL(str); - } catch (Exception e) { - e.printStackTrace(); - return null; - } - } -} diff --git a/src/main/java/org/redkale/convert/ext/package-info.java b/src/main/java/org/redkale/convert/ext/package-info.java deleted file mode 100644 index 3d10de53b..000000000 --- a/src/main/java/org/redkale/convert/ext/package-info.java +++ /dev/null @@ -1,4 +0,0 @@ -/** - * Convert的基本数据的Coder实现 - */ -package org.redkale.convert.ext; diff --git a/src/main/java/org/redkale/convert/json/JsonByteBufferReader.java b/src/main/java/org/redkale/convert/json/JsonByteBufferReader.java deleted file mode 100644 index 3e04a27d8..000000000 --- a/src/main/java/org/redkale/convert/json/JsonByteBufferReader.java +++ /dev/null @@ -1,336 +0,0 @@ -/* - * 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.json; - -import java.nio.*; -import java.nio.charset.*; -import org.redkale.convert.*; -import static org.redkale.convert.Reader.*; - -/** - * 只支持UTF-8格式 - * - * @author zhangjx - */ -public class JsonByteBufferReader extends JsonReader { - - private char currentChar; - - private ByteBuffer[] buffers; - - private int currentIndex = 0; - - private ByteBuffer currentBuffer; - - protected JsonByteBufferReader(ByteBuffer... buffers) { - this.buffers = buffers; - if (buffers != null && buffers.length > 0) this.currentBuffer = buffers[currentIndex]; - } - - @Override - protected boolean recycle() { - super.recycle(); // this.position 初始化值为-1 - this.currentIndex = 0; - this.currentChar = 0; - this.currentBuffer = null; - this.buffers = null; - return false; - } - - protected byte nextByte() { - if (this.currentBuffer.hasRemaining()) { - this.position++; - return this.currentBuffer.get(); - } - for (;;) { - this.currentBuffer = this.buffers[++this.currentIndex]; - if (this.currentBuffer.hasRemaining()) { - this.position++; - return this.currentBuffer.get(); - } - } - } - - /** - * 读取下一个字符, 不跳过空白字符 - * - * @return 有效字符或空白字符 - */ - @Override - protected final char nextChar() { - if (currentChar != 0) { - char ch = currentChar; - this.currentChar = 0; - return ch; - } - if (this.currentBuffer != null) { - int remain = this.currentBuffer.remaining(); - if (remain == 0 && this.currentIndex + 1 >= this.buffers.length) return 0; - } - byte b1 = nextByte(); - if (b1 >= 0) {// 1 byte, 7 bits: 0xxxxxxx - return (char) b1; - } else if ((b1 >> 5) == -2 && (b1 & 0x1e) != 0) { // 2 bytes, 11 bits: 110xxxxx 10xxxxxx - return (char) (((b1 << 6) ^ nextByte()) ^ (((byte) 0xC0 << 6) ^ ((byte) 0x80))); - } else if ((b1 >> 4) == -2) { // 3 bytes, 16 bits: 1110xxxx 10xxxxxx 10xxxxxx - return (char) ((b1 << 12) ^ (nextByte() << 6) ^ (nextByte() ^ (((byte) 0xE0 << 12) ^ ((byte) 0x80 << 6) ^ ((byte) 0x80)))); - } else { // 4 bytes, 21 bits: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx - throw new RuntimeException(new UnmappableCharacterException(4)); - } - } - - /** - * 读取下一个有效字符 - * - * @return 有效字符 - */ - @Override - protected final char nextGoodChar() { - char c = nextChar(); - if (c > ' ' || c == 0) return c; // 0 表示buffer结尾了 - for (;;) { - c = nextChar(); - if (c > ' ' || c == 0) return c; - } - } - - /** - * 回退最后读取的字符 - * - * @param ch 回退的字符 - */ - @Override - protected final void backChar(char ch) { - this.currentChar = ch; - } - - /** - * 判断下一个非空白字符是否为{ - * - * @return SIGN_NOLENGTH 或 SIGN_NULL - */ - @Override - public final String readObjectB(final Class clazz) { - char ch = nextGoodChar(); - if (ch == '{') return ""; - if (ch == 'n' && nextChar() == 'u' && nextChar() == 'l' && nextChar() == 'l') return null; - if (ch == 'N' && nextChar() == 'U' && nextChar() == 'L' && nextChar() == 'L') return null; - throw new ConvertException("a json object text must begin with '{' (position = " + position + ") but '" + ch + "'"); - } - - /** - * 判断下一个非空白字符是否为[ - * - * @return SIGN_NOLENGTH 或 SIGN_NULL - */ - @Override - public final int readArrayB() { - char ch = nextGoodChar(); - if (ch == '[' || ch == '{') return SIGN_NOLENGTH; - if (ch == 'n' && nextChar() == 'u' && nextChar() == 'l' && nextChar() == 'l') return SIGN_NULL; - if (ch == 'N' && nextChar() == 'U' && nextChar() == 'L' && nextChar() == 'L') return SIGN_NULL; - throw new ConvertException("a json array text must begin with '[' (position = " + position + ") but '" + ch + "'"); - } - - /** - * 判断下一个非空白字符是否: - */ - @Override - public final void readBlank() { - char ch = nextGoodChar(); - if (ch == ':') return; - throw new ConvertException("expected a ':' but '" + ch + "'(position = " + position + ")"); - } - - /** - * 判断对象是否存在下一个属性或者数组是否存在下一个元素 - * - * @return 是否存在 - */ - @Override - public final boolean hasNext() { - char ch = nextGoodChar(); - if (ch == ',') return true; - if (ch == '}' || ch == ']') return false; - backChar(ch); // { [ 交由 readObjectB 或 readMapB 或 readArrayB 读取 - return true; - } - - /** - * 读取小字符串 - * - * @return String值 - */ - @Override - public final String readSmallString() { - char ch = nextGoodChar(); - if (ch == 0) return null; - final StringBuilder sb = new StringBuilder(); - if (ch == '"' || ch == '\'') { - final char quote = ch; - for (;;) { - ch = nextChar(); - if (ch == '\\') { - char c = nextChar(); - switch (c) { - case '"': - case '\'': - case '\\': - case '/': - sb.append(c); - break; - case 'n': - sb.append('\n'); - break; - case 'r': - sb.append('\r'); - break; - case 'u': - sb.append((char) Integer.parseInt(new String(new char[]{nextChar(), nextChar(), nextChar(), nextChar()}), 16)); - break; - case 't': - sb.append('\t'); - break; - case 'b': - sb.append('\b'); - break; - case 'f': - sb.append('\f'); - break; - default: - throw new ConvertException("illegal escape(" + c + ") (position = " + this.position + ")"); - } - } else if (ch == quote || ch == 0) { - break; - } else { - sb.append(ch); - } - } - return sb.toString(); - } else { - sb.append(ch); - for (;;) { - ch = nextChar(); - if (ch == '\\') { - char c = nextChar(); - switch (c) { - case '"': - case '\'': - case '\\': - case '/': - sb.append(c); - break; - case 'n': - sb.append('\n'); - break; - case 'r': - sb.append('\r'); - break; - case 'u': - sb.append((char) Integer.parseInt(new String(new char[]{nextChar(), nextChar(), nextChar(), nextChar()}), 16)); - break; - case 't': - sb.append('\t'); - break; - case 'b': - sb.append('\b'); - break; - case 'f': - sb.append('\f'); - break; - default: - throw new ConvertException("illegal escape(" + c + ") (position = " + this.position + ")"); - } - } else if (ch == ',' || ch == ']' || ch == '}' || ch <= ' ' || ch == ':') { // ch <= ' ' 包含 0 - break; - } else { - sb.append(ch); - } - } - String rs = sb.toString(); - return "null".equalsIgnoreCase(rs) ? null : rs; - } - } - - /** - * 读取一个int值 - * - * @return int值 - */ - @Override - public final int readInt() { - char firstchar = nextGoodChar(); - if (firstchar == '"' || firstchar == '\'') { - firstchar = nextChar(); - if (firstchar == '"' || firstchar == '\'') return 0; - } - int value = 0; - final boolean negative = firstchar == '-'; - if (!negative) { - if (firstchar < '0' || firstchar > '9') throw new ConvertException("illegal escape(" + firstchar + ") (position = " + position + ")"); - value = firstchar - '0'; - } - for (;;) { - char ch = nextChar(); - if (ch == 0) break; - if (ch >= '0' && ch <= '9') { - value = (value << 3) + (value << 1) + (ch - '0'); - } else if (ch == '"' || ch == '\'') { - } else if (ch == ',' || ch == '}' || ch == ']' || ch <= ' ' || ch == ':') { - backChar(ch); - break; - } else { - throw new ConvertException("illegal escape(" + ch + ") (position = " + position + ")"); - } - } - return negative ? -value : value; - } - - /** - * 读取一个long值 - * - * @return long值 - */ - @Override - public final long readLong() { - char firstchar = nextGoodChar(); - if (firstchar == '"' || firstchar == '\'') { - firstchar = nextChar(); - if (firstchar == '"' || firstchar == '\'') return 0L; - } - long value = 0; - final boolean negative = firstchar == '-'; - if (!negative) { - if (firstchar < '0' || firstchar > '9') throw new ConvertException("illegal escape(" + firstchar + ") (position = " + position + ")"); - value = firstchar - '0'; - } - for (;;) { - char ch = nextChar(); - if (ch == 0) break; - if (ch >= '0' && ch <= '9') { - value = (value << 3) + (value << 1) + (ch - '0'); - } else if (ch == '"' || ch == '\'') { - } else if (ch == ',' || ch == '}' || ch == ']' || ch <= ' ' || ch == ':') { - backChar(ch); - break; - } else { - throw new ConvertException("illegal escape(" + ch + ") (position = " + position + ")"); - } - } - return negative ? -value : value; - } - - /** - * 读取字符串, 必须是"或者'包围的字符串值 - * - * @return String值 - */ - @Override - public final String readString() { - return readSmallString(); - } - -} diff --git a/src/main/java/org/redkale/convert/json/JsonByteBufferWriter.java b/src/main/java/org/redkale/convert/json/JsonByteBufferWriter.java deleted file mode 100644 index 68214fe0b..000000000 --- a/src/main/java/org/redkale/convert/json/JsonByteBufferWriter.java +++ /dev/null @@ -1,352 +0,0 @@ -/* - * 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.json; - -import java.nio.*; -import java.nio.charset.*; -import java.util.*; -import java.util.function.*; -import org.redkale.convert.*; -import org.redkale.util.*; - -/** - * - *

- * 详情见: http://www.redkale.org - * - * @author zhangjx - */ -public class JsonByteBufferWriter extends JsonWriter { - - protected static final Charset UTF8 = Charset.forName("UTF-8"); - - protected Charset charset; - - private final Supplier supplier; - - private ByteBuffer[] buffers; - - private int index; - - protected JsonByteBufferWriter(boolean tiny, Supplier supplier) { - this(tiny, null, supplier); - } - - protected JsonByteBufferWriter(boolean tiny, Charset charset, Supplier supplier) { - this.tiny = tiny; - this.charset = UTF8.equals(charset) ? null : charset; - this.supplier = supplier; - } - - @Override - public JsonByteBufferWriter tiny(boolean tiny) { - this.tiny = tiny; - return this; - } - - @Override - protected boolean recycle() { - this.index = 0; - this.charset = null; - this.buffers = null; - return false; - } - - @Override - public ByteBuffer[] toBuffers() { - if (buffers == null) return new ByteBuffer[0]; - for (int i = index; i < this.buffers.length; i++) { - ByteBuffer buf = this.buffers[i]; - if (buf.position() != 0) buf.flip(); - } - return this.buffers; - } - - @Override - public int count() { - if (this.buffers == null) return 0; - int len = 0; - for (ByteBuffer buffer : buffers) { - len += buffer.remaining(); - } - return len; - } - - private int expand(final int byteLength) { - if (this.buffers == null) { - this.index = 0; - this.buffers = new ByteBuffer[]{supplier.get()}; - } - ByteBuffer buffer = this.buffers[index]; - if (!buffer.hasRemaining()) { - buffer.flip(); - buffer = supplier.get(); - ByteBuffer[] bufs = new ByteBuffer[this.buffers.length + 1]; - System.arraycopy(this.buffers, 0, bufs, 0, this.buffers.length); - bufs[this.buffers.length] = buffer; - this.buffers = bufs; - this.index++; - } - int len = buffer.remaining(); - int size = 0; - while (len < byteLength) { - buffer = supplier.get(); - ByteBuffer[] bufs = new ByteBuffer[this.buffers.length + 1]; - System.arraycopy(this.buffers, 0, bufs, 0, this.buffers.length); - bufs[this.buffers.length] = buffer; - this.buffers = bufs; - len += buffer.remaining(); - size++; - } - return size; - } - - @Override - public void writeTo(final char ch) { - if (ch > Byte.MAX_VALUE) throw new ConvertException("writeTo char(int.value = " + (int) ch + ") must be less 127"); - expand(1); - this.buffers[index].put((byte) ch); - } - - @Override - public void writeTo(final char[] chs, final int start, final int len) { - writeTo(-1, false, chs, start, len); - } - - private void writeTo(int expandsize, final boolean quote, final char[] chs, final int start, final int len) { - int byteLength = quote ? 2 : 0; - ByteBuffer bb = null; - if (charset == null) { - byteLength += encodeUTF8Length(chs, start, len); - } else { - bb = charset.encode(CharBuffer.wrap(chs, start, len)); - byteLength += bb.remaining(); - } - if (expandsize < 0) expandsize = expand(byteLength); - if (expandsize == 0) { // 只需要一个buffer - final ByteBuffer buffer = this.buffers[index]; - if (quote) buffer.put((byte) '"'); - - if (charset == null) { //UTF-8 - final int limit = start + len; - for (int i = start; i < limit; i++) { - char c = chs[i]; - if (c < 0x80) { - buffer.put((byte) c); - } else if (c < 0x800) { - buffer.put((byte) (0xc0 | (c >> 6))); - buffer.put((byte) (0x80 | (c & 0x3f))); - } else { - buffer.put((byte) (0xe0 | ((c >> 12)))); - buffer.put((byte) (0x80 | ((c >> 6) & 0x3f))); - buffer.put((byte) (0x80 | (c & 0x3f))); - } - } - } else { - buffer.put(bb); - } - - if (quote) buffer.put((byte) '"'); - return; - } - ByteBuffer buffer = this.buffers[index]; - if (quote) { - if (!buffer.hasRemaining()) buffer = nextByteBuffer(); - buffer.put((byte) '"'); - } - if (charset == null) { //UTF-8 - final int limit = start + len; - for (int i = start; i < limit; i++) { - buffer = putChar(buffer, chs[i]); - } - } else { - while (bb.hasRemaining()) { - if (!buffer.hasRemaining()) buffer = nextByteBuffer(); - buffer.put(bb.get()); - } - } - if (quote) { - if (!buffer.hasRemaining()) buffer = nextByteBuffer(); - buffer.put((byte) '"'); - } - } - - private ByteBuffer putChar(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() { - this.buffers[this.index].flip(); - 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) { - char c; - int size = 0; - final char[] chars = text; - final int limit = start + len; - for (int i = start; i < limit; i++) { - c = chars[i]; - switch (c) { - case '\n': size += 2; - break; - case '\r': size += 2; - break; - case '\t': size += 2; - break; - case '\\': size += 2; - break; - case '"': size += 2; - break; - default: - size += (c < 0x80 ? 1 : (c < 0x800 ? 2 : 3)); - break; - } - } - return size; - } - - /** - * 注意: 该String值不能为null且不会进行转义, 只用于不含需要转义字符的字符串,例如enum、double、BigInteger转换的String - * - * @param quote 是否写入双引号 - * @param value String值 - */ - @Override - public void writeTo(final boolean quote, final String value) { - char[] chs = Utility.charArray(value); - writeTo(-1, quote, chs, 0, chs.length); - } - - @Override - public void writeInt(int value) { - writeTo(false, String.valueOf(value)); - } - - @Override - public void writeLong(long value) { - writeTo(false, String.valueOf(value)); - } - - @Override - public void writeString(String value) { - if (value == null) { - writeNull(); - return; - } - final char[] chs = Utility.charArray(value); - int len = 0; - for (char ch : chs) { - switch (ch) { - case '\n': len += 2; - break; - case '\r': len += 2; - break; - case '\t': len += 2; - break; - case '\\': len += 2; - break; - case '"': len += 2; - break; - default: len++; - break; - } - } - if (len == chs.length) { - writeTo(-1, true, chs, 0, len); - return; - } - int expandsize = -1; - if (this.charset == null) { //UTF-8 - final int byteLength = 2 + encodeEscapeUTF8Length(chs, 0, chs.length); - expandsize = expand(byteLength); - if (expandsize == 0) { // 只需要一个buffer - final ByteBuffer buffer = this.buffers[index]; - buffer.put((byte) '"'); - for (char c : chs) { - switch (c) { - case '\n': buffer.put((byte) '\\').put((byte) 'n'); - break; - case '\r': buffer.put((byte) '\\').put((byte) 'r'); - break; - case '\t': buffer.put((byte) '\\').put((byte) 't'); - break; - case '\\': buffer.put((byte) '\\').put((byte) '\\'); - break; - case '"': buffer.put((byte) '\\').put((byte) '"'); - break; - default: - if (c < 0x80) { - buffer.put((byte) c); - } else if (c < 0x800) { - buffer.put((byte) (0xc0 | (c >> 6))); - buffer.put((byte) (0x80 | (c & 0x3f))); - } else { - buffer.put((byte) (0xe0 | ((c >> 12)))); - buffer.put((byte) (0x80 | ((c >> 6) & 0x3f))); - buffer.put((byte) (0x80 | (c & 0x3f))); - } - break; - } - } - buffer.put((byte) '"'); - return; - } - } - StringBuilder sb = new StringBuilder(len); - for (char ch : chs) { - switch (ch) { - case '\n': sb.append("\\n"); - break; - case '\r': sb.append("\\r"); - break; - case '\t': sb.append("\\t"); - break; - case '\\': sb.append("\\\\"); - break; - case '"': sb.append("\\\""); - break; - default: sb.append(ch); - break; - } - } - char[] cs = Utility.charArray(sb); - writeTo(expandsize, true, cs, 0, sb.length()); - } - - @Override - public String toString() { - return Objects.toString(this); - } -} diff --git a/src/main/java/org/redkale/convert/json/JsonConvert.java b/src/main/java/org/redkale/convert/json/JsonConvert.java deleted file mode 100644 index 22d691775..000000000 --- a/src/main/java/org/redkale/convert/json/JsonConvert.java +++ /dev/null @@ -1,207 +0,0 @@ -/* - * 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.json; - -import java.io.*; -import java.lang.reflect.*; -import java.nio.*; -import java.nio.charset.*; -import java.util.function.*; -import org.redkale.convert.*; -import org.redkale.util.*; - -/** - * - *

- * 详情见: http://www.redkale.org - * - * @author zhangjx - */ -@SuppressWarnings("unchecked") -public final class JsonConvert extends Convert { - - public static final Type TYPE_MAP_STRING_STRING = new TypeToken>() { - }.getType(); - - private static final ObjectPool readerPool = JsonReader.createPool(Integer.getInteger("convert.json.pool.size", 16)); - - private static final ObjectPool writerPool = JsonWriter.createPool(Integer.getInteger("convert.json.pool.size", 16)); - - private final boolean tiny; - - protected JsonConvert(JsonFactory factory, boolean tiny) { - super(factory); - this.tiny = tiny; - } - - @Override - public JsonFactory getFactory() { - return (JsonFactory) factory; - } - - public static JsonConvert root() { - return JsonFactory.root().getConvert(); - } - - //------------------------------ reader ----------------------------------------------------------- - public JsonReader pollJsonReader(final ByteBuffer... buffers) { - return new JsonByteBufferReader(buffers); - } - - public JsonReader pollJsonReader(final InputStream in) { - return new JsonStreamReader(in); - } - - public JsonReader pollJsonReader() { - return readerPool.get(); - } - - public void offerJsonReader(final JsonReader in) { - if (in != null) readerPool.offer(in); - } - - //------------------------------ writer ----------------------------------------------------------- - public JsonByteBufferWriter pollJsonWriter(final Supplier supplier) { - return new JsonByteBufferWriter(tiny, supplier); - } - - public JsonWriter pollJsonWriter(final OutputStream out) { - return new JsonStreamWriter(tiny, out); - } - - public JsonWriter pollJsonWriter(final Charset charset, final OutputStream out) { - return new JsonStreamWriter(tiny, charset, out); - } - - public JsonWriter pollJsonWriter() { - return writerPool.get().tiny(tiny); - } - - public void offerJsonWriter(final JsonWriter out) { - if (out != null) writerPool.offer(out); - } - - //------------------------------ convertFrom ----------------------------------------------------------- - public T convertFrom(final Type type, final String text) { - if (text == null) return null; - return convertFrom(type, Utility.charArray(text)); - } - - public T convertFrom(final Type type, final char[] text) { - if (text == null) return null; - return convertFrom(type, text, 0, text.length); - } - - public T convertFrom(final Type type, final char[] text, final int start, final int len) { - if (text == null || type == null) return null; - final JsonReader in = readerPool.get(); - in.setText(text, start, len); - T rs = (T) factory.loadDecoder(type).convertFrom(in); - readerPool.offer(in); - return rs; - } - - public T convertFrom(final Type type, final InputStream in) { - if (type == null || in == null) return null; - return (T) factory.loadDecoder(type).convertFrom(new JsonStreamReader(in)); - } - - public T convertFrom(final Type type, final ByteBuffer... buffers) { - if (type == null || buffers == null || buffers.length == 0) return null; - return (T) factory.loadDecoder(type).convertFrom(new JsonByteBufferReader(buffers)); - } - - public T convertFrom(final Type type, final JsonReader reader) { - if (type == null) return null; - @SuppressWarnings("unchecked") - T rs = (T) factory.loadDecoder(type).convertFrom(reader); - return rs; - } - - //------------------------------ convertTo ----------------------------------------------------------- - public String convertTo(final Object value) { - if (value == null) return "null"; - return convertTo(value.getClass(), value); - } - - public String convertTo(final Type type, final Object value) { - if (type == null) return null; - if (value == null) return "null"; - final JsonWriter out = writerPool.get().tiny(tiny); - factory.loadEncoder(type).convertTo(out, value); - String result = out.toString(); - writerPool.offer(out); - return result; - } - - public void convertTo(final OutputStream out, final Object value) { - if (value == null) { - new JsonStreamWriter(tiny, out).writeNull(); - } else { - factory.loadEncoder(value.getClass()).convertTo(new JsonStreamWriter(tiny, out), value); - } - } - - public void convertTo(final OutputStream out, final Type type, final Object value) { - if (type == null) return; - if (value == null) { - new JsonStreamWriter(tiny, out).writeNull(); - } else { - factory.loadEncoder(type).convertTo(new JsonStreamWriter(tiny, out), value); - } - } - - public ByteBuffer[] convertTo(final Supplier supplier, final Object value) { - if (supplier == null) return null; - JsonByteBufferWriter out = new JsonByteBufferWriter(tiny, null, supplier); - if (value == null) { - out.writeNull(); - } else { - factory.loadEncoder(value.getClass()).convertTo(out, value); - } - return out.toBuffers(); - } - - public ByteBuffer[] convertTo(final Supplier supplier, final Type type, final Object value) { - if (supplier == null || type == null) return null; - JsonByteBufferWriter out = new JsonByteBufferWriter(tiny, null, supplier); - if (value == null) { - out.writeNull(); - } else { - factory.loadEncoder(type).convertTo(out, value); - } - return out.toBuffers(); - } - - public void convertTo(final JsonWriter writer, final Object value) { - if (value == null) { - writer.writeNull(); - } else { - factory.loadEncoder(value.getClass()).convertTo(writer, value); - } - } - - public void convertTo(final JsonWriter writer, final Type type, final Object value) { - if (type == null) return; - if (value == null) { - writer.writeNull(); - } else { - factory.loadEncoder(type).convertTo(writer, value); - } - } - - public JsonWriter convertToWriter(final Object value) { - if (value == null) return null; - return convertToWriter(value.getClass(), value); - } - - public JsonWriter convertToWriter(final Type type, final Object value) { - if (type == null) return null; - final JsonWriter out = writerPool.get().tiny(tiny); - factory.loadEncoder(type).convertTo(out, value); - return out; - } -} diff --git a/src/main/java/org/redkale/convert/json/JsonFactory.java b/src/main/java/org/redkale/convert/json/JsonFactory.java deleted file mode 100644 index c7d24d520..000000000 --- a/src/main/java/org/redkale/convert/json/JsonFactory.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * 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.json; - -import org.redkale.convert.ConvertType; -import org.redkale.convert.ConvertFactory; -import java.io.Serializable; -import java.math.*; -import java.net.*; -import org.redkale.convert.ext.*; -import org.redkale.util.*; - -/** - * - *

- * 详情见: http://www.redkale.org - * - * @author zhangjx - */ -public final class JsonFactory extends ConvertFactory { - - private static final JsonFactory instance = new JsonFactory(null, Boolean.getBoolean("convert.json.tiny")); - - 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)); - } - - private JsonFactory(JsonFactory parent, boolean tiny) { - super(parent, tiny); - } - - @Override - public JsonFactory tiny(boolean tiny) { - this.tiny = tiny; - return this; - } - - public static JsonFactory root() { - return instance; - } - - @Override - public final JsonConvert getConvert() { - if (convert == null) convert = new JsonConvert(this, tiny); - return (JsonConvert) convert; - } - - @Override - public JsonFactory createChild() { - return new JsonFactory(this, this.tiny); - } - - @Override - public JsonFactory createChild(boolean tiny) { - return new JsonFactory(this, tiny); - } - - @Override - public ConvertType getConvertType() { - return ConvertType.JSON; - } - - @Override - public boolean isReversible() { - return false; - } -} diff --git a/src/main/java/org/redkale/convert/json/JsonReader.java b/src/main/java/org/redkale/convert/json/JsonReader.java deleted file mode 100644 index b40f71b11..000000000 --- a/src/main/java/org/redkale/convert/json/JsonReader.java +++ /dev/null @@ -1,582 +0,0 @@ -/* - * 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.json; - -import org.redkale.convert.*; -import static org.redkale.convert.Reader.*; -import org.redkale.util.*; - -/** - * - *

- * 详情见: http://www.redkale.org - * - * @author zhangjx - */ -public class JsonReader extends Reader { - - protected int position = -1; - - private char[] text; - - private int limit; - - public static ObjectPool createPool(int max) { - return new ObjectPool<>(max, (Object... params) -> new JsonReader(), null, JsonReader::recycle); - } - - public JsonReader() { - } - - public JsonReader(String json) { - setText(Utility.charArray(json)); - } - - public JsonReader(char[] text) { - setText(text, 0, text.length); - } - - public JsonReader(char[] text, int start, int len) { - setText(text, start, len); - } - - public final void setText(String text) { - setText(Utility.charArray(text)); - } - - public final void setText(char[] text) { - setText(text, 0, text.length); - } - - public final void setText(char[] text, int start, int len) { - this.text = text; - this.position = start - 1; - this.limit = start + len - 1; - } - - protected boolean recycle() { - this.position = -1; - this.limit = -1; - this.text = null; - return true; - } - - public void close() { - this.recycle(); - } - - /** - * 找到指定的属性值 例如: {id : 1, data : { name : 'a', items : [1,2,3]}} seek('data.items') 直接跳转到 [1,2,3]; - * - * @param key 指定的属性名 - */ - public final void seek(String key) { - if (key == null || key.length() < 1) return; - final String[] keys = key.split("\\."); - nextGoodChar(); //读掉 { [ - for (String key1 : keys) { - while (this.hasNext()) { - String field = this.readSmallString(); - readBlank(); - if (key1.equals(field)) break; - skipValue(); - } - } - - } - - /** - * 跳过属性的值 - */ - @Override - public final void skipValue() { - final char ch = nextGoodChar(); - switch (ch) { - case '"': - case '\'': - backChar(ch); - readString(); - break; - case '{': - while (hasNext()) { - this.readSmallString(); //读掉field - this.readBlank(); - this.skipValue(); - } - break; - case '[': - while (hasNext()) { - this.skipValue(); - } - break; - default: - char c; - for (;;) { - c = nextChar(); - if (c <= ' ') return; - if (c == '}' || c == ']' || c == ',' || c == ':') { - backChar(c); - return; - } - } - } - } - - /** - * 读取下一个字符, 不跳过空白字符 - * - * @return 空白字符或有效字符 - */ - protected char nextChar() { - return this.text[++this.position]; - } - - /** - * 跳过空白字符, 返回一个非空白字符 - * - * @return 有效字符 - */ - protected char nextGoodChar() { - char c = nextChar(); - if (c > ' ') return c; - for (;;) { - c = nextChar(); - if (c > ' ') return c; - } - } - - /** - * 回退最后读取的字符 - * - * @param ch 后退的字符 - */ - protected void backChar(char ch) { - this.position--; - } - - /** - * 判断下一个非空白字符是否为{ - * - * @param clazz 类名 - * @return 返回 null 表示对象为null, 返回空字符串表示当前class与返回的class一致,返回非空字符串表示class是当前class的子类。 - */ - @Override - public String readObjectB(final Class clazz) { - this.fieldIndex = 0; //必须要重置为0 - char ch = this.text[++this.position]; - if (ch == '{') return ""; - if (ch <= ' ') { - for (;;) { - ch = this.text[++this.position]; - if (ch > ' ') break; - } - if (ch == '{') return ""; - } - if (ch == 'n' && text[++position] == 'u' && text[++position] == 'l' && text[++position] == 'l') return null; - if (ch == 'N' && text[++position] == 'U' && text[++position] == 'L' && text[++position] == 'L') return null; - throw new ConvertException("a json object text must begin with '{' (position = " + position + ") but '" + ch + "' in (" + new String(this.text) + ")"); - } - - @Override - public final void readObjectE(final Class clazz) { - } - - /** - * 判断下一个非空白字符是否为{ - * - * @return SIGN_NOLENGTH 或 SIGN_NULL - */ - @Override - public final int readMapB() { - return readArrayB(); - } - - @Override - public final void readMapE() { - } - - /** - * 判断下一个非空白字符是否为[ - * - * @return SIGN_NOLENGTH 或 SIGN_NULL - */ - @Override - public int readArrayB() { - char ch = this.text[++this.position]; - if (ch == '[') return SIGN_NOLENGTH; - if (ch == '{') return SIGN_NOLENGTH; - if (ch <= ' ') { - for (;;) { - ch = this.text[++this.position]; - if (ch > ' ') break; - } - if (ch == '[') return SIGN_NOLENGTH; - if (ch == '{') return SIGN_NOLENGTH; - } - if (ch == 'n' && text[++position] == 'u' && text[++position] == 'l' && text[++position] == 'l') return SIGN_NULL; - if (ch == 'N' && text[++position] == 'U' && text[++position] == 'L' && text[++position] == 'L') return SIGN_NULL; - throw new ConvertException("a json array text must begin with '[' (position = " + position + ") but '" + ch + "' in (" + new String(this.text) + ")"); - } - - @Override - public final void readArrayE() { - } - - /** - * 判断下一个非空白字符是否: - */ - @Override - public void readBlank() { - char ch = this.text[++this.position]; - if (ch == ':') return; - if (ch <= ' ') { - for (;;) { - ch = this.text[++this.position]; - if (ch > ' ') break; - } - if (ch == ':') return; - } - throw new ConvertException("'" + new String(text) + "'expected a ':' but '" + ch + "'(position = " + position + ") in (" + new String(this.text) + ")"); - } - - /** - * 判断对象是否存在下一个属性或者数组是否存在下一个元素 - * - * @return 是否存在 - */ - @Override - public boolean hasNext() { - char ch = this.text[++this.position]; - if (ch == ',') return true; - if (ch == '}' || ch == ']') return false; - if (ch <= ' ') { - for (;;) { - ch = this.text[++this.position]; - if (ch > ' ') break; - } - if (ch == ',') return true; - if (ch == '}' || ch == ']') return false; - } - this.position--; // { [ 交由 readObjectB 或 readMapB 或 readArrayB 读取 - return true; - } - - @Override - public final String readClassName() { - return null; - } - - @Override - public String readSmallString() { - final int eof = this.limit; - if (this.position == eof) return null; - final char[] text0 = this.text; - int currpos = this.position; - char ch = text0[++currpos]; - if (ch <= ' ') { - for (;;) { - ch = text0[++currpos]; - if (ch > ' ') break; - } - } - if (ch == '"' || ch == '\'') { - final char quote = ch; - final int start = currpos + 1; - for (;;) { - ch = text0[++currpos]; - if (ch == '\\') { - this.position = currpos - 1; - return readEscapeValue(quote, start); - } else if (ch == quote) { - break; - } - } - this.position = currpos; - char[] chs = new char[currpos - start]; - System.arraycopy(text0, start, chs, 0, chs.length); - return new String(chs); - } else { - int start = currpos; - for (;;) { - if (currpos == eof) break; - ch = text0[++currpos]; - if (ch == ',' || ch == ']' || ch == '}' || ch <= ' ' || ch == ':') break; - } - int len = currpos - start; - if (len < 1) { - this.position = currpos; - return String.valueOf(ch); - } - this.position = currpos - 1; - if (len == 4 && text0[start] == 'n' && text0[start + 1] == 'u' && text0[start + 2] == 'l' && text0[start + 3] == 'l') return null; - return new String(text0, start, len); - } - } - - /** - * 读取一个int值 - * - * @return int值 - */ - @Override - public int readInt() { - final char[] text0 = this.text; - final int eof = this.limit; - int currpos = this.position; - char firstchar = text0[++currpos]; - if (firstchar <= ' ') { - for (;;) { - firstchar = text0[++currpos]; - if (firstchar > ' ') break; - } - } - if (firstchar == '"' || firstchar == '\'') { - firstchar = text0[++currpos]; - if (firstchar == '"' || firstchar == '\'') { - this.position = currpos; - return 0; - } - } - int value = 0; - final boolean negative = firstchar == '-'; - if (!negative) { - if (firstchar < '0' || firstchar > '9') throw new ConvertException("illegal escape(" + firstchar + ") (position = " + currpos + ") in (" + new String(this.text) + ")"); - value = firstchar - '0'; - } - for (;;) { - if (currpos == eof) break; - char ch = text0[++currpos]; - int val = digits[ch]; - if (val == -3) break; - if (val == -1) throw new ConvertException("illegal escape(" + ch + ") (position = " + currpos + ") but '" + ch + "' in (" + new String(this.text) + ")"); - if (val != -2) value = value * 10 + val; - } - this.position = currpos - 1; - return negative ? -value : value; - } - - /** - * 读取一个long值 - * - * @return long值 - */ - @Override - public long readLong() { - final char[] text0 = this.text; - final int eof = this.limit; - int currpos = this.position; - char firstchar = text0[++currpos]; - if (firstchar <= ' ') { - for (;;) { - firstchar = text0[++currpos]; - if (firstchar > ' ') break; - } - } - if (firstchar == '"' || firstchar == '\'') { - firstchar = text0[++currpos]; - if (firstchar == '"' || firstchar == '\'') { - this.position = currpos; - return 0L; - } - } - long value = 0; - final boolean negative = firstchar == '-'; - if (!negative) { - if (firstchar < '0' || firstchar > '9') throw new ConvertException("illegal escape(" + firstchar + ") (position = " + currpos + ") in (" + new String(this.text) + ")"); - value = firstchar - '0'; - } - for (;;) { - if (currpos == eof) break; - char ch = text0[++currpos]; - int val = digits[ch]; - if (val == -3) break; - if (val == -1) throw new ConvertException("illegal escape(" + ch + ") (position = " + currpos + ") but '" + ch + "' in (" + new String(this.text) + ")"); - if (val != -2) value = value * 10 + val; - } - this.position = currpos - 1; - return negative ? -value : value; - } - - @Override - public final DeMember readFieldName(final DeMember[] members) { - final String exceptedfield = this.readSmallString(); - final int len = members.length; - if (this.fieldIndex >= len) this.fieldIndex = 0; - for (int k = this.fieldIndex; k < len; k++) { - if (exceptedfield.equals(members[k].getAttribute().field())) { - this.fieldIndex = k; - return members[k]; - } - } - for (int k = 0; k < this.fieldIndex; k++) { - if (exceptedfield.equals(members[k].getAttribute().field())) { - this.fieldIndex = k; - return members[k]; - } - } - return null; - //if (result == null && len == 1 && text0[start] == '@') return REFER; - } -//------------------------------------------------------------ - - @Override - public final boolean readBoolean() { - return "true".equalsIgnoreCase(this.readSmallString()); - } - - @Override - public final byte readByte() { - return (byte) readInt(); - } - - @Override - public final char readChar() { - return (char) readInt(); - } - - @Override - public final short readShort() { - return (short) readInt(); - } - - @Override - public final float readFloat() { - String chars = readSmallString(); - if (chars == null || chars.isEmpty()) return 0.f; - return Float.parseFloat(chars); - } - - @Override - public final double readDouble() { - String chars = readSmallString(); - if (chars == null || chars.isEmpty()) return 0.0; - return Double.parseDouble(chars); - } - - /** - * 读取字符串, 必须是"或者'包围的字符串值 - * - * @return String值 - */ - @Override - public String readString() { - final char[] text0 = this.text; - int currpos = this.position; - char expected = text0[++currpos]; - if (expected <= ' ') { - for (;;) { - expected = text0[++currpos]; - if (expected > ' ') break; - } - } - if (expected != '"' && expected != '\'') { - if (expected == 'n' && text0.length > currpos + 3) { - if (text0[++currpos] == 'u' && text0[++currpos] == 'l' && text0[++currpos] == 'l') { - this.position = currpos; - if (text0.length > currpos + 4) { - char ch = text0[currpos + 1]; - if (ch == ',' || ch <= ' ' || ch == '}' || ch == ']' || ch == ':') return null; - } else { - return null; - } - } - } else { - final int start = currpos; - for (;;) { - char ch = text0[currpos]; - if (ch == ',' || ch <= ' ' || ch == '}' || ch == ']' || ch == ':') break; - currpos++; - } - if (currpos == start) throw new ConvertException("expected a string after a key but '" + text0[position] + "' (position = " + position + ") in (" + new String(this.text) + ")"); - this.position = currpos - 1; - return new String(text0, start, currpos - start); - } - this.position = currpos; - throw new ConvertException("expected a ':' after a key but '" + text0[position] + "' (position = " + position + ") in (" + new String(this.text) + ")"); - } - final int start = ++currpos; - for (;;) { - char ch = text0[currpos]; - if (ch == expected) { - break; - } else if (ch == '\\') { - this.position = currpos - 1; - return readEscapeValue(expected, start); - } - currpos++; - } - this.position = currpos; - return new String(text0, start, currpos - start); - } - - private String readEscapeValue(final char expected, int start) { - StringBuilder array = new StringBuilder(); - final char[] text0 = this.text; - int pos = this.position; - array.append(text0, start, pos + 1 - start); - char c; - for (;;) { - c = text0[++pos]; - if (c == expected) { - this.position = pos; - return array.toString(); - } else if (c == '\\') { - c = text0[++pos]; - switch (c) { - case '"': - case '\'': - case '\\': - case '/': - array.append(c); - break; - case 'n': - array.append('\n'); - break; - case 'r': - array.append('\r'); - break; - case 'u': - array.append((char) Integer.parseInt(new String(new char[]{text0[++pos], text0[++pos], text0[++pos], text0[++pos]}), 16)); - break; - case 't': - array.append('\t'); - break; - case 'b': - array.append('\b'); - break; - case 'f': - array.append('\f'); - break; - default: - this.position = pos; - throw new ConvertException("illegal escape(" + c + ") (position = " + this.position + ") in (" + new String(this.text) + ")"); - } - } else { - array.append(c); - } - } - } - - final static int[] digits = new int[255]; - - static { - for (int i = 0; i < digits.length; i++) { - digits[i] = -1; //-1 错误 - } - for (int i = '0'; i <= '9'; i++) { - digits[i] = i - '0'; - } - for (int i = 'a'; i <= 'f'; i++) { - digits[i] = i - 'a' + 10; - } - for (int i = 'A'; i <= 'F'; i++) { - digits[i] = i - 'A' + 10; - } - digits['"'] = digits['\''] = -2; //-2 跳过 - digits[','] = digits['}'] = digits[']'] = digits[' '] = digits['\t'] = digits['\r'] = digits['\n'] = digits[':'] = -3; //-3退出 - - } -} diff --git a/src/main/java/org/redkale/convert/json/JsonSimpledCoder.java b/src/main/java/org/redkale/convert/json/JsonSimpledCoder.java deleted file mode 100644 index d8d4f6006..000000000 --- a/src/main/java/org/redkale/convert/json/JsonSimpledCoder.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * 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.json; - -import org.redkale.convert.SimpledCoder; - -/** - * - *

- * 详情见: http://www.redkale.org - * - * @author zhangjx - * @param 序列化/反解析的数据类型 - */ -public abstract class JsonSimpledCoder extends SimpledCoder { - -} diff --git a/src/main/java/org/redkale/convert/json/JsonStreamReader.java b/src/main/java/org/redkale/convert/json/JsonStreamReader.java deleted file mode 100644 index 836f554f8..000000000 --- a/src/main/java/org/redkale/convert/json/JsonStreamReader.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * 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.json; - -import java.io.*; -import org.redkale.convert.*; - -/** - * - * @author zhangjx - */ -class JsonStreamReader extends JsonByteBufferReader { - - private InputStream in; - - protected JsonStreamReader(InputStream in) { - this.in = in; - } - - @Override - protected boolean recycle() { - super.recycle(); // this.position 初始化值为-1 - this.in = null; - return false; - } - - @Override - protected byte nextByte() { - try { - byte b = (byte) in.read(); - this.position++; - return b; - } catch (IOException e) { - throw new ConvertException(e); - } - } -} diff --git a/src/main/java/org/redkale/convert/json/JsonStreamWriter.java b/src/main/java/org/redkale/convert/json/JsonStreamWriter.java deleted file mode 100644 index 3c34e0160..000000000 --- a/src/main/java/org/redkale/convert/json/JsonStreamWriter.java +++ /dev/null @@ -1,151 +0,0 @@ -/* - * 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.json; - -import java.io.*; -import java.nio.*; -import java.nio.charset.*; -import org.redkale.convert.*; -import org.redkale.util.*; - -/** - * - * @author zhangjx - */ -class JsonStreamWriter extends JsonByteBufferWriter { - - private OutputStream out; - - protected JsonStreamWriter(boolean tiny, OutputStream out) { - this(tiny, null, out); - } - - protected JsonStreamWriter(boolean tiny, Charset charset, OutputStream out) { - super(tiny, charset, null); - this.out = out; - } - - @Override - protected boolean recycle() { - super.recycle(); - this.out = null; - return false; - } - - @Override - public void writeTo(final char ch) { - if (ch > Byte.MAX_VALUE) throw new ConvertException("writeTo char(int.value = " + (int) ch + ") must be less 127"); - try { - out.write((byte) ch); - } catch (IOException e) { - throw new ConvertException(e); - } - } - - @Override - public void writeTo(final char[] chs, final int start, final int len) { - writeTo(false, chs, start, len); - } - - private void writeTo(final boolean quote, final char[] chs, final int start, final int len) { - try { - if (quote) out.write('"'); - if (charset == null) { //UTF-8 - final int limit = start + len; - for (int i = start; i < limit; i++) { - char c = chs[i]; - if (c < 0x80) { - out.write((byte) c); - } else if (c < 0x800) { - out.write((byte) (0xc0 | (c >> 6))); - out.write((byte) (0x80 | (c & 0x3f))); - } else { - out.write((byte) (0xe0 | ((c >> 12)))); - out.write((byte) (0x80 | ((c >> 6) & 0x3f))); - out.write((byte) (0x80 | (c & 0x3f))); - } - } - } else { - ByteBuffer bb = charset.encode(CharBuffer.wrap(chs, start, len)); - out.write(bb.array()); - } - if (quote) out.write('"'); - } catch (IOException e) { - throw new ConvertException(e); - } - } - - /** - * 注意: 该String值不能为null且不会进行转义, 只用于不含需要转义字符的字符串,例如enum、double、BigInteger转换的String - * - * @param quote 是否写入双引号 - * @param value String值 - */ - @Override - public void writeTo(final boolean quote, final String value) { - char[] chs = Utility.charArray(value); - writeTo(quote, chs, 0, chs.length); - } - - @Override - public void writeInt(int value) { - writeTo(false, String.valueOf(value)); - } - - @Override - public void writeLong(long value) { - writeTo(false, String.valueOf(value)); - } - - @Override - public void writeString(String value) { - if (value == null) { - writeNull(); - return; - } - final char[] chs = Utility.charArray(value); - int len = 0; - for (char ch : chs) { - switch (ch) { - case '\n': len += 2; - break; - case '\r': len += 2; - break; - case '\t': len += 2; - break; - case '\\': len += 2; - break; - case '"': len += 2; - break; - default: len++; - break; - } - } - if (len == chs.length) { - writeTo(true, chs, 0, len); - return; - } - StringBuilder sb = new StringBuilder(len); - for (char ch : chs) { - switch (ch) { - case '\n': sb.append("\\n"); - break; - case '\r': sb.append("\\r"); - break; - case '\t': sb.append("\\t"); - break; - case '\\': sb.append("\\\\"); - break; - case '"': sb.append("\\\""); - break; - default: sb.append(ch); - break; - } - } - char[] cs = Utility.charArray(sb); - writeTo(true, cs, 0, sb.length()); - } -} diff --git a/src/main/java/org/redkale/convert/json/JsonWriter.java b/src/main/java/org/redkale/convert/json/JsonWriter.java deleted file mode 100644 index 988b47044..000000000 --- a/src/main/java/org/redkale/convert/json/JsonWriter.java +++ /dev/null @@ -1,381 +0,0 @@ -/* - * 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.json; - -import java.nio.*; -import org.redkale.convert.*; -import org.redkale.util.*; - -/** - * - * writeTo系列的方法输出的字符不能含特殊字符 - * - *

- * 详情见: http://www.redkale.org - * - * @author zhangjx - */ -public class JsonWriter extends Writer { - - private static final char[] CHARS_TUREVALUE = "true".toCharArray(); - - private static final char[] CHARS_FALSEVALUE = "false".toCharArray(); - - private static final int defaultSize = Integer.getInteger("convert.json.writer.buffer.defsize", 1024); - - private int count; - - private char[] content; - - protected boolean tiny; - - public static ObjectPool createPool(int max) { - return new ObjectPool<>(max, (Object... params) -> new JsonWriter(), null, (JsonWriter t) -> t.recycle()); - } - - public JsonWriter() { - this(defaultSize); - } - - public JsonWriter(int size) { - this.content = new char[size > 128 ? size : 128]; - } - - @Override - public boolean tiny() { - return tiny; - } - - public JsonWriter tiny(boolean tiny) { - this.tiny = tiny; - return this; - } - - //----------------------------------------------------------------------- - //----------------------------------------------------------------------- - /** - * 返回指定至少指定长度的缓冲区 - * - * @param len - * @return - */ - private char[] expand(int len) { - int newcount = count + len; - if (newcount <= content.length) return content; - char[] newdata = new char[Math.max(content.length * 3 / 2, newcount)]; - System.arraycopy(content, 0, newdata, 0, count); - this.content = newdata; - return newdata; - } - - public void writeTo(final char ch) { //只能是 0 - 127 的字符 - expand(1); - content[count++] = ch; - } - - public void writeTo(final char[] chs, final int start, final int len) { //只能是 0 - 127 的字符 - expand(len); - System.arraycopy(chs, start, content, count, len); - count += len; - } - - /** - * 注意: 该String值不能为null且不会进行转义, 只用于不含需要转义字符的字符串,例如enum、double、BigInteger转换的String - * - * @param quote 是否加双引号 - * @param value 非null且不含需要转义的字符的String值 - */ - public void writeTo(final boolean quote, final String value) { - int len = value.length(); - expand(len + (quote ? 2 : 0)); - if (quote) content[count++] = '"'; - value.getChars(0, len, content, count); - count += len; - if (quote) content[count++] = '"'; - } - - protected boolean recycle() { - this.count = 0; - if (this.content.length > defaultSize) { - this.content = new char[defaultSize]; - } - return true; - } - - public ByteBuffer[] toBuffers() { - return new ByteBuffer[]{ByteBuffer.wrap(Utility.encodeUTF8(content, 0, count))}; - } - - public int count() { - return this.count; - } - - @Override - public void writeString(String value) { - if (value == null) { - writeNull(); - return; - } - expand(value.length() * 2 + 2); - content[count++] = '"'; - for (char ch : Utility.charArray(value)) { - switch (ch) { - case '\n': content[count++] = '\\'; - content[count++] = 'n'; - break; - case '\r': content[count++] = '\\'; - content[count++] = 'r'; - break; - case '\t': content[count++] = '\\'; - content[count++] = 't'; - break; - case '\\': content[count++] = '\\'; - content[count++] = ch; - break; - case '"': content[count++] = '\\'; - content[count++] = ch; - break; - default: content[count++] = ch; - break; - } - } - content[count++] = '"'; - } - - @Override - public final void writeFieldName(Attribute attribute) { - if (this.comma) writeTo(','); - writeTo(true, attribute.field()); - writeTo(':'); - } - - @Override - public final void writeSmallString(String value) { - writeTo(true, value); - } - - @Override - public String toString() { - return new String(content, 0, count); - } - - //---------------------------------------------------------------------------------------------- - public final void writeTo(final char... chs) { //只能是 0 - 127 的字符 - writeTo(chs, 0, chs.length); - } - - @Override - public final void writeBoolean(boolean value) { - writeTo(value ? CHARS_TUREVALUE : CHARS_FALSEVALUE); - } - - @Override - public final void writeByte(byte value) { - writeInt(value); - } - - @Override - public final void writeChar(char value) { - writeInt(value); - } - - @Override - public final void writeShort(short value) { - writeInt(value); - } - - @Override - public void writeInt(int value) { - final char sign = value >= 0 ? 0 : '-'; - if (value < 0) value = -value; - int size; - for (int i = 0;; i++) { - if (value <= sizeTable[i]) { - size = i + 1; - break; - } - } - if (sign != 0) size++; //负数 - expand(size); - - int q, r; - int charPos = count + size; - - // Generate two digits per iteration - while (value >= 65536) { - q = value / 100; - // really: r = i - (q * 100); - r = value - ((q << 6) + (q << 5) + (q << 2)); - value = q; - content[--charPos] = DigitOnes[r]; - content[--charPos] = DigitTens[r]; - } - - // Fall thru to fast mode for smaller numbers - // assert(i <= 65536, i); - for (;;) { - q = (value * 52429) >>> (16 + 3); - r = value - ((q << 3) + (q << 1)); // r = i-(q*10) ... - content[--charPos] = digits[r]; - value = q; - if (value == 0) break; - } - if (sign != 0) content[--charPos] = sign; - count += size; - } - - @Override - public void writeLong(long value) { - final char sign = value >= 0 ? 0 : '-'; - if (value < 0) value = -value; - int size = 19; - long p = 10; - for (int i = 1; i < 19; i++) { - if (value < p) { - size = i; - break; - } - p = 10 * p; - } - if (sign != 0) size++; //负数 - expand(size); - - long q; - int r; - int charPos = count + size; - - // Get 2 digits/iteration using longs until quotient fits into an int - while (value > Integer.MAX_VALUE) { - q = value / 100; - // really: r = i - (q * 100); - r = (int) (value - ((q << 6) + (q << 5) + (q << 2))); - value = q; - content[--charPos] = DigitOnes[r]; - content[--charPos] = DigitTens[r]; - } - - // Get 2 digits/iteration using ints - int q2; - int i2 = (int) value; - while (i2 >= 65536) { - q2 = i2 / 100; - // really: r = i2 - (q * 100); - r = i2 - ((q2 << 6) + (q2 << 5) + (q2 << 2)); - i2 = q2; - content[--charPos] = DigitOnes[r]; - content[--charPos] = DigitTens[r]; - } - - // Fall thru to fast mode for smaller numbers - // assert(i2 <= 65536, i2); - for (;;) { - q2 = (i2 * 52429) >>> (16 + 3); - r = i2 - ((q2 << 3) + (q2 << 1)); // r = i2-(q2*10) ... - content[--charPos] = digits[r]; - i2 = q2; - if (i2 == 0) break; - } - if (sign != 0) content[--charPos] = sign; - count += size; - } - - @Override - public final void writeFloat(float value) { - writeTo(false, String.valueOf(value)); - } - - @Override - public final void writeDouble(double value) { - writeTo(false, String.valueOf(value)); - } - - @Override - public final void wirteClassName(String clazz) { - } - - @Override - public final void writeObjectB(Object obj) { - super.writeObjectB(obj); - writeTo('{'); - } - - @Override - public final void writeObjectE(Object obj) { - writeTo('}'); - } - - @Override - public final void writeNull() { - writeTo('n', 'u', 'l', 'l'); - } - - @Override - public final void writeArrayB(int size) { - writeTo('['); - } - - @Override - public final void writeArrayMark() { - writeTo(','); - } - - @Override - public final void writeArrayE() { - writeTo(']'); - } - - @Override - public final void writeMapB(int size) { - writeTo('{'); - } - - @Override - public final void writeMapMark() { - writeTo(':'); - } - - @Override - public final void writeMapE() { - writeTo('}'); - } - - final static char[] DigitTens = { - '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', - '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', - '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', - '3', '3', '3', '3', '3', '3', '3', '3', '3', '3', - '4', '4', '4', '4', '4', '4', '4', '4', '4', '4', - '5', '5', '5', '5', '5', '5', '5', '5', '5', '5', - '6', '6', '6', '6', '6', '6', '6', '6', '6', '6', - '7', '7', '7', '7', '7', '7', '7', '7', '7', '7', - '8', '8', '8', '8', '8', '8', '8', '8', '8', '8', - '9', '9', '9', '9', '9', '9', '9', '9', '9', '9' - }; - - final static char[] DigitOnes = { - '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', - '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', - '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', - '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', - '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', - '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', - '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', - '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', - '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', - '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' - }; - - final static char[] digits = { - '0', '1', '2', '3', '4', '5', - '6', '7', '8', '9', 'a', 'b', - 'c', 'd', 'e', 'f', 'g', 'h', - 'i', 'j', 'k', 'l', 'm', 'n', - 'o', 'p', 'q', 'r', 's', 't', - 'u', 'v', 'w', 'x', 'y', 'z' - }; - - final static int[] sizeTable = {9, 99, 999, 9999, 99999, 999999, 9999999, 99999999, 999999999, Integer.MAX_VALUE}; -} diff --git a/src/main/java/org/redkale/convert/json/package-info.java b/src/main/java/org/redkale/convert/json/package-info.java deleted file mode 100644 index 7e181f13b..000000000 --- a/src/main/java/org/redkale/convert/json/package-info.java +++ /dev/null @@ -1,4 +0,0 @@ -/** - * 提供JSON的序列化和反解析功能 - */ -package org.redkale.convert.json; diff --git a/src/main/java/org/redkale/convert/package-info.java b/src/main/java/org/redkale/convert/package-info.java deleted file mode 100644 index 72764d0e0..000000000 --- a/src/main/java/org/redkale/convert/package-info.java +++ /dev/null @@ -1,4 +0,0 @@ -/** - * 提供数据的序列化和反解析功能 - */ -package org.redkale.convert; diff --git a/src/main/java/org/redkale/net/AsyncConnection.java b/src/main/java/org/redkale/net/AsyncConnection.java deleted file mode 100644 index 4c3bc1d16..000000000 --- a/src/main/java/org/redkale/net/AsyncConnection.java +++ /dev/null @@ -1,575 +0,0 @@ -/* - * 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.net.*; -import java.nio.*; -import java.nio.channels.*; -import java.util.*; -import java.util.concurrent.*; - -/** - * - *

- * 详情见: http://www.redkale.org - * - * @author zhangjx - */ -public abstract class AsyncConnection implements AsynchronousByteChannel, AutoCloseable { - - protected Map attributes; - - public abstract boolean isTCP(); - - public abstract SocketAddress getRemoteAddress(); - - public abstract SocketAddress getLocalAddress(); - - public abstract int getReadTimeoutSecond(); - - public abstract int getWriteTimeoutSecond(); - - public abstract void setReadTimeoutSecond(int readTimeoutSecond); - - public abstract void setWriteTimeoutSecond(int writeTimeoutSecond); - - public final void write(ByteBuffer[] srcs, A attachment, CompletionHandler handler) { - write(srcs, 0, srcs.length, attachment, handler); - } - - protected abstract void write(ByteBuffer[] srcs, int offset, int length, A attachment, CompletionHandler handler); - - public void dispose() {//同close, 只是去掉throws IOException - try { - this.close(); - } catch (IOException io) { - } - } - - @Override - public void close() throws IOException { - if (attributes == null) return; - try { - for (Object obj : attributes.values()) { - if (obj instanceof AutoCloseable) ((AutoCloseable) obj).close(); - } - } catch (Exception io) { - } - } - - public void setAttribute(String name, Object value) { - if (attributes == null) attributes = new HashMap<>(); - attributes.put(name, value); - } - - @SuppressWarnings("unchecked") - public final T getAttribute(String name) { - return (T) (attributes == null ? null : attributes.get(name)); - } - - public final void removeAttribute(String name) { - if (attributes != null) attributes.remove(name); - } - - public final Map getAttributes() { - return attributes; - } - - public final void clearAttribute() { - if (attributes != null) attributes.clear(); - } - - //------------------------------------------------------------------------------------------------------------------------------ - public static AsyncConnection create(final String protocol, final AsynchronousChannelGroup group, final SocketAddress address) throws IOException { - return create(protocol, group, address, 0, 0); - } - - /** - * 创建客户端连接 - * - * @param protocol 连接类型 只能是TCP或UDP - * @param address 连接点子 - * @param group 连接AsynchronousChannelGroup - * @param readTimeoutSecond0 读取超时秒数 - * @param writeTimeoutSecond0 写入超时秒数 - * @return 连接 - * @throws java.io.IOException 异常 - */ - public static AsyncConnection create(final String protocol, final AsynchronousChannelGroup group, final SocketAddress address, - final int readTimeoutSecond0, final int writeTimeoutSecond0) throws IOException { - if ("TCP".equalsIgnoreCase(protocol)) { - AsynchronousSocketChannel channel = AsynchronousSocketChannel.open(group); - try { - channel.connect(address).get(3, TimeUnit.SECONDS); - } catch (Exception e) { - throw new IOException("AsyncConnection connect " + address, e); - } - return create(channel, address, readTimeoutSecond0, writeTimeoutSecond0); - } else if ("UDP".equalsIgnoreCase(protocol)) { - DatagramChannel channel = DatagramChannel.open(); - channel.configureBlocking(true); - channel.connect(address); - return create(channel, address, true, readTimeoutSecond0, writeTimeoutSecond0); - } else { - throw new RuntimeException("AsyncConnection not support protocol " + protocol); - } - } - - private static class BIOUDPAsyncConnection extends AsyncConnection { - - private int readTimeoutSecond; - - private int writeTimeoutSecond; - - private final DatagramChannel channel; - - private final SocketAddress remoteAddress; - - private final boolean client; - - public BIOUDPAsyncConnection(final DatagramChannel ch, SocketAddress addr, - final boolean client0, final int readTimeoutSecond0, final int writeTimeoutSecond0) { - this.channel = ch; - this.client = client0; - this.readTimeoutSecond = readTimeoutSecond0; - this.writeTimeoutSecond = writeTimeoutSecond0; - this.remoteAddress = addr; - } - - @Override - public void setReadTimeoutSecond(int readTimeoutSecond) { - this.readTimeoutSecond = readTimeoutSecond; - } - - @Override - public void setWriteTimeoutSecond(int writeTimeoutSecond) { - this.writeTimeoutSecond = writeTimeoutSecond; - } - - @Override - public int getReadTimeoutSecond() { - return this.readTimeoutSecond; - } - - @Override - public int getWriteTimeoutSecond() { - return this.writeTimeoutSecond; - } - - @Override - public final SocketAddress getRemoteAddress() { - return remoteAddress; - } - - @Override - public SocketAddress getLocalAddress() { - try { - return channel.getLocalAddress(); - } catch (IOException e) { - return null; - } - } - - @Override - protected void write(ByteBuffer[] srcs, int offset, int length, A attachment, CompletionHandler handler) { - try { - int rs = 0; - for (int i = offset; i < offset + length; i++) { - rs += channel.send(srcs[i], remoteAddress); - if (i != offset) Thread.sleep(10); - } - if (handler != null) handler.completed(rs, attachment); - } catch (Exception e) { - if (handler != null) handler.failed(e, attachment); - } - } - - @Override - public void read(ByteBuffer dst, A attachment, CompletionHandler handler) { - try { - int rs = channel.read(dst); - if (handler != null) handler.completed(rs, attachment); - } catch (IOException e) { - if (handler != null) handler.failed(e, attachment); - } - } - - @Override - public Future read(ByteBuffer dst) { - try { - int rs = channel.read(dst); - return new SimpleFuture(rs); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - @Override - public void write(ByteBuffer src, A attachment, CompletionHandler handler) { - try { - int rs = channel.send(src, remoteAddress); - if (handler != null) handler.completed(rs, attachment); - } catch (IOException e) { - if (handler != null) handler.failed(e, attachment); - } - } - - @Override - public Future write(ByteBuffer src) { - try { - int rs = channel.send(src, remoteAddress); - return new SimpleFuture(rs); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - @Override - public final void close() throws IOException { - super.close(); - if (client) { - channel.close(); - } - } - - @Override - public final boolean isOpen() { - return channel.isOpen(); - } - - @Override - public final boolean isTCP() { - return false; - } - } - - public static AsyncConnection create(final DatagramChannel ch, SocketAddress addr, - final boolean client0, final int readTimeoutSecond0, final int writeTimeoutSecond0) { - return new BIOUDPAsyncConnection(ch, addr, client0, readTimeoutSecond0, writeTimeoutSecond0); - } - - private static class SimpleFuture implements Future { - - private final int rs; - - public SimpleFuture(int rs) { - this.rs = rs; - } - - @Override - public boolean cancel(boolean mayInterruptIfRunning) { - return true; - } - - @Override - public boolean isCancelled() { - return false; - } - - @Override - public boolean isDone() { - return true; - } - - @Override - public Integer get() throws InterruptedException, ExecutionException { - return rs; - } - - @Override - public Integer get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException { - return rs; - } - - } - - private static class BIOTCPAsyncConnection extends AsyncConnection { - - private int readTimeoutSecond; - - private int writeTimeoutSecond; - - private final Socket socket; - - private final ReadableByteChannel readChannel; - - private final WritableByteChannel writeChannel; - - private final SocketAddress remoteAddress; - - public BIOTCPAsyncConnection(final Socket socket, final SocketAddress addr0, final int readTimeoutSecond0, final int writeTimeoutSecond0) { - this.socket = socket; - ReadableByteChannel rc = null; - WritableByteChannel wc = null; - try { - socket.setSoTimeout(Math.max(readTimeoutSecond0, writeTimeoutSecond0)); - rc = Channels.newChannel(socket.getInputStream()); - wc = Channels.newChannel(socket.getOutputStream()); - } catch (IOException e) { - e.printStackTrace(); - } - this.readChannel = rc; - this.writeChannel = wc; - this.readTimeoutSecond = readTimeoutSecond0; - this.writeTimeoutSecond = writeTimeoutSecond0; - SocketAddress addr = addr0; - if (addr == null) { - try { - addr = socket.getRemoteSocketAddress(); - } catch (Exception e) { - //do nothing - } - } - this.remoteAddress = addr; - } - - @Override - public boolean isTCP() { - return true; - } - - @Override - public SocketAddress getRemoteAddress() { - return remoteAddress; - } - - @Override - public SocketAddress getLocalAddress() { - return socket.getLocalSocketAddress(); - } - - @Override - public int getReadTimeoutSecond() { - return readTimeoutSecond; - } - - @Override - public int getWriteTimeoutSecond() { - return writeTimeoutSecond; - } - - @Override - public void setReadTimeoutSecond(int readTimeoutSecond) { - this.readTimeoutSecond = readTimeoutSecond; - } - - @Override - public void setWriteTimeoutSecond(int writeTimeoutSecond) { - this.writeTimeoutSecond = writeTimeoutSecond; - } - - @Override - protected void write(ByteBuffer[] srcs, int offset, int length, A attachment, CompletionHandler handler) { - try { - int rs = 0; - for (int i = offset; i < offset + length; i++) { - rs += writeChannel.write(srcs[i]); - } - if (handler != null) handler.completed(rs, attachment); - } catch (IOException e) { - if (handler != null) handler.failed(e, attachment); - } - } - - @Override - public void read(ByteBuffer dst, A attachment, CompletionHandler handler) { - try { - int rs = readChannel.read(dst); - if (handler != null) handler.completed(rs, attachment); - } catch (IOException e) { - if (handler != null) handler.failed(e, attachment); - } - } - - @Override - public Future read(ByteBuffer dst) { - try { - int rs = readChannel.read(dst); - return new SimpleFuture(rs); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - @Override - public void write(ByteBuffer src, A attachment, CompletionHandler handler) { - try { - int rs = writeChannel.write(src); - if (handler != null) handler.completed(rs, attachment); - } catch (IOException e) { - if (handler != null) handler.failed(e, attachment); - } - } - - @Override - public Future write(ByteBuffer src) { - try { - int rs = writeChannel.write(src); - return new SimpleFuture(rs); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - @Override - public void close() throws IOException { - super.close(); - this.socket.close(); - } - - @Override - public boolean isOpen() { - return !socket.isClosed(); - } - } - - /** - * 通常用于 ssl socket - * - * @param socket Socket对象 - * @return 连接对象 - */ - public static AsyncConnection create(final Socket socket) { - return create(socket, null, 0, 0); - } - - public static AsyncConnection create(final Socket socket, final SocketAddress addr0, final int readTimeoutSecond0, final int writeTimeoutSecond0) { - return new BIOTCPAsyncConnection(socket, addr0, readTimeoutSecond0, writeTimeoutSecond0); - } - - private static class AIOTCPAsyncConnection extends AsyncConnection { - - private int readTimeoutSecond; - - private int writeTimeoutSecond; - - private final AsynchronousSocketChannel channel; - - private final SocketAddress remoteAddress; - - public AIOTCPAsyncConnection(final AsynchronousSocketChannel ch, final SocketAddress addr0, final int readTimeoutSecond0, final int writeTimeoutSecond0) { - this.channel = ch; - this.readTimeoutSecond = readTimeoutSecond0; - this.writeTimeoutSecond = writeTimeoutSecond0; - SocketAddress addr = addr0; - if (addr == null) { - try { - addr = ch.getRemoteAddress(); - } catch (Exception e) { - //do nothing - } - } - this.remoteAddress = addr; - } - - @Override - public void read(ByteBuffer dst, A attachment, CompletionHandler handler) { - if (readTimeoutSecond > 0) { - channel.read(dst, readTimeoutSecond, TimeUnit.SECONDS, attachment, handler); - } else { - channel.read(dst, attachment, handler); - } - } - - @Override - public void write(ByteBuffer src, A attachment, CompletionHandler handler) { - if (writeTimeoutSecond > 0) { - channel.write(src, writeTimeoutSecond, TimeUnit.SECONDS, attachment, handler); - } else { - channel.write(src, attachment, handler); - } - } - - @Override - public void write(ByteBuffer[] srcs, int offset, int length, A attachment, final CompletionHandler handler) { - channel.write(srcs, offset, length, writeTimeoutSecond > 0 ? writeTimeoutSecond : 60, TimeUnit.SECONDS, - attachment, new CompletionHandler() { - - @Override - public void completed(Long result, A attachment) { - handler.completed(result.intValue(), attachment); - } - - @Override - public void failed(Throwable exc, A attachment) { - handler.failed(exc, attachment); - } - - }); - } - - @Override - public void setReadTimeoutSecond(int readTimeoutSecond) { - this.readTimeoutSecond = readTimeoutSecond; - } - - @Override - public void setWriteTimeoutSecond(int writeTimeoutSecond) { - this.writeTimeoutSecond = writeTimeoutSecond; - } - - @Override - public int getReadTimeoutSecond() { - return this.readTimeoutSecond; - } - - @Override - public int getWriteTimeoutSecond() { - return this.writeTimeoutSecond; - } - - @Override - public final SocketAddress getRemoteAddress() { - return remoteAddress; - } - - @Override - public SocketAddress getLocalAddress() { - try { - return channel.getLocalAddress(); - } catch (IOException e) { - return null; - } - } - - @Override - public final Future read(ByteBuffer dst) { - return channel.read(dst); - } - - @Override - public final Future write(ByteBuffer src) { - return channel.write(src); - } - - @Override - public final void close() throws IOException { - super.close(); - channel.close(); - } - - @Override - public final boolean isOpen() { - return channel.isOpen(); - } - - @Override - public final boolean isTCP() { - return true; - } - - } - - public static AsyncConnection create(final AsynchronousSocketChannel ch) { - return create(ch, null, 0, 0); - } - - public static AsyncConnection create(final AsynchronousSocketChannel ch, final SocketAddress addr0, final int readTimeoutSecond0, final int writeTimeoutSecond0) { - return new AIOTCPAsyncConnection(ch, addr0, readTimeoutSecond0, writeTimeoutSecond0); - } - -} diff --git a/src/main/java/org/redkale/net/Context.java b/src/main/java/org/redkale/net/Context.java deleted file mode 100644 index 4977d5e81..000000000 --- a/src/main/java/org/redkale/net/Context.java +++ /dev/null @@ -1,133 +0,0 @@ -/* - * 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.net.*; -import java.nio.*; -import java.nio.charset.*; -import java.util.concurrent.*; -import java.util.function.*; -import java.util.logging.*; -import org.redkale.convert.bson.*; -import org.redkale.convert.json.*; -import org.redkale.util.*; -import org.redkale.watch.*; - -/** - * - *

详情见: http://www.redkale.org - * @author zhangjx - */ -public class Context { - - private static final Charset UTF8 = Charset.forName("UTF-8"); - - protected final long serverStartTime; - - protected final ExecutorService executor; - - protected final int bufferCapacity; - - protected final ObjectPool bufferPool; - - protected final ObjectPool responsePool; - - protected final PrepareServlet prepare; - - private final InetSocketAddress address; - - protected final Charset charset; - - protected final int maxbody; - - protected final int readTimeoutSecond; - - protected final int writeTimeoutSecond; - - protected final Logger logger; - - protected final BsonFactory bsonFactory; - - protected final JsonFactory jsonFactory; - - protected final WatchFactory watch; - - public Context(long serverStartTime, Logger logger, ExecutorService executor, int bufferCapacity, ObjectPool bufferPool, ObjectPool responsePool, - final int maxbody, Charset charset, InetSocketAddress address, final PrepareServlet prepare, final WatchFactory watch, - final int readTimeoutSecond, final int writeTimeoutSecond) { - this.serverStartTime = serverStartTime; - this.logger = logger; - this.executor = executor; - this.bufferCapacity = bufferCapacity; - this.bufferPool = bufferPool; - this.responsePool = responsePool; - this.maxbody = maxbody; - this.charset = UTF8.equals(charset) ? null : charset; - this.address = address; - this.prepare = prepare; - this.watch = watch; - this.readTimeoutSecond = readTimeoutSecond; - this.writeTimeoutSecond = writeTimeoutSecond; - this.jsonFactory = JsonFactory.root(); - this.bsonFactory = BsonFactory.root(); - } - - public int getMaxbody() { - return maxbody; - } - - public InetSocketAddress getServerAddress() { - return address; - } - - public long getServerStartTime() { - return serverStartTime; - } - - public Charset getCharset() { - return charset; - } - - public void submit(Runnable r) { - executor.submit(r); - } - - public int getBufferCapacity() { - return bufferCapacity; - } - - public Supplier getBufferSupplier() { - return bufferPool; - } - - public ByteBuffer pollBuffer() { - return bufferPool.get(); - } - - public void offerBuffer(ByteBuffer buffer) { - bufferPool.offer(buffer); - } - - public Logger getLogger() { - return logger; - } - - public int getReadTimeoutSecond() { - return readTimeoutSecond; - } - - public int getWriteTimeoutSecond() { - return writeTimeoutSecond; - } - - public JsonConvert getJsonConvert() { - return jsonFactory.getConvert(); - } - - public BsonConvert getBsonConvert() { - return bsonFactory.getConvert(); - } -} diff --git a/src/main/java/org/redkale/net/PrepareRunner.java b/src/main/java/org/redkale/net/PrepareRunner.java deleted file mode 100644 index 5678e7727..000000000 --- a/src/main/java/org/redkale/net/PrepareRunner.java +++ /dev/null @@ -1,99 +0,0 @@ -/* - * 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.nio.*; -import java.nio.channels.*; -import java.util.logging.*; -import org.redkale.util.*; - -/** - * - *

详情见: http://www.redkale.org - * @author zhangjx - */ -@SuppressWarnings("unchecked") -public final class PrepareRunner implements Runnable { - - private final AsyncConnection channel; - - private final Context context; - - private ByteBuffer data; - - public PrepareRunner(Context context, AsyncConnection channel, ByteBuffer data) { - this.context = context; - this.channel = channel; - this.data = data; - } - - @Override - public void run() { - final PrepareServlet prepare = context.prepare; - final ObjectPool responsePool = context.responsePool; - if (data != null) { - final Response response = responsePool.get(); - response.init(channel); - try { - prepare.prepare(data, response.request, response); - } catch (Throwable t) { - context.logger.log(Level.WARNING, "prepare servlet abort, forece to close channel ", t); - response.finish(true); - } - return; - } - final ByteBuffer buffer = context.pollBuffer(); - try { - channel.read(buffer, null, new CompletionHandler() { - @Override - public void completed(Integer count, Void attachment1) { - if (count < 1 && buffer.remaining() == buffer.limit()) { - try { - context.offerBuffer(buffer); - channel.close(); - } catch (Exception e) { - context.logger.log(Level.FINEST, "PrepareRunner close channel erroneous on no read bytes", e); - } - return; - } -// { //测试 -// buffer.flip(); -// byte[] bs = new byte[buffer.remaining()]; -// buffer.get(bs); -// System.println(new String(bs)); -// } - buffer.flip(); - final Response response = responsePool.get(); - response.init(channel); - try { - prepare.prepare(buffer, response.request, response); - } catch (Throwable t) { //此处不可 context.offerBuffer(buffer); 以免prepare.prepare内部异常导致重复 offerBuffer - context.logger.log(Level.WARNING, "prepare servlet abort, forece to close channel ", t); - response.finish(true); - } - } - - @Override - public void failed(Throwable exc, Void attachment2) { - context.offerBuffer(buffer); - try { - channel.close(); - } catch (Exception e) { - } - if (exc != null) context.logger.log(Level.FINEST, "Servlet Handler read channel erroneous, forece to close channel ", exc); - } - }); - } catch (Exception te) { - context.offerBuffer(buffer); - try { - channel.close(); - } catch (Exception e) { - } - if (te != null) context.logger.log(Level.FINEST, "Servlet read channel erroneous, forece to close channel ", te); - } - } - -} diff --git a/src/main/java/org/redkale/net/PrepareServlet.java b/src/main/java/org/redkale/net/PrepareServlet.java deleted file mode 100644 index b0ee5c272..000000000 --- a/src/main/java/org/redkale/net/PrepareServlet.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * 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.nio.*; -import java.nio.channels.*; -import java.util.*; -import java.util.concurrent.atomic.*; -import java.util.logging.*; -import org.redkale.util.*; - -/** - * - *

- * 详情见: http://www.redkale.org - * - * @author zhangjx - * @param Context的子类型 - * @param Request的子类型 - * @param

Response的子类型 - */ -public abstract class PrepareServlet, P extends Response, S extends Servlet> extends Servlet { - - protected final AtomicLong executeCounter = new AtomicLong(); //执行请求次数 - - protected final AtomicLong illRequestCounter = new AtomicLong(); //错误请求次数 - - protected final Set servlets = new HashSet<>(); - - protected final Map mappings = new HashMap<>(); - - public abstract void addServlet(S servlet, Object attachment, AnyValue conf, K... mappings); - - public final void prepare(final ByteBuffer buffer, final R request, final P response) throws IOException { - executeCounter.incrementAndGet(); - final int rs = request.readHeader(buffer); - if (rs < 0) { - response.context.offerBuffer(buffer); - if (rs != Integer.MIN_VALUE) illRequestCounter.incrementAndGet(); - response.finish(true); - } else if (rs == 0) { - response.context.offerBuffer(buffer); - request.prepare(); - this.execute(request, response); - } else { - buffer.clear(); - final AtomicInteger ai = new AtomicInteger(rs); - request.channel.read(buffer, buffer, new CompletionHandler() { - - @Override - public void completed(Integer result, ByteBuffer attachment) { - buffer.flip(); - ai.addAndGet(-request.readBody(buffer)); - if (ai.get() > 0) { - buffer.clear(); - request.channel.read(buffer, buffer, this); - } else { - response.context.offerBuffer(buffer); - request.prepare(); - try { - execute(request, response); - } catch (Exception e) { - illRequestCounter.incrementAndGet(); - response.finish(true); - request.context.logger.log(Level.WARNING, "prepare servlet abort, forece to close channel ", e); - } - } - } - - @Override - public void failed(Throwable exc, ByteBuffer attachment) { - illRequestCounter.incrementAndGet(); - response.context.offerBuffer(buffer); - response.finish(true); - if (exc != null) request.context.logger.log(Level.FINER, "Servlet read channel erroneous, forece to close channel ", exc); - } - }); - } - } - - protected AnyValue getServletConf(Servlet servlet) { - return servlet._conf; - } - - protected void setServletConf(Servlet servlet, AnyValue conf) { - servlet._conf = conf; - } -} diff --git a/src/main/java/org/redkale/net/ProtocolServer.java b/src/main/java/org/redkale/net/ProtocolServer.java deleted file mode 100644 index 64917c812..000000000 --- a/src/main/java/org/redkale/net/ProtocolServer.java +++ /dev/null @@ -1,184 +0,0 @@ -/* - * 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.IOException; -import java.net.*; -import java.nio.ByteBuffer; -import java.nio.channels.*; -import java.util.*; -import java.util.concurrent.*; - -/** - * - *

详情见: http://www.redkale.org - * @author zhangjx - */ -public abstract class ProtocolServer { - - public abstract void open() throws IOException; - - public abstract void bind(SocketAddress local, int backlog) throws IOException; - - public abstract Set> supportedOptions(); - - public abstract void setOption(SocketOption name, T value) throws IOException; - - public abstract void accept(); - - public abstract void close() throws IOException; - - public abstract AsynchronousChannelGroup getChannelGroup(); - - //--------------------------------------------------------------------- - public static ProtocolServer create(String protocol, Context context) { - if ("TCP".equalsIgnoreCase(protocol)) return new ProtocolTCPServer(context); - if ("UDP".equalsIgnoreCase(protocol)) return new ProtocolUDPServer(context); - throw new RuntimeException("ProtocolServer not support protocol " + protocol); - } - - private static final class ProtocolUDPServer extends ProtocolServer { - - private boolean running; - - private final Context context; - - private DatagramChannel serverChannel; - - public ProtocolUDPServer(Context context) { - this.context = context; - } - - @Override - public void open() throws IOException { - DatagramChannel ch = DatagramChannel.open(); - ch.configureBlocking(true); - this.serverChannel = ch; - } - - @Override - public void bind(SocketAddress local, int backlog) throws IOException { - this.serverChannel.bind(local); - } - - @Override - public void setOption(SocketOption name, T value) throws IOException { - this.serverChannel.setOption(name, value); - } - - @Override - public Set> supportedOptions() { - return this.serverChannel.supportedOptions(); - } - - @Override - public void accept() { - final DatagramChannel serchannel = this.serverChannel; - final int readTimeoutSecond = this.context.readTimeoutSecond; - final int writeTimeoutSecond = this.context.writeTimeoutSecond; - final CountDownLatch cdl = new CountDownLatch(1); - this.running = true; - new Thread() { - @Override - public void run() { - cdl.countDown(); - while (running) { - final ByteBuffer buffer = context.pollBuffer(); - try { - SocketAddress address = serchannel.receive(buffer); - buffer.flip(); - AsyncConnection conn = AsyncConnection.create(serchannel, address, false, readTimeoutSecond, writeTimeoutSecond); - context.submit(new PrepareRunner(context, conn, buffer)); - } catch (Exception e) { - context.offerBuffer(buffer); - } - } - } - }.start(); - try { - cdl.await(); - } catch (Exception e) { - e.printStackTrace(); - } - } - - @Override - public void close() throws IOException { - this.running = false; - this.serverChannel.close(); - } - - @Override - public AsynchronousChannelGroup getChannelGroup() { - return null; - } - - } - - private static final class ProtocolTCPServer extends ProtocolServer { - - private final Context context; - - private AsynchronousChannelGroup group; - - private AsynchronousServerSocketChannel serverChannel; - - public ProtocolTCPServer(Context context) { - this.context = context; - } - - @Override - public void open() throws IOException { - group = AsynchronousChannelGroup.withCachedThreadPool(context.executor, 1); - this.serverChannel = AsynchronousServerSocketChannel.open(group); - } - - @Override - public void bind(SocketAddress local, int backlog) throws IOException { - this.serverChannel.bind(local, backlog); - } - - @Override - public void setOption(SocketOption name, T value) throws IOException { - this.serverChannel.setOption(name, value); - } - - @Override - public Set> supportedOptions() { - return this.serverChannel.supportedOptions(); - } - - @Override - public void accept() { - final AsynchronousServerSocketChannel serchannel = this.serverChannel; - serchannel.accept(null, new CompletionHandler() { - - @Override - public void completed(final AsynchronousSocketChannel channel, Void attachment) { - serchannel.accept(null, this); - context.submit(new PrepareRunner(context, AsyncConnection.create(channel, null, context.readTimeoutSecond, context.writeTimeoutSecond), null)); - } - - @Override - public void failed(Throwable exc, Void attachment) { - serchannel.accept(null, this); - //if (exc != null) context.logger.log(Level.FINEST, AsynchronousServerSocketChannel.class.getSimpleName() + " accept erroneous", exc); - } - }); - } - - @Override - public void close() throws IOException { - this.serverChannel.close(); - } - - @Override - public AsynchronousChannelGroup getChannelGroup() { - return this.group; - } - } - -} diff --git a/src/main/java/org/redkale/net/Request.java b/src/main/java/org/redkale/net/Request.java deleted file mode 100644 index 8cf0cd61f..000000000 --- a/src/main/java/org/redkale/net/Request.java +++ /dev/null @@ -1,117 +0,0 @@ -/* - * 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.nio.ByteBuffer; -import java.util.*; -import org.redkale.convert.bson.BsonConvert; -import org.redkale.convert.json.JsonConvert; - -/** - * - *

- * 详情见: http://www.redkale.org - * - * @author zhangjx - */ -public abstract class Request { - - protected final C context; - - protected final BsonConvert bsonConvert; - - protected final JsonConvert jsonConvert; - - protected long createtime; - - protected boolean keepAlive; - - protected AsyncConnection channel; - - /** - * properties 与 attributes 的区别在于:调用recycle时, attributes会被清空而properties会保留; - * properties 通常存放需要永久绑定在request里的一些对象 - */ - private final Map properties = new HashMap<>(); - - protected final Map attributes = new HashMap<>(); - - protected Request(C context) { - this.context = context; - this.bsonConvert = context.getBsonConvert(); - this.jsonConvert = context.getJsonConvert(); - } - - /** - * 返回值:Integer.MIN_VALUE: 帧数据; -1:数据不合法; 0:解析完毕; >0: 需再读取的字节数。 - * - * @param buffer ByteBuffer对象 - * @return 缺少的字节数 - */ - protected abstract int readHeader(ByteBuffer buffer); - - /** - * 读取buffer,并返回读取的有效数据长度 - * - * @param buffer ByteBuffer对象 - * @return 有效数据长度 - */ - protected abstract int readBody(ByteBuffer buffer); - - protected abstract void prepare(); - - protected void recycle() { - createtime = 0; - keepAlive = false; - attributes.clear(); - channel = null; // close it by response - } - - protected T setProperty(String name, T value) { - properties.put(name, value); - return value; - } - - @SuppressWarnings("unchecked") - protected T getProperty(String name) { - return (T) properties.get(name); - } - - protected T removeProperty(String name) { - return (T)properties.remove(name); - } - - protected Map getProperties() { - return properties; - } - - public T setAttribute(String name, T value) { - attributes.put(name, value); - return value; - } - - @SuppressWarnings("unchecked") - public T getAttribute(String name) { - return (T) attributes.get(name); - } - - public T removeAttribute(String name) { - return (T)attributes.remove(name); - } - - public Map getAttributes() { - return attributes; - } - - public C getContext() { - return this.context; - } - - public long getCreatetime() { - return createtime; - } - -} diff --git a/src/main/java/org/redkale/net/Response.java b/src/main/java/org/redkale/net/Response.java deleted file mode 100644 index 38cfd694a..000000000 --- a/src/main/java/org/redkale/net/Response.java +++ /dev/null @@ -1,230 +0,0 @@ -/* - * 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.nio.*; -import java.nio.channels.*; -import java.util.function.*; - -/** - * - *

- * 详情见: http://www.redkale.org - * - * @author zhangjx - * @param Request的子类型 - */ -@SuppressWarnings("unchecked") -public abstract class Response> { - - protected final C context; - - protected final R request; - - protected AsyncConnection channel; - - private boolean inited = true; - - protected BiConsumer> recycleListener; - - private final CompletionHandler finishHandler = new CompletionHandler() { - - @Override - public void completed(Integer result, ByteBuffer attachment) { - if (attachment.hasRemaining()) { - channel.write(attachment, attachment, this); - } else { - context.offerBuffer(attachment); - finish(); - } - } - - @Override - public void failed(Throwable exc, ByteBuffer attachment) { - context.offerBuffer(attachment); - finish(true); - } - - }; - - private final CompletionHandler finishHandler2 = new CompletionHandler() { - - @Override - public void completed(Integer result, ByteBuffer[] attachments) { - int index = -1; - for (int i = 0; i < attachments.length; i++) { - if (attachments[i].hasRemaining()) { - index = i; - break; - } else { - context.offerBuffer(attachments[i]); - } - } - if (index == 0) { - channel.write(attachments, attachments, this); - } else if (index > 0) { - ByteBuffer[] newattachs = new ByteBuffer[attachments.length - index]; - System.arraycopy(attachments, index, newattachs, 0, newattachs.length); - channel.write(newattachs, newattachs, this); - } else { - finish(); - } - } - - @Override - public void failed(Throwable exc, ByteBuffer[] attachments) { - for (ByteBuffer attachment : attachments) { - context.offerBuffer(attachment); - } - finish(true); - } - - }; - - protected Response(C context, final R request) { - this.context = context; - this.request = request; - } - - protected AsyncConnection removeChannel() { - AsyncConnection ch = this.channel; - this.channel = null; - return ch; - } - - protected void prepare() { - inited = true; - } - - protected boolean recycle() { - if (!inited) return false; - boolean keepAlive = request.keepAlive; - if (recycleListener != null) { - try { - recycleListener.accept(request, this); - } catch (Exception e) { - System.err.println(request); - e.printStackTrace(); - } - recycleListener = null; - } - request.recycle(); - if (channel != null) { - if (keepAlive) { - this.context.submit(new PrepareRunner(context, channel, null)); - } else { - try { - if (channel.isOpen()) channel.close(); - } catch (Exception e) { - } - } - channel = null; - } - this.inited = false; - return true; - } - - protected void refuseAlive() { - this.request.keepAlive = false; - } - - protected void init(AsyncConnection channel) { - this.channel = channel; - this.request.channel = channel; - this.request.createtime = System.currentTimeMillis(); - } - - public void setRecycleListener(BiConsumer> recycleListener) { - this.recycleListener = recycleListener; - } - - public void finish() { - this.finish(false); - } - - public void finish(boolean kill) { - //System.println("耗时: " + (System.currentTimeMillis() - request.createtime)); - if (kill) refuseAlive(); - this.context.responsePool.offer(this); - } - - public void finish(ByteBuffer buffer) { - this.channel.write(buffer, buffer, finishHandler); - } - - public void finish(boolean kill, ByteBuffer buffer) { - if (kill) refuseAlive(); - this.channel.write(buffer, buffer, finishHandler); - } - - public void finish(ByteBuffer... buffers) { - this.channel.write(buffers, buffers, finishHandler2); - } - - public void finish(boolean kill, ByteBuffer... buffers) { - if (kill) refuseAlive(); - this.channel.write(buffers, buffers, finishHandler2); - } - - protected void send(final ByteBuffer buffer, final A attachment, final CompletionHandler handler) { - this.channel.write(buffer, attachment, new CompletionHandler() { - - @Override - public void completed(Integer result, A attachment) { - if (buffer.hasRemaining()) { - channel.write(buffer, attachment, this); - } else { - context.offerBuffer(buffer); - if (handler != null) handler.completed(result, attachment); - } - } - - @Override - public void failed(Throwable exc, A attachment) { - context.offerBuffer(buffer); - if (handler != null) handler.failed(exc, attachment); - } - - }); - } - - protected void send(final ByteBuffer[] buffers, A attachment, final CompletionHandler handler) { - this.channel.write(buffers, attachment, new CompletionHandler() { - - @Override - public void completed(Integer result, A attachment) { - int index = -1; - for (int i = 0; i < buffers.length; i++) { - if (buffers[i].hasRemaining()) { - index = i; - break; - } - context.offerBuffer(buffers[i]); - } - if (index == 0) { - channel.write(buffers, attachment, this); - } else if (index > 0) { - ByteBuffer[] newattachs = new ByteBuffer[buffers.length - index]; - System.arraycopy(buffers, index, newattachs, 0, newattachs.length); - channel.write(newattachs, attachment, this); - } else if (handler != null) handler.completed(result, attachment); - } - - @Override - public void failed(Throwable exc, A attachment) { - for (ByteBuffer buffer : buffers) { - context.offerBuffer(buffer); - } - if (handler != null) handler.failed(exc, attachment); - } - - }); - } - - public C getContext() { - return context; - } -} diff --git a/src/main/java/org/redkale/net/Server.java b/src/main/java/org/redkale/net/Server.java deleted file mode 100644 index 8fc99cc38..000000000 --- a/src/main/java/org/redkale/net/Server.java +++ /dev/null @@ -1,199 +0,0 @@ -/* - * 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.lang.reflect.*; -import java.net.*; -import java.nio.charset.*; -import java.text.*; -import java.util.*; -import java.util.concurrent.*; -import java.util.concurrent.atomic.*; -import java.util.logging.*; -import org.redkale.util.*; -import org.redkale.watch.*; - -/** - * - *

- * 详情见: http://www.redkale.org - * - * @author zhangjx - */ -public abstract class Server, P extends Response, S extends Servlet> { - - public static final String RESNAME_SERVER_ROOT = "SERVER_ROOT"; - - protected final Logger logger = Logger.getLogger(this.getClass().getSimpleName()); - - //------------------------------------------------------------- - protected final long serverStartTime; - - protected final WatchFactory watch; - - protected final String protocol; - - protected final PrepareServlet prepare; - - protected C context; - - protected AnyValue config; - - protected Charset charset; - - protected InetSocketAddress address; - - protected int backlog; - - protected ProtocolServer serverChannel; - - protected int bufferCapacity; - - protected int threads; - - protected ExecutorService executor; - - protected int bufferPoolSize; - - protected int responsePoolSize; - - protected int maxbody; - - protected int readTimeoutSecond; - - protected int writeTimeoutSecond; - - private ScheduledThreadPoolExecutor scheduler; - - protected Server(long serverStartTime, String protocol, PrepareServlet servlet, final WatchFactory watch) { - this.serverStartTime = serverStartTime; - this.protocol = protocol; - this.prepare = servlet; - this.watch = watch; - } - - public void init(final AnyValue config) throws Exception { - Objects.requireNonNull(config); - this.config = config; - this.address = new InetSocketAddress(config.getValue("host", "0.0.0.0"), config.getIntValue("port", 80)); - this.charset = Charset.forName(config.getValue("charset", "UTF-8")); - this.backlog = config.getIntValue("backlog", 8 * 1024); - this.readTimeoutSecond = config.getIntValue("readTimeoutSecond", 0); - this.writeTimeoutSecond = config.getIntValue("writeTimeoutSecond", 0); - this.maxbody = config.getIntValue("maxbody", 64 * 1024); - this.bufferCapacity = config.getIntValue("bufferCapacity", 8 * 1024); - this.threads = config.getIntValue("threads", Runtime.getRuntime().availableProcessors() * 16); - this.bufferPoolSize = config.getIntValue("bufferPoolSize", Runtime.getRuntime().availableProcessors() * 512); - this.responsePoolSize = config.getIntValue("responsePoolSize", Runtime.getRuntime().availableProcessors() * 256); - final int port = this.address.getPort(); - final AtomicInteger counter = new AtomicInteger(); - final Format f = createFormat(); - this.executor = Executors.newFixedThreadPool(threads, (Runnable r) -> { - Thread t = new WorkThread(executor, r); - t.setName("Servlet-" + protocol + "-" + port + "-Thread-" + f.format(counter.incrementAndGet())); - return t; - }); - } - - public void destroy(final AnyValue config) throws Exception { - this.prepare.destroy(context, config); - if (scheduler != null) scheduler.shutdownNow(); - } - - public InetSocketAddress getSocketAddress() { - return address; - } - - public String getProtocol() { - return protocol; - } - - public Logger getLogger() { - return this.logger; - } - - @SuppressWarnings("unchecked") - public void addServlet(S servlet, final Object attachment, AnyValue conf, K... mappings) { - this.prepare.addServlet(servlet, attachment, conf, mappings); - } - - public void start() throws IOException { - this.context = this.createContext(); - this.prepare.init(this.context, config); - if (this.watch != null) this.watch.inject(this.prepare); - this.serverChannel = ProtocolServer.create(this.protocol, context); - this.serverChannel.open(); - if (this.serverChannel.supportedOptions().contains(StandardSocketOptions.TCP_NODELAY)) { - this.serverChannel.setOption(StandardSocketOptions.TCP_NODELAY, true); - } - serverChannel.bind(address, backlog); - serverChannel.accept(); - final String threadName = "[" + Thread.currentThread().getName() + "] "; - logger.info(threadName + this.getClass().getSimpleName() + ("TCP".equalsIgnoreCase(protocol) ? "" : ("." + protocol)) + " listen: " + address - + ", threads: " + threads + ", bufferCapacity: " + bufferCapacity + ", bufferPoolSize: " + bufferPoolSize + ", responsePoolSize: " + responsePoolSize - + ", started in " + (System.currentTimeMillis() - context.getServerStartTime()) + " ms"); - } - - protected abstract C createContext(); - - public void shutdown() throws IOException { - long s = System.currentTimeMillis(); - logger.info(this.getClass().getSimpleName() + "-" + this.protocol + " shutdowning"); - try { - this.serverChannel.close(); - } catch (Exception e) { - } - logger.info(this.getClass().getSimpleName() + "-" + this.protocol + " shutdow prepare servlet"); - this.prepare.destroy(this.context, config); - long e = System.currentTimeMillis() - s; - logger.info(this.getClass().getSimpleName() + " shutdown in " + e + " ms"); - } - - protected Format createFormat() { - String sf = "0"; - if (this.threads > 10) sf = "00"; - if (this.threads > 100) sf = "000"; - if (this.threads > 1000) sf = "0000"; - return new DecimalFormat(sf); - } - - public static URL[] loadLib(final Logger logger, final String lib) throws Exception { - if (lib == null || lib.isEmpty()) return new URL[0]; - final Set set = new HashSet<>(); - for (String s : lib.split(";")) { - if (s.isEmpty()) continue; - if (s.endsWith("*")) { - File root = new File(s.substring(0, s.length() - 1)); - if (root.isDirectory()) { - for (File f : root.listFiles()) { - set.add(f.toURI().toURL()); - } - } - } else { - File f = new File(s); - if (f.canRead()) set.add(f.toURI().toURL()); - } - } - if (set.isEmpty()) return new URL[0]; - ClassLoader cl = Thread.currentThread().getContextClassLoader(); - if (cl instanceof URLClassLoader) { - URLClassLoader loader = (URLClassLoader) cl; - final Method method = URLClassLoader.class.getDeclaredMethod("addURL", URL.class); - method.setAccessible(true); - for (URL url : set) { - method.invoke(loader, url); - //if (logger != null) logger.log(Level.INFO, "Server found ClassPath({0})", url); - } - } else { - Thread.currentThread().setContextClassLoader(new URLClassLoader(set.toArray(new URL[set.size()]), cl)); - } - List list = new ArrayList<>(set); - Collections.sort(list, (URL o1, URL o2) -> o1.getFile().compareTo(o2.getFile())); - return list.toArray(new URL[list.size()]); - } - -} diff --git a/src/main/java/org/redkale/net/Servlet.java b/src/main/java/org/redkale/net/Servlet.java deleted file mode 100644 index 5324152f3..000000000 --- a/src/main/java/org/redkale/net/Servlet.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * 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 org.redkale.util.AnyValue; -import java.io.IOException; - -/** - * - *

- * 详情见: http://www.redkale.org - * - * @author zhangjx - * @param Context的子类型 - * @param Request的子类型 - * @param

Response的子类型 - */ -public abstract class Servlet, P extends Response> { - - AnyValue _conf; //当前Servlet的配置 - - public void init(C context, AnyValue config) { - } - - public abstract void execute(R request, P response) throws IOException; - - public void destroy(C context, AnyValue config) { - } - -} diff --git a/src/main/java/org/redkale/net/Transport.java b/src/main/java/org/redkale/net/Transport.java deleted file mode 100644 index da3b2adb7..000000000 --- a/src/main/java/org/redkale/net/Transport.java +++ /dev/null @@ -1,253 +0,0 @@ -/* - * 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.net.*; -import java.nio.*; -import java.nio.channels.*; -import java.util.*; -import java.util.concurrent.*; -import java.util.function.*; -import java.util.stream.*; -import org.redkale.util.*; -import org.redkale.watch.*; - -/** - * 传输客户端 - * - *

- * 详情见: http://www.redkale.org - * - * @author zhangjx - */ -public final class Transport { - - public static final String DEFAULT_PROTOCOL = "TCP"; - - protected static final int MAX_POOL_LIMIT = Runtime.getRuntime().availableProcessors() * 16; - - protected static final boolean supportTcpNoDelay; - - static { - boolean tcpNoDelay = false; - try { - AsynchronousSocketChannel channel = AsynchronousSocketChannel.open(); - tcpNoDelay = channel.supportedOptions().contains(StandardSocketOptions.TCP_NODELAY); - channel.close(); - } catch (Exception e) { - } - supportTcpNoDelay = tcpNoDelay; - } - - protected final String name; //即的name属性 - - protected final boolean tcp; - - protected final String protocol; - - protected final WatchFactory watch; - - protected final AsynchronousChannelGroup group; - - protected final InetSocketAddress clientAddress; - - protected InetSocketAddress[] remoteAddres = new InetSocketAddress[0]; - - protected final ObjectPool bufferPool; - - protected final ConcurrentHashMap> connPool = new ConcurrentHashMap<>(); - - public Transport(String name, WatchFactory watch, final ObjectPool transportBufferPool, - final AsynchronousChannelGroup transportChannelGroup, final InetSocketAddress clientAddress, final Collection addresses) { - this(name, DEFAULT_PROTOCOL, watch, transportBufferPool, transportChannelGroup, clientAddress, addresses); - } - - public Transport(String name, String protocol, WatchFactory watch, final ObjectPool transportBufferPool, - final AsynchronousChannelGroup transportChannelGroup, final InetSocketAddress clientAddress, final Collection addresses) { - this.name = name; - this.watch = watch; - this.protocol = protocol; - this.tcp = "TCP".equalsIgnoreCase(protocol); - this.group = transportChannelGroup; - this.bufferPool = transportBufferPool; - this.clientAddress = clientAddress; - updateRemoteAddresses(addresses); - } - - public Transport(final Collection transports) { - Transport first = null; - List tmpgroup = new ArrayList<>(); - for (Transport t : transports) { - if (first == null) first = t; - tmpgroup.add(t.name); - } - Collections.sort(tmpgroup); //必须按字母排列顺序确保,相同内容的transport列表组合的name相同,而不会因为list的顺序不同产生不同的name - this.name = tmpgroup.stream().collect(Collectors.joining(";")); - this.watch = first.watch; - this.protocol = first.protocol; - this.tcp = "TCP".equalsIgnoreCase(first.protocol); - this.group = first.group; - this.bufferPool = first.bufferPool; - this.clientAddress = first.clientAddress; - Set addrs = new HashSet<>(); - transports.forEach(t -> addrs.addAll(Arrays.asList(t.getRemoteAddresses()))); - updateRemoteAddresses(addrs); - } - - public final InetSocketAddress[] updateRemoteAddresses(final Collection addresses) { - InetSocketAddress[] oldAddresses = this.remoteAddres; - List list = new ArrayList<>(); - if (addresses != null) { - for (InetSocketAddress addr : addresses) { - if (clientAddress != null && clientAddress.equals(addr)) continue; - list.add(addr); - } - } - this.remoteAddres = list.toArray(new InetSocketAddress[list.size()]); - return oldAddresses; - } - - public String getName() { - return name; - } - - public void close() { - connPool.forEach((k, v) -> v.forEach(c -> c.dispose())); - } - - public InetSocketAddress getClientAddress() { - return clientAddress; - } - - public InetSocketAddress[] getRemoteAddresses() { - return remoteAddres; - } - - @Override - public String toString() { - return Transport.class.getSimpleName() + "{name = " + name + ", protocol = " + protocol + ", clientAddress = " + clientAddress + ", remoteAddres = " + Arrays.toString(remoteAddres) + "}"; - } - - public ByteBuffer pollBuffer() { - return bufferPool.get(); - } - - public Supplier getBufferSupplier() { - return bufferPool; - } - - public void offerBuffer(ByteBuffer buffer) { - bufferPool.offer(buffer); - } - - public void offerBuffer(ByteBuffer... buffers) { - for (ByteBuffer buffer : buffers) offerBuffer(buffer); - } - - public boolean isTCP() { - return tcp; - } - - public AsyncConnection pollConnection(SocketAddress addr) { - if (addr == null && remoteAddres.length == 1) addr = remoteAddres[0]; - final boolean rand = addr == null; - if (rand && remoteAddres.length < 1) throw new RuntimeException("Transport (" + this.name + ") has no remoteAddress list"); - try { - if (tcp) { - AsynchronousSocketChannel channel = null; - if (rand) { //取地址 - for (int i = 0; i < remoteAddres.length; i++) { - addr = remoteAddres[i]; - BlockingQueue queue = connPool.get(addr); - if (queue != null && !queue.isEmpty()) { - AsyncConnection conn; - while ((conn = queue.poll()) != null) { - if (conn.isOpen()) return conn; - } - } - if (channel == null) { - channel = AsynchronousSocketChannel.open(group); - if (supportTcpNoDelay) channel.setOption(StandardSocketOptions.TCP_NODELAY, true); - } - try { - channel.connect(addr).get(2, TimeUnit.SECONDS); - break; - } catch (Exception iex) { - iex.printStackTrace(); - if (i == remoteAddres.length - 1) channel = null; - } - } - } else { - channel = AsynchronousSocketChannel.open(group); - if (supportTcpNoDelay) channel.setOption(StandardSocketOptions.TCP_NODELAY, true); - channel.connect(addr).get(2, TimeUnit.SECONDS); - } - if (channel == null) return null; - return AsyncConnection.create(channel, addr, 3000, 3000); - } else { // UDP - if (rand) addr = remoteAddres[0]; - DatagramChannel channel = DatagramChannel.open(); - channel.configureBlocking(true); - channel.connect(addr); - return AsyncConnection.create(channel, addr, true, 3000, 3000); -// AsyncDatagramChannel channel = AsyncDatagramChannel.open(group); -// channel.connect(addr); -// return AsyncConnection.create(channel, addr, true, 3000, 3000); - } - } catch (Exception ex) { - throw new RuntimeException("transport address = " + addr, ex); - } - } - - public void offerConnection(final boolean forceClose, AsyncConnection conn) { - if (!forceClose && conn.isTCP()) { - if (conn.isOpen()) { - BlockingQueue queue = connPool.get(conn.getRemoteAddress()); - if (queue == null) { - queue = new ArrayBlockingQueue<>(MAX_POOL_LIMIT); - connPool.put(conn.getRemoteAddress(), queue); - } - if (!queue.offer(conn)) conn.dispose(); - } - } else { - conn.dispose(); - } - } - - public void async(SocketAddress addr, final ByteBuffer buffer, A att, final CompletionHandler handler) { - final AsyncConnection conn = pollConnection(addr); - conn.write(buffer, buffer, new CompletionHandler() { - - @Override - public void completed(Integer result, ByteBuffer attachment) { - buffer.clear(); - conn.read(buffer, buffer, new CompletionHandler() { - - @Override - public void completed(Integer result, ByteBuffer attachment) { - if (handler != null) handler.completed(result, att); - offerBuffer(buffer); - offerConnection(false, conn); - } - - @Override - public void failed(Throwable exc, ByteBuffer attachment) { - offerBuffer(buffer); - offerConnection(true, conn); - } - }); - - } - - @Override - public void failed(Throwable exc, ByteBuffer attachment) { - offerBuffer(buffer); - offerConnection(true, conn); - } - }); - } - -} diff --git a/src/main/java/org/redkale/net/WorkThread.java b/src/main/java/org/redkale/net/WorkThread.java deleted file mode 100644 index 5b17c7c40..000000000 --- a/src/main/java/org/redkale/net/WorkThread.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * 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.util.concurrent.*; - -/** - * - *

详情见: http://www.redkale.org - * @author zhangjx - */ -public class WorkThread extends Thread { - - private final ExecutorService executor; - - public WorkThread(ExecutorService executor, Runnable runner) { - super(runner); - this.executor = executor; - this.setDaemon(true); - } - - public void submit(Runnable runner) { - executor.submit(runner); - } - - public ExecutorService getExecutor() { - return executor; - } -} diff --git a/src/main/java/org/redkale/net/http/BasedHttpServlet.java b/src/main/java/org/redkale/net/http/BasedHttpServlet.java deleted file mode 100644 index 3e64deffb..000000000 --- a/src/main/java/org/redkale/net/http/BasedHttpServlet.java +++ /dev/null @@ -1,325 +0,0 @@ -/* - * 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.http; - -import org.redkale.net.Response; -import org.redkale.net.Request; -import org.redkale.util.AnyValue; -import java.io.IOException; -import java.lang.annotation.*; -import static java.lang.annotation.ElementType.*; -import static java.lang.annotation.RetentionPolicy.RUNTIME; -import java.lang.reflect.Method; -import java.nio.*; -import java.util.*; -import java.util.concurrent.*; -import jdk.internal.org.objectweb.asm.*; -import static jdk.internal.org.objectweb.asm.Opcodes.*; - -/** - * - *

- * 详情见: http://www.redkale.org - * - * @author zhangjx - */ -public abstract class BasedHttpServlet extends HttpServlet { - - /** - * 配合 BasedHttpServlet 使用。 - * 当标记为 @AuthIgnore 的方法不会再调用之前调用authenticate 方法。 - * - *

- * 详情见: http://www.redkale.org - * - * @author zhangjx - */ - @Inherited - @Documented - @Target({METHOD, TYPE}) - @Retention(RUNTIME) - protected @interface AuthIgnore { - - } - - /** - * 配合 BasedHttpServlet 使用。 - * 用于对@WebServlet对应的url进行细分。 其 url - * - *

- * 详情见: http://www.redkale.org - * - * @author zhangjx - */ - @Target({ElementType.METHOD}) - @Retention(RetentionPolicy.RUNTIME) - @Documented - protected @interface WebAction { - - int actionid() default 0; - - String url(); - } - - /** - * 配合 BasedHttpServlet 使用。 - * 当标记为 @HttpCacheable 的方法使用response.finish的参数将被缓存一定时间(默认值timeout=15秒)。 - * 通常情况下 @HttpCacheable 需要与 @AuthIgnore 一起使用,因为没有标记@AuthIgnore的方法一般输出的结果与当前用户信息有关。 - * - *

- * 详情见: http://www.redkale.org - * - * @author zhangjx - */ - @Target({ElementType.METHOD}) - @Retention(RetentionPolicy.RUNTIME) - @Documented - protected @interface HttpCacheable { - - /** - * 超时的秒数 - * - * @return 超时秒数 - */ - int timeout() default 15; - } - - private Map.Entry[] actions; - - public boolean preExecute(HttpRequest request, HttpResponse response) throws IOException { - return true; - } - - @Override - public final void execute(HttpRequest request, HttpResponse response) throws IOException { - if (!preExecute(request, response)) return; - for (Map.Entry en : actions) { - if (request.getRequestURI().startsWith(en.getKey())) { - Entry entry = en.getValue(); - if (entry.ignore || authenticate(entry.moduleid, entry.actionid, request, response)) { - if (entry.cachetimeout > 0) {//有缓存设置 - CacheEntry ce = entry.cache.get(request.getRequestURI()); - if (ce != null && ce.time + entry.cachetimeout > System.currentTimeMillis()) { //缓存有效 - response.setStatus(ce.status); - response.setContentType(ce.contentType); - response.finish(ce.getBuffers()); - return; - } - response.setBufferHandler(entry.cacheHandler); - } - entry.servlet.execute(request, response); - } - return; - } - } - throw new IOException(this.getClass().getName() + " not found method for URI(" + request.getRequestURI() + ")"); - } - - public final void preInit(HttpContext context, AnyValue config) { - String path = _prefix == null ? "" : _prefix; - WebServlet ws = this.getClass().getAnnotation(WebServlet.class); - if (ws != null && !ws.repair()) path = ""; - HashMap map = load(); - this.actions = new Map.Entry[map.size()]; - int i = -1; - for (Map.Entry en : map.entrySet()) { - actions[++i] = new AbstractMap.SimpleEntry<>(path + en.getKey(), en.getValue()); - } - } - - public final void postDestroy(HttpContext context, AnyValue config) { - } - - public abstract boolean authenticate(int module, int actionid, HttpRequest request, HttpResponse response) throws IOException; - - private HashMap load() { - final boolean typeIgnore = this.getClass().getAnnotation(AuthIgnore.class) != null; - WebServlet module = this.getClass().getAnnotation(WebServlet.class); - final int serviceid = module == null ? 0 : module.moduleid(); - final HashMap map = new HashMap<>(); - Set nameset = new HashSet<>(); - for (final Method method : this.getClass().getMethods()) { - //----------------------------------------------- - String methodname = method.getName(); - if ("service".equals(methodname) || "preExecute".equals(methodname) || "execute".equals(methodname) || "authenticate".equals(methodname)) continue; - //----------------------------------------------- - Class[] paramTypes = method.getParameterTypes(); - if (paramTypes.length != 2 || paramTypes[0] != HttpRequest.class - || paramTypes[1] != HttpResponse.class) continue; - //----------------------------------------------- - Class[] exps = method.getExceptionTypes(); - if (exps.length > 0 && (exps.length != 1 || exps[0] != IOException.class)) continue; - //----------------------------------------------- - - final WebAction action = method.getAnnotation(WebAction.class); - if (action == null) continue; - final int actionid = action.actionid(); - final String name = action.url().trim(); - - if (nameset.contains(name)) throw new RuntimeException(this.getClass().getSimpleName() + " has two same " + WebAction.class.getSimpleName() + "(" + name + ")"); - for (String n : nameset) { - if (n.contains(name) || name.contains(n)) { - throw new RuntimeException(this.getClass().getSimpleName() + " has two sub-contains " + WebAction.class.getSimpleName() + "(" + name + ", " + n + ")"); - } - } - nameset.add(name); - map.put(name, new Entry(typeIgnore, serviceid, actionid, name, method, createHttpServlet(method))); - } - return map; - } - - private HttpServlet createHttpServlet(final Method method) { - //------------------------------------------------------------------------------ - final String supDynName = HttpServlet.class.getName().replace('.', '/'); - final String interName = this.getClass().getName().replace('.', '/'); - final String interDesc = jdk.internal.org.objectweb.asm.Type.getDescriptor(this.getClass()); - final String requestSupDesc = jdk.internal.org.objectweb.asm.Type.getDescriptor(Request.class); - final String responseSupDesc = jdk.internal.org.objectweb.asm.Type.getDescriptor(Response.class); - final String requestDesc = jdk.internal.org.objectweb.asm.Type.getDescriptor(HttpRequest.class); - final String responseDesc = jdk.internal.org.objectweb.asm.Type.getDescriptor(HttpResponse.class); - String newDynName = interName + "_Dyn_" + method.getName(); - int i = 0; - for (;;) { - try { - Class.forName(newDynName.replace('/', '.')); - newDynName += "_" + (++i); - } catch (Exception ex) { - break; - } - } - //------------------------------------------------------------------------------ - ClassWriter cw = new ClassWriter(0); - FieldVisitor fv; - MethodVisitor mv; - AnnotationVisitor av0; - final String factfield = "_factServlet"; - cw.visit(V1_8, ACC_PUBLIC + ACC_FINAL + ACC_SUPER, newDynName, null, supDynName, null); - { - fv = cw.visitField(ACC_PUBLIC, factfield, interDesc, null, null); - fv.visitEnd(); - } - { //构造函数 - mv = (cw.visitMethod(ACC_PUBLIC, "", "()V", null, null)); - //mv.setDebug(true); - mv.visitVarInsn(ALOAD, 0); - mv.visitMethodInsn(INVOKESPECIAL, supDynName, "", "()V", false); - mv.visitInsn(RETURN); - mv.visitMaxs(1, 1); - mv.visitEnd(); - } - { - mv = (cw.visitMethod(ACC_PUBLIC, "execute", "(" + requestDesc + responseDesc + ")V", null, new String[]{"java/io/IOException"})); - mv.visitVarInsn(ALOAD, 0); - mv.visitFieldInsn(GETFIELD, newDynName, factfield, interDesc); - mv.visitVarInsn(ALOAD, 1); - mv.visitVarInsn(ALOAD, 2); - mv.visitMethodInsn(INVOKEVIRTUAL, interName, method.getName(), "(" + requestDesc + responseDesc + ")V", false); - mv.visitInsn(RETURN); - mv.visitMaxs(3, 3); - mv.visitEnd(); - } - { - mv = cw.visitMethod(ACC_PUBLIC + ACC_BRIDGE + ACC_SYNTHETIC, "execute", "(" + requestSupDesc + responseSupDesc + ")V", null, new String[]{"java/io/IOException"}); - mv.visitVarInsn(ALOAD, 0); - mv.visitVarInsn(ALOAD, 1); - mv.visitTypeInsn(CHECKCAST, HttpRequest.class.getName().replace('.', '/')); - mv.visitVarInsn(ALOAD, 2); - mv.visitTypeInsn(CHECKCAST, HttpResponse.class.getName().replace('.', '/')); - mv.visitMethodInsn(INVOKEVIRTUAL, newDynName, "execute", "(" + requestDesc + responseDesc + ")V", false); - mv.visitInsn(RETURN); - mv.visitMaxs(3, 3); - mv.visitEnd(); - } - cw.visitEnd(); - //------------------------------------------------------------------------------ - byte[] bytes = cw.toByteArray(); - Class newClazz = new ClassLoader(this.getClass().getClassLoader()) { - public final Class loadClass(String name, byte[] b) { - return defineClass(name, b, 0, b.length); - } - }.loadClass(newDynName.replace('/', '.'), bytes); - try { - HttpServlet instance = (HttpServlet) newClazz.newInstance(); - instance.getClass().getField(factfield).set(instance, this); - return instance; - } catch (Exception ex) { - throw new RuntimeException(ex); - } - } - - private static final class Entry { - - public Entry(boolean typeIgnore, int moduleid, int actionid, String name, Method method, HttpServlet servlet) { - this.moduleid = moduleid; - this.actionid = actionid; - this.name = name; - this.method = method; - this.servlet = servlet; - this.ignore = typeIgnore || method.getAnnotation(AuthIgnore.class) != null; - HttpCacheable hc = method.getAnnotation(HttpCacheable.class); - this.cachetimeout = hc == null ? 0 : hc.timeout() * 1000; - this.cache = cachetimeout > 0 ? new ConcurrentHashMap() : null; - this.cacheHandler = cachetimeout > 0 ? (HttpResponse response, ByteBuffer[] buffers) -> { - int status = response.getStatus(); - if (status != 200) return null; - CacheEntry ce = new CacheEntry(response.getStatus(), response.getContentType(), buffers); - cache.put(response.getRequest().getRequestURI(), ce); - return ce.getBuffers(); - } : null; - } - - public boolean isNeedCheck() { - return this.moduleid != 0 || this.actionid != 0; - } - - public final HttpResponse.BufferHandler cacheHandler; - - public final ConcurrentHashMap cache; - - public final int cachetimeout; - - public final boolean ignore; - - public final int moduleid; - - public final int actionid; - - public final String name; - - public final Method method; - - public final HttpServlet servlet; - } - - private static final class CacheEntry { - - public final long time = System.currentTimeMillis(); - - private final ByteBuffer[] buffers; - - private final int status; - - private final String contentType; - - public CacheEntry(int status, String contentType, ByteBuffer[] bufs) { - this.status = status; - this.contentType = contentType; - final ByteBuffer[] newBuffers = new ByteBuffer[bufs.length]; - for (int i = 0; i < newBuffers.length; i++) { - newBuffers[i] = bufs[i].duplicate().asReadOnlyBuffer(); - } - this.buffers = newBuffers; - } - - public ByteBuffer[] getBuffers() { - final ByteBuffer[] newBuffers = new ByteBuffer[buffers.length]; - for (int i = 0; i < newBuffers.length; i++) { - newBuffers[i] = buffers[i].duplicate(); - } - return newBuffers; - } - } -} diff --git a/src/main/java/org/redkale/net/http/HttpContext.java b/src/main/java/org/redkale/net/http/HttpContext.java deleted file mode 100644 index ce0f3dffb..000000000 --- a/src/main/java/org/redkale/net/http/HttpContext.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * 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.http; - -import java.net.*; -import java.nio.*; -import java.nio.charset.*; -import java.security.*; -import java.util.concurrent.*; -import java.util.logging.*; -import org.redkale.net.*; -import org.redkale.util.*; -import org.redkale.watch.*; - -/** - * - *

- * 详情见: http://www.redkale.org - * - * @author zhangjx - */ -public class HttpContext extends Context { - - protected final SecureRandom random = new SecureRandom(); - - public HttpContext(long serverStartTime, Logger logger, ExecutorService executor, int bufferCapacity, ObjectPool bufferPool, - ObjectPool responsePool, int maxbody, Charset charset, InetSocketAddress address, PrepareServlet prepare, - WatchFactory watch, int readTimeoutSecond, int writeTimeoutSecond) { - super(serverStartTime, logger, executor, bufferCapacity, bufferPool, responsePool, maxbody, charset, - address, prepare, watch, readTimeoutSecond, writeTimeoutSecond); - - random.setSeed(Math.abs(System.nanoTime())); - } - - protected String createSessionid() { - byte[] bytes = new byte[16]; - random.nextBytes(bytes); - return new String(Utility.binToHex(bytes)); - } - - protected WatchFactory getWatchFactory() { - return watch; - } - - protected ExecutorService getExecutor() { - return executor; - } - - protected ObjectPool getResponsePool() { - return responsePool; - } - -} diff --git a/src/main/java/org/redkale/net/http/HttpPrepareServlet.java b/src/main/java/org/redkale/net/http/HttpPrepareServlet.java deleted file mode 100644 index c9507b859..000000000 --- a/src/main/java/org/redkale/net/http/HttpPrepareServlet.java +++ /dev/null @@ -1,144 +0,0 @@ -/* - * 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.http; - -import org.redkale.util.AnyValue.DefaultAnyValue; -import java.io.*; -import java.util.*; -import java.util.AbstractMap.SimpleEntry; -import java.util.function.*; -import java.util.logging.*; -import java.util.regex.*; -import org.redkale.net.*; -import org.redkale.util.*; -import org.redkale.watch.*; - -/** - * - *

- * 详情见: http://www.redkale.org - * - * @author zhangjx - */ -public final class HttpPrepareServlet extends PrepareServlet { - - private SimpleEntry, HttpServlet>[] regArray = new SimpleEntry[0]; - - private HttpServlet resourceHttpServlet = new HttpResourceServlet(); - - @Override - public void init(HttpContext context, AnyValue config) { - this.servlets.forEach(s -> { - if (s instanceof WebSocketServlet) { - ((WebSocketServlet) s).preInit(context, getServletConf(s)); - } else if (s instanceof BasedHttpServlet) { - ((BasedHttpServlet) s).preInit(context, getServletConf(s)); - } - s.init(context, getServletConf(s)); - }); - final WatchFactory watch = context.getWatchFactory(); - if (watch != null) { - this.servlets.forEach(s -> { - watch.inject(s); - }); - } - if (config != null) { - AnyValue ssConfig = config.getAnyValue("servlets"); - AnyValue resConfig = null; - if (ssConfig != null) { - resConfig = ssConfig.getAnyValue("resource-servlet"); - if ((resConfig instanceof DefaultAnyValue) && resConfig.getValue("webroot") == null) { - ((DefaultAnyValue) resConfig).addValue("webroot", config.getValue("root")); - } - } - if (resConfig == null) { - DefaultAnyValue dresConfig = new DefaultAnyValue(); - dresConfig.addValue("webroot", config.getValue("root")); - resConfig = dresConfig; - } - this.resourceHttpServlet.init(context, resConfig); - } - } - - @Override - public void execute(HttpRequest request, HttpResponse response) throws IOException { - try { - final String uri = request.getRequestURI(); - Servlet servlet = this.mappings.isEmpty() ? null : this.mappings.get(uri); - if (servlet == null && this.regArray != null) { - for (SimpleEntry, HttpServlet> en : regArray) { - if (en.getKey().test(uri)) { - servlet = en.getValue(); - break; - } - } - } - if (servlet == null) servlet = this.resourceHttpServlet; - servlet.execute(request, response); - } catch (Exception e) { - request.getContext().getLogger().log(Level.WARNING, "Servlet occur, forece to close channel. request = " + request, e); - response.finish(500, null); - } - } - - @Override - public void addServlet(HttpServlet servlet, Object prefix, AnyValue conf, String... mappings) { - if (prefix == null) prefix = ""; - for (String mapping : mappings) { - if (!prefix.toString().isEmpty()) mapping = prefix + mapping; - if (contains(mapping, '.', '*', '{', '[', '(', '|', '^', '$', '+', '?', '\\')) { //是否是正则表达式)) - if (mapping.charAt(0) != '^') mapping = '^' + mapping; - if (mapping.endsWith("/*")) { - mapping = mapping.substring(0, mapping.length() - 1) + ".*"; - } else { - mapping = mapping + "$"; - } - if (regArray == null) { - regArray = new SimpleEntry[1]; - regArray[0] = new SimpleEntry<>(Pattern.compile(mapping).asPredicate(), servlet); - } else { - regArray = Arrays.copyOf(regArray, regArray.length + 1); - regArray[regArray.length - 1] = new SimpleEntry<>(Pattern.compile(mapping).asPredicate(), servlet); - } - } else if (mapping != null && !mapping.isEmpty()) { - this.mappings.put(mapping, servlet); - } - } - setServletConf(servlet, conf); - servlet._prefix = prefix == null ? "" : prefix.toString(); - this.servlets.add(servlet); - } - - private static boolean contains(String string, char... values) { - if (string == null) return false; - for (char ch : Utility.charArray(string)) { - for (char ch2 : values) { - if (ch == ch2) return true; - } - } - return false; - } - - public void setResourceServlet(HttpServlet servlet) { - if (servlet != null) { - this.resourceHttpServlet = servlet; - } - } - - @Override - public void destroy(HttpContext context, AnyValue config) { - this.resourceHttpServlet.destroy(context, config); - this.servlets.forEach(s -> { - s.destroy(context, getServletConf(s)); - if (s instanceof WebSocketServlet) { - ((WebSocketServlet) s).postDestroy(context, getServletConf(s)); - } else if (s instanceof BasedHttpServlet) { - ((BasedHttpServlet) s).postDestroy(context, getServletConf(s)); - } - }); - } - -} diff --git a/src/main/java/org/redkale/net/http/HttpRequest.java b/src/main/java/org/redkale/net/http/HttpRequest.java deleted file mode 100644 index a8bb9c5f7..000000000 --- a/src/main/java/org/redkale/net/http/HttpRequest.java +++ /dev/null @@ -1,813 +0,0 @@ -/* - * 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.http; - -import java.io.*; -import java.net.*; -import java.nio.ByteBuffer; -import java.nio.channels.Channels; -import java.nio.charset.Charset; -import org.redkale.convert.json.JsonConvert; -import org.redkale.net.*; -import org.redkale.util.AnyValue.DefaultAnyValue; -import org.redkale.util.ByteArray; - -/** - * Http请求包 与javax.servlet.http.HttpServletRequest 基本类似。 - * 同时提供json的解析接口: public Object getJsonParameter(Class clazz, String name) - * RedKale提倡带简单的参数的GET请求采用类似REST风格, 因此提供了 getRequstURIPath 系列接口。 - * 例如简单的翻页查询 /pipes/record/query/page:2/size:20 - * 获取页号: int page = request.getRequstURIPath("page:", 1); - * 获取行数: int size = request.getRequstURIPath("size:", 10); - * - *

- * 详情见: http://www.redkale.org - * - * @author zhangjx - */ -public class HttpRequest extends Request { - - protected static final Charset UTF8 = Charset.forName("UTF-8"); - - protected static final String SESSIONID_NAME = "JSESSIONID"; - - private String method; - - private String protocol; - - protected String requestURI; - - private long contentLength = -1; - - private String contentType; - - private String host; - - private String connection; - - protected String cookiestr; - - private HttpCookie[] cookies; - - protected String newsessionid; - - protected final DefaultAnyValue header = new DefaultAnyValue(); - - protected final DefaultAnyValue params = new DefaultAnyValue(); - - private final ByteArray array = new ByteArray(); - - private boolean bodyparsed = false; - - protected boolean boundary = false; - - private final String remoteAddrHeader; - - public HttpRequest(HttpContext context, String remoteAddrHeader) { - super(context); - this.remoteAddrHeader = remoteAddrHeader; - } - - protected void setKeepAlive(boolean keepAlive) { - this.keepAlive = keepAlive; - } - - protected boolean isKeepAlive() { - return this.keepAlive; - } - - protected AsyncConnection getChannel() { - return this.channel; - } - - protected JsonConvert getJsonConvert() { - return this.jsonConvert; - } - - @Override - protected int readHeader(final ByteBuffer buffer) { - if (!readLine(buffer, array)) return -1; - Charset charset = this.context.getCharset(); - int index = 0; - int offset = array.find(index, ' '); - if (offset <= 0) return -1; - this.method = array.toString(index, offset, charset).trim(); - index = ++offset; - offset = array.find(index, ' '); - if (offset <= 0) return -1; - int off = array.find(index, '#'); - if (off > 0) offset = off; - int qst = array.find(index, offset, (byte) '?'); - if (qst > 0) { - this.requestURI = array.toDecodeString(index, qst - index, charset).trim(); - addParameter(array, qst + 1, offset - qst - 1); - } else { - this.requestURI = array.toDecodeString(index, offset - index, charset).trim(); - } - if (this.requestURI.contains("../")) return -1; - index = ++offset; - this.protocol = array.toString(index, array.size() - index, charset).trim(); - while (readLine(buffer, array)) { - if (array.size() < 2) break; - index = 0; - offset = array.find(index, ':'); - if (offset <= 0) return -1; - String name = array.toString(index, offset, charset).trim(); - index = offset + 1; - String value = array.toString(index, array.size() - index, charset).trim(); - switch (name) { - case "Content-Type": - this.contentType = value; - break; - case "Content-Length": - this.contentLength = Long.decode(value); - break; - case "Host": - this.host = value; - break; - case "Cookie": - if (this.cookiestr == null || this.cookiestr.isEmpty()) { - this.cookiestr = value; - } else { - this.cookiestr += ";" + value; - } - break; - case "Connection": - this.connection = value; - this.setKeepAlive(!"close".equalsIgnoreCase(value)); - break; - default: - header.addValue(name, value); - } - } - array.clear(); - if (buffer.hasRemaining()) array.write(buffer, buffer.remaining()); - if (this.contentType != null && this.contentType.contains("boundary=")) { - this.boundary = true; - } - if (this.boundary) this.keepAlive = false; //文件上传必须设置keepAlive为false,因为文件过大时用户不一定会skip掉多余的数据 - if (this.contentLength > 0 && (this.contentType == null || !this.boundary)) { - if (this.contentLength > context.getMaxbody()) return -1; - int lr = (int) this.contentLength - array.size(); - return lr > 0 ? lr : 0; - } - return 0; - } - - @Override - protected int readBody(ByteBuffer buffer) { - int len = buffer.remaining(); - array.write(buffer, len); - return len; - } - - @Override - protected void prepare() { - } - - private void parseBody() { - if (this.boundary || bodyparsed) return; - addParameter(array, 0, array.size()); - bodyparsed = true; - } - - private void addParameter(final ByteArray array, final int offset, final int len) { - if (len < 1) return; - Charset charset = this.context.getCharset(); - int limit = offset + len; - int keypos = array.find(offset, limit, '='); - int valpos = array.find(offset, limit, '&'); - if (keypos <= 0 || (valpos >= 0 && valpos < keypos)) { - if (valpos > 0) addParameter(array, valpos + 1, limit - valpos - 1); - return; - } - String name = array.toDecodeString(offset, keypos - offset, charset); - ++keypos; - String value = array.toDecodeString(keypos, (valpos < 0) ? (limit - keypos) : (valpos - keypos), charset); - this.params.addValue(name, value); - if (valpos >= 0) { - addParameter(array, valpos + 1, limit - valpos - 1); - } - } - - private boolean readLine(ByteBuffer buffer, ByteArray bytes) { - byte lasted = '\r'; - bytes.clear(); - for (;;) { - if (!buffer.hasRemaining()) { - if (lasted != '\r') bytes.write(lasted); - return false; - } - byte b = buffer.get(); - if (b == -1 || (lasted == '\r' && b == '\n')) break; - if (lasted != '\r') bytes.write(lasted); - lasted = b; - } - return true; - } - - @Override - protected T setProperty(String name, T value) { - return super.setProperty(name, value); - } - - @Override - @SuppressWarnings("unchecked") - protected T getProperty(String name) { - return super.getProperty(name); - } - - @Override - protected T removeProperty(String name) { - return super.removeProperty(name); - } - - /** - * 获取客户端地址IP - * - * @return 地址 - */ - public SocketAddress getRemoteAddress() { - return this.channel.getRemoteAddress(); - } - - /** - * 获取客户端地址IP, 与getRemoteAddres() 的区别在于:本方法优先取header中指定为RemoteAddress名的值,没有则返回getRemoteAddres()的getHostAddress()。 - * 本方法适用于服务前端有如nginx的代理服务器进行中转,通过getRemoteAddres()是获取不到客户端的真实IP。 - * - * @return 地址 - */ - public String getRemoteAddr() { - if (remoteAddrHeader != null) { - String val = getHeader(remoteAddrHeader); - if (val != null) return val; - } - SocketAddress addr = getRemoteAddress(); - if (addr == null) return ""; - if (addr instanceof InetSocketAddress) return ((InetSocketAddress) addr).getAddress().getHostAddress(); - return String.valueOf(addr); - } - - /** - * 获取请求内容指定的编码字符串 - * - * @param charset 编码 - * @return 内容 - */ - public String getBody(final Charset charset) { - return charset == null ? array.toString() : array.toString(charset); - } - - /** - * 获取请求内容的UTF-8编码字符串 - * - * @return 内容 - */ - public String getBodyUTF8() { - return array.toString(UTF8); - } - - @Override - public String toString() { - parseBody(); - return this.getClass().getSimpleName() + "{method:" + this.method + ", requestURI:" + this.requestURI - + ", contentType:" + this.contentType + ", connection:" + this.connection + ", protocol:" + this.protocol - + ", contentLength:" + this.contentLength + ", cookies:" + this.cookiestr - + ", host:" + this.host + ", params:" + this.params + ", header:" + this.header + "}"; - } - - /** - * 获取文件上传对象 - * - * @return 文件上传对象 - */ - public final MultiContext getMultiContext() { - return new MultiContext(context.getCharset(), this.getContentType(), this.params, - new BufferedInputStream(Channels.newInputStream(this.channel), Math.max(array.size(), 8192)) { - { - array.copyTo(this.buf); - this.count = array.size(); - } - }, null); - } - - /** - * 获取文件上传信息列表 - * - * @return 文件上传对象集合 - * @throws IOException IO异常 - */ - public final Iterable multiParts() throws IOException { - return getMultiContext().parts(); - } - - @Override - protected void recycle() { - this.cookiestr = null; - this.cookies = null; - this.newsessionid = null; - this.method = null; - this.protocol = null; - this.requestURI = null; - this.contentType = null; - this.host = null; - this.connection = null; - this.contentLength = -1; - this.boundary = false; - this.bodyparsed = false; - - this.header.clear(); - this.params.clear(); - this.array.clear(); - super.recycle(); - } - - /** - * 获取sessionid - * - * @param create 无sessionid是否自动创建 - * @return sessionid - */ - public String getSessionid(boolean create) { - String sessionid = getCookie(SESSIONID_NAME, null); - if (create && (sessionid == null || sessionid.isEmpty())) { - sessionid = ((HttpContext) context).createSessionid(); - this.newsessionid = sessionid; - } - return sessionid; - } - - /** - * 更新sessionid - * - * @return 新的sessionid值 - */ - public String changeSessionid() { - this.newsessionid = context.createSessionid(); - return newsessionid; - } - - /** - * 使sessionid失效 - */ - public void invalidateSession() { - this.newsessionid = ""; //为空表示删除sessionid - } - - /** - * 获取所有Cookie对象 - * - * @return cookie对象数组 - */ - public HttpCookie[] getCookies() { - if (this.cookies == null) this.cookies = parseCookies(this.cookiestr); - return this.cookies; - } - - /** - * 获取Cookie值 - * - * @param name cookie名 - * @return cookie值 - */ - public String getCookie(String name) { - return getCookie(name, null); - } - - /** - * 获取Cookie值, 没有返回默认值 - * - * @param name cookie名 - * @param dfvalue 默认cookie值 - * @return cookie值 - */ - public String getCookie(String name, String dfvalue) { - for (HttpCookie cookie : getCookies()) { - if (name.equals(cookie.getName())) return cookie.getValue(); - } - return dfvalue; - } - - private static HttpCookie[] parseCookies(String cookiestr) { - if (cookiestr == null || cookiestr.isEmpty()) return new HttpCookie[0]; - String str = cookiestr.replaceAll("(^;)|(;$)", "").replaceAll(";+", ";"); - if (str.isEmpty()) return new HttpCookie[0]; - String[] strs = str.split(";"); - HttpCookie[] cookies = new HttpCookie[strs.length]; - for (int i = 0; i < strs.length; i++) { - String s = strs[i]; - int pos = s.indexOf('='); - String v = (pos < 0 ? "" : s.substring(pos + 1)); - if (v.indexOf('"') == 0 && v.lastIndexOf('"') == v.length() - 1) v = v.substring(1, v.length() - 1); - cookies[i] = new HttpCookie((pos < 0 ? s : s.substring(0, pos)), v); - } - return cookies; - } - - /** - * 获取协议名 http、https、ws、wss等 - * - * @return protocol - */ - public String getProtocol() { - return protocol; - } - - /** - * 获取请求方法 GET、POST等 - * - * @return method - */ - public String getMethod() { - return method; - } - - /** - * 获取Content-Type的header值 - * - * @return contentType - */ - public String getContentType() { - return contentType; - } - - /** - * 获取请求内容的长度, 为-1表示内容长度不确定 - * - * @return 内容长度 - */ - public long getContentLength() { - return contentLength; - } - - /** - * 获取Connection的Header值 - * - * @return Connection - */ - public String getConnection() { - return connection; - } - - /** - * 获取Host的Header值 - * - * @return Host - */ - public String getHost() { - return host; - } - - /** - * 获取请求的URL - * - * @return 请求的URL - */ - public String getRequestURI() { - return requestURI; - } - - /** - * 截取getRequestURI最后的一个/后面的部分 - * - * @return String - */ - public String getRequstURILastPath() { - if (requestURI == null) return ""; - return requestURI.substring(requestURI.lastIndexOf('/') + 1); - } - - /** - * - * 从prefix之后截取getRequestURI再对"/"进行分隔 - *

- * @param prefix 前缀 - * @return String[] - */ - public String[] getRequstURIPaths(String prefix) { - if (requestURI == null || prefix == null) return new String[0]; - return requestURI.substring(requestURI.indexOf(prefix) + prefix.length() + (prefix.endsWith("/") ? 0 : 1)).split("/"); - } - - /** - * 获取请求URL分段中含prefix段的值 - * 例如请求URL /pipes/record/query/name:hello - * 获取name参数: String name = request.getRequstURIPath("name:", "none"); - * - * @param prefix prefix段前缀 - * @param defvalue 默认值 - * @return prefix截断后的值 - */ - public String getRequstURIPath(String prefix, String defvalue) { - if (requestURI == null || prefix == null) return defvalue; - int pos = requestURI.indexOf(prefix); - if (pos < 0) return defvalue; - String sub = requestURI.substring(pos + prefix.length()); - pos = sub.indexOf('/'); - return pos < 0 ? sub : sub.substring(0, pos); - } - - /** - * 获取请求URL分段中含prefix段的short值 - * 例如请求URL /pipes/record/query/type:10 - * 获取type参数: short type = request.getRequstURIPath("type:", (short)0); - * - * @param prefix prefix段前缀 - * @param defvalue 默认short值 - * @return short值 - */ - public short getRequstURIPath(String prefix, short defvalue) { - String val = getRequstURIPath(prefix, null); - return val == null ? defvalue : Short.parseShort(val); - } - - /** - * 获取请求URL分段中含prefix段的int值 - * 例如请求URL /pipes/record/query/page:2/size:50 - * 获取page参数: int page = request.getRequstURIPath("page:", 1); - * 获取size参数: int size = request.getRequstURIPath("size:", 20); - * - * @param prefix prefix段前缀 - * @param defvalue 默认int值 - * @return int值 - */ - public int getRequstURIPath(String prefix, int defvalue) { - String val = getRequstURIPath(prefix, null); - return val == null ? defvalue : Integer.parseInt(val); - } - - /** - * 获取请求URL分段中含prefix段的long值 - * 例如请求URL /pipes/record/query/time:1453104341363/id:40 - * 获取time参数: long time = request.getRequstURIPath("time:", 0L); - * - * @param prefix prefix段前缀 - * @param defvalue 默认long值 - * @return long值 - */ - public long getRequstURIPath(String prefix, long defvalue) { - String val = getRequstURIPath(prefix, null); - return val == null ? defvalue : Long.parseLong(val); - } - - //------------------------------------------------------------------------------ - /** - * 获取所有的header名 - * - * @return header名数组 - */ - public String[] getHeaderNames() { - return header.getNames(); - } - - /** - * 获取指定的header值 - * - * @param name header名 - * @return header值 - */ - public String getHeader(String name) { - return header.getValue(name); - } - - /** - * 获取指定的header值, 没有返回默认值 - * - * @param name header名 - * @param defaultValue 默认值 - * @return header值 - */ - public String getHeader(String name, String defaultValue) { - return header.getValue(name, defaultValue); - } - - /** - * 获取指定的header的json值 - * - * @param 泛型 - * @param clazz 反序列化的类名 - * @param name header名 - * @return header值 - */ - public T getJsonHeader(Class clazz, String name) { - String v = getHeader(name); - return v == null || v.isEmpty() ? null : jsonConvert.convertFrom(clazz, v); - } - - /** - * 获取指定的header的json值 - * - * @param 泛型 - * @param convert JsonConvert对象 - * @param clazz 反序列化的类名 - * @param name header名 - * @return header值 - */ - public T getJsonHeader(JsonConvert convert, Class clazz, String name) { - String v = getHeader(name); - return v == null || v.isEmpty() ? null : convert.convertFrom(clazz, v); - } - - /** - * 获取指定的header的boolean值, 没有返回默认boolean值 - * - * @param name header名 - * @param defaultValue 默认boolean值 - * @return header值 - */ - public boolean getBooleanHeader(String name, boolean defaultValue) { - return header.getBoolValue(name, defaultValue); - } - - /** - * 获取指定的header的short值, 没有返回默认short值 - * - * @param name header名 - * @param defaultValue 默认short值 - * @return header值 - */ - public short getShortHeader(String name, short defaultValue) { - return header.getShortValue(name, defaultValue); - } - - /** - * 获取指定的header的int值, 没有返回默认int值 - * - * @param name header名 - * @param defaultValue 默认int值 - * @return header值 - */ - public int getIntHeader(String name, int defaultValue) { - return header.getIntValue(name, defaultValue); - } - - /** - * 获取指定的header的long值, 没有返回默认long值 - * - * @param name header名 - * @param defaultValue 默认long值 - * @return header值 - */ - public long getLongHeader(String name, long defaultValue) { - return header.getLongValue(name, defaultValue); - } - - /** - * 获取指定的header的float值, 没有返回默认float值 - * - * @param name header名 - * @param defaultValue 默认float值 - * @return header值 - */ - public float getFloatHeader(String name, float defaultValue) { - return header.getFloatValue(name, defaultValue); - } - - /** - * 获取指定的header的double值, 没有返回默认double值 - * - * @param name header名 - * @param defaultValue 默认double值 - * @return header值 - */ - public double getDoubleHeader(String name, double defaultValue) { - return header.getDoubleValue(name, defaultValue); - } - - //------------------------------------------------------------------------------ - /** - * 获取所有参数名 - * - * @return 参数名数组 - */ - public String[] getParameterNames() { - parseBody(); - return params.getNames(); - } - - /** - * 获取指定的参数值 - * - * @param name 参数名 - * @return 参数值 - */ - public String getParameter(String name) { - parseBody(); - return params.getValue(name); - } - - /** - * 获取指定的参数值, 没有返回默认值 - * - * @param name 参数名 - * @param defaultValue 默认值 - * @return 参数值 - */ - public String getParameter(String name, String defaultValue) { - parseBody(); - return params.getValue(name, defaultValue); - } - - /** - * 获取指定的参数json值 - * - * @param 泛型 - * @param clazz 反序列化的类名 - * @param name 参数名 - * @return 参数值 - */ - public T getJsonParameter(Class clazz, String name) { - String v = getParameter(name); - return v == null || v.isEmpty() ? null : jsonConvert.convertFrom(clazz, v); - } - - /** - * 获取指定的参数json值 - * - * @param 泛型 - * @param convert JsonConvert对象 - * @param clazz 反序列化的类名 - * @param name 参数名 - * @return 参数值 - */ - public T getJsonParameter(JsonConvert convert, Class clazz, String name) { - String v = getParameter(name); - return v == null || v.isEmpty() ? null : convert.convertFrom(clazz, v); - } - - /** - * 获取指定的参数boolean值, 没有返回默认boolean值 - * - * @param name 参数名 - * @param defaultValue 默认boolean值 - * @return 参数值 - */ - public boolean getBooleanParameter(String name, boolean defaultValue) { - parseBody(); - return params.getBoolValue(name, defaultValue); - } - - /** - * 获取指定的参数short值, 没有返回默认short值 - * - * @param name 参数名 - * @param defaultValue 默认short值 - * @return 参数值 - */ - public short getShortParameter(String name, short defaultValue) { - parseBody(); - return params.getShortValue(name, defaultValue); - } - - /** - * 获取指定的参数int值, 没有返回默认int值 - * - * @param name 参数名 - * @param defaultValue 默认int值 - * @return 参数值 - */ - public int getIntParameter(String name, int defaultValue) { - parseBody(); - return params.getIntValue(name, defaultValue); - } - - /** - * 获取指定的参数long值, 没有返回默认long值 - * - * @param name 参数名 - * @param defaultValue 默认long值 - * @return 参数值 - */ - public long getLongParameter(String name, long defaultValue) { - parseBody(); - return params.getLongValue(name, defaultValue); - } - - /** - * 获取指定的参数float值, 没有返回默认float值 - * - * @param name 参数名 - * @param defaultValue 默认float值 - * @return 参数值 - */ - public float getFloatParameter(String name, float defaultValue) { - parseBody(); - return params.getFloatValue(name, defaultValue); - } - - /** - * 获取指定的参数double值, 没有返回默认double值 - * - * @param name 参数名 - * @param defaultValue 默认double值 - * @return 参数值 - */ - public double getDoubleParameter(String name, double defaultValue) { - parseBody(); - return params.getDoubleValue(name, defaultValue); - } - -} diff --git a/src/main/java/org/redkale/net/http/HttpResourceServlet.java b/src/main/java/org/redkale/net/http/HttpResourceServlet.java deleted file mode 100644 index 61ca75178..000000000 --- a/src/main/java/org/redkale/net/http/HttpResourceServlet.java +++ /dev/null @@ -1,262 +0,0 @@ -/* - * 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.http; - -import java.io.*; -import java.nio.*; -import java.nio.file.*; -import static java.nio.file.StandardWatchEventKinds.*; -import java.util.*; -import java.util.AbstractMap.SimpleEntry; -import java.util.concurrent.*; -import java.util.concurrent.atomic.*; -import java.util.function.*; -import java.util.logging.*; -import java.util.regex.*; -import org.redkale.util.*; - -/** - * - *

- * 详情见: http://www.redkale.org - * - * @author zhangjx - */ -public final class HttpResourceServlet extends HttpServlet { - - private static final Logger logger = Logger.getLogger(HttpResourceServlet.class.getSimpleName()); - - protected class WatchThread extends Thread { - - protected final File root; - - protected final WatchService watcher; - - public WatchThread(File root) throws IOException { - this.root = root; - this.setName("Servlet-ResourceWatch-Thread"); - this.setDaemon(true); - this.watcher = this.root.toPath().getFileSystem().newWatchService(); - } - - @Override - public void run() { - try { - final String rootstr = root.getCanonicalPath(); - while (!this.isInterrupted()) { - final WatchKey key = watcher.take(); - final Path parent = keymaps.get(key); - if (parent == null) { - key.cancel(); - continue; - } - key.pollEvents().stream().forEach((event) -> { - try { - Path path = parent.resolve((Path) event.context()); - 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); - } else if (event.kind() == ENTRY_MODIFY) { - FileEntry en = files.get(uri); - if (en != null) { - Thread.sleep(5000L); //等待update file完毕 - en.update(); - } - } - } catch (Exception ex) { - logger.log(Level.FINE, event.context() + " occur erroneous", ex); - } - }); - key.reset(); - } - } catch (Exception e) { - } - } - } - - //缓存总大小, 默认128M - protected long cachelimit = 128 * 1024 * 1024L; - - protected final LongAdder cachedLength = new LongAdder(); - - //最大可缓存的文件大小, 大于该值的文件将不被缓存 - protected long cachelengthmax = 1 * 1024 * 1024; - - protected File root = new File("./root/"); - - protected final ConcurrentHashMap files = new ConcurrentHashMap<>(); - - protected final ConcurrentHashMap keymaps = new ConcurrentHashMap<>(); - - protected SimpleEntry[] locationRewrites; - - protected WatchThread watchThread; - - protected Predicate ranges; - - @Override - public void init(HttpContext context, AnyValue config) { - if (config != null) { - String rootstr = config.getValue("webroot", "root"); - if (rootstr.indexOf(':') < 0 && rootstr.indexOf('/') != 0 && System.getProperty("APP_HOME") != null) { - rootstr = new File(System.getProperty("APP_HOME"), rootstr).getPath(); - } - String rangesValue = config.getValue("ranges"); - this.ranges = rangesValue != null ? Pattern.compile(rangesValue).asPredicate() : null; - try { - this.root = new File(rootstr).getCanonicalFile(); - } catch (IOException ioe) { - this.root = new File(rootstr); - } - AnyValue cacheconf = config.getAnyValue("caches"); - if (cacheconf != null) { - this.cachelimit = parseLenth(cacheconf.getValue("limit"), 0 * 1024 * 1024L); - this.cachelengthmax = parseLenth(cacheconf.getValue("lengthmax"), 1 * 1024 * 1024L); - } - List> locations = new ArrayList<>(); - for (AnyValue av : config.getAnyValues("rewrite")) { - if ("location".equals(av.getValue("type"))) { - String m = av.getValue("match"); - String f = av.getValue("forward"); - if (m != null && f != null) { - locations.add(new SimpleEntry<>(Pattern.compile(m), f)); - } - } - } - this.locationRewrites = locations.isEmpty() ? null : locations.toArray(new SimpleEntry[locations.size()]); - } - if (this.cachelimit < 1) return; //不缓存不需要开启WatchThread监听 - if (this.root != null) { - try { - this.watchThread = new WatchThread(this.root); - this.watchThread.start(); - } catch (IOException ex) { - logger.log(Level.WARNING, HttpResourceServlet.class.getSimpleName() + " start watch-thread error", ex); - } - } - } - - @Override - public void destroy(HttpContext context, AnyValue config) { - if (this.watchThread != null) { - try { - this.watchThread.watcher.close(); - } catch (IOException ex) { - logger.log(Level.WARNING, HttpResourceServlet.class.getSimpleName() + " close watch-thread error", ex); - } - if (this.watchThread.isAlive()) this.watchThread.interrupt(); - } - } - - private static long parseLenth(String value, long defValue) { - if (value == null) return defValue; - value = value.toUpperCase().replace("B", ""); - if (value.endsWith("G")) return Long.decode(value.replace("G", "")) * 1024 * 1024 * 1024; - if (value.endsWith("M")) return Long.decode(value.replace("M", "")) * 1024 * 1024; - if (value.endsWith("K")) return Long.decode(value.replace("K", "")) * 1024; - return Long.decode(value); - } - - @Override - public void execute(HttpRequest request, HttpResponse response) throws IOException { - String uri = request.getRequestURI(); - if (locationRewrites != null) { - for (SimpleEntry entry : locationRewrites) { - Matcher matcher = entry.getKey().matcher(uri); - if (matcher.find()) { - StringBuffer sb = new StringBuffer(uri.length()); - matcher.appendReplacement(sb, entry.getValue()); - matcher.appendTail(sb); - uri = sb.toString(); - break; - } - } - } - if (uri.length() == 0 || uri.equals("/")) uri = "/index.html"; - //System.out.println(request); - FileEntry entry; - if (watchThread == null) { - entry = createFileEntry(uri); - } else { //有缓存 - entry = files.computeIfAbsent(uri, x -> createFileEntry(x)); - } - if (entry == null) { - response.finish404(); - } else { - response.finishFile(entry.file, entry.content); - } - } - - private FileEntry createFileEntry(String uri) { - File file = new File(root, uri); - if (file.isDirectory()) file = new File(file, "index.html"); - if (!file.isFile() || !file.canRead()) return null; - FileEntry en = new FileEntry(this, file); - if (watchThread == null) return en; - try { - Path p = file.getParentFile().toPath(); - keymaps.put(p.register(watchThread.watcher, ENTRY_MODIFY, ENTRY_DELETE), p); - } catch (IOException e) { - logger.log(Level.INFO, HttpResourceServlet.class.getSimpleName() + " watch FileEntry(" + uri + ") erroneous", e); - } - return en; - } - - private static final class FileEntry { - - final File file; - - private final HttpResourceServlet servlet; - - ByteBuffer content; - - public FileEntry(final HttpResourceServlet servlet, File file) { - this.servlet = servlet; - this.file = file; - update(); - } - - public void update() { - if (this.content != null) { - this.servlet.cachedLength.add(0L - this.content.remaining()); - this.content = null; - } - long length = this.file.length(); - if (length > this.servlet.cachelengthmax) return; - if (this.servlet.cachedLength.longValue() + length > this.servlet.cachelimit) return; //超过缓存总容量 - try { - FileInputStream in = new FileInputStream(file); - ByteArrayOutputStream out = new ByteArrayOutputStream((int) file.length()); - byte[] bytes = new byte[10240]; - int pos; - while ((pos = in.read(bytes)) != -1) { - out.write(bytes, 0, pos); - } - in.close(); - byte[] bs = out.toByteArray(); - ByteBuffer buf = ByteBuffer.allocateDirect(bs.length); - buf.put(bs); - buf.flip(); - this.content = buf.asReadOnlyBuffer(); - this.servlet.cachedLength.add(this.content.remaining()); - } catch (Exception e) { - logger.log(Level.INFO, HttpResourceServlet.class.getSimpleName() + " update FileEntry(" + file + ") erroneous", e); - } - } - - @Override - protected void finalize() throws Throwable { - if (this.content != null) this.servlet.cachedLength.add(0L - this.content.remaining()); - super.finalize(); - } - - public long getCachedLength() { - return this.content == null ? 0L : this.content.remaining(); - } - - } -} diff --git a/src/main/java/org/redkale/net/http/HttpResponse.java b/src/main/java/org/redkale/net/http/HttpResponse.java deleted file mode 100644 index 8d255897f..000000000 --- a/src/main/java/org/redkale/net/http/HttpResponse.java +++ /dev/null @@ -1,739 +0,0 @@ -/* - * 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.http; - -import java.io.*; -import java.lang.reflect.Type; -import java.net.HttpCookie; -import java.nio.ByteBuffer; -import java.nio.channels.*; -import java.nio.file.*; -import java.text.*; -import java.util.*; -import java.util.concurrent.atomic.AtomicLong; -import org.redkale.convert.json.JsonConvert; -import org.redkale.net.*; -import org.redkale.util.AnyValue.DefaultAnyValue; -import org.redkale.util.AnyValue.Entry; -import org.redkale.util.*; - -/** - * Http响应包 与javax.servlet.http.HttpServletResponse 基本类似。 - * 同时提供发送json的系列接口: public void finishJson(Type type, Object obj) - * RedKale提倡http+json的接口风格, 所以主要输出的数据格式为json, 同时提供异步接口。 - * - *

- * 详情见: http://www.redkale.org - * - * @author zhangjx - */ -public class HttpResponse extends Response { - - /** - * HttpResponse.finish 方法内调用 - * 主要给@HttpCacheable使用 - * - */ - protected static interface BufferHandler { - - public ByteBuffer[] execute(final HttpResponse response, final ByteBuffer[] buffers); - } - - private static final ByteBuffer buffer304 = ByteBuffer.wrap("HTTP/1.1 304 Not Modified\r\n\r\n".getBytes()).asReadOnlyBuffer(); - - private static final ByteBuffer buffer404 = ByteBuffer.wrap("HTTP/1.1 404 Not Found\r\nContent-Length:0\r\n\r\n".getBytes()).asReadOnlyBuffer(); - - protected static final byte[] LINE = new byte[]{'\r', '\n'}; - - private static final Set 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 httpCodes = new HashMap<>(); - - static { - options.add(StandardOpenOption.READ); - GMT_DATE_FORMAT.setTimeZone(TimeZone.getTimeZone("GMT")); - - httpCodes.put(100, "Continue"); - httpCodes.put(101, "Switching Protocols"); - - httpCodes.put(200, "OK"); - httpCodes.put(201, "Created"); - httpCodes.put(202, "Accepted"); - httpCodes.put(203, "Non-Authoritative Information"); - httpCodes.put(204, "No Content"); - httpCodes.put(205, "Reset Content"); - httpCodes.put(206, "Partial Content"); - - httpCodes.put(300, "Multiple Choices"); - httpCodes.put(301, "Moved Permanently"); - httpCodes.put(302, "Found"); - httpCodes.put(303, "See Other"); - httpCodes.put(304, "Not Modified"); - httpCodes.put(305, "Use Proxy"); - httpCodes.put(307, "Temporary Redirect"); - - httpCodes.put(400, "Bad Request"); - httpCodes.put(401, "Unauthorized"); - httpCodes.put(402, "Payment Required"); - httpCodes.put(403, "Forbidden"); - httpCodes.put(404, "Not Found"); - httpCodes.put(405, "Method Not Allowed"); - httpCodes.put(406, "Not Acceptable"); - httpCodes.put(407, "Proxy Authentication Required"); - httpCodes.put(408, "Request Timeout"); - httpCodes.put(409, "Conflict"); - httpCodes.put(410, "Gone"); - httpCodes.put(411, "Length Required"); - httpCodes.put(412, "Precondition Failed"); - httpCodes.put(413, "Request Entity Too Large"); - httpCodes.put(414, "Request URI Too Long"); - httpCodes.put(415, "Unsupported Media Type"); - httpCodes.put(416, "Requested Range Not Satisfiable"); - httpCodes.put(417, "Expectation Failed"); - - httpCodes.put(500, "Internal Server Error"); - httpCodes.put(501, "Not Implemented"); - httpCodes.put(502, "Bad Gateway"); - httpCodes.put(503, "Service Unavailable"); - httpCodes.put(504, "Gateway Timeout"); - httpCodes.put(505, "HTTP Version Not Supported"); - } - - private int status = 200; - - private String contentType = "text/plain; charset=utf-8"; - - private long contentLength = -1; - - private HttpCookie[] cookies; - - private boolean headsended = false; - - private BufferHandler bufferHandler; - //------------------------------------------------ - - private final DefaultAnyValue header = new DefaultAnyValue(); - - private final String[][] defaultAddHeaders; - - private final String[][] defaultSetHeaders; - - private final HttpCookie defcookie; - - public static ObjectPool createPool(AtomicLong creatCounter, AtomicLong cycleCounter, int max, Creator creator) { - return new ObjectPool<>(creatCounter, cycleCounter, max, creator, (x) -> ((HttpResponse) x).prepare(), (x) -> ((HttpResponse) x).recycle()); - } - - public HttpResponse(HttpContext context, HttpRequest request, String[][] defaultAddHeaders, String[][] defaultSetHeaders, HttpCookie defcookie) { - super(context, request); - this.defaultAddHeaders = defaultAddHeaders; - this.defaultSetHeaders = defaultSetHeaders; - this.defcookie = defcookie; - } - - @Override - protected AsyncConnection removeChannel() { - return super.removeChannel(); - } - - @Override - protected boolean recycle() { - this.status = 200; - this.contentLength = -1; - this.contentType = null; - this.cookies = null; - this.headsended = false; - this.header.clear(); - this.bufferHandler = null; - return super.recycle(); - } - - @Override - protected void init(AsyncConnection channel) { - super.init(channel); - } - - /** - * 获取状态码对应的状态描述 - * - * @param status 状态码 - * @return 状态描述 - */ - protected String getHttpCode(int status) { - return httpCodes.get(status); - } - - protected HttpRequest getRequest() { - return request; - } - - protected String getHttpCode(int status, String defValue) { - String v = httpCodes.get(status); - return v == null ? defValue : v; - } - - /** - * 增加Cookie值 - * - * @param cookies cookie - */ - public void addCookie(HttpCookie... cookies) { - if (this.cookies == null) { - this.cookies = cookies; - } else { - HttpCookie[] news = new HttpCookie[this.cookies.length + cookies.length]; - System.arraycopy(this.cookies, 0, news, 0, this.cookies.length); - System.arraycopy(cookies, 0, news, this.cookies.length, cookies.length); - this.cookies = news; - } - } - - /** - * 将对象以JSON格式输出 - * - * @param obj 输出对象 - */ - public void finishJson(final Object obj) { - this.contentType = "text/plain; charset=utf-8"; - finish(request.getJsonConvert().convertTo(context.getBufferSupplier(), obj)); - } - - /** - * 将对象以JSON格式输出 - * - * @param convert 指定的JsonConvert - * @param obj 输出对象 - */ - public void finishJson(final JsonConvert convert, final Object obj) { - this.contentType = "text/plain; charset=utf-8"; - finish(convert.convertTo(context.getBufferSupplier(), obj)); - } - - /** - * 将对象以JSON格式输出 - * - * @param type 指定的类型 - * @param obj 输出对象 - */ - public void finishJson(final Type type, final Object obj) { - this.contentType = "text/plain; charset=utf-8"; - finish(request.getJsonConvert().convertTo(context.getBufferSupplier(), type, obj)); - } - - /** - * 将对象以JSON格式输出 - * - * @param convert 指定的JsonConvert - * @param type 指定的类型 - * @param obj 输出对象 - */ - public void finishJson(final JsonConvert convert, final Type type, final Object obj) { - this.contentType = "text/plain; charset=utf-8"; - finish(convert.convertTo(context.getBufferSupplier(), type, obj)); - } - - /** - * 将对象以JSON格式输出 - * - * @param objs 输出对象 - */ - public void finishJson(final Object... objs) { - this.contentType = "text/plain; charset=utf-8"; - finish(request.getJsonConvert().convertTo(context.getBufferSupplier(), objs)); - } - - /** - * 将指定字符串以响应结果输出 - * - * @param obj 输出内容 - */ - public void finish(String obj) { - if (obj == null || obj.isEmpty()) { - final ByteBuffer headbuf = createHeader(); - headbuf.flip(); - super.finish(headbuf); - return; - } - if (context.getCharset() == null) { - if (bufferHandler != null) { - bufferHandler.execute(this, new ByteBuffer[]{ByteBuffer.wrap(Utility.encodeUTF8(obj))}); - } - final char[] chars = Utility.charArray(obj); - this.contentLength = Utility.encodeUTF8Length(chars); - final ByteBuffer headbuf = createHeader(); - ByteBuffer buf2 = Utility.encodeUTF8(headbuf, (int) this.contentLength, chars); - headbuf.flip(); - if (buf2 == null) { - super.finish(headbuf); - } else { - super.finish(headbuf, buf2); - } - } else { - ByteBuffer buffer = context.getCharset().encode(obj); - if (bufferHandler != null) { - ByteBuffer[] bufs = bufferHandler.execute(this, new ByteBuffer[]{buffer}); - if (bufs != null) buffer = bufs[0]; - } - this.contentLength = buffer.remaining(); - final ByteBuffer headbuf = createHeader(); - headbuf.flip(); - super.finish(headbuf, buffer); - } - } - - /** - * 以指定响应码附带内容输出 - * - * @param status 响应码 - * @param message 输出内容 - */ - public void finish(int status, String message) { - this.status = status; - if (status != 200) super.refuseAlive(); - finish(message); - } - - /** - * 以304状态码输出 - * - */ - public void finish304() { - super.finish(buffer304.duplicate()); - } - - /** - * 以404状态码输出 - * - */ - public void finish404() { - super.finish(buffer404.duplicate()); - } - - /** - * 将指定ByteBuffer按响应结果输出 - * - * @param buffer 输出内容 - */ - @Override - public void finish(ByteBuffer buffer) { - finish(false, buffer); - } - - /** - * 将指定ByteBuffer按响应结果输出 - * - * @param kill 输出后是否强制关闭连接 - * @param buffer 输出内容 - */ - @Override - public void finish(boolean kill, ByteBuffer buffer) { - if (!this.headsended) { - this.contentLength = buffer == null ? 0 : buffer.remaining(); - ByteBuffer headbuf = createHeader(); - headbuf.flip(); - if (buffer == null) { - super.finish(kill, headbuf); - } else { - super.finish(kill, new ByteBuffer[]{headbuf, buffer}); - } - } else { - super.finish(kill, buffer); - } - } - - /** - * 将指定ByteBuffer数组按响应结果输出 - * - * @param buffers 输出内容 - */ - @Override - public void finish(ByteBuffer... buffers) { - finish(false, buffers); - } - - /** - * 将指定ByteBuffer数组按响应结果输出 - * - * @param kill 输出后是否强制关闭连接 - * @param buffers 输出内容 - */ - @Override - public void finish(boolean kill, ByteBuffer... buffers) { - if (bufferHandler != null) { - ByteBuffer[] bufs = bufferHandler.execute(this, buffers); - if (bufs != null) buffers = bufs; - } - if (kill) refuseAlive(); - if (!this.headsended) { - long len = 0; - for (ByteBuffer buf : buffers) { - len += buf.remaining(); - } - this.contentLength = len; - ByteBuffer headbuf = createHeader(); - headbuf.flip(); - if (buffers == null) { - super.finish(kill, headbuf); - } else { - ByteBuffer[] newbuffers = new ByteBuffer[buffers.length + 1]; - newbuffers[0] = headbuf; - System.arraycopy(buffers, 0, newbuffers, 1, buffers.length); - super.finish(kill, newbuffers); - } - } else { - super.finish(kill, buffers); - } - } - - /** - * 异步输出指定内容 - * - * @param 泛型 - * @param buffer 输出内容 - * @param attachment 异步回调参数 - * @param handler 异步回调函数 - */ - public void sendBody(ByteBuffer buffer, A attachment, CompletionHandler handler) { - if (!this.headsended) { - if (this.contentLength < 0) this.contentLength = buffer == null ? 0 : buffer.remaining(); - ByteBuffer headbuf = createHeader(); - headbuf.flip(); - if (buffer == null) { - super.send(headbuf, attachment, handler); - } else { - super.send(new ByteBuffer[]{headbuf, buffer}, attachment, handler); - } - } else { - super.send(buffer, attachment, handler); - } - } - - /** - * 将指定文件按响应结果输出 - * - * @param file 输出文件 - * @throws IOException IO异常 - */ - public void finish(File file) throws IOException { - finishFile(file, null); - } - - /** - * 将指定文件句柄或文件内容按响应结果输出,若fileBody不为null则只输出fileBody内容 - * - * @param file 输出文件 - * @param fileBody 文件内容, 没有则输出file - * @throws IOException IO异常 - */ - protected void finishFile(final File file, ByteBuffer fileBody) throws IOException { - if (file == null || !file.isFile() || !file.canRead()) { - finish404(); - return; - } - if (fileBody != null) fileBody = fileBody.duplicate().asReadOnlyBuffer(); - final long length = file.length(); - final String match = request.getHeader("If-None-Match"); - if (match != null && (file.lastModified() + "-" + length).equals(match)) { - finish304(); - return; - } - this.contentLength = fileBody == null ? file.length() : fileBody.remaining(); - this.contentType = MimeType.getByFilename(file.getName()); - if (this.contentType == null) this.contentType = "application/octet-stream"; - String range = request.getHeader("Range"); - if (range != null && (!range.startsWith("bytes=") || range.indexOf(',') >= 0)) range = null; - long start = -1; - long len = -1; - if (range != null) { - range = range.substring("bytes=".length()); - int pos = range.indexOf('-'); - start = pos == 0 ? 0 : Integer.parseInt(range.substring(0, pos)); - long end = (pos == range.length() - 1) ? -1 : Long.parseLong(range.substring(pos + 1)); - long clen = end > 0 ? (end - start + 1) : (file.length() - start); - this.status = 206; - addHeader("Accept-Ranges", "bytes"); - addHeader("Content-Range", "bytes " + start + "-" + (end > 0 ? end : length - 1) + "/" + length); - this.contentLength = clen; - len = end > 0 ? clen : end; - } - this.addHeader("ETag", file.lastModified() + "-" + length); - ByteBuffer hbuffer = createHeader(); - hbuffer.flip(); - if (fileBody == null) { - finishFile(hbuffer, file, start, len); - } else { - if (start >= 0) { - fileBody.position((int) start); - if (len > 0) fileBody.limit((int) (fileBody.position() + len)); - } - super.finish(hbuffer, fileBody); - } - } - - private void finishFile(ByteBuffer hbuffer, File file, long offset, long length) throws IOException { - this.channel.write(hbuffer, hbuffer, new TransferFileHandler(AsynchronousFileChannel.open(file.toPath(), options, ((HttpContext) context).getExecutor()), offset, length)); - } - - private ByteBuffer createHeader() { - this.headsended = true; - ByteBuffer buffer = this.context.pollBuffer(); - buffer.put(("HTTP/1.1 " + this.status + " " + (this.status == 200 ? "OK" : httpCodes.get(this.status)) + "\r\n").getBytes()); - - buffer.put(("Content-Type: " + (this.contentType == null ? "text/plain; charset=utf-8" : this.contentType) + "\r\n").getBytes()); - - if (this.contentLength > 0) { - buffer.put(("Content-Length: " + this.contentLength + "\r\n").getBytes()); - } - if (!this.request.isKeepAlive()) { - buffer.put("Connection: close\r\n".getBytes()); - } - if (this.defaultAddHeaders != null) { - for (String[] headers : this.defaultAddHeaders) { - if (headers.length > 3) { - String v = request.getParameter(headers[2]); - if (v != null) this.header.addValue(headers[0], v); - } else if (headers.length > 2) { - String v = request.getHeader(headers[2]); - if (v != null) this.header.addValue(headers[0], v); - } else { - this.header.addValue(headers[0], headers[1]); - } - } - } - if (this.defaultSetHeaders != null) { - for (String[] headers : this.defaultSetHeaders) { - if (headers.length > 3) { - String v = request.getParameter(headers[2]); - if (v != null) this.header.setValue(headers[0], v); - } else if (headers.length > 2) { - String v = request.getHeader(headers[2]); - if (v != null) this.header.setValue(headers[0], v); - } else { - this.header.setValue(headers[0], headers[1]); - } - } - } - for (Entry en : this.header.getStringEntrys()) { - buffer.put((en.name + ": " + en.getValue() + "\r\n").getBytes()); - } - if (request.newsessionid != null) { - String domain = defcookie == null ? null : defcookie.getDomain(); - if (domain == null) { - domain = ""; - } else { - domain = "Domain=" + domain + "; "; - } - String path = defcookie == null ? null : defcookie.getPath(); - if (path == null || path.isEmpty()) path = "/"; - if (request.newsessionid.isEmpty()) { - buffer.put(("Set-Cookie: " + HttpRequest.SESSIONID_NAME + "=; " + domain + "Path=" + path + "; Max-Age=0; HttpOnly\r\n").getBytes()); - } else { - buffer.put(("Set-Cookie: " + HttpRequest.SESSIONID_NAME + "=" + request.newsessionid + "; " + domain + "Path=" + path + "; HttpOnly\r\n").getBytes()); - } - } - if (this.cookies != null) { - for (HttpCookie cookie : this.cookies) { - if (cookie == null) continue; - if (defcookie != null) { - if (defcookie.getDomain() != null && cookie.getDomain() == null) cookie.setDomain(defcookie.getDomain()); - if (defcookie.getPath() != null && cookie.getPath() == null) cookie.setPath(defcookie.getPath()); - } - buffer.put(("Set-Cookie: " + genString(cookie) + "\r\n").getBytes()); - } - } - buffer.put(LINE); - return buffer; - } - - private CharSequence genString(HttpCookie cookie) { - StringBuilder sb = new StringBuilder(); - sb.append(cookie.getName()).append("=\"").append(cookie.getValue()).append('"').append("; Version=1"); - if (cookie.getDomain() != null) sb.append("; Domain=").append(cookie.getDomain()); - if (cookie.getPath() != null) sb.append("; Path=").append(cookie.getPath()); - 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))); - } - } - if (cookie.getSecure()) sb.append("; Secure"); - if (cookie.isHttpOnly()) sb.append("; HttpOnly"); - return sb; - } - - /** - * 跳过header的输出 - * 通常应用场景是,调用者的输出内容里已经包含了HTTP的响应头信息,因此需要调用此方法避免重复输出HTTP响应头信息。 - * - */ - public void skipHeader() { - this.headsended = true; - } - - protected DefaultAnyValue duplicateHeader() { - return this.header.duplicate(); - } - - /** - * 设置Header值 - * - * @param name header名 - * @param value header值 - */ - public void setHeader(String name, Object value) { - this.header.setValue(name, String.valueOf(value)); - } - - /** - * 添加Header值 - * - * @param name header名 - * @param value header值 - */ - public void addHeader(String name, Object value) { - this.header.addValue(name, String.valueOf(value)); - } - - /** - * 设置状态码 - * - * @param status 状态码 - */ - public void setStatus(int status) { - this.status = status; - } - - /** - * 获取状态码 - * - * @return 状态码 - */ - public int getStatus() { - return this.status; - } - - /** - * 获取 ContentType - * - * @return ContentType - */ - public String getContentType() { - return contentType; - } - - /** - * 设置 ContentType - * - * @param contentType ContentType - */ - public void setContentType(String contentType) { - this.contentType = contentType; - } - - /** - * 获取内容长度 - * - * @return 内容长度 - */ - public long getContentLength() { - return contentLength; - } - - /** - * 设置内容长度 - * - * @param contentLength 内容长度 - */ - public void setContentLength(long contentLength) { - this.contentLength = contentLength; - } - - /** - * 获取输出时的拦截器 - * - * @return 拦截器 - */ - protected BufferHandler getBufferHandler() { - return bufferHandler; - } - - /** - * 设置输出时的拦截器 - * - * @param bufferHandler 拦截器 - */ - protected void setBufferHandler(BufferHandler bufferHandler) { - this.bufferHandler = bufferHandler; - } - - protected final class TransferFileHandler implements CompletionHandler { - - private final AsynchronousFileChannel filechannel; - - private final long max; //需要读取的字节数, -1表示读到文件结尾 - - private long count;//读取文件的字节数 - - private long position = 0; - - private boolean next = false; - - private boolean read = true; - - public TransferFileHandler(AsynchronousFileChannel channel) { - this.filechannel = channel; - this.max = -1; - } - - public TransferFileHandler(AsynchronousFileChannel channel, long offset, long len) { - this.filechannel = channel; - this.position = offset <= 0 ? 0 : offset; - this.max = len; - } - - @Override - public void completed(Integer result, ByteBuffer attachment) { - if (result < 0 || (max > 0 && count >= max)) { - failed(null, attachment); - return; - } - if (read) { - read = false; - if (next) { - position += result; - } else { - next = true; - } - attachment.clear(); - filechannel.read(attachment, position, attachment, this); - } else { - read = true; - if (max > 0) { - count += result; - if (count > max) { - attachment.limit((int) (attachment.position() + max - count)); - } - } - attachment.flip(); - channel.write(attachment, attachment, this); - } - } - - @Override - public void failed(Throwable exc, ByteBuffer attachment) { - getContext().offerBuffer(attachment); - finish(true); - try { - filechannel.close(); - } catch (IOException e) { - } - } - - } -} diff --git a/src/main/java/org/redkale/net/http/HttpServer.java b/src/main/java/org/redkale/net/http/HttpServer.java deleted file mode 100644 index f1d817d66..000000000 --- a/src/main/java/org/redkale/net/http/HttpServer.java +++ /dev/null @@ -1,131 +0,0 @@ -/* - * 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.http; - -import java.net.HttpCookie; -import java.nio.ByteBuffer; -import java.util.*; -import java.util.concurrent.atomic.AtomicLong; -import org.redkale.net.*; -import org.redkale.util.*; -import org.redkale.watch.WatchFactory; - -/** - * - *

- * 详情见: http://www.redkale.org - * - * @author zhangjx - */ -public final class HttpServer extends Server { - - public HttpServer() { - this(System.currentTimeMillis(), null); - } - - public HttpServer(long serverStartTime, final WatchFactory watch) { - super(serverStartTime, "TCP", new HttpPrepareServlet(), watch); - } - - @Override - public void init(AnyValue config) throws Exception { - super.init(config); - AnyValue conf = config == null ? null : config.getAnyValue("servlets"); - } - - public void addHttpServlet(HttpServlet servlet, final String prefix, AnyValue conf, String... mappings) { - this.prepare.addServlet(servlet, prefix, conf, mappings); - } - - @Override - @SuppressWarnings("unchecked") - protected HttpContext createContext() { - final int port = this.address.getPort(); - AtomicLong createBufferCounter = watch == null ? new AtomicLong() : watch.createWatchNumber("HTTP_" + port + ".Buffer.creatCounter"); - AtomicLong cycleBufferCounter = watch == null ? new AtomicLong() : watch.createWatchNumber("HTTP_" + port + ".Buffer.cycleCounter"); - final int rcapacity = Math.max(this.bufferCapacity, 16 * 1024 + 8); //兼容 HTTP 2.0 - ObjectPool bufferPool = new ObjectPool<>(createBufferCounter, cycleBufferCounter, this.bufferPoolSize, - (Object... params) -> ByteBuffer.allocateDirect(rcapacity), null, (e) -> { - if (e == null || e.isReadOnly() || e.capacity() != rcapacity) return false; - e.clear(); - return true; - }); - final List defaultAddHeaders = new ArrayList<>(); - final List defaultSetHeaders = new ArrayList<>(); - HttpCookie defaultCookie = null; - String remoteAddrHeader = null; - if (config != null) { - AnyValue reqs = config == null ? null : config.getAnyValue("request"); - if (reqs != null) { - AnyValue raddr = reqs.getAnyValue("remoteaddr"); - remoteAddrHeader = raddr == null ? null : raddr.getValue("value"); - if (remoteAddrHeader != null) { - if (remoteAddrHeader.startsWith("request.headers.")) { - remoteAddrHeader = remoteAddrHeader.substring("request.headers.".length()); - } else { - remoteAddrHeader = null; - } - } - } - - AnyValue resps = config == null ? null : config.getAnyValue("response"); - if (resps != null) { - AnyValue[] addHeaders = resps.getAnyValues("addheader"); - if (addHeaders.length > 0) { - for (int i = 0; i < addHeaders.length; i++) { - String val = addHeaders[i].getValue("value"); - if (val == null) continue; - if (val.startsWith("request.parameters.")) { - defaultAddHeaders.add(new String[]{addHeaders[i].getValue("name"), val, val.substring("request.parameters.".length()), null}); - } else if (val.startsWith("request.headers.")) { - defaultAddHeaders.add(new String[]{addHeaders[i].getValue("name"), val, val.substring("request.headers.".length())}); - } else if (val.startsWith("system.property.")) { - String v = System.getProperty(val.substring("system.property.".length())); - if (v != null) defaultAddHeaders.add(new String[]{addHeaders[i].getValue("name"), v}); - } else { - defaultAddHeaders.add(new String[]{addHeaders[i].getValue("name"), val}); - } - } - } - AnyValue[] setHeaders = resps.getAnyValues("setheader"); - if (setHeaders.length > 0) { - for (int i = 0; i < setHeaders.length; i++) { - String val = setHeaders[i].getValue("value"); - if (val != null && val.startsWith("request.parameters.")) { - defaultSetHeaders.add(new String[]{setHeaders[i].getValue("name"), val, val.substring("request.parameters.".length()), null}); - } else if (val != null && val.startsWith("request.headers.")) { - defaultSetHeaders.add(new String[]{setHeaders[i].getValue("name"), val, val.substring("request.headers.".length())}); - } else { - defaultSetHeaders.add(new String[]{setHeaders[i].getValue("name"), val}); - } - } - } - AnyValue defcookieValue = resps.getAnyValue("defcookie"); - if (defcookieValue != null) { - String domain = defcookieValue.getValue("domain"); - String path = defcookieValue.getValue("path"); - if (domain != null || path != null) { - defaultCookie = new HttpCookie("DEFAULTCOOKIE", ""); - defaultCookie.setDomain(domain); - defaultCookie.setPath(path); - } - } - } - } - final String[][] addHeaders = defaultAddHeaders.isEmpty() ? null : defaultAddHeaders.toArray(new String[defaultAddHeaders.size()][]); - final String[][] setHeaders = defaultSetHeaders.isEmpty() ? null : defaultSetHeaders.toArray(new String[defaultSetHeaders.size()][]); - final HttpCookie defCookie = defaultCookie; - final String addrHeader = remoteAddrHeader; - AtomicLong createResponseCounter = watch == null ? new AtomicLong() : watch.createWatchNumber("HTTP_" + port + ".Response.creatCounter"); - AtomicLong cycleResponseCounter = watch == null ? new AtomicLong() : watch.createWatchNumber("HTTP_" + port + ".Response.cycleCounter"); - ObjectPool responsePool = HttpResponse.createPool(createResponseCounter, cycleResponseCounter, this.responsePoolSize, null); - HttpContext httpcontext = new HttpContext(this.serverStartTime, this.logger, executor, rcapacity, bufferPool, responsePool, - this.maxbody, this.charset, this.address, this.prepare, this.watch, this.readTimeoutSecond, this.writeTimeoutSecond); - responsePool.setCreator((Object... params) -> new HttpResponse(httpcontext, new HttpRequest(httpcontext, addrHeader), addHeaders, setHeaders, defCookie)); - return httpcontext; - } - -} diff --git a/src/main/java/org/redkale/net/http/HttpServlet.java b/src/main/java/org/redkale/net/http/HttpServlet.java deleted file mode 100644 index e8fe6bf94..000000000 --- a/src/main/java/org/redkale/net/http/HttpServlet.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * 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.http; - -import org.redkale.net.Servlet; - -/** - * - *

- * 详情见: http://www.redkale.org - * - * @author zhangjx - */ -public abstract class HttpServlet extends Servlet { - - String _prefix = ""; //当前HttpServlet的path前缀 - - @Override - public final boolean equals(Object obj) { - return obj != null && obj.getClass() == this.getClass(); - } - - @Override - public final int hashCode() { - return this.getClass().hashCode(); - } - -} diff --git a/src/main/java/org/redkale/net/http/MimeType.java b/src/main/java/org/redkale/net/http/MimeType.java deleted file mode 100644 index 13d1fbe0a..000000000 --- a/src/main/java/org/redkale/net/http/MimeType.java +++ /dev/null @@ -1,199 +0,0 @@ -/* - * 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.http; - -import java.util.*; - -/** - * - *

详情见: http://www.redkale.org - * @author zhangjx - */ -public class MimeType { - - private final static Map contentTypes = new HashMap<>(); - - static { - contentTypes.put("abs", "audio/x-mpeg"); - contentTypes.put("ai", "application/postscript"); - contentTypes.put("aif", "audio/x-aiff"); - contentTypes.put("aifc", "audio/x-aiff"); - contentTypes.put("aiff", "audio/x-aiff"); - contentTypes.put("aim", "application/x-aim"); - contentTypes.put("art", "image/x-jg"); - contentTypes.put("asf", "video/x-ms-asf"); - contentTypes.put("asx", "video/x-ms-asf"); - contentTypes.put("au", "audio/basic"); - contentTypes.put("avi", "video/x-msvideo"); - contentTypes.put("avx", "video/x-rad-screenplay"); - contentTypes.put("bcpio", "application/x-bcpio"); - contentTypes.put("bin", "application/octet-stream"); - contentTypes.put("bmp", "image/bmp"); - contentTypes.put("body", "text/html"); - contentTypes.put("cdf", "application/x-cdf"); - contentTypes.put("cer", "application/x-x509-ca-cert"); - contentTypes.put("class", "application/java"); - contentTypes.put("cpio", "application/x-cpio"); - contentTypes.put("csh", "application/x-csh"); - contentTypes.put("css", "text/css"); - contentTypes.put("dib", "image/bmp"); - contentTypes.put("doc", "application/msword"); - contentTypes.put("dtd", "application/xml-dtd"); - contentTypes.put("dv", "video/x-dv"); - contentTypes.put("dvi", "application/x-dvi"); - contentTypes.put("eps", "application/postscript"); - contentTypes.put("etx", "text/x-setext"); - contentTypes.put("exe", "application/octet-stream"); - contentTypes.put("gif", "image/gif"); - contentTypes.put("gk", "application/octet-stream"); - contentTypes.put("gtar", "application/x-gtar"); - contentTypes.put("gz", "application/x-gzip"); - contentTypes.put("hdf", "application/x-hdf"); - contentTypes.put("hqx", "application/mac-binhex40"); - contentTypes.put("htc", "text/x-component"); - contentTypes.put("htm", "text/html"); - contentTypes.put("html", "text/html"); - contentTypes.put("hqx", "application/mac-binhex40"); - contentTypes.put("ief", "image/ief"); - contentTypes.put("jad", "text/vnd.sun.j2me.app-descriptor"); - contentTypes.put("jar", "application/java-archive"); - contentTypes.put("java", "text/plain"); - contentTypes.put("jnlp", "application/x-java-jnlp-file"); - contentTypes.put("jpe", "image/jpeg"); - contentTypes.put("jpeg", "image/jpeg"); - contentTypes.put("jpg", "image/jpeg"); - contentTypes.put("js", "text/javascript"); - contentTypes.put("kar", "audio/x-midi"); - contentTypes.put("latex", "application/x-latex"); - contentTypes.put("log", "text/plain"); - contentTypes.put("m3u", "audio/x-mpegurl"); - contentTypes.put("mac", "image/x-macpaint"); - contentTypes.put("man", "application/x-troff-man"); - contentTypes.put("mathml", "application/mathml+xml"); - contentTypes.put("me", "application/x-troff-me"); - contentTypes.put("mid", "audio/x-midi"); - contentTypes.put("midi", "audio/x-midi"); - contentTypes.put("mif", "application/x-mif"); - contentTypes.put("mov", "video/quicktime"); - contentTypes.put("movie", "video/x-sgi-movie"); - contentTypes.put("mp1", "audio/x-mpeg"); - contentTypes.put("mp2", "audio/x-mpeg"); - contentTypes.put("mp3", "audio/x-mpeg"); - contentTypes.put("mpa", "audio/x-mpeg"); - contentTypes.put("mp4", "video/mp4"); - contentTypes.put("ogv", "video/ogv"); - contentTypes.put("webm", "video/webm"); - contentTypes.put("flv", "video/x-flv"); - contentTypes.put("mpe", "video/mpeg"); - contentTypes.put("mpeg", "video/mpeg"); - contentTypes.put("mpega", "audio/x-mpeg"); - contentTypes.put("mpg", "video/mpeg"); - contentTypes.put("mpv2", "video/mpeg2"); - contentTypes.put("ms", "application/x-wais-source"); - contentTypes.put("nc", "application/x-netcdf"); - contentTypes.put("oda", "application/oda"); - contentTypes.put("ogg", "application/ogg"); - contentTypes.put("out", "text/plain"); - contentTypes.put("pbm", "image/x-portable-bitmap"); - contentTypes.put("pct", "image/pict"); - contentTypes.put("pdf", "application/pdf"); - contentTypes.put("pgm", "image/x-portable-graymap"); - contentTypes.put("pic", "image/pict"); - contentTypes.put("pict", "image/pict"); - contentTypes.put("pls", "audio/x-scpls"); - contentTypes.put("png", "image/png"); - contentTypes.put("pnm", "image/x-portable-anymap"); - contentTypes.put("pnt", "image/x-macpaint"); - contentTypes.put("ppm", "image/x-portable-pixmap"); - contentTypes.put("ppt", "application/powerpoint"); - contentTypes.put("ps", "application/postscript"); - contentTypes.put("psd", "image/x-photoshop"); - contentTypes.put("qt", "video/quicktime"); - contentTypes.put("qti", "image/x-quicktime"); - contentTypes.put("qtif", "image/x-quicktime"); - contentTypes.put("ras", "image/x-cmu-raster"); - contentTypes.put("rdf", "application/rdf+xml"); - contentTypes.put("rgb", "image/x-rgb"); - contentTypes.put("rm", "application/vnd.rn-realmedia"); - contentTypes.put("roff", "application/x-troff"); - contentTypes.put("rtf", "application/rtf"); - contentTypes.put("rtx", "text/richtext"); - contentTypes.put("sh", "application/x-sh"); - contentTypes.put("shar", "application/x-shar"); - contentTypes.put("shtml", "text/x-server-parsed-html"); - contentTypes.put("sit", "application/x-stuffit"); - contentTypes.put("smf", "audio/x-midi"); - contentTypes.put("snd", "audio/basic"); - contentTypes.put("src", "application/x-wais-source"); - contentTypes.put("sv4cpio", "application/x-sv4cpio"); - contentTypes.put("sv4crc", "application/x-sv4crc"); - contentTypes.put("svg", "image/svg+xml"); - contentTypes.put("svgz", "image/svg+xml"); - contentTypes.put("swf", "application/x-shockwave-flash"); - contentTypes.put("t", "application/x-troff"); - contentTypes.put("tar", "application/x-tar"); - contentTypes.put("tcl", "application/x-tcl"); - contentTypes.put("tex", "application/x-tex"); - contentTypes.put("texi", "application/x-texinfo"); - contentTypes.put("texinfo", "application/x-texinfo"); - contentTypes.put("tif", "image/tiff"); - contentTypes.put("tiff", "image/tiff"); - contentTypes.put("tr", "application/x-troff"); - contentTypes.put("tsv", "text/tab-separated-values"); - contentTypes.put("txt", "text/plain"); - contentTypes.put("ulw", "audio/basic"); - contentTypes.put("ustar", "application/x-ustar"); - contentTypes.put("xbm", "image/x-xbitmap"); - contentTypes.put("xml", "application/xml"); - contentTypes.put("xpm", "image/x-xpixmap"); - contentTypes.put("xsl", "application/xml"); - contentTypes.put("xslt", "application/xslt+xml"); - contentTypes.put("xwd", "image/x-xwindowdump"); - contentTypes.put("vsd", "application/x-visio"); - contentTypes.put("vxml", "application/voicexml+xml"); - contentTypes.put("wav", "audio/x-wav"); - contentTypes.put("wbmp", "image/vnd.wap.wbmp"); - contentTypes.put("wml", "text/vnd.wap.wml"); - contentTypes.put("wmlc", "application/vnd.wap.wmlc"); - contentTypes.put("wmls", "text/vnd.wap.wmls"); - contentTypes.put("wmlscriptc", "application/vnd.wap.wmlscriptc"); - contentTypes.put("wrl", "x-world/x-vrml"); - contentTypes.put("xht", "application/xhtml+xml"); - contentTypes.put("xhtml", "application/xhtml+xml"); - contentTypes.put("xls", "application/vnd.ms-excel"); - contentTypes.put("xul", "application/vnd.mozilla.xul+xml"); - contentTypes.put("Z", "application/x-compress"); - contentTypes.put("z", "application/x-compress"); - contentTypes.put("zip", "application/zip"); - } - - public static String get(String extension) { - return contentTypes.getOrDefault(extension, "text/plain"); - } - - public static String get(String extension, String defaultCt) { - return contentTypes.getOrDefault(extension, defaultCt); - } - - public static boolean contains(String extension) { - return contentTypes.containsKey(extension); - } - - public static void add(String extension, String contentType) { - if (extension != null && extension.length() != 0 && contentType != null && contentType.length() != 0) { - contentTypes.put(extension, contentType); - } - } - - public static String getByFilename(String fileName) { - int length = fileName.length(); - int newEnd = fileName.lastIndexOf('#'); - if (newEnd == -1) newEnd = length; - int i = fileName.lastIndexOf('.', newEnd); - return (i < 0) ? null : get(fileName.substring(i + 1, newEnd)); - } - -} diff --git a/src/main/java/org/redkale/net/http/MultiContext.java b/src/main/java/org/redkale/net/http/MultiContext.java deleted file mode 100644 index b3fcccb44..000000000 --- a/src/main/java/org/redkale/net/http/MultiContext.java +++ /dev/null @@ -1,245 +0,0 @@ -/* - * To change this license header, choose License Headers input Project Properties. - * To change this template file, choose Tools | Templates - * and open the template input the editor. - */ -package org.redkale.net.http; - -import org.redkale.util.ByteArray; -import java.io.*; -import java.nio.charset.*; -import java.util.*; -import java.util.concurrent.atomic.*; -import java.util.logging.*; -import java.util.regex.*; -import org.redkale.util.AnyValue.DefaultAnyValue; - -/** - * - *

- * 详情见: http://www.redkale.org - * - * @author zhangjx - */ -public final class MultiContext { - - private static final Logger logger = Logger.getLogger(MultiContext.class.getSimpleName()); - - private static final Charset UTF8 = Charset.forName("UTF-8"); - - private final String contentType; - - private final InputStream in; - - private final Charset charset; - - private final String boundary; - - private final byte[] endboundarray; - - private final ByteArray buf = new ByteArray(64); - - private final DefaultAnyValue parameters; - - private final Pattern fielnamePattern; - - private static final Iterable emptyIterable = () -> new Iterator() { - - @Override - public boolean hasNext() { - return false; - } - - @Override - public MultiPart next() { - return null; - } - }; - - public MultiContext(final Charset charsetName, final String contentType, final DefaultAnyValue params, final InputStream in, String fielnameRegex) { - this.charset = charsetName == null ? UTF8 : charsetName; - this.contentType = contentType.trim(); - this.parameters = params; - this.boundary = parseBoundary(this.contentType); - this.endboundarray = ("--" + this.boundary + "--").getBytes(); - this.in = in instanceof BufferedInputStream ? in : new BufferedInputStream(in); - this.fielnamePattern = fielnameRegex == null || fielnameRegex.isEmpty() ? null : Pattern.compile(fielnameRegex); - } - - private String parseBoundary(String contentType) { - if (!contentType.startsWith("multipart/")) { - return null; - } - for (String str : contentType.split(";")) { - int pos = str.indexOf("boundary="); - if (pos >= 0) return str.substring(pos + "boundary=".length()).trim(); - } - return null; - } - - public boolean isMultipart() { - return this.boundary != null; - } - - public Iterable parts() throws IOException { - if (!isMultipart()) return emptyIterable; - final String boundarystr = "--" + this.boundary; - final Pattern fielnameReg = this.fielnamePattern; - final String endboundary = boundarystr + "--"; - final byte[] boundarray = ("\n" + boundarystr).getBytes(); - final byte[] buffer = new byte[boundarray.length]; - final InputStream input = this.in; - final DefaultAnyValue params = this.parameters; - final AtomicBoolean finaled = new AtomicBoolean(false); - return () -> new Iterator() { - - private String boundaryline; - - private MultiPart lastentry; - - @Override - public boolean hasNext() { - try { - if (lastentry != null) { - lastentry.skip(); - if (finaled.get()) return false; - } - if (boundaryline == null) boundaryline = readBoundary(); - //if (debug) System.out.print("boundaryline=" + boundaryline + " "); - if (endboundary.equals(boundaryline) || !boundarystr.equals(boundaryline)) { //结尾或异常 - lastentry = null; - return false; - } - final String disposition = readLine(); - //if (debug) System.out.println("disposition=" + disposition); - if (disposition.contains("; filename=\"")) { //是上传文件 - String contentType = readLine(); - //if (debug) System.out.println("file.contentType=" + contentType); - contentType = contentType.substring(contentType.indexOf(':') + 1).trim(); - readLine(); //读掉空白行 - String name = parseValue(disposition, "name"); - String filename = parseValue(disposition, "filename"); - if (filename == null || filename.isEmpty()) { //没有上传 - readLine(); //读掉空白行 - this.boundaryline = null; - this.lastentry = null; - return this.hasNext(); - } else { - int p1 = filename.lastIndexOf('/'); - if (p1 < 0) p1 = filename.lastIndexOf('\\'); - if (p1 >= 0) filename = filename.substring(p1 + 1); - } - final AtomicLong counter = new AtomicLong(0); - InputStream source = new InputStream() { - - private int bufposition = buffer.length; - - private boolean end; - - @Override - public int read() throws IOException { - if (end) return -1; - final byte[] buf = buffer; - int ch = (this.bufposition < buf.length) ? (buf[this.bufposition++] & 0xff) : input.read(); - if ((ch == '\r' && readBuffer())) return -1; - counter.incrementAndGet(); - return ch; - } - - private boolean readBuffer() throws IOException { - final byte[] buf = buffer; - final int pos = this.bufposition; - int s = 0; - for (int i = pos; i < buf.length; i++) { - buf[s++] = buf[i]; - } - int readed = 0; - while ((readed += input.read(buf, s + readed, pos - readed)) != pos); - this.bufposition = 0; - if (Arrays.equals(boundarray, buf)) { - this.end = true; - int c1 = input.read(); - int c2 = input.read(); - finaled.set(c1 == '-' && c2 == '-'); - return true; - } - return false; - } - - @Override - public long skip(long count) throws IOException { - if (end) return -1; - if (count <= 0) return 0; - long s = 0; - while (read() != -1) { - s++; - if (--count <= 0) break; - } - return s; - } - }; - this.lastentry = new MultiPart(filename, name, contentType, counter, source); - if (fielnameReg != null && !fielnameReg.matcher(filename).matches()) { - return this.hasNext(); - } - return true; - } else { //不是文件 - readLine(); //读掉空白 - params.addValue(parseValue(disposition, "name"), readLine()); - this.boundaryline = null; - this.lastentry = null; - return this.hasNext(); - } - } catch (IOException ex) { - logger.log(Level.FINER, "list multiparts abort", ex); - return false; - } - } - - @Override - public MultiPart next() { - return lastentry; - } - - }; - } - - private String readLine() throws IOException { - return readLine(false); - } - - private String readBoundary() throws IOException { - return readLine(true); - } - - private String readLine(boolean bd) throws IOException { // bd : 是否是读取boundary - byte lasted = '\r'; - buf.clear(); - final int bc = this.endboundarray.length; - int c = 0; - for (;;) { - int b = in.read(); - c++; - if (b == -1 || (lasted == '\r' && b == '\n')) break; - if (lasted != '\r') buf.write(lasted); - lasted = (byte) b; - if (bd && bc == c) { - buf.write(lasted); - if (buf.equal(this.endboundarray)) break; - buf.removeLastByte(); - } - } - if (buf.size() == 0) return ""; - return buf.toString(this.charset).trim(); - } - - private static String parseValue(final String str, String name) { - if (str == null) return null; - final String key = "; " + name + "=\""; - int pos = str.indexOf(key); - if (pos < 0) return null; - String sub = str.substring(pos + key.length()); - return sub.substring(0, sub.indexOf('"')); - } - -} diff --git a/src/main/java/org/redkale/net/http/MultiPart.java b/src/main/java/org/redkale/net/http/MultiPart.java deleted file mode 100644 index 8d7ff886e..000000000 --- a/src/main/java/org/redkale/net/http/MultiPart.java +++ /dev/null @@ -1,116 +0,0 @@ -/* - * 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.http; - -import java.io.*; -import java.util.concurrent.atomic.AtomicLong; - -/** - * - *

详情见: http://www.redkale.org - * @author zhangjx - */ -public final class MultiPart { - - private final String filename; - - private final String name; - - private final String contentType; - - private final InputStream in; - - private final AtomicLong received; - - MultiPart(String filename, String name, String contentType, AtomicLong received, InputStream in) { - this.filename = filename; - this.name = name; - this.in = in; - this.contentType = contentType; - this.received = received; - } - - @Override - public String toString() { - return this.getClass().getSimpleName() + "{" + "name=" + name + ", filename=" + filename + ", contentType=" + contentType + ", received=" + received + '}'; - } - - public boolean save(File file) throws IOException { - return save(Long.MAX_VALUE, file); - } - - public boolean save(long max, File file) throws IOException { - OutputStream out = new FileOutputStream(file); - boolean rs = save(max, out); - out.close(); - return rs; - } - - public byte[] getContentBytes() throws IOException { - return getContentBytes(Long.MAX_VALUE); - } - - /** - * 将文件流读进bytes, 如果超出max指定的值则返回null - * - * @param max 最大长度限制 - * @return 内容 - * @throws IOException 异常 - */ - public byte[] getContentBytes(long max) throws IOException { - ByteArrayOutputStream out = new ByteArrayOutputStream(); - return save(max, out) ? out.toByteArray() : null; - } - - public boolean save(OutputStream out) throws IOException { - return save(Long.MAX_VALUE, out); - } - - /** - * 将文件流写进out, 如果超出max指定的值则中断并返回false - * - * @param max 最大长度限制 - * @param out 输出流 - * @return 是否成功 - * @throws IOException 异常 - */ - public boolean save(long max, OutputStream out) throws IOException { - byte[] bytes = new byte[4096]; - int pos; - InputStream in0 = this.getInputStream(); - while ((pos = in0.read(bytes)) != -1) { - if (max < 0) return false; - out.write(bytes, 0, pos); - max -= pos; - } - return true; - } - - public String getContentType() { - return contentType; - } - - public String getFilename() { - return filename; - } - - public String getName() { - return name; - } - - public InputStream getInputStream() { - return in; - } - - public long getReceived() { - return received.get(); - } - - public void skip() throws IOException { - in.skip(Long.MAX_VALUE); - } - -} diff --git a/src/main/java/org/redkale/net/http/WebInitParam.java b/src/main/java/org/redkale/net/http/WebInitParam.java deleted file mode 100644 index fdda0b5c2..000000000 --- a/src/main/java/org/redkale/net/http/WebInitParam.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * 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.http; - -import java.lang.annotation.*; - -/** - * 功能同JSR 315 (java-servlet 3.0) 规范中的 @WebInitParam - * - *

详情见: http://www.redkale.org - * @author zhangjx - */ -@Target({ElementType.TYPE}) -@Retention(RetentionPolicy.RUNTIME) -@Documented -public @interface WebInitParam { - - String name(); - - String value(); - - String description() default ""; -} diff --git a/src/main/java/org/redkale/net/http/WebServlet.java b/src/main/java/org/redkale/net/http/WebServlet.java deleted file mode 100644 index c0cb0acc2..000000000 --- a/src/main/java/org/redkale/net/http/WebServlet.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * 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.http; - -import java.lang.annotation.*; - -/** - * 功能同JSR 315 (java-servlet 3.0) 规范中的 @WebServlet - * - * - *

详情见: http://www.redkale.org - * @author zhangjx - */ -@Documented -@Target({ElementType.TYPE}) -@Retention(RetentionPolicy.RUNTIME) -public @interface WebServlet { - - String name() default ""; - - boolean repair() default true; - - String[] value() default {}; - - int moduleid() default 0; - - WebInitParam[] initParams() default {}; -} diff --git a/src/main/java/org/redkale/net/http/WebSocket.java b/src/main/java/org/redkale/net/http/WebSocket.java deleted file mode 100644 index c984f9abb..000000000 --- a/src/main/java/org/redkale/net/http/WebSocket.java +++ /dev/null @@ -1,453 +0,0 @@ -/* - * 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.http; - -import org.redkale.net.http.WebSocketPacket.FrameType; -import java.io.*; -import java.net.*; -import java.util.*; -import java.util.concurrent.ConcurrentHashMap; -import org.redkale.net.*; - -/** - *

- * 一个WebSocket连接对应一个WebSocket实体,即一个WebSocket会绑定一个TCP连接。
- * WebSocket 有两种模式:
- *  1) 普通模式: 协议上符合HTML5规范, 其流程顺序如下:
- *      1.1 onOpen 若返回null,视为WebSocket的连接不合法,强制关闭WebSocket连接;通常用于判断登录态。
- *      1.2 createGroupid 若返回null,视为WebSocket的连接不合法,强制关闭WebSocket连接;通常用于判断用户权限是否符合。
- *      1.3 onConnected WebSocket成功连接后在准备接收数据前回调此方法。
- *      1.4 onMessage/onFragment+ WebSocket接收到消息后回调此消息类方法。
- *      1.5 onClose WebSocket被关闭后回调此方法。
- *
- *  此模式下 以上方法都应该被重载。
- *
- *  2) 原始二进制模式: 此模式有别于HTML5规范,可以视为原始的TCP连接。通常用于音频视频通讯场景。其流程顺序如下:
- *      2.1 onOpen 若返回null,视为WebSocket的连接不合法,强制关闭WebSocket连接;通常用于判断登录态。
- *      2.2 createGroupid 若返回null,视为WebSocket的连接不合法,强制关闭WebSocket连接;通常用于判断用户权限是否符合。
- *      2.3 onRead WebSocket成功连接后回调此方法, 由此方法处理原始的TCP连接, 同时业务代码去控制WebSocket的关闭。
- *
- *  此模式下 以上方法都应该被重载。
- * 
- *

- * 详情见: http://www.redkale.org - * - * @author zhangjx - */ -public abstract class WebSocket { - - //消息不合法 - public static final int RETCODE_SEND_ILLPACKET = 1 << 1; //2 - - //ws已经关闭 - public static final int RETCODE_WSOCKET_CLOSED = 1 << 2; //4 - - //socket的buffer不合法 - public static final int RETCODE_ILLEGALBUFFER = 1 << 3; //8 - - //ws发送消息异常 - public static final int RETCODE_SENDEXCEPTION = 1 << 4; //16 - - public static final int RETCODE_ENGINE_NULL = 1 << 5; //32 - - public static final int RETCODE_NODESERVICE_NULL = 1 << 6; //64 - - public static final int RETCODE_GROUP_EMPTY = 1 << 7; //128 - - public static final int RETCODE_WSOFFLINE = 1 << 8; //256 - - WebSocketRunner _runner; //不可能为空 - - WebSocketEngine _engine; //不可能为空 - - WebSocketGroup _group; //不可能为空 - - Serializable _sessionid; //不可能为空 - - Serializable _groupid; //不可能为空 - - SocketAddress _remoteAddress;//不可能为空 - - String _remoteAddr;//不可能为空 - - private final long createtime = System.currentTimeMillis(); - - private final Map attributes = new ConcurrentHashMap<>(); - - protected WebSocket() { - } - - //---------------------------------------------------------------- - /** - * 发送消息体, 包含二进制/文本 - * - * @param packet WebSocketPacket - * @return 0表示成功, 非0表示错误码 - */ - public final int send(WebSocketPacket packet) { - int rs = RETCODE_WSOCKET_CLOSED; - if (this._runner != null) rs = this._runner.sendMessage(packet); - if (_engine.finest) _engine.logger.finest("wsgroupid:" + getGroupid() + " send websocket result is " + rs + " on " + this + " by message(" + packet + ")"); - return rs; - } - - /** - * 发送单一的文本消息 - * - * @param text 不可为空 - * @return 0表示成功, 非0表示错误码 - */ - public final int send(String text) { - return send(text, true); - } - - /** - * 发送文本消息 - * - * @param text 不可为空 - * @param last 是否最后一条 - * @return 0表示成功, 非0表示错误码 - */ - public final int send(String text, boolean last) { - return send(new WebSocketPacket(text, last)); - } - - public final int sendPing() { - //if (_engine.finest) _engine.logger.finest(this + " on "+_engine.getEngineid()+" ping..."); - return send(WebSocketPacket.DEFAULT_PING_PACKET); - } - - public final int sendPing(byte[] data) { - return send(new WebSocketPacket(FrameType.PING, data)); - } - - public final int sendPong(byte[] data) { - return send(new WebSocketPacket(FrameType.PONG, data)); - } - - public final long getCreatetime() { - return createtime; - } - - /** - * 发送单一的二进制消息 - * - * @param data byte[] - * @return 0表示成功, 非0表示错误码 - */ - public final int send(byte[] data) { - return send(data, true); - } - - /** - * 发送二进制消息 - * - * @param data 不可为空 - * @param last 是否最后一条 - * @return 0表示成功, 非0表示错误码 - */ - public final int send(byte[] data, boolean last) { - return send(new WebSocketPacket(data, last)); - } - - /** - * 发送消息, 消息类型是String或byte[] - * - * @param message 不可为空, 只能是String或者byte[] - * @param last 是否最后一条 - * @return 0表示成功, 非0表示错误码 - */ - public final int send(Serializable message, boolean last) { - return send(new WebSocketPacket(message, last)); - } - - //---------------------------------------------------------------- - /** - * 给指定groupid的WebSocketGroup下所有WebSocket节点发送文本消息 - * - * @param groupid groupid - * @param text 不可为空 - * @return 为0表示成功, 其他值表示异常 - */ - public final int sendEachMessage(Serializable groupid, String text) { - return sendEachMessage(groupid, text, true); - } - - /** - * 给指定groupid的WebSocketGroup下所有WebSocket节点发送二进制消息 - * - * @param groupid groupid - * @param data 不可为空 - * @return 为0表示成功, 其他值表示异常 - */ - public final int sendEachMessage(Serializable groupid, byte[] data) { - return WebSocket.this.sendEachMessage(groupid, data, true); - } - - /** - * 给指定groupid的WebSocketGroup下所有WebSocket节点发送文本消息 - * - * @param groupid groupid - * @param text 不可为空 - * @param last 是否最后一条 - * @return 为0表示成功, 其他值表示异常 - */ - public final int sendEachMessage(Serializable groupid, String text, boolean last) { - return sendMessage(groupid, false, text, last); - } - - /** - * 给指定groupid的WebSocketGroup下所有WebSocket节点发送二进制消息 - * - * @param groupid groupid - * @param data 不可为空 - * @param last 是否最后一条 - * @return 为0表示成功, 其他值表示异常 - */ - public final int sendEachMessage(Serializable groupid, byte[] data, boolean last) { - return sendMessage(groupid, false, data, last); - } - - /** - * 给指定groupid的WebSocketGroup下最近接入的WebSocket节点发送文本消息 - * - * @param groupid groupid - * @param text 不可为空 - * @return 为0表示成功, 其他值表示异常 - */ - public final int sendRecentMessage(Serializable groupid, String text) { - return sendRecentMessage(groupid, text, true); - } - - /** - * 给指定groupid的WebSocketGroup下最近接入的WebSocket节点发送二进制消息 - * - * @param groupid groupid - * @param data 不可为空 - * @return 为0表示成功, 其他值表示异常 - */ - public final int sendRecentMessage(Serializable groupid, byte[] data) { - return sendRecentMessage(groupid, data, true); - } - - /** - * 给指定groupid的WebSocketGroup下最近接入的WebSocket节点发送文本消息 - * - * @param groupid groupid - * @param text 不可为空 - * @param last 是否最后一条 - * @return 为0表示成功, 其他值表示异常 - */ - public final int sendRecentMessage(Serializable groupid, String text, boolean last) { - return sendMessage(groupid, true, text, last); - } - - /** - * 给指定groupid的WebSocketGroup下最近接入的WebSocket节点发送二进制消息 - * - * @param groupid groupid - * @param data 不可为空 - * @param last 是否最后一条 - * @return 为0表示成功, 其他值表示异常 - */ - public final int sendRecentMessage(Serializable groupid, byte[] data, boolean last) { - return sendMessage(groupid, true, data, last); - } - - private int sendMessage(Serializable groupid, boolean recent, String text, boolean last) { - if (_engine.node == null) return RETCODE_NODESERVICE_NULL; - int rs = _engine.node.sendMessage(groupid, recent, text, last); - if (_engine.finest) _engine.logger.finest("wsgroupid:" + groupid + " " + (recent ? "recent " : "") + "send websocket result is " + rs + " on " + this + " by message(" + text + ")"); - return rs; - } - - private int sendMessage(Serializable groupid, boolean recent, byte[] data, boolean last) { - if (_engine.node == null) return RETCODE_NODESERVICE_NULL; - int rs = _engine.node.sendMessage(groupid, recent, data, last); - if (_engine.finest) _engine.logger.finest("wsgroupid:" + groupid + " " + (recent ? "recent " : "") + "send websocket result is " + rs + " on " + this + " by message(byte[" + data.length + "])"); - return rs; - } - - /** - * 获取在线用户的节点地址列表 - * - * @param groupid groupid - * @return 地址列表 - */ - protected final Collection getOnlineNodes(Serializable groupid) { - return _engine.node.getOnlineNodes(groupid); - } - - /** - * 获取在线用户的详细连接信息 - * - * @param groupid groupid - * @return 地址集合 - */ - protected final Map> getOnlineRemoteAddress(Serializable groupid) { - return _engine.node.getOnlineRemoteAddress(groupid); - } - - /** - * 获取当前WebSocket下的属性 - * - * @param 属性值的类型 - * @param name 属性名 - * @return 属性值 - */ - @SuppressWarnings("unchecked") - public final T getAttribute(String name) { - return (T) attributes.get(name); - } - - /** - * 移出当前WebSocket下的属性 - * - * @param 属性值的类型 - * @param name 属性名 - * @return 属性值 - */ - public final T removeAttribute(String name) { - return (T) attributes.remove(name); - } - - /** - * 给当前WebSocket下的增加属性 - * - * @param name 属性值 - * @param value 属性值 - */ - public final void setAttribute(String name, Object value) { - attributes.put(name, value); - } - - /** - * 获取当前WebSocket所属的groupid - * - * @return groupid - */ - public final Serializable getGroupid() { - return _groupid; - } - - /** - * 获取当前WebSocket的会话ID, 不会为null - * - * @return sessionid - */ - public final Serializable getSessionid() { - return _sessionid; - } - - /** - * 获取客户端直接地址, 当WebSocket连接是由代理服务器转发的,则该值固定为代理服务器的IP地址 - * - * @return SocketAddress - */ - public final SocketAddress getRemoteAddress() { - return _remoteAddress; - } - - /** - * 获取客户端真实地址 同 HttpRequest.getRemoteAddr() - * - * @return String - */ - public final String getRemoteAddr() { - return _remoteAddr; - } - - //------------------------------------------------------------------- - /** - * 获取当前WebSocket所属的WebSocketGroup, 不会为null - * - * @return WebSocketGroup - */ - protected final WebSocketGroup getWebSocketGroup() { - return _group; - } - - /** - * 获取指定groupid的WebSocketGroup, 没有返回null - * - * @param groupid groupid - * @return WebSocketGroup - */ - protected final WebSocketGroup getWebSocketGroup(Serializable groupid) { - return _engine.getWebSocketGroup(groupid); - } - - /** - * 获取当前进程节点所有在线的WebSocketGroup - * - * @return WebSocketGroup列表 - */ - protected final Collection getWebSocketGroups() { - return _engine.getWebSocketGroups(); - } - - //------------------------------------------------------------------- - /** - * 返回sessionid, null表示连接不合法或异常,默认实现是request.getSessionid(false),通常需要重写该方法 - * - * @param request HttpRequest - * @return sessionid - */ - public Serializable onOpen(final HttpRequest request) { - return request.getSessionid(false); - } - - /** - * 创建groupid, null表示异常, 必须实现该方法, 通常为用户ID为groupid - * - * @return groupid - */ - protected abstract Serializable createGroupid(); - - /** - * 标记为WebSocketBinary才需要重写此方法 - * - * @param channel 请求连接 - */ - public void onRead(AsyncConnection channel) { - } - - public void onConnected() { - } - - public void onMessage(String text) { - } - - public void onPing(byte[] bytes) { - } - - public void onPong(byte[] bytes) { - } - - public void onMessage(byte[] bytes) { - } - - public void onFragment(String text, boolean last) { - } - - public void onFragment(byte[] bytes, boolean last) { - } - - public void onClose(int code, String reason) { - } - - /** - * 显式地关闭WebSocket - */ - public final void close() { - if (this._runner != null) this._runner.closeRunner(); - } - - @Override - public String toString() { - return "ws" + Objects.hashCode(this) + "@" + _remoteAddr; - } -} diff --git a/src/main/java/org/redkale/net/http/WebSocketBinary.java b/src/main/java/org/redkale/net/http/WebSocketBinary.java deleted file mode 100644 index 30590f2b4..000000000 --- a/src/main/java/org/redkale/net/http/WebSocketBinary.java +++ /dev/null @@ -1,24 +0,0 @@ -/* - * 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.http; - -import java.lang.annotation.*; -import static java.lang.annotation.ElementType.*; -import static java.lang.annotation.RetentionPolicy.RUNTIME; - -/** - * 被标记为 @WebSocketBinary 的WebSocketServlet 将使用原始的TCP传输, 通常用于类似音频/视频传输场景 - * - *

详情见: http://www.redkale.org - * @author zhangjx - */ -@Inherited -@Documented -@Target({TYPE}) -@Retention(RUNTIME) -public @interface WebSocketBinary { - -} diff --git a/src/main/java/org/redkale/net/http/WebSocketEngine.java b/src/main/java/org/redkale/net/http/WebSocketEngine.java deleted file mode 100644 index 0ea5b28e7..000000000 --- a/src/main/java/org/redkale/net/http/WebSocketEngine.java +++ /dev/null @@ -1,101 +0,0 @@ -/* - * 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.http; - -import static org.redkale.net.http.WebSocketServlet.DEFAILT_LIVEINTERVAL; -import java.io.*; -import java.util.*; -import java.util.concurrent.*; -import java.util.concurrent.atomic.*; -import java.util.logging.*; -import org.redkale.util.*; - -/** - * - *

详情见: http://www.redkale.org - * @author zhangjx - */ -public final class WebSocketEngine { - - private static final AtomicInteger sequence = new AtomicInteger(); - - private final int index; - - private final String engineid; - - protected final WebSocketNode node; - - private final Map containers = new ConcurrentHashMap<>(); - - private ScheduledThreadPoolExecutor scheduler; - - protected final Logger logger; - - protected final boolean finest; - - protected WebSocketEngine(String engineid, WebSocketNode node, Logger logger) { - this.engineid = engineid; - this.node = node; - this.logger = logger; - this.index = sequence.getAndIncrement(); - this.finest = logger.isLoggable(Level.FINEST); - } - - void init(AnyValue conf) { - final int liveinterval = conf == null ? DEFAILT_LIVEINTERVAL : conf.getIntValue("liveinterval", DEFAILT_LIVEINTERVAL); - if (liveinterval <= 0) return; - if (scheduler != null) return; - this.scheduler = new ScheduledThreadPoolExecutor(1, (Runnable r) -> { - final Thread t = new Thread(r, engineid + "-WebSocket-LiveInterval-Thread"); - t.setDaemon(true); - return t; - }); - long delay = (liveinterval - System.currentTimeMillis() / 1000 % liveinterval) + index * 5; - scheduler.scheduleWithFixedDelay(() -> { - getWebSocketGroups().stream().forEach(x -> x.sendEachPing()); - }, delay, liveinterval, TimeUnit.SECONDS); - if (finest) logger.finest(this.getClass().getSimpleName() + "(" + engineid + ")" + " start keeplive(delay:" + delay + ", interval:" + liveinterval + "s) scheduler executor"); - } - - void add(WebSocket socket) { - WebSocketGroup group = containers.get(socket._groupid); - if (group == null) { - group = new WebSocketGroup(socket._groupid); - containers.putIfAbsent(socket._groupid, group); - } - group.add(socket); - if (node != null) node.connect(socket._groupid, engineid, socket.toString()); - } - - void remove(WebSocket socket) { - final WebSocketGroup group = containers.get(socket._groupid); - if (group == null) { - if (node != null) node.disconnect(socket._groupid, engineid); - return; - } - group.remove(socket); - if (group.isEmpty()) { - containers.remove(socket._groupid); - if (node != null) node.disconnect(socket._groupid, engineid); - } - } - - Collection getWebSocketGroups() { - return containers.values(); - } - - public WebSocketGroup getWebSocketGroup(Serializable groupid) { - return containers.get(groupid); - } - - void close() { - if (scheduler != null) scheduler.shutdownNow(); - } - - public String getEngineid() { - return engineid; - } -} diff --git a/src/main/java/org/redkale/net/http/WebSocketGroup.java b/src/main/java/org/redkale/net/http/WebSocketGroup.java deleted file mode 100644 index 74cafc85a..000000000 --- a/src/main/java/org/redkale/net/http/WebSocketGroup.java +++ /dev/null @@ -1,139 +0,0 @@ -/* - * 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.http; - -import java.io.*; -import java.util.*; -import java.util.concurrent.CopyOnWriteArrayList; -import java.util.stream.Stream; - -/** - * - *

- * 详情见: http://www.redkale.org - * - * @author zhangjx - */ -public final class WebSocketGroup { - - private final Serializable groupid; - - private WebSocket recentWebSocket; - - private final List list = new CopyOnWriteArrayList<>(); - - private final Map attributes = new HashMap<>(); - - WebSocketGroup(Serializable groupid) { - this.groupid = groupid; - } - - public Serializable getGroupid() { - return groupid; - } - - public Stream getWebSockets() { - return list.stream(); - } - - void remove(WebSocket socket) { - list.remove(socket); - } - - void add(WebSocket socket) { - socket._group = this; - this.recentWebSocket = socket; - list.add(socket); - } - - void setRecentWebSocket(WebSocket socket) { - this.recentWebSocket = socket; - } - - public final boolean isEmpty() { - return list.isEmpty(); - } - - public final int size() { - return list.size(); - } - - /** - * 最近发送消息的WebSocket - * - * @return WebSocket - */ - public final WebSocket getRecentWebSocket() { - return recentWebSocket; - } - - @SuppressWarnings("unchecked") - public final T getAttribute(String name) { - return (T) attributes.get(name); - } - - public final void removeAttribute(String name) { - attributes.remove(name); - } - - public final void setAttribute(String name, Object value) { - attributes.put(name, value); - } - - public final int send(boolean recent, Serializable message, boolean last) { - if (recent) { - return recentWebSocket.send(message, last); - } else { - return sendEach(message, last); - } - } - - public final int sendEach(Serializable message) { - return sendEach(message, true); - } - - public final int sendEach(WebSocketPacket packet) { - int rs = 0; - for (WebSocket s : list) { - rs |= s.send(packet); - } - return rs; - } - - public final int sendEachPing() { - int rs = 0; - for (WebSocket s : list) { - rs |= s.sendPing(); - } - return rs; - } - - public final int sendRecent(Serializable message) { - return sendRecent(message, true); - } - - public final int sendRecent(WebSocketPacket packet) { - return recentWebSocket.send(packet); - } - - public final int sendEach(Serializable message, boolean last) { - int rs = 0; - for (WebSocket s : list) { - rs |= s.send(message, last); - } - return rs; - } - - public final int sendRecent(Serializable message, boolean last) { - return recentWebSocket.send(message, last); - } - - @Override - public String toString() { - return "{groupid: " + groupid + ", list.size: " + (list == null ? -1 : list.size()) + "}"; - } - -} diff --git a/src/main/java/org/redkale/net/http/WebSocketNode.java b/src/main/java/org/redkale/net/http/WebSocketNode.java deleted file mode 100644 index 5c614151f..000000000 --- a/src/main/java/org/redkale/net/http/WebSocketNode.java +++ /dev/null @@ -1,235 +0,0 @@ -/* - * 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.http; - -import static org.redkale.net.http.WebSocket.*; -import java.io.*; -import java.net.*; -import java.util.*; -import java.util.concurrent.*; -import java.util.logging.*; -import javax.annotation.*; -import org.redkale.boot.*; -import org.redkale.service.*; -import org.redkale.source.*; -import org.redkale.util.*; - -/** - * - *

- * 详情见: http://www.redkale.org - * - * @author zhangjx - */ -public abstract class WebSocketNode { - - protected final Logger logger = Logger.getLogger(this.getClass().getSimpleName()); - - protected final boolean finest = logger.isLoggable(Level.FINEST); - - @Resource(name = Application.RESNAME_SERVER_ADDR) - protected InetSocketAddress localSncpAddress; //为SncpServer的服务address - - @DynRemote - protected WebSocketNode remoteNode; - - //存放所有用户分布在节点上的队列信息,Set 为 sncpnode 的集合 - @Resource(name = "$") - protected CacheSource source; - - //存放本地节点上所有在线用户的队列信息,Set 为 engineid 的集合 - protected final ConcurrentHashMap> localNodes = new ConcurrentHashMap(); - - protected final ConcurrentHashMap engines = new ConcurrentHashMap(); - - public void init(AnyValue conf) { - - } - - public void destroy(AnyValue conf) { - HashMap> nodes = new HashMap<>(localNodes); - nodes.forEach((k, v) -> { - new HashSet<>(v).forEach(e -> { - if (engines.containsKey(e)) disconnect(k, e); - }); - }); - } - - protected abstract List getOnlineRemoteAddresses(@DynTargetAddress InetSocketAddress targetAddress, Serializable groupid); - - protected abstract int sendMessage(@DynTargetAddress InetSocketAddress targetAddress, Serializable groupid, boolean recent, Serializable message, boolean last); - - protected abstract void connect(Serializable groupid, InetSocketAddress addr); - - protected abstract void disconnect(Serializable groupid, InetSocketAddress addr); - - //-------------------------------------------------------------------------------- - protected List remoteOnlineRemoteAddresses(@DynTargetAddress InetSocketAddress targetAddress, Serializable groupid) { - if (remoteNode == null) return null; - try { - return remoteNode.getOnlineRemoteAddresses(targetAddress, groupid); - } catch (Exception e) { - logger.log(Level.WARNING, "remote " + targetAddress + " websocket getOnlineRemoteAddresses error", e); - return null; - } - } - - /** - * 获取在线用户的节点地址列表 - * - * @param groupid groupid - * @return 地址列表 - */ - public Collection getOnlineNodes(final Serializable groupid) { - return source.getCollection(groupid); - } - - /** - * 获取在线用户的详细连接信息 - * - * @param groupid groupid - * @return 地址集合 - */ - public Map> getOnlineRemoteAddress(final Serializable groupid) { - Collection nodes = getOnlineNodes(groupid); - if (nodes == null) return null; - final Map> map = new HashMap(); - for (InetSocketAddress nodeAddress : nodes) { - List list = getOnlineRemoteAddresses(nodeAddress, groupid); - if (list == null) list = new ArrayList(); - map.put(nodeAddress, list); - } - return map; - } - - public final void connect(Serializable groupid, String engineid, String wsinfo) { - if (finest) logger.finest(localSncpAddress + " receive websocket connect event (" + groupid + " on " + engineid + ")."); - Set engineids = localNodes.get(groupid); - if (engineids == null) { - engineids = new CopyOnWriteArraySet<>(); - localNodes.putIfAbsent(groupid, engineids); - } - if (localSncpAddress != null && engineids.isEmpty()) connect(groupid, localSncpAddress); - engineids.add(engineid); - } - - public final void disconnect(Serializable groupid, String engineid) { - if (finest) logger.finest(localSncpAddress + " receive websocket disconnect event (" + groupid + " on " + engineid + ")."); - Set engineids = localNodes.get(groupid); - if (engineids == null || engineids.isEmpty()) return; - engineids.remove(engineid); - if (engineids.isEmpty()) { - localNodes.remove(groupid); - if (localSncpAddress != null) disconnect(groupid, localSncpAddress); - } - } - - final void putWebSocketEngine(WebSocketEngine engine) { - engines.put(engine.getEngineid(), engine); - } - - public final int sendMessage(Serializable groupid, boolean recent, Serializable message, boolean last) { - final Set engineids = localNodes.get(groupid); - if (finest) logger.finest("websocket want send message {groupid:" + groupid + ", content:'" + message + "'} from locale node to " + engineids); - int rscode = RETCODE_GROUP_EMPTY; - if (engineids != null && !engineids.isEmpty()) { - for (String engineid : engineids) { - final WebSocketEngine engine = engines.get(engineid); - if (engine != null) { //在本地 - final WebSocketGroup group = engine.getWebSocketGroup(groupid); - if (group == null || group.isEmpty()) { - engineids.remove(engineid); - if (finest) logger.finest("websocket want send message {engineid:'" + engineid + "', groupid:" + groupid + ", content:'" + message + "'} but websocket group is empty "); - rscode = RETCODE_GROUP_EMPTY; - break; - } - rscode = group.send(recent, message, last); - } - } - } - if ((recent && rscode == 0) || remoteNode == null) { - if (finest) { - if ((recent && rscode == 0)) { - logger.finest("websocket want send recent message success"); - } else { - logger.finest("websocket remote node is null"); - } - } - return rscode; - } - //-----------------------发送远程的----------------------------- - Collection addrs = source.getCollection(groupid); - if (finest) logger.finest("websocket found groupid:" + groupid + " on " + addrs); - if (addrs != null && !addrs.isEmpty()) { //对方连接在远程节点(包含本地节点),所以正常情况下addrs不会为空。 - if (recent) { - InetSocketAddress one = null; - for (InetSocketAddress addr : addrs) { - one = addr; - } - rscode = remoteNode.sendMessage(one, groupid, recent, message, last); - } else { - for (InetSocketAddress addr : addrs) { - if (!addr.equals(localSncpAddress)) { - rscode |= remoteNode.sendMessage(addr, groupid, recent, message, last); - } - } - } - } else { - rscode = RETCODE_GROUP_EMPTY; - } - return rscode; - } - - //-------------------------------------------------------------------------------- - public final int sendEachMessage(Serializable groupid, String text) { - return sendMessage(groupid, false, text); - } - - public final int sendEachMessage(Serializable groupid, String text, boolean last) { - return sendMessage(groupid, false, text, last); - } - - public final int sendRecentMessage(Serializable groupid, String text) { - return sendMessage(groupid, true, text); - } - - public final int sendRecentMessage(Serializable groupid, String text, boolean last) { - return sendMessage(groupid, true, text, last); - } - - public final int sendMessage(Serializable groupid, boolean recent, String text) { - return sendMessage(groupid, recent, text, true); - } - - public final int sendMessage(Serializable groupid, boolean recent, String text, boolean last) { - return sendMessage(groupid, recent, (Serializable) text, last); - } - - //-------------------------------------------------------------------------------- - public final int sendEachMessage(Serializable groupid, byte[] data) { - return sendMessage(groupid, false, data); - } - - public final int sendEachMessage(Serializable groupid, byte[] data, boolean last) { - return sendMessage(groupid, false, data, last); - } - - public final int sendRecentMessage(Serializable groupid, byte[] data) { - return sendMessage(groupid, true, data); - } - - public final int sendRecentMessage(Serializable groupid, byte[] data, boolean last) { - return sendMessage(groupid, true, data, last); - } - - public final int sendMessage(Serializable groupid, boolean recent, byte[] data) { - return sendMessage(groupid, recent, data, true); - } - - public final int sendMessage(Serializable groupid, boolean recent, byte[] data, boolean last) { - return sendMessage(groupid, recent, (Serializable) data, last); - } -} diff --git a/src/main/java/org/redkale/net/http/WebSocketPacket.java b/src/main/java/org/redkale/net/http/WebSocketPacket.java deleted file mode 100644 index e5fd02622..000000000 --- a/src/main/java/org/redkale/net/http/WebSocketPacket.java +++ /dev/null @@ -1,123 +0,0 @@ -/* - * 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.http; - -import org.redkale.util.Utility; -import java.io.*; - -/** - * - *

详情见: http://www.redkale.org - * @author zhangjx - */ -public final class WebSocketPacket { - - public static final WebSocketPacket DEFAULT_PING_PACKET = new WebSocketPacket(FrameType.PING, new byte[0]); - - public static enum FrameType { - - TEXT(0x01), BINARY(0x02), CLOSE(0x08), PING(0x09), PONG(0x0A); - - private final int value; - - private FrameType(int v) { - this.value = v; - } - - public int getValue() { - return value; - } - - public static FrameType valueOf(int v) { - switch (v) { - case 0x01: return TEXT; - case 0x02: return BINARY; - case 0x08: return CLOSE; - case 0x09: return PING; - case 0x0A: return PONG; - default: return null; - } - } - } - - protected FrameType type; - - protected String payload; - - protected byte[] bytes; - - protected boolean last = true; - - public WebSocketPacket() { - } - - public WebSocketPacket(String payload) { - this(payload, true); - } - - public WebSocketPacket(Serializable message, boolean fin) { - boolean bin = message != null && message.getClass() == byte[].class; - if (bin) { - this.type = FrameType.BINARY; - this.bytes = (byte[]) message; - } else { - this.type = FrameType.TEXT; - this.payload = String.valueOf(message); - } - this.last = fin; - } - - public WebSocketPacket(String payload, boolean fin) { - this.type = FrameType.TEXT; - this.payload = payload; - this.last = fin; - } - - public WebSocketPacket(byte[] data) { - this(FrameType.BINARY, data, true); - } - - public WebSocketPacket(byte[] data, boolean fin) { - this(FrameType.BINARY, data, fin); - } - - public WebSocketPacket(FrameType type, byte[] data) { - this(type, data, true); - } - - public WebSocketPacket(FrameType type, byte[] data, boolean fin) { - this.type = type; - if (type == FrameType.TEXT) { - this.payload = new String(Utility.decodeUTF8(data)); - } else { - this.bytes = data; - } - this.last = fin; - } - - public byte[] getContent() { - if (this.type == FrameType.TEXT) return Utility.encodeUTF8(getPayload()); - if (this.bytes == null) return new byte[0]; - return this.bytes; - } - - public String getPayload() { - return payload; - } - - public byte[] getBytes() { - return bytes; - } - - public boolean isLast() { - return last; - } - - @Override - public String toString() { - return this.getClass().getSimpleName() + "[type=" + type + ", last=" + last + (payload != null ? (", payload=" + payload) : "") + (bytes != null ? (", bytes=[" + bytes.length + ']') : "") + "]"; - } -} diff --git a/src/main/java/org/redkale/net/http/WebSocketRunner.java b/src/main/java/org/redkale/net/http/WebSocketRunner.java deleted file mode 100644 index 362ae707d..000000000 --- a/src/main/java/org/redkale/net/http/WebSocketRunner.java +++ /dev/null @@ -1,526 +0,0 @@ -/* - * 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.http; - -import org.redkale.net.AsyncConnection; -import org.redkale.net.Context; -import static org.redkale.net.http.WebSocket.*; -import org.redkale.net.http.WebSocketPacket.FrameType; -import java.nio.ByteBuffer; -import java.nio.channels.*; -import java.security.SecureRandom; -import java.util.*; -import java.util.concurrent.*; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.logging.*; - -/** - * - *

详情见: http://www.redkale.org - * @author zhangjx - */ -public class WebSocketRunner implements Runnable { - - private final WebSocketEngine engine; - - private final AsyncConnection channel; - - private final WebSocket webSocket; - - protected final Context context; - - private ByteBuffer readBuffer; - - private ByteBuffer writeBuffer; - - protected boolean closed = false; - - private AtomicBoolean writing = new AtomicBoolean(); - - private final Coder coder = new Coder(); - - private final BlockingQueue queue = new ArrayBlockingQueue(1024); - - private final boolean wsbinary; - - public WebSocketRunner(Context context, WebSocket webSocket, AsyncConnection channel, final boolean wsbinary) { - this.context = context; - this.engine = webSocket._engine; - this.webSocket = webSocket; - this.channel = channel; - this.wsbinary = wsbinary; - webSocket._runner = this; - this.coder.logger = context.getLogger(); - this.coder.debugable = false;//context.getLogger().isLoggable(Level.FINEST); - this.readBuffer = context.pollBuffer(); - this.writeBuffer = context.pollBuffer(); - } - - @Override - public void run() { - final boolean debug = this.coder.debugable; - try { - webSocket.onConnected(); - channel.setReadTimeoutSecond(300); //读取超时5分钟 - if (channel.isOpen()) { - if (wsbinary) { - webSocket.onRead(channel); - return; - } - channel.read(readBuffer, null, new CompletionHandler() { - - private ByteBuffer recentExBuffer; - - //当接收的数据流长度大于ByteBuffer长度时, 则需要额外的ByteBuffer 辅助; - private final List readBuffers = new ArrayList<>(); - - @Override - public void completed(Integer count, Void attachment1) { - if (count < 1 && readBuffers.isEmpty()) { - closeRunner(); - if (debug) context.getLogger().log(Level.FINEST, "WebSocketRunner abort on read buffer count, force to close channel, live " + (System.currentTimeMillis() - webSocket.getCreatetime()) / 1000 + " seconds"); - return; - } - if (readBuffer == null) return; - if (!readBuffer.hasRemaining() && (recentExBuffer == null || !recentExBuffer.hasRemaining())) { - final ByteBuffer buffer = context.pollBuffer(); - recentExBuffer = buffer; - readBuffers.add(buffer); - channel.read(buffer, null, this); - return; - } - readBuffer.flip(); - try { - ByteBuffer[] exBuffers = null; - if (!readBuffers.isEmpty()) { - exBuffers = readBuffers.toArray(new ByteBuffer[readBuffers.size()]); - readBuffers.clear(); - recentExBuffer = null; - for (ByteBuffer b : exBuffers) { - b.flip(); - } - } - WebSocketPacket packet = coder.decode(readBuffer, exBuffers); - if (exBuffers != null) { - for (ByteBuffer b : exBuffers) { - context.offerBuffer(b); - } - } - if (packet == null) { - failed(null, attachment1); - if (debug) context.getLogger().log(Level.FINEST, "WebSocketRunner abort on decode WebSocketPacket, force to close channel, live " + (System.currentTimeMillis() - webSocket.getCreatetime()) / 1000 + " seconds"); - return; - } - if (readBuffer != null) { - readBuffer.clear(); - channel.read(readBuffer, null, this); - } - webSocket._group.setRecentWebSocket(webSocket); - try { - if (packet.type == FrameType.TEXT) { - webSocket.onMessage(packet.getPayload()); - } else if (packet.type == FrameType.BINARY) { - webSocket.onMessage(packet.getBytes()); - } else if (packet.type == FrameType.PONG) { - webSocket.onPong(packet.getBytes()); - } else if (packet.type == FrameType.PING) { - webSocket.onPing(packet.getBytes()); - } - } catch (Exception e) { - context.getLogger().log(Level.INFO, "WebSocket onMessage error (" + packet + ")", e); - } - } catch (Throwable t) { - closeRunner(); - if (debug) context.getLogger().log(Level.FINEST, "WebSocketRunner abort on read WebSocketPacket, force to close channel, live " + (System.currentTimeMillis() - webSocket.getCreatetime()) / 1000 + " seconds", t); - } - } - - @Override - public void failed(Throwable exc, Void attachment2) { - closeRunner(); - if (exc != null) { - context.getLogger().log(Level.FINEST, "WebSocketRunner read WebSocketPacket failed, force to close channel, live " + (System.currentTimeMillis() - webSocket.getCreatetime()) / 1000 + " seconds", exc); - } - } - }); - } else { - closeRunner(); - context.getLogger().log(Level.FINEST, "WebSocketRunner abort by AsyncConnection closed"); - } - } catch (Exception e) { - closeRunner(); - context.getLogger().log(Level.FINEST, "WebSocketRunner abort on read bytes from channel, force to close channel, live " + (System.currentTimeMillis() - webSocket.getCreatetime()) / 1000 + " seconds", e); - } - } - - public int sendMessage(WebSocketPacket packet) { - if (packet == null) return RETCODE_SEND_ILLPACKET; - if (closed) return RETCODE_WSOCKET_CLOSED; - final boolean debug = this.coder.debugable; - //System.out.println("推送消息"); - final byte[] bytes = coder.encode(packet); - if (debug) context.getLogger().log(Level.FINEST, "send web socket message's length = " + bytes.length); - if (writing.getAndSet(true)) { - queue.add(bytes); - return 0; - } - if (writeBuffer == null) return RETCODE_ILLEGALBUFFER; - ByteBuffer sendBuffer = null; - if (bytes.length <= writeBuffer.capacity()) { - writeBuffer.clear(); - writeBuffer.put(bytes); - writeBuffer.flip(); - sendBuffer = writeBuffer; - } else { - sendBuffer = ByteBuffer.wrap(bytes); - } - try { - channel.write(sendBuffer, sendBuffer, new CompletionHandler() { - - @Override - public void completed(Integer result, ByteBuffer attachment) { - if (attachment == null || closed) return; - try { - if (attachment.hasRemaining()) { - if (debug) context.getLogger().log(Level.FINEST, "WebSocketRunner write completed reemaining: " + attachment.remaining()); - channel.write(attachment, attachment, this); - return; - } - byte[] bs = queue.poll(); - if (bs != null && writeBuffer != null) { - ByteBuffer sendBuffer; - if (bs.length <= writeBuffer.capacity()) { - writeBuffer.clear(); - writeBuffer.put(bs); - writeBuffer.flip(); - sendBuffer = writeBuffer; - } else { - sendBuffer = ByteBuffer.wrap(bs); - } - channel.write(sendBuffer, sendBuffer, this); - return; - } - } catch (NullPointerException e) { - } catch (Exception e) { - closeRunner(); - context.getLogger().log(Level.WARNING, "WebSocket sendMessage abort on rewrite, force to close channel, live " + (System.currentTimeMillis() - webSocket.getCreatetime()) / 1000 + " seconds", e); - } - writing.set(false); - } - - @Override - public void failed(Throwable exc, ByteBuffer attachment) { - writing.set(false); - closeRunner(); - if (exc != null) { - context.getLogger().log(Level.FINE, "WebSocket sendMessage on CompletionHandler failed, force to close channel, live " + (System.currentTimeMillis() - webSocket.getCreatetime()) / 1000 + " seconds", exc); - } - } - }); - return 0; - } catch (Exception t) { - writing.set(false); - closeRunner(); - context.getLogger().log(Level.FINE, "WebSocket sendMessage abort, force to close channel, live " + (System.currentTimeMillis() - webSocket.getCreatetime()) / 1000 + " seconds", t); - return RETCODE_SENDEXCEPTION; - } - } - - public void closeRunner() { - if (closed) return; - synchronized (this) { - if (closed) return; - closed = true; - try { - channel.close(); - } catch (Throwable t) { - } - context.offerBuffer(readBuffer); - context.offerBuffer(writeBuffer); - readBuffer = null; - writeBuffer = null; - engine.remove(webSocket); - webSocket.onClose(0, null); - } - } - - private static final class Masker { - - public static final int MASK_SIZE = 4; - - private ByteBuffer buffer; - - private ByteBuffer[] exbuffers; - - private byte[] mask; - - private int index = 0; - - public Masker(ByteBuffer buffer, ByteBuffer... exbuffers) { - this.buffer = buffer; - this.exbuffers = exbuffers == null || exbuffers.length == 0 ? null : exbuffers; - } - - public Masker() { - generateMask(); - } - - public int remaining() { - int r = buffer.remaining(); - if (exbuffers != null) { - for (ByteBuffer b : exbuffers) { - r += b.remaining(); - } - } - return r; - } - - public byte get() { - return buffer.get(); - } - - public byte[] get(final int size) { - byte[] bytes = new byte[size]; - if (buffer.remaining() >= size) { - buffer.get(bytes); - } else { //必须有 exbuffers - int offset = buffer.remaining(); - buffer.get(bytes, 0, buffer.remaining()); - for (ByteBuffer b : exbuffers) { - b.get(bytes, offset, b.remaining()); - offset += b.remaining(); - } - } - return bytes; - } - - public byte unmask() { - final byte b = get(); - return mask == null ? b : (byte) (b ^ mask[index++ % MASK_SIZE]); - } - - public byte[] unmask(int count) { - byte[] bytes = get(count); - if (mask != null) { - for (int i = 0; i < bytes.length; i++) { - bytes[i] ^= mask[index++ % MASK_SIZE]; - } - } - - return bytes; - } - - public void generateMask() { - mask = new byte[MASK_SIZE]; - new SecureRandom().nextBytes(mask); - } - - public void mask(byte[] bytes, int location, byte b) { - bytes[location] = mask == null ? b : (byte) (b ^ mask[index++ % MASK_SIZE]); - } - - public void mask(byte[] target, int location, byte[] bytes) { - if (bytes != null && target != null) { - for (int i = 0; i < bytes.length; i++) { - target[location + i] = mask == null ? bytes[i] : (byte) (bytes[i] ^ mask[index++ % MASK_SIZE]); - } - } - } - - public byte[] maskAndPrepend(byte[] packet) { - byte[] masked = new byte[packet.length + MASK_SIZE]; - System.arraycopy(getMask(), 0, masked, 0, MASK_SIZE); - mask(masked, MASK_SIZE, packet); - return masked; - } - - public void setBuffer(ByteBuffer buffer) { - this.buffer = buffer; - } - - public byte[] getMask() { - return mask; - } - - public void readMask() { - mask = get(MASK_SIZE); - } - } - - private static final class Coder { - - protected byte inFragmentedType; - - protected byte outFragmentedType; - - protected final boolean maskData = false; - - protected boolean processingFragment; - - private boolean debugable; - - private Logger logger; - - /** - * 0 1 2 3 - * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 - * +-+-+-+-+-------+-+-------------+-------------------------------+ - * |F|R|R|R| opcode|M| Payload len | Extended payload length | - * |I|S|S|S| (4) |A| (7) | (16/64) | - * |N|V|V|V| |S| | (if payload len==126/127) | - * | |1|2|3| |K| | | - * +-+-+-+-+-------+-+-------------+ - - - - - - - - - - - - - - - + - * | Extended payload length continued, if payload len == 127 | - * + - - - - - - - - - - - - - - - +-------------------------------+ - * | |Masking-key, if MASK set to 1 | - * +-------------------------------+-------------------------------+ - * | Masking-key (continued) | Payload Data | - * +-------------------------------- - - - - - - - - - - - - - - - + - * : Payload Data continued : - * + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - * | Payload Data continued | - * +-----------------------------------------------------------------------+ - * - * @param buffer - * @param exbuffers - * @return - */ - public WebSocketPacket decode(final ByteBuffer buffer, ByteBuffer... exbuffers) { - final boolean debug = this.debugable; - if (debug) { - int remain = buffer.remaining(); - if (exbuffers != null) { - for (ByteBuffer b : exbuffers) { - remain += b == null ? 0 : b.remaining(); - } - } - logger.log(Level.FINEST, "read web socket message's length = " + remain); - } - if (buffer.remaining() < 2) return null; - byte opcode = buffer.get(); - final boolean last = (opcode & 0b1000000) != 0; - final boolean checkrsv = false;//暂时不校验 - if (checkrsv && (opcode & 0b01110000) != 0) { - if (debug) logger.log(Level.FINE, "rsv1 rsv2 rsv3 must be 0, but not (" + opcode + ")"); - return null; //rsv1 rsv2 rsv3 must be 0 - } - //0x00 表示一个后续帧 - //0x01 表示一个文本帧 - //0x02 表示一个二进制帧 - //0x03-07 为以后的非控制帧保留 - //0x8 表示一个连接关闭 - //0x9 表示一个ping - //0xA 表示一个pong - //0x0B-0F 为以后的控制帧保留 - final boolean control = (opcode & 0x08) == 0x08; //是否控制帧 - //final boolean continuation = opcode == 0; - FrameType type = FrameType.valueOf(opcode & 0xf); - if (type == FrameType.CLOSE) { - if (debug) logger.log(Level.FINEST, " receive close command from websocket client"); - return null; - } - byte lengthCode = buffer.get(); - final Masker masker = new Masker(buffer, exbuffers); - final boolean masked = (lengthCode & 0x80) == 0x80; - if (masked) lengthCode ^= 0x80; //mask - int length; - if (lengthCode <= 125) { - length = lengthCode; - } else { - if (control) { - if (debug) logger.log(Level.FINE, " receive control command from websocket client"); - return null; - } - - final int lengthBytes = lengthCode == 126 ? 2 : 8; - if (buffer.remaining() < lengthBytes) { - if (debug) logger.log(Level.FINE, " read illegal message length from websocket, expect " + lengthBytes + " but " + buffer.remaining()); - return null; - } - length = toInt(masker.unmask(lengthBytes)); - } - if (masked) { - if (buffer.remaining() < Masker.MASK_SIZE) { - if (debug) logger.log(Level.FINE, " read illegal masker length from websocket, expect " + Masker.MASK_SIZE + " but " + buffer.remaining()); - return null; - } - masker.readMask(); - } - if (masker.remaining() < length) { - if (debug) logger.log(Level.FINE, " read illegal remaining length from websocket, expect " + length + " but " + masker.remaining()); - return null; - } - final byte[] data = masker.unmask(length); - if (data.length != length) { - if (debug) logger.log(Level.FINE, " read illegal unmask length from websocket, expect " + length + " but " + data.length); - return null; - } - return new WebSocketPacket(type, data, last); - } - - public byte[] encode(WebSocketPacket frame) { - byte opcode = (byte) (frame.type.getValue() | 0x80); - final byte[] bytes = frame.getContent(); - final byte[] lengthBytes = encodeLength(bytes.length); - - int length = 1 + lengthBytes.length + bytes.length + (maskData ? Masker.MASK_SIZE : 0); - int payloadStart = 1 + lengthBytes.length + (maskData ? Masker.MASK_SIZE : 0); - final byte[] packet = new byte[length]; - packet[0] = opcode; - System.arraycopy(lengthBytes, 0, packet, 1, lengthBytes.length); - if (maskData) { - Masker masker = new Masker(); - packet[1] |= 0x80; - masker.mask(packet, payloadStart, bytes); - System.arraycopy(masker.getMask(), 0, packet, payloadStart - Masker.MASK_SIZE, Masker.MASK_SIZE); - } else { - System.arraycopy(bytes, 0, packet, payloadStart, bytes.length); - } - return packet; - } - - private static byte[] encodeLength(final int length) { - byte[] lengthBytes; - if (length <= 125) { - lengthBytes = new byte[1]; - lengthBytes[0] = (byte) length; - } else { - byte[] b = toArray(length); - if (length <= 0xFFFF) { - lengthBytes = new byte[3]; - lengthBytes[0] = 126; - System.arraycopy(b, 6, lengthBytes, 1, 2); - } else { - lengthBytes = new byte[9]; - lengthBytes[0] = 127; - System.arraycopy(b, 0, lengthBytes, 1, 8); - } - } - return lengthBytes; - } - - private static byte[] toArray(long length) { - long value = length; - byte[] b = new byte[8]; - for (int i = 7; i >= 0 && value > 0; i--) { - b[i] = (byte) (value & 0xFF); - value >>= 8; - } - return b; - } - - private static int toInt(byte[] bytes) { - int value = 0; - for (int i = 0; i < bytes.length; i++) { - value <<= 8; - value ^= (int) bytes[i] & 0xFF; - } - return value; - } - - } - -} diff --git a/src/main/java/org/redkale/net/http/WebSocketServlet.java b/src/main/java/org/redkale/net/http/WebSocketServlet.java deleted file mode 100644 index aace0cfee..000000000 --- a/src/main/java/org/redkale/net/http/WebSocketServlet.java +++ /dev/null @@ -1,148 +0,0 @@ -/* - * 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.http; - -import java.io.*; -import java.net.*; -import java.nio.*; -import java.nio.channels.*; -import java.security.*; -import java.util.*; -import java.util.logging.*; -import javax.annotation.*; -import org.redkale.util.*; - -/** - *

- * 当WebSocketServlet接收一个TCP连接后,进行协议判断,如果成功就会创建一个WebSocket。
- *
- *                                    WebSocketServlet
- *                                            |
- *                                            |
- *                                    WebSocketEngine
- *                                    /             \
- *                                 /                  \
- *                              /                       \
- *                     WebSocketGroup1            WebSocketGroup2
- *                        /        \                /        \
- *                      /           \             /           \
- *               WebSocket1     WebSocket2   WebSocket3    WebSocket4
- *
- * 
- * - *

- * 详情见: http://www.redkale.org - * - * @author zhangjx - */ -public abstract class WebSocketServlet extends HttpServlet { - - public static final String WEBPARAM__LIVEINTERVAL = "liveinterval"; - - public static final int DEFAILT_LIVEINTERVAL = 60; - - protected final Logger logger = Logger.getLogger(this.getClass().getSimpleName()); - - private final MessageDigest digest = getMessageDigest(); - - private static MessageDigest getMessageDigest() { - try { - return MessageDigest.getInstance("SHA-1"); - } catch (Exception e) { - throw new RuntimeException(e); - } - } - - //是否用于二进制流传输 - protected final boolean wsbinary = getClass().getAnnotation(WebSocketBinary.class) != null; - - @Resource(name = "$") - protected WebSocketNode node; - - protected WebSocketEngine engine; - - public final void preInit(HttpContext context, AnyValue conf) { - InetSocketAddress addr = context.getServerAddress(); - this.engine = new WebSocketEngine(addr.getHostString() + ":" + addr.getPort() + "-[" + name() + "]", this.node, logger); - this.node.putWebSocketEngine(engine); - this.node.init(conf); - this.engine.init(conf); - } - - public final void postDestroy(HttpContext context, AnyValue conf) { - this.node.destroy(conf); - super.destroy(context, conf); - engine.close(); - } - - public String name() { - return this.getClass().getSimpleName().replace("Servlet", "").replace("WebSocket", "").toLowerCase(); - } - - @Override - public final void execute(final HttpRequest request, final HttpResponse response) throws IOException { - final boolean debug = logger.isLoggable(Level.FINEST); - if (!"GET".equalsIgnoreCase(request.getMethod()) - || !request.getConnection().contains("Upgrade") - || !"websocket".equalsIgnoreCase(request.getHeader("Upgrade"))) { - if (debug) logger.finest("WebSocket connect abort, (Not GET Method) or (Connection != Upgrade) or (Upgrade != websocket). request=" + request); - response.finish(true); - return; - } - String key = request.getHeader("Sec-WebSocket-Key"); - if (key == null) { - if (debug) logger.finest("WebSocket connect abort, Not found Sec-WebSocket-Key header. request=" + request); - response.finish(true); - return; - } - final WebSocket webSocket = this.createWebSocket(); - webSocket._engine = engine; - webSocket._remoteAddress = request.getRemoteAddress(); - webSocket._remoteAddr = request.getRemoteAddr(); - Serializable sessionid = webSocket.onOpen(request); - if (sessionid == null) { - if (debug) logger.finest("WebSocket connect abort, Not found sessionid. request=" + request); - response.finish(true); - return; - } - webSocket._sessionid = sessionid; - request.setKeepAlive(true); - byte[] bytes = (key + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11").getBytes(); - synchronized (digest) { - bytes = digest.digest(bytes); - } - key = Base64.getEncoder().encodeToString(bytes); - response.setStatus(101); - response.setHeader("Connection", "Upgrade"); - response.addHeader("Upgrade", "websocket"); - response.addHeader("Sec-WebSocket-Accept", key); - response.sendBody((ByteBuffer) null, null, new CompletionHandler() { - - @Override - public void completed(Integer result, Void attachment) { - HttpContext context = response.getContext(); - Serializable groupid = webSocket.createGroupid(); - if (groupid == null) { - if (debug) logger.finest("WebSocket connect abort, Create groupid abort. request = " + request); - response.finish(true); - return; - } - webSocket._groupid = groupid; - engine.add(webSocket); - context.submit(new WebSocketRunner(context, webSocket, response.removeChannel(), wsbinary)); - response.finish(true); - } - - @Override - public void failed(Throwable exc, Void attachment) { - logger.log(Level.FINEST, "WebSocket connect abort, Response send abort. request = " + request, exc); - response.finish(true); - } - }); - } - - protected abstract WebSocket createWebSocket(); -} diff --git a/src/main/java/org/redkale/net/http/package-info.java b/src/main/java/org/redkale/net/http/package-info.java deleted file mode 100644 index 3d749a21f..000000000 --- a/src/main/java/org/redkale/net/http/package-info.java +++ /dev/null @@ -1,4 +0,0 @@ -/** - * HTTP协议包,提供HTTP协议服务器 - */ -package org.redkale.net.http; diff --git a/src/main/java/org/redkale/net/package-info.java b/src/main/java/org/redkale/net/package-info.java deleted file mode 100644 index 5f10d5ca0..000000000 --- a/src/main/java/org/redkale/net/package-info.java +++ /dev/null @@ -1,4 +0,0 @@ -/** - * 网络TCP/UDP基础服务包 - */ -package org.redkale.net; diff --git a/src/main/java/org/redkale/net/sncp/ServiceWrapper.java b/src/main/java/org/redkale/net/sncp/ServiceWrapper.java deleted file mode 100644 index 072666f84..000000000 --- a/src/main/java/org/redkale/net/sncp/ServiceWrapper.java +++ /dev/null @@ -1,143 +0,0 @@ -/* - * 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.sncp; - -import org.redkale.service.Service; -import org.redkale.util.AnyValue; -import java.util.*; -import java.util.stream.*; -import org.redkale.util.*; - -/** - * Service对象的封装类 - * - *

- * 详情见: http://www.redkale.org - * - * @author zhangjx - * @param Service的子类 - */ -public final class ServiceWrapper implements Comparable { - - private static volatile int maxClassNameLength = 0; - - private static volatile int maxNameLength = 0; - - private final T service; - - private final AnyValue conf; - - private final String sncpGroup; //自身的组节点名 可能为null - - private final Set groups; //所有的组节点,包含自身 - - private final String name; - - private final boolean remote; - - private final Class[] types; - - @SuppressWarnings("unchecked") - public ServiceWrapper(Class type, T service, String name, String sncpGroup, Set groups, AnyValue conf) { - this.service = service; - this.conf = conf; - this.sncpGroup = sncpGroup; - this.groups = groups; - this.name = name; - this.remote = Sncp.isRemote(service); - ResourceType rty = service.getClass().getAnnotation(ResourceType.class); - this.types = rty == null ? new Class[]{type == null ? (Class) service.getClass() : type} : rty.value(); - - maxNameLength = Math.max(maxNameLength, name.length()); - StringBuilder s = new StringBuilder(); - if (this.types.length == 1) { - s.append(types[0].getName()); - } else { - s.append('['); - s.append(Arrays.asList(this.types).stream().map((Class t) -> t.getName()).collect(Collectors.joining(","))); - s.append(']'); - } - maxClassNameLength = Math.max(maxClassNameLength, s.length() + 1); - } - - public String toSimpleString() { - StringBuilder sb = new StringBuilder(); - sb.append(remote ? "RemoteService" : "LocalService "); - int len; - if (types.length == 1) { - sb.append("(type= ").append(types[0].getName()); - len = maxClassNameLength - types[0].getName().length(); - } else { - StringBuilder s = new StringBuilder(); - s.append('['); - s.append(Arrays.asList(this.types).stream().map((Class t) -> t.getName()).collect(Collectors.joining(","))); - s.append(']'); - sb.append("(types=").append(s); - len = maxClassNameLength - s.length(); - } - - for (int i = 0; i < len; i++) { - sb.append(' '); - } - sb.append(", name='").append(name).append("'"); - for (int i = 0; i < maxNameLength - name.length(); i++) { - sb.append(' '); - } - sb.append(")"); - return sb.toString(); - } - - @Override - public boolean equals(Object obj) { - if (obj == this) return true; - if (obj == null) return false; - if (!(obj instanceof ServiceWrapper)) return false; - ServiceWrapper other = (ServiceWrapper) obj; - return (this.types[0].equals(other.types[0]) && this.remote == other.remote && this.name.equals(other.name) && Objects.equals(this.sncpGroup, other.sncpGroup)); - } - - @Override - public int hashCode() { - int hash = 3; - hash = 67 * hash + Objects.hashCode(this.types[0]); - hash = 67 * hash + Objects.hashCode(this.sncpGroup); - hash = 67 * hash + Objects.hashCode(this.name); - hash = 67 * hash + (this.remote ? 1 : 0); - return hash; - } - - @Override - public int compareTo(ServiceWrapper o) { - int rs = this.types[0].getName().compareTo(o.types[0].getName()); - if (rs == 0) rs = this.name.compareTo(o.name); - return rs; - } - - public Class[] getTypes() { - return types; - } - - public Service getService() { - return service; - } - - public AnyValue getConf() { - return conf; - } - - public String getName() { - return name; - } - - public boolean isRemote() { - return remote; - } - - public Set getGroups() { - return groups; - } - -} diff --git a/src/main/java/org/redkale/net/sncp/Sncp.java b/src/main/java/org/redkale/net/sncp/Sncp.java deleted file mode 100644 index 27b50a267..000000000 --- a/src/main/java/org/redkale/net/sncp/Sncp.java +++ /dev/null @@ -1,1102 +0,0 @@ -/* - * 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.sncp; - -import org.redkale.net.sncp.SncpClient.SncpAction; -import java.lang.annotation.*; -import java.lang.reflect.*; -import java.net.*; -import java.security.*; -import java.util.*; -import java.util.function.*; -import jdk.internal.org.objectweb.asm.*; -import static jdk.internal.org.objectweb.asm.ClassWriter.COMPUTE_FRAMES; -import static jdk.internal.org.objectweb.asm.Opcodes.*; -import jdk.internal.org.objectweb.asm.Type; -import org.redkale.convert.bson.*; -import org.redkale.net.*; -import org.redkale.service.*; -import org.redkale.util.*; -import org.redkale.service.DynRemote; - -/** - * Service Node Communicate Protocol - * 生成Service的本地模式或远程模式Service-Class的工具类 - * - *

- * 详情见: http://www.redkale.org - * - * @author zhangjx - */ -public abstract class Sncp { - - static final String LOCALPREFIX = "_DynLocal"; - - static final String REMOTEPREFIX = "_DynRemote"; - - private static final MessageDigest md5; - - static { //64进制 - MessageDigest d = null; - try { - d = MessageDigest.getInstance("MD5"); - } catch (NoSuchAlgorithmException ex) { - ex.printStackTrace(); - } - md5 = d; - } - - private Sncp() { - } - - public static long nodeid(InetSocketAddress ip) { - byte[] bytes = ip.getAddress().getAddress(); - return ((0L + ip.getPort()) << 32) | ((0xffffffff & bytes[0]) << 24) | ((0xffffff & bytes[1]) << 16) | ((0xffff & bytes[2]) << 8) | (0xff & bytes[3]); - } - - public static DLong hash(final java.lang.reflect.Method method) { - if (method == null) return DLong.ZERO; - StringBuilder sb = new StringBuilder(); //不能使用method.toString() 因为包含declaringClass信息导致接口与实现类的方法hash不一致 - sb.append(method.getReturnType().getName()).append(' '); - sb.append(method.getName()); - sb.append('('); - boolean first = true; - for (Class pt : method.getParameterTypes()) { - if (!first) sb.append(','); - sb.append(pt.getName()); - first = false; - } - sb.append(')'); - return hash(sb.toString()); - } - - /** - * 对类名或者name字符串进行hash。 - * - * @param name String - * @return hash值 - */ - public static DLong hash(final String name) { - if (name == null || name.isEmpty()) return DLong.ZERO; - byte[] bytes = name.trim().getBytes(); - synchronized (md5) { - bytes = md5.digest(bytes); - } - return DLong.create(bytes); - } - - public static boolean isRemote(Service service) { - SncpDyn dyn = service.getClass().getAnnotation(SncpDyn.class); - return dyn != null && dyn.remote(); - } - - /** - *

-     * public class TestService implements Service{
-     *
-     *      public String findSomeThing(){
-     *          return "hello";
-     *      }
-     *
-     *      @MultiRun(selfrun = false)
-     *      public void createSomeThing(TestBean bean){
-     *          //do something
-     *      }
-     *
-     *      @MultiRun
-     *      public String updateSomeThing(String id){
-     *          return "hello" + id;
-     *      }
-     * }
-     * 
- * - *
-     * @Resource(name = "")
-     * @SncpDyn(remote = false)
-     * @ResourceType({TestService.class})
-     * public final class _DynLocalTestService extends TestService{
-     *
-     *      @Resource
-     *      private BsonConvert _convert;
-     *
-     *      private Transport _sameGroupTransport;
-     *
-     *      private Transport[] _diffGroupTransports;
-     *
-     *      private SncpClient _client;
-     *
-     *      private String _selfstring;
-     *
-     *      @Override
-     *      public String toString() {
-     *          return _selfstring == null ? super.toString() : _selfstring;
-     *      }
-     *
-     *      @Override
-     *      public void createSomeThing(TestBean bean){
-     *          this._createSomeThing(false, true, true, bean);
-     *      }
-     *
-     *      @SncpDyn(remote = false, index = 0)
-     *      public void _createSomeThing(boolean selfrunnable, boolean samerunnable, boolean diffrunnable, TestBean bean){
-     *          if(selfrunnable) super.createSomeThing(bean);
-     *          if (_client== null) return;
-     *          if (samerunnable) _client.remoteSameGroup(_convert, _sameGroupTransport, 0, true, false, false, bean);
-     *          if (diffrunnable) _client.remoteDiffGroup(_convert, _diffGroupTransports, 0, true, true, false, bean);
-     *      }
-     *
-     *      @Override
-     *      public String updateSomeThing(String id){
-     *          return this._updateSomeThing(true, true, true, id);
-     *      }
-     *
-     *      @SncpDyn(remote = false, index = 1)
-     *      public String _updateSomeThing(boolean selfrunnable, boolean samerunnable, boolean diffrunnable, String id){
-     *          String rs = super.updateSomeThing(id);
-     *          if (_client== null) return;
-     *          if (samerunnable) _client.remoteSameGroup(_convert, _sameGroupTransport, 1, true, false, false, id);
-     *          if (diffrunnable) _client.remoteDiffGroup(_convert, _diffGroupTransports, 1, true, true, false, id);
-     *          return rs;
-     *      }
-     * }
-     * 
- * - * 创建Service的本地模式Class - * - * @param Service子类 - * @param name 资源名 - * @param serviceClass Service类 - * @return Service实例 - */ - @SuppressWarnings("unchecked") - protected static Class createLocalServiceClass(final String name, final Class serviceClass) { - if (serviceClass == null) return null; - if (!Service.class.isAssignableFrom(serviceClass)) return serviceClass; - int mod = serviceClass.getModifiers(); - if (!java.lang.reflect.Modifier.isPublic(mod)) return serviceClass; - if (java.lang.reflect.Modifier.isAbstract(mod)) return serviceClass; - final List methods = SncpClient.parseMethod(serviceClass); - final String supDynName = serviceClass.getName().replace('.', '/'); - final String clientName = SncpClient.class.getName().replace('.', '/'); - final String clientDesc = Type.getDescriptor(SncpClient.class); - final String convertDesc = Type.getDescriptor(BsonConvert.class); - final String sncpDynDesc = Type.getDescriptor(SncpDyn.class); - final String transportDesc = Type.getDescriptor(Transport.class); - final String transportsDesc = Type.getDescriptor(Transport[].class); - ClassLoader loader = Sncp.class.getClassLoader(); - String newDynName = supDynName.substring(0, supDynName.lastIndexOf('/') + 1) + LOCALPREFIX + serviceClass.getSimpleName(); - if (!name.isEmpty()) { - boolean normal = true; - for (char ch : name.toCharArray()) { - if (!((ch >= '0' && ch <= '9') || ch == '_' || (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z'))) normal = false; - } - newDynName += "_" + (normal ? name : hash(name)); - } - try { - return (Class) Class.forName(newDynName.replace('/', '.')); - } catch (Exception ex) { - } - //------------------------------------------------------------------------------ - ClassWriter cw = new ClassWriter(COMPUTE_FRAMES); - FieldVisitor fv; - AsmMethodVisitor mv; - AnnotationVisitor av0; - - cw.visit(V1_8, ACC_PUBLIC + ACC_FINAL + ACC_SUPER, newDynName, null, supDynName, null); - { - av0 = cw.visitAnnotation("Ljavax/annotation/Resource;", true); - av0.visit("name", name); - av0.visitEnd(); - } - { - av0 = cw.visitAnnotation(sncpDynDesc, true); - av0.visit("remote", Boolean.FALSE); - av0.visitEnd(); - } - { - av0 = cw.visitAnnotation(Type.getDescriptor(ResourceType.class), true); - { - AnnotationVisitor av1 = av0.visitArray("value"); - ResourceType rty = serviceClass.getAnnotation(ResourceType.class); - if (rty == null) { - av1.visit(null, Type.getType(Type.getDescriptor(serviceClass))); - } else { - for (Class cl : rty.value()) { - av1.visit(null, Type.getType(Type.getDescriptor(cl))); - } - } - av1.visitEnd(); - } - av0.visitEnd(); - } - - { - fv = cw.visitField(ACC_PRIVATE, "_convert", convertDesc, null, null); - av0 = fv.visitAnnotation("Ljavax/annotation/Resource;", true); - av0.visitEnd(); - fv.visitEnd(); - } - { - fv = cw.visitField(ACC_PRIVATE, "_sameGroupTransport", transportDesc, null, null); - fv.visitEnd(); - } - { - fv = cw.visitField(ACC_PRIVATE, "_diffGroupTransports", transportsDesc, null, null); - fv.visitEnd(); - } - { - fv = cw.visitField(ACC_PRIVATE, "_client", clientDesc, null, null); - fv.visitEnd(); - } - - { - fv = cw.visitField(ACC_PRIVATE, "_selfstring", "Ljava/lang/String;", null, null); - fv.visitEnd(); - } - { //构造函数 - mv = new AsmMethodVisitor(cw.visitMethod(ACC_PUBLIC, "", "()V", null, null)); - //mv.setDebug(true); - mv.visitVarInsn(ALOAD, 0); - mv.visitMethodInsn(INVOKESPECIAL, supDynName, "", "()V", false); - mv.visitInsn(RETURN); - mv.visitMaxs(1, 1); - mv.visitEnd(); - } - { // toString() - mv = new AsmMethodVisitor(cw.visitMethod(ACC_PUBLIC, "toString", "()Ljava/lang/String;", null, null)); - mv.visitVarInsn(ALOAD, 0); - mv.visitFieldInsn(GETFIELD, newDynName, "_selfstring", "Ljava/lang/String;"); - Label l1 = new Label(); - mv.visitJumpInsn(IFNONNULL, l1); - mv.visitVarInsn(ALOAD, 0); - mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "toString", "()Ljava/lang/String;", false); - Label l2 = new Label(); - mv.visitJumpInsn(GOTO, l2); - mv.visitLabel(l1); - mv.visitVarInsn(ALOAD, 0); - mv.visitFieldInsn(GETFIELD, newDynName, "_selfstring", "Ljava/lang/String;"); - mv.visitLabel(l2); - mv.visitInsn(ARETURN); - mv.visitMaxs(1, 1); - mv.visitEnd(); - } - int i = - 1; - for (final Method method : methods) { - final MultiRun mrun = method.getAnnotation(MultiRun.class); - if (mrun == null) continue; - final Class returnType = method.getReturnType(); - final String methodDesc = Type.getMethodDescriptor(method); - final Class[] paramtypes = method.getParameterTypes(); - final int index = ++i; - { //原始方法 - mv = new AsmMethodVisitor(cw.visitMethod(ACC_PUBLIC + (method.isVarArgs() ? ACC_VARARGS : 0), method.getName(), methodDesc, null, null)); - //mv.setDebug(true); - { //给参数加上 Annotation - final Annotation[][] anns = method.getParameterAnnotations(); - for (int k = 0; k < anns.length; k++) { - for (Annotation ann : anns[k]) { - if (ann instanceof SncpDyn || ann instanceof MultiRun) continue; //必须过滤掉 MultiRun、SncpDyn,否则生成远程模式Service时会出错 - visitAnnotation(mv.visitParameterAnnotation(k, Type.getDescriptor(ann.annotationType()), true), ann); - } - } - } - mv.visitVarInsn(ALOAD, 0); - mv.visitInsn(mrun.selfrun() ? ICONST_1 : ICONST_0); - mv.visitInsn(mrun.samerun() ? ICONST_1 : ICONST_0); - mv.visitInsn(mrun.diffrun() ? ICONST_1 : ICONST_0); - int varindex = 0; - for (Class pt : paramtypes) { - if (pt.isPrimitive()) { - if (pt == long.class) { - mv.visitVarInsn(LLOAD, ++varindex); - ++varindex; - } else if (pt == double.class) { - mv.visitVarInsn(DLOAD, ++varindex); - ++varindex; - } else if (pt == float.class) { - mv.visitVarInsn(FLOAD, ++varindex); - } else { - mv.visitVarInsn(ILOAD, ++varindex); - } - } else { - mv.visitVarInsn(ALOAD, ++varindex); - } - } - mv.visitMethodInsn(INVOKEVIRTUAL, newDynName, "_" + method.getName(), "(ZZZ" + methodDesc.substring(1), false); - if (returnType == void.class) { - mv.visitInsn(RETURN); - } else if (returnType.isPrimitive()) { - if (returnType == long.class) { - mv.visitInsn(LRETURN); - } else if (returnType == float.class) { - mv.visitInsn(FRETURN); - } else if (returnType == double.class) { - mv.visitInsn(DRETURN); - } else { - mv.visitInsn(IRETURN); - } - } else { - mv.visitInsn(ARETURN); - } - mv.visitMaxs(varindex + 3, varindex + 1); - mv.visitEnd(); - } - { // _方法 _方法比无_方法多了三个参数 - mv = new AsmMethodVisitor(cw.visitMethod(ACC_PUBLIC + (method.isVarArgs() ? ACC_VARARGS : 0), "_" + method.getName(), "(ZZZ" + methodDesc.substring(1), null, null)); - //mv.setDebug(true); - { //给参数加上 Annotation - final Annotation[][] anns = method.getParameterAnnotations(); - for (int k = 0; k < anns.length; k++) { - for (Annotation ann : anns[k]) { - if (ann instanceof SncpDyn || ann instanceof MultiRun) continue; //必须过滤掉 MultiRun、SncpDyn,否则生成远程模式Service时会出错 - visitAnnotation(mv.visitParameterAnnotation(k, Type.getDescriptor(ann.annotationType()), true), ann); - } - } - } - av0 = mv.visitAnnotation(sncpDynDesc, true); - av0.visit("remote", Boolean.FALSE); - av0.visit("index", index); - av0.visitEnd(); - //---------------------------- 调用selfrun --------------------------------- - Label selfLabel = new Label(); - if (returnType == void.class) { // if - mv.visitVarInsn(ILOAD, 1); - mv.visitJumpInsn(IFEQ, selfLabel); - } - mv.visitVarInsn(ALOAD, 0); - int varindex = 3; //空3给selfrunnable、samerunnable、diffrunnable - for (Class pt : paramtypes) { - if (pt.isPrimitive()) { - if (pt == long.class) { - mv.visitVarInsn(LLOAD, ++varindex); - ++varindex; - } else if (pt == double.class) { - mv.visitVarInsn(DLOAD, ++varindex); - ++varindex; - } else if (pt == float.class) { - mv.visitVarInsn(FLOAD, ++varindex); - } else { - mv.visitVarInsn(ILOAD, ++varindex); - } - } else { - mv.visitVarInsn(ALOAD, ++varindex); - } - } - mv.visitMethodInsn(INVOKESPECIAL, supDynName, method.getName(), methodDesc, false); - if (returnType == void.class) { // end if - mv.visitLabel(selfLabel); - } - if (returnType == void.class) { - } else if (returnType.isPrimitive()) { - if (returnType == long.class) { - mv.visitVarInsn(LSTORE, ++varindex); - ++varindex; //多加1 - } else if (returnType == float.class) { - mv.visitVarInsn(FSTORE, ++varindex); - } else if (returnType == double.class) { - mv.visitVarInsn(DSTORE, ++varindex); - ++varindex; //多加1 - } else { - mv.visitVarInsn(ISTORE, ++varindex); - } - } else { - mv.visitVarInsn(ASTORE, ++varindex); - } - final int rsindex = varindex; // - - //---------------------------if (_client== null) return ---------------------------------- - mv.visitVarInsn(ALOAD, 0); - mv.visitFieldInsn(GETFIELD, newDynName, "_client", clientDesc); - Label clientLabel = new Label(); - mv.visitJumpInsn(IFNONNULL, clientLabel); - if (returnType == void.class) { - mv.visitInsn(RETURN); - } else if (returnType.isPrimitive()) { - if (returnType == long.class) { - mv.visitVarInsn(LLOAD, rsindex); - mv.visitInsn(LRETURN); - } else if (returnType == float.class) { - mv.visitVarInsn(FLOAD, rsindex); - mv.visitInsn(FRETURN); - } else if (returnType == double.class) { - mv.visitVarInsn(DLOAD, rsindex); - mv.visitInsn(DRETURN); - } else { - mv.visitVarInsn(ILOAD, rsindex); - mv.visitInsn(IRETURN); - } - } else { - mv.visitVarInsn(ALOAD, rsindex); - mv.visitInsn(ARETURN); - } - mv.visitLabel(clientLabel); - //---------------------------- 调用samerun --------------------------------- - mv.visitVarInsn(ILOAD, 2); //读取 samerunnable - Label sameLabel = new Label(); - mv.visitJumpInsn(IFEQ, sameLabel); //判断 samerunnable - - mv.visitVarInsn(ALOAD, 0);//调用 _client - mv.visitFieldInsn(GETFIELD, newDynName, "_client", clientDesc); - mv.visitVarInsn(ALOAD, 0); //传递 _convert - mv.visitFieldInsn(GETFIELD, newDynName, "_convert", convertDesc); - mv.visitVarInsn(ALOAD, 0); //传递 _sameGroupTransport - mv.visitFieldInsn(GETFIELD, newDynName, "_sameGroupTransport", transportDesc); - - if (index <= 5) { //第几个 SncpAction - mv.visitInsn(ICONST_0 + index); - } else { - mv.visitIntInsn(BIPUSH, index); - } - if (paramtypes.length + 3 <= 5) { //参数总数量 - mv.visitInsn(ICONST_0 + paramtypes.length + 3); - } else { - mv.visitIntInsn(BIPUSH, paramtypes.length + 3); - } - - mv.visitTypeInsn(ANEWARRAY, "java/lang/Object"); - - mv.visitInsn(DUP); - mv.visitInsn(ICONST_0); - mv.visitInsn(ICONST_1); //第一个参数 selfrunnable - mv.visitMethodInsn(INVOKESTATIC, "java/lang/Boolean", "valueOf", "(Z)Ljava/lang/Boolean;", false); - mv.visitInsn(AASTORE); - - mv.visitInsn(DUP); - mv.visitInsn(ICONST_1); - mv.visitInsn(ICONST_0); //第一个参数 samerunnable - mv.visitMethodInsn(INVOKESTATIC, "java/lang/Boolean", "valueOf", "(Z)Ljava/lang/Boolean;", false); - mv.visitInsn(AASTORE); - - mv.visitInsn(DUP); - mv.visitInsn(ICONST_2); - mv.visitInsn(ICONST_0); //第二个参数 diffrunnable - mv.visitMethodInsn(INVOKESTATIC, "java/lang/Boolean", "valueOf", "(Z)Ljava/lang/Boolean;", false); - mv.visitInsn(AASTORE); - - int insn = 3; - for (int j = 0; j < paramtypes.length; j++) { - final Class pt = paramtypes[j]; - mv.visitInsn(DUP); - insn++; - if (j <= 2) { - mv.visitInsn(ICONST_0 + j + 3); - } else { - mv.visitIntInsn(BIPUSH, j + 3); - } - if (pt.isPrimitive()) { - if (pt == long.class) { - mv.visitVarInsn(LLOAD, insn++); - } else if (pt == float.class) { - mv.visitVarInsn(FLOAD, insn++); - } else if (pt == double.class) { - mv.visitVarInsn(DLOAD, insn++); - } else { - mv.visitVarInsn(ILOAD, insn); - } - Class bigclaz = java.lang.reflect.Array.get(java.lang.reflect.Array.newInstance(pt, 1), 0).getClass(); - mv.visitMethodInsn(INVOKESTATIC, bigclaz.getName().replace('.', '/'), "valueOf", "(" + Type.getDescriptor(pt) + ")" + Type.getDescriptor(bigclaz), false); - } else { - mv.visitVarInsn(ALOAD, insn); - } - mv.visitInsn(AASTORE); - } - mv.visitMethodInsn(INVOKEVIRTUAL, clientName, mrun.async() ? "asyncRemoteSameGroup" : "remoteSameGroup", "(" + convertDesc + transportDesc + "I[Ljava/lang/Object;)V", false); - mv.visitLabel(sameLabel); - //---------------------------- 调用diffrun --------------------------------- - mv.visitVarInsn(ILOAD, 3); //读取 diffrunnable - Label diffLabel = new Label(); - mv.visitJumpInsn(IFEQ, diffLabel); //判断 diffrunnable - - mv.visitVarInsn(ALOAD, 0); - mv.visitFieldInsn(GETFIELD, newDynName, "_client", clientDesc); - mv.visitVarInsn(ALOAD, 0); - mv.visitFieldInsn(GETFIELD, newDynName, "_convert", convertDesc); - mv.visitVarInsn(ALOAD, 0); - mv.visitFieldInsn(GETFIELD, newDynName, "_diffGroupTransports", transportsDesc); - - if (index <= 5) { //第几个 SncpAction - mv.visitInsn(ICONST_0 + index); - } else { - mv.visitIntInsn(BIPUSH, index); - } - if (paramtypes.length + 3 <= 5) { //参数总数量 - mv.visitInsn(ICONST_0 + paramtypes.length + 3); - } else { - mv.visitIntInsn(BIPUSH, paramtypes.length + 3); - } - - mv.visitTypeInsn(ANEWARRAY, "java/lang/Object"); - - mv.visitInsn(DUP); - mv.visitInsn(ICONST_0); - mv.visitInsn(ICONST_1); //第一个参数 samerunnable - mv.visitMethodInsn(INVOKESTATIC, "java/lang/Boolean", "valueOf", "(Z)Ljava/lang/Boolean;", false); - mv.visitInsn(AASTORE); - - mv.visitInsn(DUP); - mv.visitInsn(ICONST_1); - mv.visitInsn(ICONST_1); //第二个参数 diffrunnable - mv.visitMethodInsn(INVOKESTATIC, "java/lang/Boolean", "valueOf", "(Z)Ljava/lang/Boolean;", false); - mv.visitInsn(AASTORE); - - mv.visitInsn(DUP); - mv.visitInsn(ICONST_2); - mv.visitInsn(ICONST_0); //第二个参数 diffrunnable - mv.visitMethodInsn(INVOKESTATIC, "java/lang/Boolean", "valueOf", "(Z)Ljava/lang/Boolean;", false); - mv.visitInsn(AASTORE); - - insn = 3; - for (int j = 0; j < paramtypes.length; j++) { - final Class pt = paramtypes[j]; - mv.visitInsn(DUP); - insn++; - if (j <= 2) { - mv.visitInsn(ICONST_0 + j + 3); - } else { - mv.visitIntInsn(BIPUSH, j + 3); - } - if (pt.isPrimitive()) { - if (pt == long.class) { - mv.visitVarInsn(LLOAD, insn++); - } else if (pt == float.class) { - mv.visitVarInsn(FLOAD, insn++); - } else if (pt == double.class) { - mv.visitVarInsn(DLOAD, insn++); - } else { - mv.visitVarInsn(ILOAD, insn); - } - Class bigclaz = java.lang.reflect.Array.get(java.lang.reflect.Array.newInstance(pt, 1), 0).getClass(); - mv.visitMethodInsn(INVOKESTATIC, bigclaz.getName().replace('.', '/'), "valueOf", "(" + Type.getDescriptor(pt) + ")" + Type.getDescriptor(bigclaz), false); - } else { - mv.visitVarInsn(ALOAD, insn); - } - mv.visitInsn(AASTORE); - } - mv.visitMethodInsn(INVOKEVIRTUAL, clientName, mrun.async() ? "asyncRemoteDiffGroup" : "remoteDiffGroup", "(" + convertDesc + transportsDesc + "I[Ljava/lang/Object;)V", false); - mv.visitLabel(diffLabel); - - if (returnType == void.class) { - mv.visitInsn(RETURN); - } else if (returnType.isPrimitive()) { - if (returnType == long.class) { - mv.visitVarInsn(LLOAD, rsindex); - mv.visitInsn(LRETURN); - } else if (returnType == float.class) { - mv.visitVarInsn(FLOAD, rsindex); - mv.visitInsn(FRETURN); - } else if (returnType == double.class) { - mv.visitVarInsn(DLOAD, rsindex); - mv.visitInsn(DRETURN); - } else { - mv.visitVarInsn(ILOAD, rsindex); - mv.visitInsn(IRETURN); - } - } else { - mv.visitVarInsn(ALOAD, rsindex); - mv.visitInsn(ARETURN); - } - - mv.visitMaxs(Math.max(varindex, 10), varindex + 4); - mv.visitEnd(); - } - } - cw.visitEnd(); - byte[] bytes = cw.toByteArray(); - Class newClazz = new ClassLoader(loader) { - public final Class loadClass(String name, byte[] b) { - return defineClass(name, b, 0, b.length); - } - }.loadClass(newDynName.replace('/', '.'), bytes); - return (Class) newClazz; - } - - private static void visitAnnotation(final AnnotationVisitor av, final Annotation ann) { - try { - for (Method anm : ann.annotationType().getMethods()) { - final String mname = anm.getName(); - if ("equals".equals(mname) || "hashCode".equals(mname) || "toString".equals(mname) || "annotationType".equals(mname)) continue; - final Object r = anm.invoke(ann); - if (r instanceof String[]) { - AnnotationVisitor av1 = av.visitArray(mname); - for (String item : (String[]) r) { - av1.visit(null, item); - } - av1.visitEnd(); - } else if (r instanceof Class[]) { - AnnotationVisitor av1 = av.visitArray(mname); - for (Class item : (Class[]) r) { - av1.visit(null, Type.getType(item)); - } - av1.visitEnd(); - } else if (r instanceof Enum[]) { - AnnotationVisitor av1 = av.visitArray(mname); - for (Enum item : (Enum[]) r) { - av1.visitEnum(null, Type.getDescriptor(item.getClass()), ((Enum) item).name()); - } - av1.visitEnd(); - } else if (r instanceof Annotation[]) { - AnnotationVisitor av1 = av.visitArray(mname); - for (Annotation item : (Annotation[]) r) { - visitAnnotation(av1.visitAnnotation(null, Type.getDescriptor(((Annotation) item).annotationType())), item); - } - av1.visitEnd(); - } else if (r instanceof Class) { - av.visit(mname, Type.getType((Class) r)); - } else if (r instanceof Enum) { - av.visitEnum(mname, Type.getDescriptor(r.getClass()), ((Enum) r).name()); - } else if (r instanceof Annotation) { - visitAnnotation(av.visitAnnotation(null, Type.getDescriptor(((Annotation) r).annotationType())), (Annotation) r); - } else { - av.visit(mname, r); - } - } - av.visitEnd(); - } catch (Exception e) { - e.printStackTrace(); - } - } - - /** - * - * 创建本地模式Service实例 - * - * @param Service泛型 - * @param name 资源名 - * @param executor 线程池 - * @param resourceFactory 资源容器 - * @param serviceClass Service类 - * @param clientAddress 本地IP地址 - * @param sameGroupTransport 同组的通信组件 - * @param diffGroupTransports 异组的通信组件列表 - * @return Service的本地模式实例 - */ - @SuppressWarnings("unchecked") - public static T createLocalService(final String name, final Consumer executor, final ResourceFactory resourceFactory, - final Class serviceClass, final InetSocketAddress clientAddress, final Transport sameGroupTransport, final Collection diffGroupTransports) { - try { - final Class newClazz = createLocalServiceClass(name, serviceClass); - T rs = (T) newClazz.newInstance(); - //-------------------------------------- - Service remoteService = null; - Transport remoteTransport = null; - { - Class loop = newClazz; - do { - for (Field field : loop.getDeclaredFields()) { - int mod = field.getModifiers(); - if (Modifier.isFinal(mod) || Modifier.isStatic(mod)) continue; - if (field.getAnnotation(DynRemote.class) == null) continue; - if (!field.getType().isAssignableFrom(newClazz)) continue; - field.setAccessible(true); - if (remoteTransport == null) { - List list = new ArrayList<>(); - if (sameGroupTransport != null) list.add(sameGroupTransport); - if (diffGroupTransports != null) list.addAll(diffGroupTransports); - if (!list.isEmpty()) { - Transport tmp = new Transport(list); - synchronized (resourceFactory) { - Transport old = resourceFactory.find(tmp.getName(), Transport.class); - if (old != null) { - remoteTransport = old; - } else { - remoteTransport = tmp; - resourceFactory.register(tmp.getName(), tmp); - } - } - } - } - if (remoteService == null && remoteTransport != null) { - remoteService = createRemoteService(name, executor, serviceClass, clientAddress, remoteTransport); - } - if (remoteService != null) field.set(rs, remoteService); - } - } while ((loop = loop.getSuperclass()) != Object.class); - } - SncpClient client = null; - { - try { - Field e = newClazz.getDeclaredField("_client"); - e.setAccessible(true); - client = new SncpClient(name, serviceClass, executor, false, newClazz, clientAddress); - e.set(rs, client); - } catch (NoSuchFieldException ne) { - } - } - { - StringBuilder sb = new StringBuilder(); - sb.append(newClazz.getName()).append("{name = '").append(name).append("'"); - if (client != null) { - sb.append(", serviceid = ").append(client.getServiceid()); - sb.append(", action.size = ").append(client.getActionCount()); - List groups = new ArrayList<>(); - if (sameGroupTransport != null) groups.add(sameGroupTransport.getName()); - if (diffGroupTransports != null) { - for (Transport t : diffGroupTransports) { - groups.add(t.getName()); - } - } - sb.append(", address = ").append(clientAddress).append(", groups = ").append(groups); - sb.append(", sameaddrs = ").append(sameGroupTransport == null ? null : Arrays.asList(sameGroupTransport.getRemoteAddresses())); - - List addrs = new ArrayList<>(); - if (diffGroupTransports != null) { - for (Transport t : diffGroupTransports) { - addrs.addAll(Arrays.asList(t.getRemoteAddresses())); - } - } - sb.append(", diffaddrs = ").append(addrs); - } else { - sb.append(", ").append(MultiRun.class.getSimpleName().toLowerCase()).append(" = false"); - } - sb.append("}"); - Field s = newClazz.getDeclaredField("_selfstring"); - s.setAccessible(true); - s.set(rs, sb.toString()); - } - if (client == null) return rs; - { - Field c = newClazz.getDeclaredField("_sameGroupTransport"); - c.setAccessible(true); - c.set(rs, sameGroupTransport); - } - if (diffGroupTransports != null) { - Field t = newClazz.getDeclaredField("_diffGroupTransports"); - t.setAccessible(true); - t.set(rs, diffGroupTransports.toArray(new Transport[diffGroupTransports.size()])); - } - return rs; - } catch (RuntimeException rex) { - throw rex; - } catch (Exception ex) { - throw new RuntimeException(ex); - } - - } - - /** - *
-     * @Resource(name = "")
-     * @SncpDyn(remote = true)
-     * @ResourceType({TestService.class})
-     * public final class _DynRemoteTestService extends TestService{
-     *
-     *      @Resource
-     *      private BsonConvert _convert;
-     *
-     *      private Transport _transport;
-     *
-     *      private SncpClient _client;
-     *
-     *      private String _selfstring;
-     *
-     *      @Override
-     *      public String toString() {
-     *          return _selfstring == null ? super.toString() : _selfstring;
-     *      }
-     *
-     *      @SncpDyn(remote = false, index = 0)
-     *      public void _createSomeThing(boolean selfrunnable, boolean samerunnable, boolean diffrunnable, TestBean bean){
-     *          _client.remote(_convert, _transport, 0, selfrunnable, samerunnable, diffrunnable, bean);
-     *      }
-     *
-     *      @SncpDyn(remote = false, index = 1)
-     *      public String _updateSomeThing(boolean selfrunnable, boolean samerunnable, boolean diffrunnable, String id){
-     *          return _client.remote(_convert, _transport, 1, selfrunnable, samerunnable, diffrunnable, id);
-     *      }
-     *
-     *      @Override
-     *      public void createSomeThing(TestBean bean){
-     *          _client.remote(_convert, _transport, 2, bean);
-     *      }
-     *
-     *      @Override
-     *      public String findSomeThing(){
-     *          return _client.remote(_convert, _transport, 3);
-     *      }
-     *
-     *      @Override
-     *      public String updateSomeThing(String id){
-     *          return  _client.remote(_convert, _transport, 4, id);
-     *      }
-     * }
-     * 
- * - * 创建远程模式的Service实例 - * - * @param Service泛型 - * @param name 资源名 - * @param executor 线程池 - * @param serviceClass Service类 - * @param clientAddress 本地IP地址 - * @param transport 通信组件 - * - * @return Service的远程模式实例 - */ - @SuppressWarnings("unchecked") - public static T createRemoteService(final String name, final Consumer executor, final Class serviceClass, - final InetSocketAddress clientAddress, final Transport transport) { - if (serviceClass == null) return null; - if (!Service.class.isAssignableFrom(serviceClass)) return null; - int mod = serviceClass.getModifiers(); - boolean realed = !(java.lang.reflect.Modifier.isAbstract(mod) || serviceClass.isInterface()); - if (!java.lang.reflect.Modifier.isPublic(mod)) return null; - final String supDynName = serviceClass.getName().replace('.', '/'); - final String clientName = SncpClient.class.getName().replace('.', '/'); - final String clientDesc = Type.getDescriptor(SncpClient.class); - final String sncpDynDesc = Type.getDescriptor(SncpDyn.class); - final String convertDesc = Type.getDescriptor(BsonConvert.class); - final String transportDesc = Type.getDescriptor(Transport.class); - final String anyValueDesc = Type.getDescriptor(AnyValue.class); - ClassLoader loader = Sncp.class.getClassLoader(); - String newDynName = supDynName.substring(0, supDynName.lastIndexOf('/') + 1) + REMOTEPREFIX + serviceClass.getSimpleName(); - final SncpClient client = new SncpClient(name, serviceClass, executor, true, realed ? createLocalServiceClass(name, serviceClass) : serviceClass, clientAddress); - try { - Class newClazz = Class.forName(newDynName.replace('/', '.')); - T rs = (T) newClazz.newInstance(); - Field c = newClazz.getDeclaredField("_client"); - c.setAccessible(true); - c.set(rs, client); - Field t = newClazz.getDeclaredField("_transport"); - t.setAccessible(true); - t.set(rs, transport); - { - StringBuilder sb = new StringBuilder(); - sb.append(newClazz.getName()).append("{name = '").append(name); - sb.append("', serviceid = ").append(client.getServiceid()); - sb.append(", action.size = ").append(client.getActionCount()); - sb.append(", address = ").append(clientAddress).append(", groups = ").append(transport == null ? null : transport.getName()); - sb.append(", remoteaddrs = ").append(transport == null ? null : Arrays.asList(transport.getRemoteAddresses())); - sb.append("}"); - Field s = newClazz.getDeclaredField("_selfstring"); - s.setAccessible(true); - s.set(rs, sb.toString()); - } - return rs; - } catch (Exception ex) { - } - //------------------------------------------------------------------------------ - ClassWriter cw = new ClassWriter(COMPUTE_FRAMES); - FieldVisitor fv; - AsmMethodVisitor mv; - AnnotationVisitor av0; - - cw.visit(V1_8, ACC_PUBLIC + ACC_FINAL + ACC_SUPER, newDynName, null, serviceClass.isInterface() ? "java/lang/Object" : supDynName, serviceClass.isInterface() ? new String[]{supDynName} : null); - { - av0 = cw.visitAnnotation("Ljavax/annotation/Resource;", true); - av0.visit("name", name); - av0.visitEnd(); - } - { - av0 = cw.visitAnnotation(Type.getDescriptor(ResourceType.class), true); - { - AnnotationVisitor av1 = av0.visitArray("value"); - ResourceType rty = serviceClass.getAnnotation(ResourceType.class); - if (rty == null) { - av1.visit(null, Type.getType(Type.getDescriptor(serviceClass))); - } else { - for (Class cl : rty.value()) { - av1.visit(null, Type.getType(Type.getDescriptor(cl))); - } - } - av1.visitEnd(); - } - av0.visitEnd(); - } - { - av0 = cw.visitAnnotation(sncpDynDesc, true); - av0.visit("remote", Boolean.TRUE); - av0.visitEnd(); - } - { - fv = cw.visitField(ACC_PRIVATE, "_convert", convertDesc, null, null); - av0 = fv.visitAnnotation("Ljavax/annotation/Resource;", true); - av0.visitEnd(); - fv.visitEnd(); - } - { - fv = cw.visitField(ACC_PRIVATE, "_transport", transportDesc, null, null); - fv.visitEnd(); - } - { - fv = cw.visitField(ACC_PRIVATE, "_client", clientDesc, null, null); - fv.visitEnd(); - } - { - fv = cw.visitField(ACC_PRIVATE, "_selfstring", "Ljava/lang/String;", null, null); - fv.visitEnd(); - } - { //构造函数 - mv = new AsmMethodVisitor(cw.visitMethod(ACC_PUBLIC, "", "()V", null, null)); - //mv.setDebug(true); - mv.visitVarInsn(ALOAD, 0); - mv.visitMethodInsn(INVOKESPECIAL, serviceClass.isInterface() ? "java/lang/Object" : supDynName, "", "()V", false); - mv.visitInsn(RETURN); - mv.visitMaxs(1, 1); - mv.visitEnd(); - } - { //init - mv = new AsmMethodVisitor(cw.visitMethod(ACC_PUBLIC, "init", "(" + anyValueDesc + ")V", null, null)); - mv.visitInsn(RETURN); - mv.visitMaxs(0, 2); - mv.visitEnd(); - } - { //destroy - mv = new AsmMethodVisitor(cw.visitMethod(ACC_PUBLIC, "destroy", "(" + anyValueDesc + ")V", null, null)); - mv.visitInsn(RETURN); - mv.visitMaxs(0, 2); - mv.visitEnd(); - } - { // toString() - mv = new AsmMethodVisitor(cw.visitMethod(ACC_PUBLIC, "toString", "()Ljava/lang/String;", null, null)); - mv.visitVarInsn(ALOAD, 0); - mv.visitFieldInsn(GETFIELD, newDynName, "_selfstring", "Ljava/lang/String;"); - Label l1 = new Label(); - mv.visitJumpInsn(IFNONNULL, l1); - mv.visitVarInsn(ALOAD, 0); - mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "toString", "()Ljava/lang/String;", false); - Label l2 = new Label(); - mv.visitJumpInsn(GOTO, l2); - mv.visitLabel(l1); - mv.visitVarInsn(ALOAD, 0); - mv.visitFieldInsn(GETFIELD, newDynName, "_selfstring", "Ljava/lang/String;"); - mv.visitLabel(l2); - mv.visitInsn(ARETURN); - mv.visitMaxs(1, 1); - mv.visitEnd(); - } - int i = -1; - for (final SncpAction entry : client.actions) { - final int index = ++i; - final java.lang.reflect.Method method = entry.method; - { - mv = new AsmMethodVisitor(cw.visitMethod(ACC_PUBLIC, method.getName(), Type.getMethodDescriptor(method), null, null)); - //mv.setDebug(true); - { //给参数加上 Annotation - final Annotation[][] anns = method.getParameterAnnotations(); - for (int k = 0; k < anns.length; k++) { - for (Annotation ann : anns[k]) { - visitAnnotation(mv.visitParameterAnnotation(k, Type.getDescriptor(ann.annotationType()), true), ann); - } - } - } - mv.visitVarInsn(ALOAD, 0); - mv.visitFieldInsn(GETFIELD, newDynName, "_client", clientDesc); - mv.visitVarInsn(ALOAD, 0); - mv.visitFieldInsn(GETFIELD, newDynName, "_convert", convertDesc); - mv.visitVarInsn(ALOAD, 0); - mv.visitFieldInsn(GETFIELD, newDynName, "_transport", transportDesc); - if (index <= 5) { - mv.visitInsn(ICONST_0 + index); - } else { - mv.visitIntInsn(BIPUSH, index); - } - - { //传参数 - int paramlen = entry.paramTypes.length; - if (paramlen <= 5) { - mv.visitInsn(ICONST_0 + paramlen); - } else { - mv.visitIntInsn(BIPUSH, paramlen); - } - mv.visitTypeInsn(ANEWARRAY, "java/lang/Object"); - java.lang.reflect.Type[] paramtypes = entry.paramTypes; - int insn = 0; - for (int j = 0; j < paramtypes.length; j++) { - final java.lang.reflect.Type pt = paramtypes[j]; - mv.visitInsn(DUP); - insn++; - if (j <= 5) { - mv.visitInsn(ICONST_0 + j); - } else { - mv.visitIntInsn(BIPUSH, j); - } - if (pt instanceof Class && ((Class) pt).isPrimitive()) { - if (pt == long.class) { - mv.visitVarInsn(LLOAD, insn++); - } else if (pt == float.class) { - mv.visitVarInsn(FLOAD, insn++); - } else if (pt == double.class) { - mv.visitVarInsn(DLOAD, insn++); - } else { - mv.visitVarInsn(ILOAD, insn); - } - Class bigclaz = java.lang.reflect.Array.get(java.lang.reflect.Array.newInstance((Class) pt, 1), 0).getClass(); - mv.visitMethodInsn(INVOKESTATIC, bigclaz.getName().replace('.', '/'), "valueOf", "(" + Type.getDescriptor((Class) pt) + ")" + Type.getDescriptor(bigclaz), false); - } else { - mv.visitVarInsn(ALOAD, insn); - } - mv.visitInsn(AASTORE); - } - } - - mv.visitMethodInsn(INVOKEVIRTUAL, clientName, "remote", "(" + convertDesc + transportDesc + "I[Ljava/lang/Object;)Ljava/lang/Object;", false); - //mv.visitMethodInsn(INVOKEVIRTUAL, convertName, "convertFrom", convertFromDesc, false); - if (method.getGenericReturnType() == void.class) { - mv.visitInsn(POP); - mv.visitInsn(RETURN); - } else { - Class returnclz = method.getReturnType(); - Class bigPrimitiveClass = returnclz.isPrimitive() ? java.lang.reflect.Array.get(java.lang.reflect.Array.newInstance(returnclz, 1), 0).getClass() : returnclz; - mv.visitTypeInsn(CHECKCAST, (returnclz.isPrimitive() ? bigPrimitiveClass : returnclz).getName().replace('.', '/')); - if (returnclz.isPrimitive()) { - String bigPrimitiveName = bigPrimitiveClass.getName().replace('.', '/'); - try { - java.lang.reflect.Method pm = bigPrimitiveClass.getMethod(returnclz.getSimpleName() + "Value"); - mv.visitMethodInsn(INVOKEVIRTUAL, bigPrimitiveName, pm.getName(), Type.getMethodDescriptor(pm), false); - } catch (Exception ex) { - throw new RuntimeException(ex); //不可能会发生 - } - if (returnclz == long.class) { - mv.visitInsn(LRETURN); - } else if (returnclz == float.class) { - mv.visitInsn(FRETURN); - } else if (returnclz == double.class) { - mv.visitInsn(DRETURN); - } else { - mv.visitInsn(IRETURN); - } - } else { - mv.visitInsn(ARETURN); - } - } - mv.visitMaxs(20, 20); - mv.visitEnd(); - } - } - cw.visitEnd(); - byte[] bytes = cw.toByteArray(); - Class newClazz = new ClassLoader(loader) { - public final Class loadClass(String name, byte[] b) { - return defineClass(name, b, 0, b.length); - } - }.loadClass(newDynName.replace('/', '.'), bytes); - try { - T rs = (T) newClazz.newInstance(); - Field c = newClazz.getDeclaredField("_client"); - c.setAccessible(true); - c.set(rs, client); - Field t = newClazz.getDeclaredField("_transport"); - t.setAccessible(true); - t.set(rs, transport); - { - StringBuilder sb = new StringBuilder(); - sb.append(newClazz.getName()).append("{name = '").append(name); - sb.append("', serviceid = ").append(client.getServiceid()); - sb.append(", action.size = ").append(client.getActionCount()); - sb.append(", address = ").append(clientAddress).append(", groups = ").append(transport == null ? null : transport.getName()); - sb.append(", remotes = ").append(transport == null ? null : Arrays.asList(transport.getRemoteAddresses())); - sb.append("}"); - Field s = newClazz.getDeclaredField("_selfstring"); - s.setAccessible(true); - s.set(rs, sb.toString()); - } - return rs; - } catch (Exception ex) { - throw new RuntimeException(ex); - } - - } -} diff --git a/src/main/java/org/redkale/net/sncp/SncpClient.java b/src/main/java/org/redkale/net/sncp/SncpClient.java deleted file mode 100644 index f63662f7c..000000000 --- a/src/main/java/org/redkale/net/sncp/SncpClient.java +++ /dev/null @@ -1,544 +0,0 @@ -/* - * To change this license header, choose License Headers reader Project Properties. - * To change this template file, choose Tools | Templates - * and open the template reader the editor. - */ -package org.redkale.net.sncp; - -import java.lang.annotation.*; -import java.lang.reflect.*; -import java.net.*; -import java.nio.*; -import java.nio.channels.*; -import java.util.*; -import java.util.concurrent.*; -import java.util.function.*; -import java.util.logging.*; -import org.redkale.convert.bson.*; -import org.redkale.convert.json.*; -import org.redkale.net.*; -import static org.redkale.net.sncp.SncpRequest.*; -import org.redkale.service.*; -import org.redkale.util.*; -import org.redkale.service.DynCall; - -/** - * - *

- * 详情见: http://www.redkale.org - * - * @author zhangjx - */ -public final class SncpClient { - - protected static final class SncpAction { - - protected final DLong actionid; - - protected final Method method; - - protected final Type resultTypes; //void 必须设为 null - - protected final Type[] paramTypes; - - protected final Attribute[] paramAttrs; // 为null表示无DynCall处理,index=0固定为null, 其他为参数标记的DynCall回调方法 - - protected final int handlerFuncParamIndex; - - protected final int handlerAttachParamIndex; - - protected final int addressTargetParamIndex; - - protected final int addressSourceParamIndex; - - public SncpAction(Method method, DLong actionid) { - this.actionid = actionid; - Type rt = method.getGenericReturnType(); - if (rt instanceof TypeVariable) { - TypeVariable tv = (TypeVariable) rt; - if (tv.getBounds().length == 1) rt = tv.getBounds()[0]; - } - this.resultTypes = rt == void.class ? null : rt; - this.paramTypes = method.getGenericParameterTypes(); - this.method = method; - Annotation[][] anns = method.getParameterAnnotations(); - int targetAddrIndex = -1; - int sourceAddrIndex = -1; - int handlerAttachIndex = -1; - int handlerFuncIndex = -1; - boolean hasattr = false; - Attribute[] atts = new Attribute[paramTypes.length + 1]; - if (anns.length > 0) { - Class[] params = method.getParameterTypes(); - for (int i = 0; i < params.length; i++) { - if (CompletionHandler.class.isAssignableFrom(params[i])) { - handlerFuncIndex = i; - break; - } - } - for (int i = 0; i < anns.length; i++) { - if (anns[i].length > 0) { - for (Annotation ann : anns[i]) { - if (ann.annotationType() == DynAttachment.class) { - handlerAttachIndex = i; - } else if (ann.annotationType() == DynTargetAddress.class && SocketAddress.class.isAssignableFrom(params[i])) { - targetAddrIndex = i; - } else if (ann.annotationType() == DynSourceAddress.class && SocketAddress.class.isAssignableFrom(params[i])) { - sourceAddrIndex = i; - } - } - for (Annotation ann : anns[i]) { - if (ann.annotationType() == DynCall.class) { - try { - atts[i + 1] = ((DynCall) ann).value().newInstance(); - hasattr = true; - } catch (Exception e) { - logger.log(Level.SEVERE, DynCall.class.getSimpleName() + ".attribute cannot a newInstance for" + method, e); - } - break; - } - } - } - } - } - this.addressTargetParamIndex = targetAddrIndex; - this.addressSourceParamIndex = sourceAddrIndex; - this.handlerFuncParamIndex = handlerFuncIndex; - this.handlerAttachParamIndex = handlerAttachIndex; - this.paramAttrs = hasattr ? atts : null; - if (this.handlerFuncParamIndex >= 0 && method.getReturnType() != void.class) throw new RuntimeException(method + " has CompletionHandler type parameter but return type is not void"); - } - - @Override - public String toString() { - return "{" + actionid + "," + (method == null ? "null" : method.getName()) + "}"; - } - } - - protected static final Logger logger = Logger.getLogger(SncpClient.class.getSimpleName()); - - protected final boolean finest = logger.isLoggable(Level.FINEST); - - protected final JsonConvert jsonConvert = JsonFactory.root().getConvert(); - - protected final String name; - - protected final boolean remote; - - private final Class serviceClass; - - protected final InetSocketAddress clientAddress; - - private final byte[] addrBytes; - - private final int addrPort; - - protected final DLong serviceid; - - protected final SncpAction[] actions; - - protected final Consumer executor; - - public SncpClient(final String serviceName, final Class serviceType, final Consumer executor, - final boolean remote, final Class serviceClass, final InetSocketAddress clientAddress) { - this.remote = remote; - this.executor = executor; - this.serviceClass = serviceClass; - this.clientAddress = clientAddress; - this.name = serviceName; - this.serviceid = Sncp.hash(serviceType.getName() + ':' + serviceName); - final List methodens = new ArrayList<>(); - //------------------------------------------------------------------------------ - for (java.lang.reflect.Method method : parseMethod(serviceClass)) { - methodens.add(new SncpAction(method, Sncp.hash(method))); - } - this.actions = methodens.toArray(new SncpAction[methodens.size()]); - this.addrBytes = clientAddress == null ? new byte[4] : clientAddress.getAddress().getAddress(); - this.addrPort = clientAddress == null ? 0 : clientAddress.getPort(); - } - - public InetSocketAddress getClientAddress() { - return clientAddress; - } - - public DLong getServiceid() { - return serviceid; - } - - public int getActionCount() { - return actions.length; - } - - @Override - public String toString() { - String service = serviceClass.getName(); - if (remote) service = service.replace(Sncp.LOCALPREFIX, Sncp.REMOTEPREFIX); - return this.getClass().getSimpleName() + "(service = " + service + ", serviceid = " + serviceid + ", name = '" + name - + "', address = " + (clientAddress == null ? "" : (clientAddress.getHostString() + ":" + clientAddress.getPort())) - + ", actions.size = " + actions.length + ")"; - } - - public static List parseMethod(final Class serviceClass) { - final List list = new ArrayList<>(); - final List multis = new ArrayList<>(); - final Map actionids = new HashMap<>(); - - for (final java.lang.reflect.Method method : serviceClass.getMethods()) { - if (method.isSynthetic()) continue; - final int mod = method.getModifiers(); - if (Modifier.isStatic(mod)) continue; - if (Modifier.isFinal(mod)) continue; - if (method.getName().equals("getClass") || method.getName().equals("toString")) continue; - if (method.getName().equals("equals") || method.getName().equals("hashCode")) continue; - if (method.getName().equals("notify") || method.getName().equals("notifyAll") || method.getName().equals("wait")) continue; - if (method.getName().equals("init") || method.getName().equals("destroy")) continue; - //if (onlySncpDyn && method.getAnnotation(SncpDyn.class) == null) continue; - DLong actionid = Sncp.hash(method); - Method old = actionids.get(actionid); - if (old != null) { - if (old.getDeclaringClass().equals(method.getDeclaringClass())) - throw new RuntimeException(serviceClass.getName() + " have one more same action(Method=" + method + ", " + old + ", actionid=" + actionid + ")"); - continue; - } - actionids.put(actionid, method); - if (method.getAnnotation(SncpDyn.class) != null) { - multis.add(method); - } else { - list.add(method); - } - } - multis.sort((m1, m2) -> m1.getAnnotation(SncpDyn.class).index() - m2.getAnnotation(SncpDyn.class).index()); - list.sort((Method o1, Method o2) -> { - if (!o1.getName().equals(o2.getName())) return o1.getName().compareTo(o2.getName()); - if (o1.getParameterCount() != o2.getParameterCount()) return o1.getParameterCount() - o2.getParameterCount(); - return 0; - }); - //带SncpDyn必须排在前面 - multis.addAll(list); - return multis; - } - - public void remoteSameGroup(final BsonConvert convert, Transport transport, final int index, final Object... params) { - final SncpAction action = actions[index]; - if (action.handlerFuncParamIndex >= 0) params[action.handlerFuncParamIndex] = null; //不能让远程调用handler,因为之前本地方法已经调用过了 - for (InetSocketAddress addr : transport.getRemoteAddresses()) { - remote0(null, convert, transport, addr, action, params); - } - } - - public void asyncRemoteSameGroup(final BsonConvert convert, Transport transport, final int index, final Object... params) { - if (executor != null) { - executor.accept(() -> { - remoteSameGroup(convert, transport, index, params); - }); - } else { - remoteSameGroup(convert, transport, index, params); - } - } - - public void remoteDiffGroup(final BsonConvert convert, Transport[] transports, final int index, final Object... params) { - if (transports == null || transports.length < 1) return; - final SncpAction action = actions[index]; - if (action.handlerFuncParamIndex >= 0) params[action.handlerFuncParamIndex] = null; //不能让远程调用handler,因为之前本地方法已经调用过了 - for (Transport transport : transports) { - remote0(null, convert, transport, null, action, params); - } - } - - public void asyncRemoteDiffGroup(final BsonConvert convert, Transport[] transports, final int index, final Object... params) { - if (transports == null || transports.length < 1) return; - if (executor != null) { - executor.accept(() -> { - remoteDiffGroup(convert, transports, index, params); - }); - } else { - remoteDiffGroup(convert, transports, index, params); - } - } - - //只给远程模式调用的 - public T remote(final BsonConvert convert, Transport transport, final int index, final Object... params) { - final SncpAction action = actions[index]; - final CompletionHandler handlerFunc = action.handlerFuncParamIndex >= 0 ? (CompletionHandler) params[action.handlerFuncParamIndex] : null; - if (action.handlerFuncParamIndex >= 0) params[action.handlerFuncParamIndex] = null; - Future future = remote0(handlerFunc, convert, transport, null, action, params); - if (handlerFunc != null) return null; - final BsonReader reader = convert.pollBsonReader(); - try { - reader.setBytes(future.get(5, TimeUnit.SECONDS)); - byte i; - while ((i = reader.readByte()) != 0) { - final Attribute attr = action.paramAttrs[i]; - attr.set(params[i - 1], convert.convertFrom(attr.type(), reader)); - } - return convert.convertFrom(action.resultTypes, reader); - } catch (InterruptedException | ExecutionException | TimeoutException e) { - logger.log(Level.SEVERE, actions[index].method + " sncp (params: " + jsonConvert.convertTo(params) + ") remote error", e); - throw new RuntimeException(actions[index].method + " sncp remote error", e); - } finally { - convert.offerBsonReader(reader); - } - } - - public void remote(final BsonConvert convert, Transport[] transports, final int index, final Object... params) { - if (transports == null || transports.length < 1) return; - remote(convert, transports[0], index, params); - for (int i = 1; i < transports.length; i++) { - remote0(null, convert, transports[i], null, actions[index], params); - } - } - - private Future remote0(final CompletionHandler handler, final BsonConvert convert, final Transport transport, final SocketAddress addr0, final SncpAction action, final Object... params) { - Type[] myparamtypes = action.paramTypes; - if (action.addressSourceParamIndex >= 0) params[action.addressSourceParamIndex] = this.clientAddress; - final BsonWriter writer = convert.pollBsonWriter(transport.getBufferSupplier()); // 将head写入 - writer.writeTo(DEFAULT_HEADER); - for (int i = 0; i < params.length; i++) { - convert.convertTo(writer, myparamtypes[i], params[i]); - } - final int reqBodyLength = writer.count() - HEADER_SIZE; //body总长度 - final long seqid = System.nanoTime(); - final DLong actionid = action.actionid; - final SocketAddress addr = addr0 == null ? (action.addressTargetParamIndex >= 0 ? (SocketAddress) params[action.addressTargetParamIndex] : null) : addr0; - final AsyncConnection conn = transport.pollConnection(addr); - if (conn == null || !conn.isOpen()) { - logger.log(Level.SEVERE, action.method + " sncp (params: " + jsonConvert.convertTo(params) + ") cannot connect " + (conn == null ? addr : conn.getRemoteAddress())); - throw new RuntimeException("sncp " + (conn == null ? addr : conn.getRemoteAddress()) + " cannot connect"); - } - final ByteBuffer[] sendBuffers = writer.toBuffers(); - fillHeader(sendBuffers[0], seqid, actionid, reqBodyLength); - - final ByteBuffer buffer = transport.pollBuffer(); - final SncpFuture future = new SncpFuture(); - conn.write(sendBuffers, sendBuffers, new CompletionHandler() { - - @Override - public void completed(Integer result, ByteBuffer[] attachments) { - int index = -1; - for (int i = 0; i < attachments.length; i++) { - if (attachments[i].hasRemaining()) { - index = i; - break; - } else { - transport.offerBuffer(attachments[i]); - } - } - if (index == 0) { - conn.write(attachments, attachments, this); - return; - } else if (index > 0) { - ByteBuffer[] newattachs = new ByteBuffer[attachments.length - index]; - System.arraycopy(attachments, index, newattachs, 0, newattachs.length); - conn.write(newattachs, newattachs, this); - return; - } - //----------------------- 读取返回结果 ------------------------------------- - buffer.clear(); - conn.read(buffer, null, new CompletionHandler() { - - private byte[] body; - - private int received; - - @Override - public void completed(Integer count, Void attachment2) { - if (count < 1 && buffer.remaining() == buffer.limit()) { //没有数据可读 - future.set(new RuntimeException(action.method + " sncp[" + conn.getRemoteAddress() + "] remote no response data")); - transport.offerBuffer(buffer); - transport.offerConnection(true, conn); - return; - } - if (received < 1 && buffer.limit() < buffer.remaining() + HEADER_SIZE) { //header都没读全 - conn.read(buffer, attachment2, this); - return; - } - buffer.flip(); - if (received > 0) { - int offset = this.received; - this.received += buffer.remaining(); - buffer.get(body, offset, Math.min(buffer.remaining(), this.body.length - offset)); - if (this.received < this.body.length) {// 数据仍然不全,需要继续读取 - buffer.clear(); - conn.read(buffer, attachment2, this); - } else { - success(); - } - return; - } - checkResult(seqid, action, buffer); - - final int respBodyLength = buffer.getInt(); - final int retcode = buffer.getInt(); - if (retcode != 0) { - logger.log(Level.SEVERE, action.method + " sncp (params: " + jsonConvert.convertTo(params) + ") deal error (retcode=" + retcode + ", retinfo=" + SncpResponse.getRetCodeInfo(retcode) + ")"); - throw new RuntimeException("remote service(" + action.method + ") deal error (retcode=" + retcode + ", retinfo=" + SncpResponse.getRetCodeInfo(retcode) + ")"); - } - - if (respBodyLength > buffer.remaining()) { // 数据不全,需要继续读取 - this.body = new byte[respBodyLength]; - this.received = buffer.remaining(); - buffer.get(body, 0, this.received); - buffer.clear(); - conn.read(buffer, attachment2, this); - } else { - this.body = new byte[respBodyLength]; - buffer.get(body, 0, respBodyLength); - success(); - } - } - - public void success() { - future.set(this.body); - transport.offerBuffer(buffer); - transport.offerConnection(false, conn); - if (handler != null) { - final Object handlerAttach = action.handlerAttachParamIndex >= 0 ? params[action.handlerAttachParamIndex] : null; - final BsonReader reader = convert.pollBsonReader(); - try { - reader.setBytes(this.body); - int i; - while ((i = (reader.readByte() & 0xff)) != 0) { - final Attribute attr = action.paramAttrs[i]; - attr.set(params[i - 1], convert.convertFrom(attr.type(), reader)); - } - Object rs = convert.convertFrom(action.resultTypes, reader); - handler.completed(rs, handlerAttach); - } catch (Exception e) { - handler.failed(e, handlerAttach); - } finally { - convert.offerBsonReader(reader); - } - } - } - - @Override - public void failed(Throwable exc, Void attachment2) { - logger.log(Level.SEVERE, action.method + " sncp (params: " + jsonConvert.convertTo(params) + ") remote read exec failed", exc); - future.set(new RuntimeException(action.method + " sncp remote exec failed")); - transport.offerBuffer(buffer); - transport.offerConnection(true, conn); - if (handler != null) { - final Object handlerAttach = action.handlerAttachParamIndex >= 0 ? params[action.handlerAttachParamIndex] : null; - handler.failed(exc, handlerAttach); - } - } - }); - } - - @Override - public void failed(Throwable exc, ByteBuffer[] attachment) { - logger.log(Level.SEVERE, action.method + " sncp (params: " + jsonConvert.convertTo(params) + ") remote write exec failed", exc); - transport.offerBuffer(buffer); - transport.offerConnection(true, conn); - } - }); - return future; - } - - private void checkResult(long seqid, final SncpAction action, ByteBuffer buffer) { - long rseqid = buffer.getLong(); - if (rseqid != seqid) throw new RuntimeException("sncp(" + action.method + ") response.seqid = " + seqid + ", but request.seqid =" + rseqid); - if (buffer.getChar() != HEADER_SIZE) throw new RuntimeException("sncp(" + action.method + ") buffer receive header.length not " + HEADER_SIZE); - DLong rserviceid = DLong.read(buffer); - if (!rserviceid.equals(serviceid)) throw new RuntimeException("sncp(" + action.method + ") response.serviceid = " + serviceid + ", but request.serviceid =" + rserviceid); - DLong raction = DLong.read(buffer); - if (!action.actionid.equals(raction)) throw new RuntimeException("sncp(" + action.method + ") response.actionid = " + action.actionid + ", but request.actionid =(" + raction + ")"); - buffer.getInt(); //地址 - buffer.getChar(); //端口 - } - - private void fillHeader(ByteBuffer buffer, long seqid, DLong actionid, int bodyLength) { - //---------------------head---------------------------------- - final int currentpos = buffer.position(); - buffer.position(0); - buffer.putLong(seqid); //序列号 - buffer.putChar((char) HEADER_SIZE); //header长度 - DLong.write(buffer, this.serviceid); - DLong.write(buffer, actionid); - buffer.put(addrBytes); - buffer.putChar((char) this.addrPort); - buffer.putInt(bodyLength); //body长度 - buffer.putInt(0); //结果码, 请求方固定传0 - buffer.position(currentpos); - } - - protected static final class SncpFuture implements Future { - - private volatile boolean done; - - private T result; - - private RuntimeException ex; - - public SncpFuture() { - } - - public SncpFuture(T result) { - this.result = result; - this.done = true; - } - - public void set(T result) { - this.result = result; - this.done = true; - synchronized (this) { - notifyAll(); - } - } - - public void set(RuntimeException ex) { - this.ex = ex; - this.done = true; - synchronized (this) { - notifyAll(); - } - } - - @Override - public boolean cancel(boolean mayInterruptIfRunning) { - return false; - } - - @Override - public boolean isCancelled() { - return false; - } - - @Override - public boolean isDone() { - return done; - } - - @Override - public T get() throws InterruptedException, ExecutionException { - if (done) { - if (ex != null) throw ex; - return result; - } - synchronized (this) { - if (!done) wait(10_000); - } - if (done) { - if (ex != null) throw ex; - return result; - } - throw new InterruptedException(); - } - - @Override - public T get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException { - if (done) { - if (ex != null) throw ex; - return result; - } - synchronized (this) { - if (!done) wait(unit.toMillis(timeout)); - } - if (done) { - if (ex != null) throw ex; - return result; - } - throw new TimeoutException(); - } - } -} diff --git a/src/main/java/org/redkale/net/sncp/SncpContext.java b/src/main/java/org/redkale/net/sncp/SncpContext.java deleted file mode 100644 index 54bfdb470..000000000 --- a/src/main/java/org/redkale/net/sncp/SncpContext.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * 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.sncp; - -import java.net.*; -import java.nio.*; -import java.nio.charset.*; -import java.util.concurrent.*; -import java.util.logging.*; -import org.redkale.net.*; -import org.redkale.util.*; -import org.redkale.watch.*; - -/** - * - * @author zhangjx - */ -public class SncpContext extends Context { - - public SncpContext(long serverStartTime, Logger logger, ExecutorService executor, int bufferCapacity, ObjectPool bufferPool, - ObjectPool responsePool, int maxbody, Charset charset, InetSocketAddress address, PrepareServlet prepare, - WatchFactory watch, int readTimeoutSecond, int writeTimeoutSecond) { - super(serverStartTime, logger, executor, bufferCapacity, bufferPool, responsePool, maxbody, charset, - address, prepare, watch, readTimeoutSecond, writeTimeoutSecond); - } -} diff --git a/src/main/java/org/redkale/net/sncp/SncpDyn.java b/src/main/java/org/redkale/net/sncp/SncpDyn.java deleted file mode 100644 index ea5a74866..000000000 --- a/src/main/java/org/redkale/net/sncp/SncpDyn.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * 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.sncp; - -import java.lang.annotation.*; -import static java.lang.annotation.ElementType.*; -import static java.lang.annotation.RetentionPolicy.RUNTIME; - -/** - * 修饰由SNCP协议动态生成的class、和method - * 本地模式:动态生成的_DynLocalXXXXService类其带有@MultiRun方法均会打上@SncpDyn(remote = false, index=N) 的注解 - * 远程模式:动态生成的_DynRemoteXXXService类会打上@SncpDyn(remote = true) 的注解 - * - *

详情见: http://www.redkale.org - * @author zhangjx - */ -@Inherited -@Documented -@Target({METHOD, TYPE}) -@Retention(RUNTIME) -public @interface SncpDyn { - - boolean remote(); - - int index() default 0; //排列顺序, 主要用于Method -} diff --git a/src/main/java/org/redkale/net/sncp/SncpDynServlet.java b/src/main/java/org/redkale/net/sncp/SncpDynServlet.java deleted file mode 100644 index 846ac094c..000000000 --- a/src/main/java/org/redkale/net/sncp/SncpDynServlet.java +++ /dev/null @@ -1,428 +0,0 @@ -/* - * 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.sncp; - -import static org.redkale.net.sncp.SncpRequest.DEFAULT_HEADER; -import java.io.*; -import java.lang.annotation.*; -import java.lang.reflect.*; -import java.nio.*; -import java.util.*; -import java.util.function.*; -import java.util.logging.*; -import javax.annotation.*; -import jdk.internal.org.objectweb.asm.*; -import static jdk.internal.org.objectweb.asm.Opcodes.*; -import jdk.internal.org.objectweb.asm.Type; -import org.redkale.convert.bson.*; -import org.redkale.service.*; -import org.redkale.util.*; -import org.redkale.service.DynCall; - -/** - * - *

- * 详情见: http://www.redkale.org - * - * @author zhangjx - */ -public final class SncpDynServlet extends SncpServlet { - - private static volatile int maxClassNameLength = 0; - - private static volatile int maxNameLength = 0; - - private static final Logger logger = Logger.getLogger(SncpDynServlet.class.getSimpleName()); - - private final boolean finest = logger.isLoggable(Level.FINEST); - - private final Class type; - - private final String serviceName; - - private final DLong serviceid; - - private final HashMap actions = new HashMap<>(); - - private Supplier bufferSupplier; - - public SncpDynServlet(final BsonConvert convert, final String serviceName, final Class type, final Service service) { - this.serviceName = serviceName; - this.type = type; - this.serviceid = Sncp.hash(type.getName() + ':' + serviceName); - Set actionids = new HashSet<>(); - for (java.lang.reflect.Method method : service.getClass().getMethods()) { - if (method.isSynthetic()) continue; - if (Modifier.isStatic(method.getModifiers())) continue; - if (Modifier.isFinal(method.getModifiers())) continue; - if (method.getName().equals("getClass") || method.getName().equals("toString")) continue; - if (method.getName().equals("equals") || method.getName().equals("hashCode")) continue; - if (method.getName().equals("notify") || method.getName().equals("notifyAll") || method.getName().equals("wait")) continue; - if (method.getName().equals("init") || method.getName().equals("destroy") || method.getName().equals("name")) continue; - final DLong actionid = Sncp.hash(method); - SncpServletAction action = SncpServletAction.create(service, actionid, method); - action.convert = convert; - if (actionids.contains(actionid)) { - throw new RuntimeException(type.getName() + " have action(Method=" + method + ", actionid=" + actionid + ") same to (" + actions.get(actionid).method + ")"); - } - actions.put(actionid, action); - actionids.add(actionid); - } - maxNameLength = Math.max(maxNameLength, serviceName.length() + 1); - maxClassNameLength = Math.max(maxClassNameLength, type.getName().length()); - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append(this.getClass().getSimpleName()).append("(type=").append(type.getName()); - int len = maxClassNameLength - type.getName().length(); - for (int i = 0; i < len; i++) { - sb.append(' '); - } - sb.append(", serviceid=").append(serviceid).append(", name='").append(serviceName).append("'"); - for (int i = 0; i < maxNameLength - serviceName.length(); i++) { - sb.append(' '); - } - sb.append(", actions.size=").append(actions.size() > 9 ? "" : " ").append(actions.size()).append(")"); - return sb.toString(); - } - - - @Override - public DLong getServiceid() { - return serviceid; - } - - @Override - public int compareTo(SncpServlet o0) { - if (!(o0 instanceof SncpDynServlet)) return 1; - SncpDynServlet o = (SncpDynServlet) o0; - int rs = this.type.getName().compareTo(o.type.getName()); - if (rs == 0) rs = this.serviceName.compareTo(o.serviceName); - return rs; - } - - @Override - public void execute(SncpRequest request, SncpResponse response) throws IOException { - if (bufferSupplier == null) { - bufferSupplier = request.getContext().getBufferSupplier(); - } - SncpServletAction action = actions.get(request.getActionid()); - //if (finest) logger.log(Level.FINEST, "sncpdyn.execute: " + request + ", " + (action == null ? "null" : action.method)); - if (action == null) { - response.finish(SncpResponse.RETCODE_ILLACTIONID, null); //无效actionid - } else { - BsonWriter out = action.convert.pollBsonWriter(bufferSupplier); - out.writeTo(DEFAULT_HEADER); - BsonReader in = action.convert.pollBsonReader(); - try { - in.setBytes(request.getBody()); - action.action(in, out); - response.finish(0, out); - } catch (Throwable t) { - response.getContext().getLogger().log(Level.INFO, "sncp execute error(" + request + ")", t); - response.finish(SncpResponse.RETCODE_THROWEXCEPTION, null); - } finally { - action.convert.offerBsonReader(in); - action.convert.offerBsonWriter(out); - } - } - } - - public static abstract class SncpServletAction { - - public Method method; - - @Resource - protected BsonConvert convert; - - protected org.redkale.util.Attribute[] paramAttrs; // 为null表示无DynCall处理,index=0固定为null, 其他为参数标记的DynCall回调方法 - - protected java.lang.reflect.Type[] paramTypes; //index=0表示返回参数的type, void的返回参数类型为null - - public abstract void action(final BsonReader in, final BsonWriter out) throws Throwable; - - public final void callParameter(final BsonWriter out, final Object... params) { - if (paramAttrs != null) { - for (int i = 1; i < paramAttrs.length; i++) { - org.redkale.util.Attribute attr = paramAttrs[i]; - if (attr == null) continue; - out.writeByte((byte) i); - convert.convertTo(out, attr.type(), attr.get(params[i - 1])); - } - } - out.writeByte((byte) 0); - } - - /** - *

-         *  public class TestService implements Service {
-         *      public boolean change(TestBean bean, String name, int id) {
-         *
-         *      }
-         *  }
-         *
-         *  public class DynActionTestService_change extends SncpServletAction {
-         *
-         *      public TestService service;
-         *
-         *      @Override
-         *      public void action(final BsonReader in, final BsonWriter out) throws Throwable {
-         *          TestBean arg1 = convert.convertFrom(paramTypes[1], in);
-         *          String arg2 = convert.convertFrom(paramTypes[2], in);
-         *          int arg3 = convert.convertFrom(paramTypes[3], in);
-         *          Object rs = service.change(arg1, arg2, arg3);
-         *          callParameter(out, arg1, arg2, arg3);
-         *          convert.convertTo(out, paramTypes[0], rs);
-         *      }
-         *  }
-         * 
- * - * @param service Service - * @param actionid 操作ID - * @param method 方法 - * @return SncpServletAction - */ - @SuppressWarnings("unchecked") - public static SncpServletAction create(final Service service, final DLong actionid, final Method method) { - final Class serviceClass = service.getClass(); - final String supDynName = SncpServletAction.class.getName().replace('.', '/'); - final String serviceName = serviceClass.getName().replace('.', '/'); - final String convertName = BsonConvert.class.getName().replace('.', '/'); - final String convertReaderDesc = Type.getDescriptor(BsonReader.class); - final String convertWriterDesc = Type.getDescriptor(BsonWriter.class); - final String serviceDesc = Type.getDescriptor(serviceClass); - String newDynName = serviceName.substring(0, serviceName.lastIndexOf('/') + 1) - + "DynAction" + serviceClass.getSimpleName() + "_" + method.getName() + "_" + actionid; - while (true) { - try { - Class.forName(newDynName.replace('/', '.')); - newDynName += "_"; - } catch (Exception ex) { - break; - } - } - //------------------------------------------------------------- - ClassWriter cw = new ClassWriter(0); - FieldVisitor fv; - AsmMethodVisitor mv; - - cw.visit(V1_8, ACC_PUBLIC + ACC_FINAL + ACC_SUPER, newDynName, null, supDynName, null); - - { - { - fv = cw.visitField(ACC_PUBLIC, "service", serviceDesc, null, null); - fv.visitEnd(); - } - fv.visitEnd(); - } - { // constructor方法 - mv = new AsmMethodVisitor(cw.visitMethod(ACC_PUBLIC, "", "()V", null, null)); - mv.visitVarInsn(ALOAD, 0); - mv.visitMethodInsn(INVOKESPECIAL, supDynName, "", "()V", false); - mv.visitInsn(RETURN); - mv.visitMaxs(1, 1); - mv.visitEnd(); - } - String convertFromDesc = "(Ljava/lang/reflect/Type;" + convertReaderDesc + ")Ljava/lang/Object;"; - try { - convertFromDesc = Type.getMethodDescriptor(BsonConvert.class.getMethod("convertFrom", java.lang.reflect.Type.class, BsonReader.class)); - } catch (Exception ex) { - throw new RuntimeException(ex); //不可能会发生 - } - { // action方法 - mv = new AsmMethodVisitor(cw.visitMethod(ACC_PUBLIC, "action", "(" + convertReaderDesc + convertWriterDesc + ")V", null, new String[]{"java/lang/Throwable"})); - //mv.setDebug(true); - int iconst = ICONST_1; - int intconst = 1; - int store = 3; //action的参数个数+1 - final Class[] paramClasses = method.getParameterTypes(); - int[][] codes = new int[paramClasses.length][2]; - for (int i = 0; i < paramClasses.length; i++) { //参数 - mv.visitVarInsn(ALOAD, 0); - mv.visitFieldInsn(GETFIELD, newDynName, "convert", Type.getDescriptor(BsonConvert.class)); - mv.visitVarInsn(ALOAD, 0); - mv.visitFieldInsn(GETFIELD, newDynName, "paramTypes", "[Ljava/lang/reflect/Type;"); - if (iconst > ICONST_5) { - mv.visitIntInsn(BIPUSH, intconst); - } else { - mv.visitInsn(iconst); // - } - mv.visitInsn(AALOAD); - mv.visitVarInsn(ALOAD, 1); - - mv.visitMethodInsn(INVOKEVIRTUAL, convertName, "convertFrom", convertFromDesc, false); - int load = ALOAD; - int v = 0; - if (paramClasses[i].isPrimitive()) { - int storecode = ISTORE; - load = ILOAD; - if (paramClasses[i] == long.class) { - storecode = LSTORE; - load = LLOAD; - v = 1; - } else if (paramClasses[i] == float.class) { - storecode = FSTORE; - load = FLOAD; - v = 1; - } else if (paramClasses[i] == double.class) { - storecode = DSTORE; - load = DLOAD; - v = 1; - } - Class bigPrimitiveClass = Array.get(Array.newInstance(paramClasses[i], 1), 0).getClass(); - String bigPrimitiveName = bigPrimitiveClass.getName().replace('.', '/'); - try { - Method pm = bigPrimitiveClass.getMethod(paramClasses[i].getSimpleName() + "Value"); - mv.visitTypeInsn(CHECKCAST, bigPrimitiveName); - mv.visitMethodInsn(INVOKEVIRTUAL, bigPrimitiveName, pm.getName(), Type.getMethodDescriptor(pm), false); - } catch (Exception ex) { - throw new RuntimeException(ex); //不可能会发生 - } - mv.visitVarInsn(storecode, store); - } else { - mv.visitTypeInsn(CHECKCAST, paramClasses[i].getName().replace('.', '/')); - mv.visitVarInsn(ASTORE, store); // - } - codes[i] = new int[]{load, store}; - store += v; - iconst++; - intconst++; - store++; - } - { //调用service - mv.visitVarInsn(ALOAD, 0); - mv.visitFieldInsn(GETFIELD, newDynName, "service", serviceDesc); - for (int[] j : codes) { - mv.visitVarInsn(j[0], j[1]); - } - mv.visitMethodInsn(INVOKEVIRTUAL, serviceName, method.getName(), Type.getMethodDescriptor(method), false); - } - - final Class returnClass = method.getReturnType(); - if (returnClass != void.class) { - if (returnClass.isPrimitive()) { - Class bigClass = Array.get(Array.newInstance(returnClass, 1), 0).getClass(); - try { - Method vo = bigClass.getMethod("valueOf", returnClass); - mv.visitMethodInsn(INVOKESTATIC, bigClass.getName().replace('.', '/'), vo.getName(), Type.getMethodDescriptor(vo), false); - } catch (Exception ex) { - throw new RuntimeException(ex); //不可能会发生 - } - } - mv.visitVarInsn(ASTORE, store); //11 - } - //------------------------- callParameter 方法 -------------------------------- - mv.visitVarInsn(ALOAD, 0); - mv.visitVarInsn(ALOAD, 2); - if (paramClasses.length <= 5) { //参数总数量 - mv.visitInsn(ICONST_0 + paramClasses.length); - } else { - mv.visitIntInsn(BIPUSH, paramClasses.length); - } - mv.visitTypeInsn(ANEWARRAY, "java/lang/Object"); - int insn = 2; - for (int j = 0; j < paramClasses.length; j++) { - final Class pt = paramClasses[j]; - mv.visitInsn(DUP); - insn++; - if (j <= 5) { - mv.visitInsn(ICONST_0 + j); - } else { - mv.visitIntInsn(BIPUSH, j); - } - if (pt.isPrimitive()) { - if (pt == long.class) { - mv.visitVarInsn(LLOAD, insn++); - } else if (pt == float.class) { - mv.visitVarInsn(FLOAD, insn++); - } else if (pt == double.class) { - mv.visitVarInsn(DLOAD, insn++); - } else { - mv.visitVarInsn(ILOAD, insn); - } - Class bigclaz = java.lang.reflect.Array.get(java.lang.reflect.Array.newInstance(pt, 1), 0).getClass(); - mv.visitMethodInsn(INVOKESTATIC, bigclaz.getName().replace('.', '/'), "valueOf", "(" + Type.getDescriptor(pt) + ")" + Type.getDescriptor(bigclaz), false); - } else { - mv.visitVarInsn(ALOAD, insn); - } - mv.visitInsn(AASTORE); - } - mv.visitMethodInsn(INVOKEVIRTUAL, newDynName, "callParameter", "(" + convertWriterDesc + "[Ljava/lang/Object;)V", false); - - //-------------------------直接返回 或者 调用convertTo方法 -------------------------------- - int maxStack = codes.length > 0 ? codes[codes.length - 1][1] : 1; - if (returnClass == void.class) { //返回 - mv.visitInsn(RETURN); - maxStack = 8; - } else { - mv.visitVarInsn(ALOAD, 0); - mv.visitFieldInsn(GETFIELD, newDynName, "convert", Type.getDescriptor(BsonConvert.class)); - mv.visitVarInsn(ALOAD, 2); - mv.visitVarInsn(ALOAD, 0); - mv.visitFieldInsn(GETFIELD, newDynName, "paramTypes", "[Ljava/lang/reflect/Type;"); - mv.visitInsn(ICONST_0); - mv.visitInsn(AALOAD); - mv.visitVarInsn(ALOAD, store); - mv.visitMethodInsn(INVOKEVIRTUAL, convertName, "convertTo", "(" + convertWriterDesc + "Ljava/lang/reflect/Type;Ljava/lang/Object;)V", false); - mv.visitInsn(RETURN); - store++; - if (maxStack < 10) maxStack = 10; - } - mv.visitMaxs(maxStack, store); - mv.visitEnd(); - } - cw.visitEnd(); - - byte[] bytes = cw.toByteArray(); - Class newClazz = new ClassLoader(serviceClass.getClassLoader()) { - public final Class loadClass(String name, byte[] b) { - return defineClass(name, b, 0, b.length); - } - }.loadClass(newDynName.replace('/', '.'), bytes); - try { - SncpServletAction instance = (SncpServletAction) newClazz.newInstance(); - instance.method = method; - java.lang.reflect.Type[] ptypes = method.getGenericParameterTypes(); - java.lang.reflect.Type[] types = new java.lang.reflect.Type[ptypes.length + 1]; - java.lang.reflect.Type rt = method.getGenericReturnType(); - if (rt instanceof TypeVariable) { - TypeVariable tv = (TypeVariable) rt; - if (tv.getBounds().length == 1) rt = tv.getBounds()[0]; - } - types[0] = rt; - System.arraycopy(ptypes, 0, types, 1, ptypes.length); - instance.paramTypes = types; - - org.redkale.util.Attribute[] atts = new org.redkale.util.Attribute[ptypes.length + 1]; - Annotation[][] anns = method.getParameterAnnotations(); - boolean hasattr = false; - for (int i = 0; i < anns.length; i++) { - if (anns[i].length > 0) { - for (Annotation ann : anns[i]) { - if (ann.annotationType() == DynCall.class) { - try { - atts[i + 1] = ((DynCall) ann).value().newInstance(); - hasattr = true; - } catch (Exception e) { - logger.log(Level.SEVERE, DynCall.class.getSimpleName() + ".attribute cannot a newInstance for" + method, e); - } - break; - } - } - } - } - if (hasattr) instance.paramAttrs = atts; - newClazz.getField("service").set(instance, service); - return instance; - } catch (Exception ex) { - throw new RuntimeException(ex); //不可能会发生 - } - } - } - -} diff --git a/src/main/java/org/redkale/net/sncp/SncpPrepareServlet.java b/src/main/java/org/redkale/net/sncp/SncpPrepareServlet.java deleted file mode 100644 index 626e83814..000000000 --- a/src/main/java/org/redkale/net/sncp/SncpPrepareServlet.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * 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.sncp; - -import org.redkale.net.PrepareServlet; -import org.redkale.util.AnyValue; -import java.io.IOException; -import java.nio.ByteBuffer; -import java.util.*; -import org.redkale.util.*; - -/** - * - *

- * 详情见: http://www.redkale.org - * - * @author zhangjx - */ -public class SncpPrepareServlet extends PrepareServlet { - - private static final ByteBuffer pongBuffer = ByteBuffer.wrap("PONG".getBytes()).asReadOnlyBuffer(); - - @Override - public void addServlet(SncpServlet servlet, Object attachment, AnyValue conf, DLong... mappings) { - addServlet((SncpServlet) servlet, conf); - } - - public void addServlet(SncpServlet servlet, AnyValue conf) { - setServletConf(servlet, conf); - synchronized (mappings) { - mappings.put(servlet.getServiceid(), servlet); - servlets.add(servlet); - } - } - - public List getSncpServlets() { - ArrayList list = new ArrayList<>(servlets.size()); - servlets.forEach(x -> list.add((SncpServlet) x)); - return list; - } - - @Override - public void init(SncpContext context, AnyValue config) { - servlets.forEach(s -> s.init(context, getServletConf(s))); - } - - @Override - public void destroy(SncpContext context, AnyValue config) { - servlets.forEach(s -> s.destroy(context, getServletConf(s))); - } - - @Override - public void execute(SncpRequest request, SncpResponse response) throws IOException { - if (request.isPing()) { - response.finish(pongBuffer.duplicate()); - return; - } - SncpServlet servlet = (SncpServlet) mappings.get(request.getServiceid()); - if (servlet == null) { - response.finish(SncpResponse.RETCODE_ILLSERVICEID, null); //无效serviceid - } else { - servlet.execute(request, response); - } - } - -} diff --git a/src/main/java/org/redkale/net/sncp/SncpRequest.java b/src/main/java/org/redkale/net/sncp/SncpRequest.java deleted file mode 100644 index c465870fb..000000000 --- a/src/main/java/org/redkale/net/sncp/SncpRequest.java +++ /dev/null @@ -1,139 +0,0 @@ -/* - * 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.sncp; - -import java.net.*; -import java.nio.*; -import org.redkale.convert.bson.*; -import org.redkale.net.*; -import org.redkale.util.*; - -/** - * - *

- * 详情见: http://www.redkale.org - * - * @author zhangjx - */ -public final class SncpRequest extends Request { - - public static final int HEADER_SIZE = 56; - - public static final byte[] DEFAULT_HEADER = new byte[HEADER_SIZE]; - - protected final BsonConvert convert; - - private long seqid; - - private DLong serviceid; - - private DLong actionid; - - private int bodylength; - - private int bodyoffset; - - private boolean ping; - - private byte[] body; - - private byte[] bufferbytes = new byte[6]; - - protected SncpRequest(SncpContext context) { - super(context); - this.convert = context.getBsonConvert(); - } - - @Override - protected int readHeader(ByteBuffer buffer) { - if (buffer.remaining() < HEADER_SIZE) { - this.ping = true; - return 0; - } - //---------------------head---------------------------------- - this.seqid = buffer.getLong(); - if (buffer.getChar() != HEADER_SIZE) { - context.getLogger().finest("sncp buffer header.length not " + HEADER_SIZE); - return -1; - } - this.serviceid = DLong.read(buffer); - this.actionid = DLong.read(buffer); - buffer.get(bufferbytes); - this.bodylength = buffer.getInt(); - - if (buffer.getInt() != 0) { - context.getLogger().finest("sncp buffer header.retcode not 0"); - return -1; - } - //---------------------body---------------------------------- - this.body = new byte[this.bodylength]; - int len = Math.min(this.bodylength, buffer.remaining()); - buffer.get(body, 0, len); - this.bodyoffset = len; - return bodylength - len; - } - - @Override - protected int readBody(ByteBuffer buffer) { - final int framelen = buffer.remaining(); - buffer.get(this.body, this.bodyoffset, framelen); - this.bodyoffset += framelen; - return framelen; - } - - @Override - protected void prepare() { - this.keepAlive = true; - } - - @Override - public String toString() { - return SncpRequest.class.getSimpleName() + "{seqid=" + this.seqid - + ",serviceid=" + this.serviceid + ",actionid=" + this.actionid - + ",bodylength=" + this.bodylength + ",bodyoffset=" + this.bodyoffset - + ",remoteAddress=" + getRemoteAddress() + "}"; - } - - @Override - protected void recycle() { - this.seqid = 0; - this.serviceid = null; - this.actionid = null; - this.bodylength = 0; - this.bodyoffset = 0; - this.body = null; - this.ping = false; - this.bufferbytes[0] = 0; - super.recycle(); - } - - protected boolean isPing() { - return ping; - } - - public byte[] getBody() { - return body; - } - - public long getSeqid() { - return seqid; - } - - public DLong getServiceid() { - return serviceid; - } - - public DLong getActionid() { - return actionid; - } - - public InetSocketAddress getRemoteAddress() { - if (bufferbytes[0] == 0) return null; - return new InetSocketAddress((0xff & bufferbytes[0]) + "." + (0xff & bufferbytes[1]) + "." + (0xff & bufferbytes[2]) + "." + (0xff & bufferbytes[3]), - ((0xff00 & (bufferbytes[4] << 8)) | (0xff & bufferbytes[5]))); - } - -} diff --git a/src/main/java/org/redkale/net/sncp/SncpResponse.java b/src/main/java/org/redkale/net/sncp/SncpResponse.java deleted file mode 100644 index 422e576de..000000000 --- a/src/main/java/org/redkale/net/sncp/SncpResponse.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * 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.sncp; - -import static org.redkale.net.sncp.SncpRequest.HEADER_SIZE; -import java.nio.*; -import java.util.concurrent.atomic.*; -import org.redkale.convert.bson.*; -import org.redkale.net.*; -import org.redkale.util.*; - -/** - * - *

- * 详情见: http://www.redkale.org - * - * @author zhangjx - */ -public final class SncpResponse extends Response { - - public static final int RETCODE_ILLSERVICEID = (1 << 10); //无效serviceid - - public static final int RETCODE_ILLACTIONID = (1 << 11); //无效actionid - - public static final int RETCODE_THROWEXCEPTION = (1 << 30); //内部异常 - - public static ObjectPool createPool(AtomicLong creatCounter, AtomicLong cycleCounter, int max, Creator creator) { - return new ObjectPool<>(creatCounter, cycleCounter, max, creator, (x) -> ((SncpResponse) x).prepare(), (x) -> ((SncpResponse) x).recycle()); - } - - private final byte[] addrBytes; - - private final int addrPort; - - public static String getRetCodeInfo(int retcode) { - if (retcode == RETCODE_ILLSERVICEID) return "serviceid is invalid"; - if (retcode == RETCODE_ILLACTIONID) return "actionid is invalid"; - if (retcode == RETCODE_THROWEXCEPTION) return "Inner exception"; - return null; - } - - protected SncpResponse(SncpContext context, SncpRequest request) { - super(context, request); - this.addrBytes = context.getServerAddress().getAddress().getAddress(); - this.addrPort = context.getServerAddress().getPort(); - } - - public void finish(final int retcode, final BsonWriter out) { - if (out == null) { - final ByteBuffer buffer = context.pollBuffer(); - fillHeader(buffer, 0, retcode); - finish(buffer); - return; - } - final int respBodyLength = out.count(); //body总长度 - final ByteBuffer[] buffers = out.toBuffers(); - fillHeader(buffers[0], respBodyLength - HEADER_SIZE, retcode); - finish(buffers); - } - - private void fillHeader(ByteBuffer buffer, int bodyLength, int retcode) { - //---------------------head---------------------------------- - final int currentpos = buffer.position(); - buffer.position(0); - buffer.putLong(request.getSeqid()); - buffer.putChar((char) SncpRequest.HEADER_SIZE); - DLong.write(buffer, request.getServiceid()); - DLong.write(buffer, request.getActionid()); - buffer.put(addrBytes); - buffer.putChar((char) this.addrPort); - buffer.putInt(bodyLength); - buffer.putInt(retcode); - buffer.position(currentpos); - } -} diff --git a/src/main/java/org/redkale/net/sncp/SncpServer.java b/src/main/java/org/redkale/net/sncp/SncpServer.java deleted file mode 100644 index b223d7ef0..000000000 --- a/src/main/java/org/redkale/net/sncp/SncpServer.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * 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.sncp; - -import java.nio.*; -import java.util.*; -import java.util.concurrent.atomic.*; -import org.redkale.convert.bson.*; -import org.redkale.net.*; -import org.redkale.util.*; -import org.redkale.watch.*; - -/** - * Service Node Communicate Protocol - * - *

- * 详情见: http://www.redkale.org - * - * @author zhangjx - */ -@SuppressWarnings("unchecked") -public final class SncpServer extends Server { - - public SncpServer() { - this(System.currentTimeMillis(), null); - } - - public SncpServer(long serverStartTime, final WatchFactory watch) { - super(serverStartTime, "TCP", new SncpPrepareServlet(), watch); - } - - @Override - public void init(AnyValue config) throws Exception { - super.init(config); - } - - public void addService(ServiceWrapper entry) { - for (Class type : entry.getTypes()) { - SncpDynServlet sds = new SncpDynServlet(BsonFactory.root().getConvert(), entry.getName(), type, entry.getService()); - this.prepare.addServlet(sds, null, entry.getConf()); - } - } - - public List getSncpServlets() { - return ((SncpPrepareServlet) this.prepare).getSncpServlets(); - } - - @Override - @SuppressWarnings("unchecked") - protected SncpContext createContext() { - final int port = this.address.getPort(); - AtomicLong createBufferCounter = watch == null ? new AtomicLong() : watch.createWatchNumber("SNCP_" + port + ".Buffer.creatCounter"); - AtomicLong cycleBufferCounter = watch == null ? new AtomicLong() : watch.createWatchNumber("SNCP_" + port + ".Buffer.cycleCounter"); - final int rcapacity = Math.max(this.bufferCapacity, 4 * 1024); - ObjectPool bufferPool = new ObjectPool<>(createBufferCounter, cycleBufferCounter, this.bufferPoolSize, - (Object... params) -> ByteBuffer.allocateDirect(rcapacity), null, (e) -> { - if (e == null || e.isReadOnly() || e.capacity() != rcapacity) return false; - e.clear(); - return true; - }); - AtomicLong createResponseCounter = watch == null ? new AtomicLong() : watch.createWatchNumber("SNCP_" + port + ".Response.creatCounter"); - AtomicLong cycleResponseCounter = watch == null ? new AtomicLong() : watch.createWatchNumber("SNCP_" + port + ".Response.cycleCounter"); - ObjectPool responsePool = SncpResponse.createPool(createResponseCounter, cycleResponseCounter, this.responsePoolSize, null); - SncpContext sncpcontext = new SncpContext(this.serverStartTime, this.logger, executor, rcapacity, bufferPool, responsePool, - this.maxbody, this.charset, this.address, this.prepare, this.watch, this.readTimeoutSecond, this.writeTimeoutSecond); - responsePool.setCreator((Object... params) -> new SncpResponse(sncpcontext, new SncpRequest(sncpcontext))); - return sncpcontext; - } - -} diff --git a/src/main/java/org/redkale/net/sncp/SncpServlet.java b/src/main/java/org/redkale/net/sncp/SncpServlet.java deleted file mode 100644 index bfe46615a..000000000 --- a/src/main/java/org/redkale/net/sncp/SncpServlet.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * 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.sncp; - -import org.redkale.net.*; -import org.redkale.util.*; - -/** - * - *

- * 详情见: http://www.redkale.org - * - * @author zhangjx - */ -public abstract class SncpServlet extends Servlet implements Comparable { - - public abstract DLong getServiceid(); - - @Override - public final boolean equals(Object obj) { - return obj != null && obj.getClass() == this.getClass(); - } - - @Override - public final int hashCode() { - return this.getClass().hashCode(); - } - - @Override - public int compareTo(SncpServlet o) { - return 0; - } -} diff --git a/src/main/java/org/redkale/net/sncp/package-info.java b/src/main/java/org/redkale/net/sncp/package-info.java deleted file mode 100644 index 60085c7d0..000000000 --- a/src/main/java/org/redkale/net/sncp/package-info.java +++ /dev/null @@ -1,4 +0,0 @@ -/** - * SNCP协议包,提供SNCP协议服务器 - */ -package org.redkale.net.sncp; diff --git a/src/main/java/org/redkale/service/CacheSourceService.java b/src/main/java/org/redkale/service/CacheSourceService.java deleted file mode 100644 index 22e43c63e..000000000 --- a/src/main/java/org/redkale/service/CacheSourceService.java +++ /dev/null @@ -1,492 +0,0 @@ -/* - * 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.service; - -import java.beans.*; -import java.io.*; -import java.lang.reflect.*; -import java.nio.channels.*; -import java.util.*; -import java.util.concurrent.*; -import java.util.function.*; -import java.util.logging.*; -import javax.annotation.*; -import org.redkale.convert.*; -import org.redkale.convert.json.*; -import org.redkale.net.sncp.*; -import org.redkale.source.*; -import org.redkale.util.*; - -/** - * - * @param key类型 - * @param value类型 - *

- * 详情见: http://www.redkale.org - * @author zhangjx - */ -@AutoLoad(false) -@ResourceType({CacheSourceService.class, CacheSource.class}) -public class CacheSourceService implements CacheSource, Service, AutoCloseable { - - @Resource(name = "APP_HOME") - private File home; - - @Resource - private JsonConvert convert; - - private boolean needStore; - - private Class keyType; - - private Type objValueType; - - private Type setValueType; - - private Type listValueType; - - private ScheduledThreadPoolExecutor scheduler; - - private Consumer expireHandler; - - private final Logger logger = Logger.getLogger(this.getClass().getSimpleName()); - - protected final ConcurrentHashMap> container = new ConcurrentHashMap<>(); - - public CacheSourceService() { - } - - public final CacheSourceService setStoreType(Class keyType, Class valueType) { - this.keyType = keyType; - this.objValueType = valueType; - this.setValueType = TypeToken.createParameterizedType(null, CopyOnWriteArraySet.class, valueType); - this.listValueType = TypeToken.createParameterizedType(null, ConcurrentLinkedQueue.class, valueType); - this.setNeedStore(this.keyType != null && this.keyType != Serializable.class && this.objValueType != null); - return this; - } - - public final void setNeedStore(boolean needStore) { - this.needStore = needStore; - } - - @Override - public void init(AnyValue conf) { - final CacheSourceService self = this; - AnyValue prop = conf == null ? null : conf.getAnyValue("property"); - if (keyType == null && prop != null) { - String storeKeyStr = prop.getValue("key-type"); - String storeValueStr = prop.getValue("value-type"); - if (storeKeyStr != null && storeValueStr != null) { - try { - this.setStoreType(Class.forName(storeKeyStr), Class.forName(storeValueStr)); - } catch (Exception e) { - logger.log(Level.SEVERE, self.getClass().getSimpleName() + " load key & value store class (" + storeKeyStr + ", " + storeValueStr + ") error", e); - } - } - if (prop.getBoolValue("store-ignore", false)) setNeedStore(false); - } - String expireHandlerClass = prop == null ? null : prop.getValue("expirehandler"); - if (expireHandlerClass != null) { - try { - this.expireHandler = (Consumer) Class.forName(expireHandlerClass).newInstance(); - } catch (Exception e) { - logger.log(Level.SEVERE, self.getClass().getSimpleName() + " new expirehandler class (" + expireHandlerClass + ") instance error", e); - } - } - if (scheduler == null) { - this.scheduler = new ScheduledThreadPoolExecutor(1, (Runnable r) -> { - final Thread t = new Thread(r, self.getClass().getSimpleName() + "-Expirer-Thread"); - t.setDaemon(true); - return t; - }); - final List keys = new ArrayList<>(); - scheduler.scheduleWithFixedDelay(() -> { - keys.clear(); - int now = (int) (System.currentTimeMillis() / 1000); - container.forEach((k, x) -> { - if (x.expireSeconds > 0 && (now > (x.lastAccessed + x.expireSeconds))) { - keys.add(x.key); - } - }); - for (K key : keys) { - CacheEntry entry = container.remove(key); - if (expireHandler != null && entry != null) expireHandler.accept(entry); - } - }, 10, 10, TimeUnit.SECONDS); - logger.finest(self.getClass().getSimpleName() + ":" + self.name() + " start schedule expire executor"); - } - if (Sncp.isRemote(self)) return; - - boolean datasync = false; //是否从远程同步过数据 - //----------同步数据……----------- - // TODO - if (!this.needStore) return; - try { - File store = new File(home, "cache/" + name()); - if (!store.isFile() || !store.canRead()) return; - LineNumberReader reader = new LineNumberReader(new FileReader(store)); - if (this.keyType == null) this.keyType = Serializable.class; - if (this.objValueType == null) { - this.objValueType = Object.class; - this.setValueType = TypeToken.createParameterizedType(null, CopyOnWriteArraySet.class, this.objValueType); - this.listValueType = TypeToken.createParameterizedType(null, ConcurrentLinkedQueue.class, this.objValueType); - } - final Type storeObjType = TypeToken.createParameterizedType(null, CacheEntry.class, keyType, objValueType); - final Type storeSetType = TypeToken.createParameterizedType(null, CacheEntry.class, keyType, setValueType); - final Type storeListType = TypeToken.createParameterizedType(null, CacheEntry.class, keyType, listValueType); - String line; - while ((line = reader.readLine()) != null) { - if (line.isEmpty()) continue; - CacheEntry entry = convert.convertFrom(line.startsWith(CacheEntry.JSON_SET_KEY) ? storeSetType : (line.startsWith(CacheEntry.JSON_LIST_KEY) ? storeListType : storeObjType), line); - if (entry.isExpired()) continue; - if (datasync && container.containsKey(entry.key)) continue; //已经同步了 - container.put(entry.key, entry); - } - reader.close(); - store.delete(); - } catch (Exception e) { - logger.log(Level.SEVERE, CacheSource.class.getSimpleName() + "(" + name() + ") load store file error ", e); - } - } - - @Override - public void close() throws Exception { //给Application 关闭时调用 - destroy(null); - } - - public String name() { - return this.getClass().getAnnotation(Resource.class).name(); - } - - @Override - public void destroy(AnyValue conf) { - if (scheduler != null) scheduler.shutdownNow(); - if (!this.needStore || Sncp.isRemote(this) || container.isEmpty()) return; - try { - File store = new File(home, "cache/" + name()); - store.getParentFile().mkdirs(); - PrintStream stream = new PrintStream(store, "UTF-8"); - final Type storeObjType = TypeToken.createParameterizedType(null, CacheEntry.class, keyType, objValueType); - final Type storeSetType = TypeToken.createParameterizedType(null, CacheEntry.class, keyType, setValueType); - final Type storeListType = TypeToken.createParameterizedType(null, CacheEntry.class, keyType, listValueType); - Collection> entrys = (Collection>) container.values(); - for (CacheEntry entry : entrys) { - stream.println(convert.convertTo(entry.isSetCacheType() ? storeSetType : (entry.isListCacheType() ? storeListType : storeObjType), entry)); - } - container.clear(); - stream.close(); - } catch (Exception e) { - logger.log(Level.SEVERE, CacheSource.class.getSimpleName() + "(" + name() + ") store to file error ", e); - } - } - - @Override - public boolean exists(K key) { - if (key == null) return false; - CacheEntry entry = container.get(key); - if (entry == null) return false; - return !entry.isExpired(); - } - - @Override - public void exists(final CompletionHandler handler, @DynAttachment final K key) { - if (handler != null) handler.completed(exists(key), key); - } - - @Override - public V get(K key) { - if (key == null) return null; - CacheEntry entry = container.get(key); - if (entry == null || entry.isExpired() || entry.value == null) return null; - if (entry.isListCacheType()) return (V) new ArrayList((Collection) entry.value); - if (entry.isSetCacheType()) return (V) new HashSet((Collection) entry.value); - return (V) entry.getValue(); - } - - @Override - public void get(final CompletionHandler handler, @DynAttachment final K key) { - if (handler != null) handler.completed(get(key), key); - } - - @Override - @MultiRun - public V getAndRefresh(K key, final int expireSeconds) { - if (key == null) return null; - CacheEntry entry = container.get(key); - if (entry == null || entry.isExpired() || entry.value == null) return null; - entry.lastAccessed = (int) (System.currentTimeMillis() / 1000); - entry.expireSeconds = expireSeconds; - if (entry.isListCacheType()) return (V) new ArrayList((Collection) entry.value); - if (entry.isSetCacheType()) return (V) new HashSet((Collection) entry.value); - return (V) entry.getValue(); - } - - @Override - public void getAndRefresh(final CompletionHandler handler, @DynAttachment final K key, final int expireSeconds) { - V rs = getAndRefresh(key, expireSeconds); - if (handler != null) handler.completed(rs, key); - } - - @Override - @MultiRun - public void refresh(K key, final int expireSeconds) { - if (key == null) return; - CacheEntry entry = container.get(key); - if (entry == null) return; - entry.lastAccessed = (int) (System.currentTimeMillis() / 1000); - entry.expireSeconds = expireSeconds; - } - - @Override - public void refresh(final CompletionHandler handler, final K key, final int expireSeconds) { - refresh(key, expireSeconds); - if (handler != null) handler.completed(null, key); - } - - @Override - @MultiRun - public void set(K key, V value) { - if (key == null) return; - CacheEntry entry = container.get(key); - if (entry == null) { - entry = new CacheEntry(CacheEntryType.OBJECT, key, value); - container.putIfAbsent(key, entry); - } else { - entry.expireSeconds = 0; - entry.value = value; - entry.lastAccessed = (int) (System.currentTimeMillis() / 1000); - } - } - - @Override - public void set(final CompletionHandler handler, @DynAttachment final K key, final V value) { - set(key, value); - if (handler != null) handler.completed(null, key); - } - - @Override - @MultiRun - public void set(int expireSeconds, K key, V value) { - if (key == null) return; - CacheEntry entry = container.get(key); - if (entry == null) { - entry = new CacheEntry(CacheEntryType.OBJECT, expireSeconds, key, value); - container.putIfAbsent(key, entry); - } else { - if (expireSeconds > 0) entry.expireSeconds = expireSeconds; - entry.lastAccessed = (int) (System.currentTimeMillis() / 1000); - entry.value = value; - } - } - - @Override - public void set(final CompletionHandler handler, final int expireSeconds, @DynAttachment final K key, final V value) { - set(expireSeconds, key, value); - if (handler != null) handler.completed(null, key); - } - - @Override - @MultiRun - public void setExpireSeconds(K key, int expireSeconds) { - if (key == null) return; - CacheEntry entry = container.get(key); - if (entry == null) return; - entry.expireSeconds = expireSeconds; - } - - @Override - public void setExpireSeconds(final CompletionHandler handler, @DynAttachment final K key, final int expireSeconds) { - setExpireSeconds(key, expireSeconds); - if (handler != null) handler.completed(null, key); - } - - @Override - @MultiRun - public void remove(K key) { - if (key == null) return; - container.remove(key); - } - - @Override - public void remove(final CompletionHandler handler, @DynAttachment final K key) { - remove(key); - if (handler != null) handler.completed(null, key); - } - - @Override - public Collection getCollection(final K key) { - return (Collection) get(key); - } - - @Override - public void getCollection(final CompletionHandler, K> handler, @DynAttachment final K key) { - if (handler != null) handler.completed(getCollection(key), key); - } - - @Override - public Collection getCollectionAndRefresh(final K key, final int expireSeconds) { - return (Collection) getAndRefresh(key, expireSeconds); - } - - @Override - public void getCollectionAndRefresh(final CompletionHandler, K> handler, @DynAttachment final K key, final int expireSeconds) { - if (handler != null) handler.completed(getCollectionAndRefresh(key, expireSeconds), key); - } - - @Override - @MultiRun - public void appendListItem(K key, V value) { - if (key == null) return; - CacheEntry entry = container.get(key); - if (entry == null || !entry.isListCacheType()) { - Collection list = new ConcurrentLinkedQueue<>(); - entry = new CacheEntry(CacheEntryType.LIST, key, list); - CacheEntry old = container.putIfAbsent(key, entry); - if (old != null) list = (Collection) old.value; - list.add(value); - } else { - ((Collection) entry.getValue()).add(value); - } - } - - @Override - public void appendListItem(final CompletionHandler handler, @DynAttachment final K key, final V value) { - appendListItem(key, value); - if (handler != null) handler.completed(null, key); - } - - @Override - @MultiRun - public void removeListItem(K key, V value) { - if (key == null) return; - CacheEntry entry = container.get(key); - if (entry == null || !entry.isListCacheType()) return; - ((Collection) entry.getValue()).remove(value); - } - - @Override - public void removeListItem(final CompletionHandler handler, @DynAttachment final K key, final V value) { - removeListItem(key, value); - if (handler != null) handler.completed(null, key); - } - - @Override - @MultiRun - public void appendSetItem(K key, V value) { - if (key == null) return; - CacheEntry entry = container.get(key); - if (entry == null || !entry.isSetCacheType()) { - Collection set = new CopyOnWriteArraySet(); - entry = new CacheEntry(CacheEntryType.SET, key, set); - CacheEntry old = container.putIfAbsent(key, entry); - if (old != null) set = (Collection) old.value; - set.add(value); - } else { - ((Collection) entry.getValue()).add(value); - } - } - - @Override - public void appendSetItem(final CompletionHandler handler, @DynAttachment final K key, final V value) { - appendSetItem(key, value); - if (handler != null) handler.completed(null, key); - } - - @Override - @MultiRun - public void removeSetItem(K key, V value) { - if (key == null) return; - CacheEntry entry = container.get(key); - if (entry == null || !(entry.value instanceof Set)) return; - ((Set) entry.getValue()).remove(value); - } - - @Override - public void removeSetItem(final CompletionHandler handler, @DynAttachment final K key, final V value) { - removeSetItem(key, value); - if (handler != null) handler.completed(null, key); - } - - public static enum CacheEntryType { - OBJECT, SET, LIST; - } - - public static final class CacheEntry { - - public static final String JSON_SET_KEY = "{\"cacheType\":\"" + CacheEntryType.SET + "\""; - - public static final String JSON_LIST_KEY = "{\"cacheType\":\"" + CacheEntryType.LIST + "\""; - - private final CacheEntryType cacheType; - - private final K key; - - //<=0表示永久保存 - private int expireSeconds; - - private volatile int lastAccessed; //最后刷新时间 - - private T value; - - public CacheEntry(CacheEntryType cacheType, K key, T value) { - this(cacheType, 0, key, value); - } - - public CacheEntry(CacheEntryType cacheType, int expireSeconds, K key, T value) { - this(cacheType, expireSeconds, (int) (System.currentTimeMillis() / 1000), key, value); - } - - @ConstructorProperties({"cacheType", "expireSeconds", "lastAccessed", "key", "value"}) - public CacheEntry(CacheEntryType cacheType, int expireSeconds, int lastAccessed, K key, T value) { - this.cacheType = cacheType; - this.expireSeconds = expireSeconds; - this.lastAccessed = lastAccessed; - this.key = key; - this.value = value; - } - - @Override - public String toString() { - return JsonFactory.root().getConvert().convertTo(this); - } - - @ConvertColumn(ignore = true) - public boolean isListCacheType() { - return cacheType == CacheEntryType.LIST; - } - - @ConvertColumn(ignore = true) - public boolean isSetCacheType() { - return cacheType == CacheEntryType.SET; - } - - @ConvertColumn(ignore = true) - public boolean isExpired() { - return (expireSeconds > 0 && lastAccessed + expireSeconds < (System.currentTimeMillis() / 1000)); - } - - public CacheEntryType getCacheType() { - return cacheType; - } - - public int getExpireSeconds() { - return expireSeconds; - } - - public int getLastAccessed() { - return lastAccessed; - } - - public T getValue() { - return value; - } - - public K getKey() { - return key; - } - - } -} diff --git a/src/main/java/org/redkale/service/DataCacheListenerService.java b/src/main/java/org/redkale/service/DataCacheListenerService.java deleted file mode 100644 index 1e5bf37be..000000000 --- a/src/main/java/org/redkale/service/DataCacheListenerService.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * 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.service; - -import java.io.*; -import javax.annotation.*; -import org.redkale.source.*; -import org.redkale.util.*; - -/** - * - *

- * 详情见: http://www.redkale.org - * - * @author zhangjx - */ -@AutoLoad(false) -@ResourceType({DataCacheListenerService.class, DataCacheListener.class}) -public class DataCacheListenerService implements DataCacheListener, Service { - - @Resource(name = "$") - private DataSource source; - - @Override - @MultiRun(selfrun = false, async = true) - public void insertCache(Class clazz, T... entitys) { - ((DataDefaultSource) source).insertCache(clazz, entitys); - } - - @Override - @MultiRun(selfrun = false, async = true) - public void updateCache(Class clazz, T... entitys) { - ((DataDefaultSource) source).updateCache(clazz, entitys); - } - - @Override - @MultiRun(selfrun = false, async = true) - public void deleteCache(Class clazz, Serializable... ids) { - ((DataDefaultSource) source).deleteCache(clazz, ids); - } - -} diff --git a/src/main/java/org/redkale/service/DataSQLListenerService.java b/src/main/java/org/redkale/service/DataSQLListenerService.java deleted file mode 100644 index b1b356467..000000000 --- a/src/main/java/org/redkale/service/DataSQLListenerService.java +++ /dev/null @@ -1,128 +0,0 @@ -/* - * 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.service; - -import org.redkale.source.DataSQLListener; -import org.redkale.source.DataSource; -import org.redkale.source.DataDefaultSource; -import org.redkale.util.AnyValue; -import org.redkale.util.AutoLoad; -import java.io.*; -import java.util.*; -import java.util.concurrent.*; -import java.util.logging.*; -import javax.annotation.Resource; -import org.redkale.util.*; - -/** - * 暂时不实现 - * - *

- * 详情见: http://www.redkale.org - * - * @author zhangjx - */ -@Deprecated -@AutoLoad(false) -@ResourceType({DataSQLListenerService.class, DataSQLListener.class}) -public class DataSQLListenerService implements DataSQLListener, Service { - - private static final String format = "%1$tY-%1$tm-%1$td %1$tH:%1$tM:%1$tS.%tL"; - - protected final Logger logger = Logger.getLogger(this.getClass().getSimpleName()); - - private final boolean finest = logger.isLoggable(Level.FINEST); - - @Resource(name = "APP_HOME") - private File home; - - @Resource(name = "$") - private DataSource source; - - private final BlockingQueue queue = new ArrayBlockingQueue<>(1024 * 1024); - - private PrintStream syncfile; - - @Override - public void init(AnyValue config) { - new Thread() { - { - setName(DataSQLListener.class.getSimpleName() + "-Thread"); - setDaemon(true); - } - - @Override - public void run() { - while (true) { - try { - String sql = queue.take(); - send(sql); - } catch (Exception e) { - logger.log(Level.SEVERE, this.getName() + " occur error"); - } - } - } - }.start(); - - } - - public String name() { - return this.getClass().getAnnotation(Resource.class).name(); - } - - @Override - public void destroy(AnyValue config) { - if (syncfile != null) syncfile.close(); - } - - private void write(String... sqls) { - try { - if (syncfile == null) { - File root = new File(home, "dbsync"); - root.mkdirs(); - syncfile = new PrintStream(new FileOutputStream(new File(root, "sql-" + name() + ".sql"), true), false, "UTF-8"); - } - for (String sql : sqls) { - syncfile.print(sql + ";\r\n"); - } - syncfile.flush(); - } catch (Exception e) { - logger.log(Level.WARNING, "write sql file error. (" + name() + ", " + Arrays.toString(sqls) + ")", e); - } - } - - @Override - public void insert(String... sqls) { - put(sqls); - } - - @Override - public void update(String... sqls) { - put(sqls); - } - - @Override - public void delete(String... sqls) { - put(sqls); - } - - private void put(String... sqls) { - String date = String.format(format, System.currentTimeMillis()); - for (String sql : sqls) { - try { - queue.put("/* " + date + " */ " + sql); - } catch (Exception e) { - write(sql); - } - } - } - - @MultiRun(selfrun = false, async = true) - public void send(String... sqls) { - ((DataDefaultSource) source).directExecute(sqls); - } - -} diff --git a/src/main/java/org/redkale/service/DataSourceService.java b/src/main/java/org/redkale/service/DataSourceService.java deleted file mode 100644 index ef3fcfaf9..000000000 --- a/src/main/java/org/redkale/service/DataSourceService.java +++ /dev/null @@ -1,561 +0,0 @@ -/* - * 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.service; - -import java.io.*; -import java.nio.channels.*; -import java.sql.*; -import java.util.*; -import java.util.function.*; -import javax.annotation.*; -import org.redkale.source.*; -import org.redkale.util.*; - -/** - * DataSource对应的Service类, 该类主要特点是将所有含FilterBean参数的方法重载成FilterNode对应的方法。 - * - *

- * 详情见: http://www.redkale.org - * - * @author zhangjx - */ -@AutoLoad(false) -@ResourceType({DataSourceService.class, DataSource.class}) -public class DataSourceService implements DataSource, Service, AutoCloseable { - - @Resource(name = "$") - private DataSource source; - - @Override - public void insert(@DynCall(DataCallArrayAttribute.class) T... values) { - source.insert(values); - } - - @Override - public void insert(final CompletionHandler handler, @DynAttachment @DynCall(DataCallArrayAttribute.class) final T... values) { - source.insert(values); - if (handler != null) handler.completed(null, values); - } - - @Override - public void delete(T... values) { - source.delete(values); - } - - @Override - public void delete(final CompletionHandler handler, @DynAttachment final T... values) { - source.delete(values); - if (handler != null) handler.completed(null, values); - } - - @Override - public void delete(final Class clazz, final Serializable... ids) { - source.delete(clazz, ids); - } - - @Override - public void delete(final CompletionHandler handler, final Class clazz, @DynAttachment final Serializable... ids) { - source.delete(clazz, ids); - if (handler != null) handler.completed(null, ids); - } - - @Override - public void delete(final Class clazz, FilterNode node) { - source.delete(clazz, node); - } - - @Override - public void delete(final CompletionHandler handler, final Class clazz, @DynAttachment final FilterNode node) { - source.delete(clazz, node); - if (handler != null) handler.completed(null, node); - } - - @Override - public void update(T... values) { - source.update(values); - } - - @Override - public void update(final CompletionHandler handler, @DynAttachment final T... values) { - source.update(values); - if (handler != null) handler.completed(null, values); - } - - @Override - public void updateColumn(final Class clazz, final Serializable id, final String column, final Serializable value) { - source.updateColumn(clazz, id, column, value); - } - - @Override - public void updateColumn(final CompletionHandler handler, final Class clazz, @DynAttachment final Serializable id, final String column, final Serializable value) { - source.updateColumn(clazz, id, column, value); - if (handler != null) handler.completed(null, id); - } - - @Override - public void updateColumnIncrement(final Class clazz, final Serializable id, final String column, long incvalue) { - source.updateColumnIncrement(clazz, id, column, incvalue); - } - - @Override - public void updateColumnIncrement(final CompletionHandler handler, final Class clazz, @DynAttachment final Serializable id, final String column, long incvalue) { - source.updateColumnIncrement(clazz, id, column, incvalue); - if (handler != null) handler.completed(null, id); - } - - @Override - public void updateColumnAnd(final Class clazz, final Serializable id, final String column, long incvalue) { - source.updateColumnAnd(clazz, id, column, incvalue); - } - - @Override - public void updateColumnAnd(final CompletionHandler handler, final Class clazz, @DynAttachment final Serializable id, final String column, long incvalue) { - source.updateColumnAnd(clazz, id, column, incvalue); - if (handler != null) handler.completed(null, id); - } - - @Override - public void updateColumnOr(final Class clazz, final Serializable id, final String column, long incvalue) { - source.updateColumnOr(clazz, id, column, incvalue); - } - - @Override - public void updateColumnOr(final CompletionHandler handler, final Class clazz, @DynAttachment final Serializable id, final String column, long incvalue) { - source.updateColumnOr(clazz, id, column, incvalue); - if (handler != null) handler.completed(null, id); - } - - @Override - public void updateColumns(T value, final String... columns) { - source.updateColumns(value, columns); - } - - @Override - public void updateColumns(final CompletionHandler handler, @DynAttachment final T value, final String... columns) { - source.updateColumns(value, columns); - if (handler != null) handler.completed(null, value); - } - - @Override - public Number getNumberResult(final Class entityClass, FilterFunc func, final String column) { - return source.getNumberResult(entityClass, func, column); - } - - @Override - public void getNumberResult(final CompletionHandler handler, final Class entityClass, final FilterFunc func, @DynAttachment final String column) { - Number rs = source.getNumberResult(entityClass, func, column); - if (handler != null) handler.completed(rs, column); - } - - @Override - public final Number getNumberResult(final Class entityClass, FilterFunc func, final String column, FilterBean bean) { - return getNumberResult(entityClass, func, column, FilterNodeBean.createFilterNode(bean)); - } - - @Override - public final void getNumberResult(final CompletionHandler handler, final Class entityClass, final FilterFunc func, final String column, final FilterBean bean) { - getNumberResult(handler, entityClass, func, column, FilterNodeBean.createFilterNode(bean)); - } - - @Override - public Number getNumberResult(final Class entityClass, FilterFunc func, final String column, FilterNode node) { - return source.getNumberResult(entityClass, func, column, node); - } - - @Override - public void getNumberResult(final CompletionHandler handler, final Class entityClass, final FilterFunc func, final String column, @DynAttachment final FilterNode node) { - Number rs = source.getNumberResult(entityClass, func, column, node); - if (handler != null) handler.completed(rs, node); - } - - @Override - public Map queryColumnMap(final Class entityClass, final String keyColumn, FilterFunc func, final String funcColumn) { - return source.queryColumnMap(entityClass, keyColumn, func, funcColumn); - } - - @Override - public void queryColumnMap(final CompletionHandler, String> handler, final Class entityClass, final String keyColumn, final FilterFunc func, @DynAttachment final String funcColumn) { - Map map = source.queryColumnMap(entityClass, keyColumn, func, funcColumn); - if (handler != null) handler.completed(map, funcColumn); - } - - @Override - public final Map queryColumnMap(final Class entityClass, final String keyColumn, FilterFunc func, final String funcColumn, FilterBean bean) { - return queryColumnMap(entityClass, keyColumn, func, funcColumn, FilterNodeBean.createFilterNode(bean)); - } - - @Override - public final void queryColumnMap(final CompletionHandler, FilterNode> handler, final Class entityClass, final String keyColumn, final FilterFunc func, final String funcColumn, final FilterBean bean) { - queryColumnMap(handler, entityClass, keyColumn, func, funcColumn, FilterNodeBean.createFilterNode(bean)); - } - - @Override - public Map queryColumnMap(final Class entityClass, final String keyColumn, FilterFunc func, final String funcColumn, FilterNode node) { - return source.queryColumnMap(entityClass, keyColumn, func, funcColumn, node); - } - - @Override - public void queryColumnMap(final CompletionHandler, FilterNode> handler, final Class entityClass, final String keyColumn, final FilterFunc func, final String funcColumn, @DynAttachment final FilterNode node) { - Map map = source.queryColumnMap(entityClass, keyColumn, func, funcColumn, node); - if (handler != null) handler.completed(map, node); - } - - @Override - public T find(final Class clazz, final Serializable pk) { - return source.find(clazz, pk); - } - - @Override - public void find(final CompletionHandler handler, final Class clazz, @DynAttachment final Serializable pk) { - T rs = source.find(clazz, pk); - if (handler != null) handler.completed(rs, pk); - } - - @Override - public T find(final Class clazz, SelectColumn selects, final Serializable pk) { - return source.find(clazz, selects, pk); - } - - @Override - public void find(final CompletionHandler handler, final Class clazz, final SelectColumn selects, @DynAttachment final Serializable pk) { - T rs = source.find(clazz, selects, pk); - if (handler != null) handler.completed(rs, pk); - } - - @Override - public T find(final Class clazz, final String column, final Serializable key) { - return source.find(clazz, column, key); - } - - @Override - public void find(final CompletionHandler handler, final Class clazz, final String column, @DynAttachment final Serializable key) { - T rs = source.find(clazz, column, key); - if (handler != null) handler.completed(rs, key); - } - - @Override - public final T find(final Class clazz, FilterBean bean) { - return find(clazz, FilterNodeBean.createFilterNode(bean)); - } - - @Override - public final void find(final CompletionHandler handler, final Class clazz, final FilterBean bean) { - find(handler, clazz, FilterNodeBean.createFilterNode(bean)); - } - - @Override - public T find(final Class clazz, FilterNode node) { - return source.find(clazz, node); - } - - @Override - public void find(final CompletionHandler handler, final Class clazz, @DynAttachment final FilterNode node) { - T rs = source.find(clazz, node); - if (handler != null) handler.completed(rs, node); - } - - @Override - public final T find(final Class clazz, final SelectColumn selects, FilterBean bean) { - return find(clazz, selects, FilterNodeBean.createFilterNode(bean)); - } - - @Override - public final void find(final CompletionHandler handler, final Class clazz, final SelectColumn selects, final FilterBean bean) { - find(handler, clazz, selects, FilterNodeBean.createFilterNode(bean)); - } - - @Override - public T find(final Class clazz, final SelectColumn selects, final FilterNode node) { - return source.find(clazz, selects, node); - } - - @Override - public void find(final CompletionHandler handler, final Class clazz, final SelectColumn selects, @DynAttachment final FilterNode node) { - T rs = source.find(clazz, selects, node); - if (handler != null) handler.completed(rs, node); - } - - @Override - public boolean exists(final Class clazz, final Serializable pk) { - return source.exists(clazz, pk); - } - - @Override - public void exists(final CompletionHandler handler, final Class clazz, @DynAttachment final Serializable pk) { - boolean rs = source.exists(clazz, pk); - if (handler != null) handler.completed(rs, pk); - } - - @Override - public final boolean exists(final Class clazz, FilterBean bean) { - return exists(clazz, FilterNodeBean.createFilterNode(bean)); - } - - @Override - public final void exists(final CompletionHandler handler, final Class clazz, final FilterBean bean) { - exists(handler, clazz, FilterNodeBean.createFilterNode(bean)); - } - - @Override - public boolean exists(final Class clazz, FilterNode node) { - return source.exists(clazz, node); - } - - @Override - public void exists(final CompletionHandler handler, final Class clazz, @DynAttachment final FilterNode node) { - boolean rs = source.exists(clazz, node); - if (handler != null) handler.completed(rs, node); - } - - @Override - public HashSet queryColumnSet(String selectedColumn, Class clazz, final String column, final Serializable key) { - return source.queryColumnSet(selectedColumn, clazz, column, key); - } - - @Override - public void queryColumnSet(final CompletionHandler, Serializable> handler, final String selectedColumn, final Class clazz, final String column, @DynAttachment final Serializable key) { - HashSet rs = source.queryColumnSet(selectedColumn, clazz, column, key); - if (handler != null) handler.completed(rs, key); - } - - @Override - public final HashSet queryColumnSet(String selectedColumn, Class clazz, FilterBean bean) { - return queryColumnSet(selectedColumn, clazz, FilterNodeBean.createFilterNode(bean)); - } - - @Override - public final void queryColumnSet(final CompletionHandler, FilterNode> handler, final String selectedColumn, final Class clazz, final FilterBean bean) { - queryColumnSet(handler, selectedColumn, clazz, FilterNodeBean.createFilterNode(bean)); - } - - @Override - public HashSet queryColumnSet(String selectedColumn, Class clazz, FilterNode node) { - return source.queryColumnSet(selectedColumn, clazz, node); - } - - @Override - public void queryColumnSet(final CompletionHandler, FilterNode> handler, final String selectedColumn, final Class clazz, @DynAttachment final FilterNode node) { - HashSet rs = source.queryColumnSet(selectedColumn, clazz, node); - if (handler != null) handler.completed(rs, node); - } - - @Override - public List queryColumnList(String selectedColumn, Class clazz, final String column, final Serializable key) { - return source.queryColumnList(selectedColumn, clazz, column, key); - } - - @Override - public void queryColumnList(final CompletionHandler, Serializable> handler, final String selectedColumn, final Class clazz, final String column, @DynAttachment final Serializable key) { - List rs = source.queryColumnList(selectedColumn, clazz, column, key); - if (handler != null) handler.completed(rs, key); - } - - @Override - public final List queryColumnList(String selectedColumn, Class clazz, FilterBean bean) { - return queryColumnList(selectedColumn, clazz, FilterNodeBean.createFilterNode(bean)); - } - - @Override - public final void queryColumnList(final CompletionHandler, FilterNode> handler, final String selectedColumn, final Class clazz, @DynAttachment final FilterBean bean) { - queryColumnList(handler, selectedColumn, clazz, FilterNodeBean.createFilterNode(bean)); - } - - @Override - public List queryColumnList(String selectedColumn, Class clazz, FilterNode node) { - return source.queryColumnList(selectedColumn, clazz, node); - } - - @Override - public void queryColumnList(final CompletionHandler, FilterNode> handler, final String selectedColumn, final Class clazz, @DynAttachment final FilterNode node) { - List rs = source.queryColumnList(selectedColumn, clazz, node); - if (handler != null) handler.completed(rs, node); - } - - @Override - public final Sheet queryColumnSheet(String selectedColumn, Class clazz, Flipper flipper, FilterBean bean) { - return queryColumnSheet(selectedColumn, clazz, flipper, FilterNodeBean.createFilterNode(bean)); - } - - @Override - public final void queryColumnSheet(final CompletionHandler, FilterNode> handler, final String selectedColumn, final Class clazz, final Flipper flipper, final FilterBean bean) { - queryColumnSheet(handler, selectedColumn, clazz, flipper, FilterNodeBean.createFilterNode(bean)); - } - - @Override - public Sheet queryColumnSheet(String selectedColumn, Class clazz, Flipper flipper, FilterNode node) { - return source.queryColumnSheet(selectedColumn, clazz, flipper, node); - } - - @Override - public void queryColumnSheet(final CompletionHandler, FilterNode> handler, final String selectedColumn, final Class clazz, final Flipper flipper, @DynAttachment final FilterNode node) { - Sheet rs = source.queryColumnSheet(selectedColumn, clazz, flipper, node); - if (handler != null) handler.completed(rs, node); - } - - @Override - public List queryList(final Class clazz, final String column, final Serializable key) { - return source.queryList(clazz, column, key); - } - - @Override - public void queryList(final CompletionHandler, Serializable> handler, final Class clazz, final String column, @DynAttachment final Serializable key) { - List rs = source.queryList(clazz, column, key); - if (handler != null) handler.completed(rs, key); - } - - @Override - public final List queryList(final Class clazz, final FilterBean bean) { - return queryList(clazz, FilterNodeBean.createFilterNode(bean)); - } - - @Override - public final void queryList(final CompletionHandler, FilterNode> handler, final Class clazz, final FilterBean bean) { - queryList(handler, clazz, FilterNodeBean.createFilterNode(bean)); - } - - @Override - public List queryList(final Class clazz, final FilterNode node) { - return source.queryList(clazz, node); - } - - @Override - public void queryList(final CompletionHandler, FilterNode> handler, final Class clazz, @DynAttachment final FilterNode node) { - List rs = source.queryList(clazz, node); - if (handler != null) handler.completed(rs, node); - } - - @Override - public final List queryList(final Class clazz, final SelectColumn selects, final FilterBean bean) { - return queryList(clazz, FilterNodeBean.createFilterNode(bean)); - } - - @Override - public final void queryList(final CompletionHandler, FilterNode> handler, final Class clazz, final SelectColumn selects, final FilterBean bean) { - queryList(handler, clazz, selects, FilterNodeBean.createFilterNode(bean)); - } - - @Override - public List queryList(final Class clazz, final SelectColumn selects, final FilterNode node) { - return source.queryList(clazz, selects, node); - } - - @Override - public void queryList(final CompletionHandler, FilterNode> handler, final Class clazz, final SelectColumn selects, @DynAttachment final FilterNode node) { - List rs = source.queryList(clazz, selects, node); - if (handler != null) handler.completed(rs, node); - } - - @Override - public List queryList(final Class clazz, final Flipper flipper, final String column, final Serializable key) { - return source.queryList(clazz, flipper, column, key); - } - - @Override - public void queryList(final CompletionHandler, Serializable> handler, final Class clazz, final Flipper flipper, final String column, @DynAttachment final Serializable key) { - List rs = source.queryList(clazz, flipper, column, key); - if (handler != null) handler.completed(rs, key); - } - - @Override - public final List queryList(final Class clazz, final Flipper flipper, final FilterBean bean) { - return queryList(clazz, flipper, FilterNodeBean.createFilterNode(bean)); - } - - @Override - public final void queryList(final CompletionHandler, FilterNode> handler, final Class clazz, final Flipper flipper, final FilterBean bean) { - queryList(handler, clazz, flipper, FilterNodeBean.createFilterNode(bean)); - } - - @Override - public List queryList(final Class clazz, final Flipper flipper, final FilterNode node) { - return source.queryList(clazz, flipper, node); - } - - @Override - public void queryList(final CompletionHandler, FilterNode> handler, final Class clazz, final Flipper flipper, @DynAttachment final FilterNode node) { - List rs = source.queryList(clazz, flipper, node); - if (handler != null) handler.completed(rs, node); - } - - @Override - public final List queryList(final Class clazz, final SelectColumn selects, final Flipper flipper, final FilterBean bean) { - return queryList(clazz, selects, flipper, FilterNodeBean.createFilterNode(bean)); - } - - @Override - public final void queryList(final CompletionHandler, FilterNode> handler, final Class clazz, SelectColumn selects, final Flipper flipper, final FilterBean bean) { - queryList(handler, clazz, selects, flipper, FilterNodeBean.createFilterNode(bean)); - } - - @Override - public List queryList(final Class clazz, final SelectColumn selects, final Flipper flipper, final FilterNode node) { - return source.queryList(clazz, selects, flipper, node); - } - - @Override - public void queryList(final CompletionHandler, FilterNode> handler, final Class clazz, SelectColumn selects, final Flipper flipper, @DynAttachment final FilterNode node) { - List rs = source.queryList(clazz, selects, flipper, node); - if (handler != null) handler.completed(rs, node); - } - - @Override - public final Sheet querySheet(final Class clazz, final Flipper flipper, final FilterBean bean) { - return querySheet(clazz, flipper, FilterNodeBean.createFilterNode(bean)); - } - - @Override - public final void querySheet(final CompletionHandler, FilterNode> handler, final Class clazz, final Flipper flipper, final FilterBean bean) { - querySheet(handler, clazz, flipper, FilterNodeBean.createFilterNode(bean)); - } - - @Override - public Sheet querySheet(final Class clazz, final Flipper flipper, final FilterNode node) { - return source.querySheet(clazz, flipper, node); - } - - @Override - public void querySheet(final CompletionHandler, FilterNode> handler, final Class clazz, final Flipper flipper, @DynAttachment final FilterNode node) { - Sheet rs = source.querySheet(clazz, flipper, node); - if (handler != null) handler.completed(rs, node); - } - - @Override - public final Sheet querySheet(final Class clazz, final SelectColumn selects, final Flipper flipper, final FilterBean bean) { - return querySheet(clazz, selects, flipper, FilterNodeBean.createFilterNode(bean)); - } - - @Override - public final void querySheet(final CompletionHandler, FilterNode> handler, final Class clazz, final SelectColumn selects, final Flipper flipper, final FilterBean bean) { - querySheet(handler, clazz, selects, flipper, FilterNodeBean.createFilterNode(bean)); - } - - @Override - public Sheet querySheet(final Class clazz, final SelectColumn selects, final Flipper flipper, final FilterNode node) { - return source.querySheet(clazz, selects, flipper, node); - } - - @Override - public void querySheet(final CompletionHandler, FilterNode> handler, final Class clazz, final SelectColumn selects, final Flipper flipper, @DynAttachment final FilterNode node) { - Sheet rs = source.querySheet(clazz, selects, flipper, node); - if (handler != null) handler.completed(rs, node); - } - - @Override - public void close() throws Exception { - source.getClass().getMethod("close").invoke(source); - } - - @Override - public final void directQuery(String sql, Consumer consumer) { - source.directQuery(sql, consumer); - } - - @Override - public final int[] directExecute(String... sqls) { - return source.directExecute(sqls); - } - -} diff --git a/src/main/java/org/redkale/service/DynAttachment.java b/src/main/java/org/redkale/service/DynAttachment.java deleted file mode 100644 index 713aa91b8..000000000 --- a/src/main/java/org/redkale/service/DynAttachment.java +++ /dev/null @@ -1,25 +0,0 @@ -/* - * 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.service; - -import java.lang.annotation.*; -import static java.lang.annotation.ElementType.PARAMETER; -import static java.lang.annotation.RetentionPolicy.RUNTIME; - -/** - * SNCP协议中用于CompletionHandler回调函数中的attach字段。 - * - * - *

详情见: http://www.redkale.org - * @author zhangjx - */ -@Inherited -@Documented -@Target({PARAMETER}) -@Retention(RUNTIME) -public @interface DynAttachment { - -} diff --git a/src/main/java/org/redkale/service/DynCall.java b/src/main/java/org/redkale/service/DynCall.java deleted file mode 100644 index f92c423e3..000000000 --- a/src/main/java/org/redkale/service/DynCall.java +++ /dev/null @@ -1,25 +0,0 @@ -/* - * 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.service; - -import java.lang.annotation.*; -import static java.lang.annotation.RetentionPolicy.RUNTIME; -import org.redkale.util.*; - -/** - * 参数回写, 当Service的方法需要更改参数对象内部的数据时,需要使用DynCall - * - *

详情见: http://www.redkale.org - * @author zhangjx - */ -@Inherited -@Documented -@Target({ElementType.PARAMETER}) -@Retention(RUNTIME) -public @interface DynCall { - - Class value(); -} diff --git a/src/main/java/org/redkale/service/DynRemote.java b/src/main/java/org/redkale/service/DynRemote.java deleted file mode 100644 index 0b7b017e8..000000000 --- a/src/main/java/org/redkale/service/DynRemote.java +++ /dev/null @@ -1,24 +0,0 @@ -/* - * 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.service; - -import java.lang.annotation.*; -import static java.lang.annotation.ElementType.*; -import static java.lang.annotation.RetentionPolicy.RUNTIME; - -/** - * 用于在 Service 中创建自身远程模式的对象 - * - *

详情见: http://www.redkale.org - * @author zhangjx - */ -@Inherited -@Documented -@Target({FIELD}) -@Retention(RUNTIME) -public @interface DynRemote { - -} diff --git a/src/main/java/org/redkale/service/DynSourceAddress.java b/src/main/java/org/redkale/service/DynSourceAddress.java deleted file mode 100644 index 21c2d4c64..000000000 --- a/src/main/java/org/redkale/service/DynSourceAddress.java +++ /dev/null @@ -1,25 +0,0 @@ -/* - * 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.service; - -import java.lang.annotation.*; -import static java.lang.annotation.ElementType.PARAMETER; -import static java.lang.annotation.RetentionPolicy.RUNTIME; - -/** - * SNCP协议中标记为来源地址参数, 该注解只能标记在类型为SocketAddress或InetSocketAddress的参数上。 - * - * - *

详情见: http://www.redkale.org - * @author zhangjx - */ -@Inherited -@Documented -@Target({PARAMETER}) -@Retention(RUNTIME) -public @interface DynSourceAddress { - -} diff --git a/src/main/java/org/redkale/service/DynTargetAddress.java b/src/main/java/org/redkale/service/DynTargetAddress.java deleted file mode 100644 index d600c5eb9..000000000 --- a/src/main/java/org/redkale/service/DynTargetAddress.java +++ /dev/null @@ -1,25 +0,0 @@ -/* - * 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.service; - -import java.lang.annotation.*; -import static java.lang.annotation.ElementType.PARAMETER; -import static java.lang.annotation.RetentionPolicy.RUNTIME; - -/** - * SNCP协议中标记为目标地址参数, 该注解只能标记在类型为SocketAddress或InetSocketAddress的参数上。 - * - * - *

详情见: http://www.redkale.org - * @author zhangjx - */ -@Inherited -@Documented -@Target({PARAMETER}) -@Retention(RUNTIME) -public @interface DynTargetAddress { - -} diff --git a/src/main/java/org/redkale/service/LocalService.java b/src/main/java/org/redkale/service/LocalService.java deleted file mode 100644 index c944e4957..000000000 --- a/src/main/java/org/redkale/service/LocalService.java +++ /dev/null @@ -1,25 +0,0 @@ -/* - * 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.service; - -import java.lang.annotation.*; -import static java.lang.annotation.ElementType.TYPE; -import static java.lang.annotation.RetentionPolicy.RUNTIME; - -/** - * 本地模式注解。 - * 声明为LocalService的Service将不会变成远程模式,只能以本地模式存在, 无论配置文件中是否配置成远程模式都会被忽略。 - * - *

详情见: http://www.redkale.org - * @author zhangjx - */ -@Inherited -@Documented -@Target({TYPE}) -@Retention(RUNTIME) -public @interface LocalService { - -} diff --git a/src/main/java/org/redkale/service/MultiRun.java b/src/main/java/org/redkale/service/MultiRun.java deleted file mode 100644 index 5e47f28c1..000000000 --- a/src/main/java/org/redkale/service/MultiRun.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * 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.service; - -import java.lang.annotation.*; -import static java.lang.annotation.ElementType.*; -import static java.lang.annotation.RetentionPolicy.RUNTIME; - -/** - * MultiRun 只对本地模式Service有效 - * - *

- * 详情见: http://www.redkale.org - * - * @author zhangjx - */ -@Inherited -@Documented -@Target({METHOD}) -@Retention(RUNTIME) -public @interface MultiRun { - - boolean selfrun() default true; //当前本地实例是否运行指定操作;只有当指定操作的方法的返回值为void时,该值才能为true,否则忽略。 - - boolean samerun() default true; //是否同组节点运行指定操作 - - boolean diffrun() default true; //是否不同组节点运行指定操作 - - boolean async() default true; //分布式运行是否采用异步模式 -} diff --git a/src/main/java/org/redkale/service/RetResult.java b/src/main/java/org/redkale/service/RetResult.java deleted file mode 100644 index 4e8406026..000000000 --- a/src/main/java/org/redkale/service/RetResult.java +++ /dev/null @@ -1,116 +0,0 @@ -/* - * 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.service; - -import org.redkale.convert.json.*; - -/** - * 通用的结果对象,在常见的HTTP+JSON接口中返回的结果需要含结果码,错误信息,和实体对象。 - * - *

- * 详情见: http://www.redkale.org - * - * @author zhangjx - * @param 结果对象的泛型 - */ -public class RetResult { - - protected static final class RetSuccessResult extends RetResult { - - public RetSuccessResult() { - } - - @Override - public void setRetcode(int retcode) { - } - - @Override - public void setRetinfo(String retinfo) { - } - - @Override - public void setResult(T result) { - } - } - - public static final RetResult SUCCESS = new RetSuccessResult(); - - protected int retcode; - - protected String retinfo; - - private T result; - - public RetResult() { - } - - public RetResult(T result) { - this.result = result; - } - - public RetResult(int retcode) { - this.retcode = retcode; - } - - public RetResult(int retcode, String retinfo) { - this.retcode = retcode; - this.retinfo = retinfo; - } - - public RetResult(int retcode, String retinfo, T result) { - this.retcode = retcode; - this.retinfo = retinfo; - this.result = result; - } - - /** - * 判断结果是否成功返回, retcode = 0 视为成功, 否则视为错误码 - * - * @return 是否成功 - */ - public boolean isSuccess() { - return retcode == 0; - } - - /** - * 结果码 0表示成功、 非0表示错误 - * - * @return 结果码 - */ - public int getRetcode() { - return retcode; - } - - public void setRetcode(int retcode) { - this.retcode = retcode; - } - - public String getRetinfo() { - return retinfo; - } - - public void setRetinfo(String retinfo) { - this.retinfo = retinfo; - } - - /** - * 结果对象, 通常只有在retcode = 0时值才有效 - * - * @return 结果对象 - */ - public T getResult() { - return result; - } - - public void setResult(T result) { - this.result = result; - } - - @Override - public String toString() { - return JsonFactory.root().getConvert().convertTo(this); - } -} diff --git a/src/main/java/org/redkale/service/Service.java b/src/main/java/org/redkale/service/Service.java deleted file mode 100644 index 8e653c602..000000000 --- a/src/main/java/org/redkale/service/Service.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * 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.service; - -import org.redkale.util.*; - -/** - * 所有Service的实现类不得声明为final, 允许远程模式的public方法都不能声明为final。 - * 注意: "$"是一个很特殊的Service.name值 。 被标记为@Resource(name = "$") 的Service的资源名与所属父Service的资源名一致。 - * - *

- * Service的资源类型
- * 业务逻辑的Service通常有两种编写方式:
- *    1、只写一个Service实现类。
- *    2、先定义业务的Service接口或抽象类,再编写具体实现类。
- * 第二种方式需要在具体实现类上使用@ResourceType指明资源注入的类型。
- * 
- * - *

- * 详情见: http://www.redkale.org - * - * @author zhangjx - */ -public interface Service { - - /** - * 该方法必须是可以重复调用, 当reload时需要重复调用init方法 - * - * @param config 配置参数 - */ - default void init(AnyValue config) { - - } - - /** - * 进程退出时,调用Service销毁 - * - * @param config 配置参数 - */ - default void destroy(AnyValue config) { - - } - -} diff --git a/src/main/java/org/redkale/service/WebSocketNodeService.java b/src/main/java/org/redkale/service/WebSocketNodeService.java deleted file mode 100644 index 2809debb1..000000000 --- a/src/main/java/org/redkale/service/WebSocketNodeService.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * 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.service; - -import static org.redkale.net.http.WebSocket.*; -import java.io.*; -import java.net.*; -import java.util.*; -import org.redkale.net.http.*; -import org.redkale.util.*; - -/** - * - *

- * 详情见: http://www.redkale.org - * - * @author zhangjx - */ -@AutoLoad(false) -@ResourceType({WebSocketNodeService.class, WebSocketNode.class}) -public class WebSocketNodeService extends WebSocketNode implements Service { - - @Override - public void init(AnyValue conf) { - super.init(conf); - } - - @Override - public void destroy(AnyValue conf) { - super.destroy(conf); - } - - @Override - public List getOnlineRemoteAddresses(@DynTargetAddress InetSocketAddress targetAddress, Serializable groupid) { - if (localSncpAddress == null || !localSncpAddress.equals(targetAddress)) return remoteOnlineRemoteAddresses(targetAddress, groupid); - final Set engineids = localNodes.get(groupid); - if (engineids == null || engineids.isEmpty()) return null; - final List rs = new ArrayList<>(); - for (String engineid : engineids) { - final WebSocketEngine engine = engines.get(engineid); - if (engine == null) continue; - final WebSocketGroup group = engine.getWebSocketGroup(groupid); - group.getWebSockets().forEach(x -> rs.add("ws" + Objects.hashCode(x) + '@' + x.getRemoteAddr())); - } - return rs; - } - - @Override - public int sendMessage(@DynTargetAddress InetSocketAddress addr, Serializable groupid, boolean recent, Serializable message, boolean last) { - final Set engineids = localNodes.get(groupid); - if (engineids == null || engineids.isEmpty()) return RETCODE_GROUP_EMPTY; - int code = RETCODE_GROUP_EMPTY; - for (String engineid : engineids) { - final WebSocketEngine engine = engines.get(engineid); - if (engine != null) { //在本地 - final WebSocketGroup group = engine.getWebSocketGroup(groupid); - if (group == null || group.isEmpty()) { - if (finest) logger.finest("receive websocket message {engineid:'" + engineid + "', groupid:" + groupid + ", content:'" + message + "'} from " + addr + " but send result is " + RETCODE_GROUP_EMPTY); - return RETCODE_GROUP_EMPTY; - } - code = group.send(recent, message, last); - if (finest) logger.finest("websocket node send message (" + message + ") from " + addr + " result is " + code); - } - } - return code; - } - - @Override - public void connect(Serializable groupid, InetSocketAddress addr) { - source.appendSetItem(groupid, addr); - if (finest) logger.finest(WebSocketNodeService.class.getSimpleName() + ".event: " + groupid + " connect from " + addr); - } - - @Override - public void disconnect(Serializable groupid, InetSocketAddress addr) { - source.removeSetItem(groupid, addr); - if (finest) logger.finest(WebSocketNodeService.class.getSimpleName() + ".event: " + groupid + " disconnect from " + addr); - } -} diff --git a/src/main/java/org/redkale/service/package-info.java b/src/main/java/org/redkale/service/package-info.java deleted file mode 100644 index 0bf67060d..000000000 --- a/src/main/java/org/redkale/service/package-info.java +++ /dev/null @@ -1,4 +0,0 @@ -/** - * Service接口和模式配置包 - */ -package org.redkale.service; diff --git a/src/main/java/org/redkale/source/CacheSource.java b/src/main/java/org/redkale/source/CacheSource.java deleted file mode 100644 index 7fff58b61..000000000 --- a/src/main/java/org/redkale/source/CacheSource.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * 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.source; - -import java.io.*; -import java.nio.channels.*; -import java.util.*; - -/** - * - * @param key的类型 - * @param value的类型 - *

- * 详情见: http://www.redkale.org - * @author zhangjx - */ -public interface CacheSource { - - default boolean isOpen() { - return true; - } - - public boolean exists(final K key); - - public V get(final K key); - - public V getAndRefresh(final K key, final int expireSeconds); - - public void refresh(final K key, final int expireSeconds); - - public void set(final K key, final V value); - - public void set(final int expireSeconds, final K key, final V value); - - public void setExpireSeconds(final K key, final int expireSeconds); - - public void remove(final K key); - - public Collection getCollection(final K key); - - public Collection getCollectionAndRefresh(final K key, final int expireSeconds); - - public void appendListItem(final K key, final V value); - - public void removeListItem(final K key, final V value); - - public void appendSetItem(final K key, final V value); - - public void removeSetItem(final K key, final V value); - - //----------------------异步版--------------------------------- - public void exists(final CompletionHandler handler, final K key); - - public void get(final CompletionHandler handler, final K key); - - public void getAndRefresh(final CompletionHandler handler, final K key, final int expireSeconds); - - public void refresh(final CompletionHandler handler, final K key, final int expireSeconds); - - public void set(final CompletionHandler handler, final K key, final V value); - - public void set(final CompletionHandler handler, final int expireSeconds, final K key, final V value); - - public void setExpireSeconds(final CompletionHandler handler, final K key, final int expireSeconds); - - public void remove(final CompletionHandler handler, final K key); - - public void getCollection(final CompletionHandler, K> handler, final K key); - - public void getCollectionAndRefresh(final CompletionHandler, K> handler, final K key, final int expireSeconds); - - public void appendListItem(final CompletionHandler handler, final K key, final V value); - - public void removeListItem(final CompletionHandler handler, final K key, final V value); - - public void appendSetItem(final CompletionHandler handler, final K key, final V value); - - public void removeSetItem(final CompletionHandler handler, final K key, final V value); - - default void isOpen(final CompletionHandler handler) { - if (handler != null) handler.completed(Boolean.TRUE, null); - } -} diff --git a/src/main/java/org/redkale/source/DataCacheListener.java b/src/main/java/org/redkale/source/DataCacheListener.java deleted file mode 100644 index d26b809ec..000000000 --- a/src/main/java/org/redkale/source/DataCacheListener.java +++ /dev/null @@ -1,22 +0,0 @@ -/* - * 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.source; - -import java.io.Serializable; - -/** - * - *

详情见: http://www.redkale.org - * @author zhangjx - */ -public interface DataCacheListener { - - public void insertCache(Class clazz, T... entitys); - - public void updateCache(Class clazz, T... entitys); - - public void deleteCache(Class clazz, Serializable... ids); -} diff --git a/src/main/java/org/redkale/source/DataCallArrayAttribute.java b/src/main/java/org/redkale/source/DataCallArrayAttribute.java deleted file mode 100644 index 405707b2e..000000000 --- a/src/main/java/org/redkale/source/DataCallArrayAttribute.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * 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.source; - -import java.io.*; -import java.lang.reflect.*; -import org.redkale.util.*; - -/** - * - *

- * 详情见: http://www.redkale.org - * - * @author zhangjx - * @param Entity类的类型 - * @param 字段的类型 - */ -public final class DataCallArrayAttribute implements Attribute { - - public static final DataCallArrayAttribute instance = new DataCallArrayAttribute(); - - @Override - public Class type() { - return (Class) Object.class; - } - - @Override - public Class declaringClass() { - return (Class) (Class) Object[].class; - } - - @Override - public String field() { - return ""; - } - - @Override - public F get(final T[] objs) { - if (objs == null || objs.length == 0) return null; - final Attribute attr = DataCallAttribute.load(objs[0].getClass()); - final Object keys = Array.newInstance(attr.type(), objs.length); - for (int i = 0; i < objs.length; i++) { - Array.set(keys, i, attr.get(objs[i])); - } - return (F) keys; - } - - @Override - public void set(final T[] objs, final F keys) { - if (objs == null || objs.length == 0) return; - final Attribute attr = DataCallAttribute.load(objs[0].getClass()); - for (int i = 0; i < objs.length; i++) { - attr.set(objs[i], (Serializable) Array.get(keys, i)); - } - } - -} diff --git a/src/main/java/org/redkale/source/DataCallAttribute.java b/src/main/java/org/redkale/source/DataCallAttribute.java deleted file mode 100644 index 478846e24..000000000 --- a/src/main/java/org/redkale/source/DataCallAttribute.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * 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.source; - -import java.io.*; -import java.lang.reflect.*; -import java.util.concurrent.*; -import org.redkale.util.*; - -/** - * - *

详情见: http://www.redkale.org - * @author zhangjx - */ -public class DataCallAttribute implements Attribute { - - public static final DataCallAttribute instance = new DataCallAttribute(); - - private static final ConcurrentHashMap attributes = new ConcurrentHashMap<>(); - - static Attribute load(final Class clazz) { - Attribute rs = attributes.get(clazz); - if (rs != null) return rs; - synchronized (attributes) { - rs = attributes.get(clazz); - if (rs == null) { - Class cltmp = clazz; - do { - for (Field field : cltmp.getDeclaredFields()) { - if (field.getAnnotation(javax.persistence.Id.class) == null) continue; - try { - rs = Attribute.create(cltmp, field); - attributes.put(clazz, rs); - return rs; - } catch (RuntimeException e) { - } - } - } while ((cltmp = cltmp.getSuperclass()) != Object.class); - } - return rs; - } - } - - @Override - public Class type() { - return Serializable.class; - } - - @Override - public Class declaringClass() { - return Object.class; - } - - @Override - public String field() { - return ""; - } - - @Override - public Serializable get(final Object obj) { - if (obj == null) return null; - return load(obj.getClass()).get(obj); - } - - @Override - public void set(final Object obj, final Serializable key) { - if (obj == null) return; - load(obj.getClass()).set(obj, key); - } -} diff --git a/src/main/java/org/redkale/source/DataDefaultSource.java b/src/main/java/org/redkale/source/DataDefaultSource.java deleted file mode 100644 index dde52bf11..000000000 --- a/src/main/java/org/redkale/source/DataDefaultSource.java +++ /dev/null @@ -1,1738 +0,0 @@ -/* - * 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.source; - -import static org.redkale.source.FilterNode.*; -import java.io.*; -import java.lang.reflect.*; -import java.net.*; -import java.nio.channels.*; -import java.sql.*; -import java.util.*; -import java.util.concurrent.atomic.*; -import java.util.function.*; -import java.util.logging.*; -import javax.annotation.*; -import javax.sql.*; -import javax.xml.stream.*; -import org.redkale.util.*; - -/** - * - *

- * 详情见: http://www.redkale.org - * - * @author zhangjx - */ -@SuppressWarnings("unchecked") -public final class DataDefaultSource implements DataSource, Function, AutoCloseable { - - public static final String DATASOURCE_CONFPATH = "DATASOURCE_CONFPATH"; - - static final String JDBC_CONNECTIONSMAX = "javax.persistence.connections.limit"; - - static final String JDBC_CONTAIN_SQLTEMPLATE = "javax.persistence.contain.sqltemplate"; - - static final String JDBC_NOTCONTAIN_SQLTEMPLATE = "javax.persistence.notcontain.sqltemplate"; - - static final String JDBC_URL = "javax.persistence.jdbc.url"; - - static final String JDBC_USER = "javax.persistence.jdbc.user"; - - static final String JDBC_PWD = "javax.persistence.jdbc.password"; - - static final String JDBC_DRIVER = "javax.persistence.jdbc.driver"; - - static final String JDBC_SOURCE = "javax.persistence.jdbc.source"; - - private static final Flipper FLIPPER_ONE = new Flipper(1); - - final Logger logger = Logger.getLogger(DataDefaultSource.class.getSimpleName()); - - final AtomicBoolean debug = new AtomicBoolean(logger.isLoggable(Level.FINEST)); - - final String name; - - final URL conf; - - final boolean cacheForbidden; - - private final JDBCPoolSource readPool; - - private final JDBCPoolSource writePool; - - @Resource(name = "property.datasource.nodeid") - private int nodeid; - - @Resource(name = "$") - private DataSQLListener writeListener; - - @Resource(name = "$") - private DataCacheListener cacheListener; - - private final Function fullloader = (t) -> querySheet(false, false, t, null, null, (FilterNode) null).list(true); - - public DataDefaultSource() throws IOException { - this(""); - } - - public DataDefaultSource(final String unitName) throws IOException { - this(unitName, System.getProperty(DATASOURCE_CONFPATH) == null - ? DataDefaultSource.class.getResource("/META-INF/persistence.xml") - : new File(System.getProperty(DATASOURCE_CONFPATH)).toURI().toURL()); - } - - public DataDefaultSource(final String unitName, URL url) throws IOException { - if (url == null) url = this.getClass().getResource("/persistence.xml"); - InputStream in = url.openStream(); - Map map = loadProperties(in); - Properties readprop = null; - Properties writeprop = null; - if (unitName != null) { - readprop = map.get(unitName); - writeprop = readprop; - if (readprop == null) { - readprop = map.get(unitName + ".read"); - writeprop = map.get(unitName + ".write"); - } - } - if ((unitName == null || unitName.isEmpty()) || readprop == null) { - String key = null; - for (Map.Entry en : map.entrySet()) { - key = en.getKey(); - readprop = en.getValue(); - writeprop = readprop; - break; - } - if (key != null && (key.endsWith(".read") || key.endsWith(".write"))) { - if (key.endsWith(".read")) { - writeprop = map.get(key.substring(0, key.lastIndexOf('.')) + ".write"); - } else { - readprop = map.get(key.substring(0, key.lastIndexOf('.')) + ".read"); - } - } - } - if (readprop == null) throw new RuntimeException("not found persistence properties (unit:" + unitName + ")"); - this.name = unitName; - this.conf = url; - this.readPool = new JDBCPoolSource(this, "read", readprop); - this.writePool = new JDBCPoolSource(this, "write", writeprop); - this.cacheForbidden = "NONE".equalsIgnoreCase(readprop.getProperty("shared-cache-mode")); - } - - public DataDefaultSource(String unitName, Properties readprop, Properties writeprop) { - this.name = unitName; - this.conf = null; - this.readPool = new JDBCPoolSource(this, "read", readprop); - this.writePool = new JDBCPoolSource(this, "write", writeprop); - this.cacheForbidden = "NONE".equalsIgnoreCase(readprop.getProperty("shared-cache-mode")); - } - - public static Map create(final InputStream in) { - Map map = loadProperties(in); - Map maps = new HashMap<>(); - map.entrySet().stream().forEach((en) -> { - if (en.getKey().endsWith(".read") || en.getKey().endsWith(".write")) { - String key = en.getKey().substring(0, en.getKey().lastIndexOf('.')); - if (maps.containsKey(key)) return; - boolean read = en.getKey().endsWith(".read"); - Properties rp = read ? en.getValue() : map.get(key + ".read"); - Properties wp = read ? map.get(key + ".write") : en.getValue(); - maps.put(key, new Properties[]{rp, wp}); - } else { - maps.put(en.getKey(), new Properties[]{en.getValue(), en.getValue()}); - } - }); - Map result = new HashMap<>(); - maps.entrySet().stream().forEach((en) -> { - result.put(en.getKey(), new DataDefaultSource(en.getKey(), en.getValue()[0], en.getValue()[1])); - }); - return result; - } - - static Map loadProperties(final InputStream in0) { - final Map map = new LinkedHashMap(); - Properties result = new Properties(); - boolean flag = false; - try (final InputStream in = in0) { - XMLStreamReader reader = XMLInputFactory.newFactory().createXMLStreamReader(in); - while (reader.hasNext()) { - int event = reader.next(); - if (event == XMLStreamConstants.START_ELEMENT) { - if ("persistence-unit".equalsIgnoreCase(reader.getLocalName())) { - if (!result.isEmpty()) result = new Properties(); - map.put(reader.getAttributeValue(null, "name"), result); - flag = true; - } else if (flag && "property".equalsIgnoreCase(reader.getLocalName())) { - String name = reader.getAttributeValue(null, "name"); - String value = reader.getAttributeValue(null, "value"); - if (name == null) continue; - result.put(name, value); - } else if (flag && "shared-cache-mode".equalsIgnoreCase(reader.getLocalName())) { - result.put(reader.getLocalName(), reader.getElementText()); - } - } - } - in.close(); - } catch (Exception ex) { - throw new RuntimeException(ex); - } - return map; - } - - static ConnectionPoolDataSource createDataSource(Properties property) { - try { - return createDataSource(property.getProperty(JDBC_SOURCE, property.getProperty(JDBC_DRIVER)), - property.getProperty(JDBC_URL), property.getProperty(JDBC_USER), property.getProperty(JDBC_PWD)); - } catch (Exception ex) { - throw new RuntimeException("(" + property + ") have no jdbc parameters", ex); - } - } - - static ConnectionPoolDataSource createDataSource(final String source0, String url, String user, String password) throws Exception { - String source = source0; - if (source0.contains("Driver")) { //为了兼容JPA的配置文件 - switch (source0) { - case "org.mariadb.jdbc.Driver": - source = "org.mariadb.jdbc.MySQLDataSource"; - break; - case "com.mysql.jdbc.Driver": - source = "com.mysql.jdbc.jdbc2.optional.MysqlConnectionPoolDataSource"; - break; - case "oracle.jdbc.driver.OracleDriver": - source = "oracle.jdbc.pool.OracleConnectionPoolDataSource"; - break; - case "com.microsoft.sqlserver.jdbc.SQLServerDriver": - source = "com.microsoft.sqlserver.jdbc.SQLServerConnectionPoolDataSource"; - break; - } - } - final Class clazz = Class.forName(source); - Object pdsource = clazz.newInstance(); - Method seturlm; - try { - seturlm = clazz.getMethod("setUrl", String.class); - } catch (Exception e) { - seturlm = clazz.getMethod("setURL", String.class); - } - seturlm.invoke(pdsource, url); - clazz.getMethod("setUser", String.class).invoke(pdsource, user); - clazz.getMethod("setPassword", String.class).invoke(pdsource, password); - return (ConnectionPoolDataSource) pdsource; - } - - public final String name() { - return name; - } - - @Override - public void close() throws Exception { - readPool.close(); - writePool.close(); - } - - public String getName() { - return name; - } - - private Connection createReadSQLConnection() { - return readPool.poll(); - } - - private Connection createWriteSQLConnection() { - return writePool.poll(); - } - - private void closeSQLConnection(final Connection sqlconn) { - if (sqlconn == null) return; - try { - sqlconn.close(); - } catch (Exception e) { - logger.log(Level.WARNING, "closeSQLConnection abort", e); - } - } - - @Override - public final int[] directExecute(String... sqls) { - Connection conn = createWriteSQLConnection(); - try { - return directExecute(conn, sqls); - } finally { - closeSQLConnection(conn); - } - } - - private int[] directExecute(final Connection conn, String... sqls) { - if (sqls.length == 0) return new int[0]; - try { - final Statement stmt = conn.createStatement(); - final int[] rs = new int[sqls.length]; - int i = -1; - for (String sql : sqls) { - rs[++i] = stmt.execute(sql) ? 1 : 0; - - } - stmt.close(); - return rs; - } catch (SQLException e) { - throw new RuntimeException(e); - } - } - - @Override - public EntityInfo apply(Class t) { - return loadEntityInfo(t); - } - - private EntityInfo loadEntityInfo(Class clazz) { - return EntityInfo.load(clazz, this.nodeid, this.cacheForbidden, this.readPool.props, fullloader); - } - - /** - * 将entity的对象全部加载到Cache中去,如果clazz没有被@javax.persistence.Cacheable注解则不做任何事 - * - * @param Entity类泛型 - * @param clazz Entity类 - */ - public void refreshCache(Class clazz) { - EntityInfo info = loadEntityInfo(clazz); - EntityCache cache = info.getCache(); - if (cache == null) return; - cache.fullLoad(queryList(clazz, (FilterNode) null)); - } - - //----------------------insertCache----------------------------- - /** - * 新增对象, 必须是Entity对象 - * - * @param Entity类泛型 - * @param values Entity对象 - */ - @Override - public void insert(T... values) { - if (values.length == 0) return; - final EntityInfo info = loadEntityInfo((Class) values[0].getClass()); - if (info.isVirtualEntity()) { - insert(null, info, values); - return; - } - Connection conn = createWriteSQLConnection(); - try { - insert(conn, info, values); - } finally { - closeSQLConnection(conn); - } - } - - @Override - public void insert(final CompletionHandler handler, final T... values) { - insert(values); - if (handler != null) handler.completed(null, values); - } - - private void insert(final Connection conn, final EntityInfo info, T... values) { - if (values.length == 0) return; - try { - if (!info.isVirtualEntity()) { - final String sql = info.insertSQL; - final PreparedStatement prestmt = info.autoGenerated - ? conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS) : conn.prepareStatement(sql); - final Class primaryType = info.getPrimary().type(); - final Attribute primary = info.getPrimary(); - final boolean distributed = info.distributed; - Attribute[] attrs = info.insertAttributes; - String[] sqls = null; - if (distributed && !info.initedPrimaryValue && primaryType.isPrimitive()) { - synchronized (info) { - if (!info.initedPrimaryValue) { - Statement stmt = conn.createStatement(); - ResultSet rs = stmt.executeQuery("SELECT MAX(" + info.getPrimarySQLColumn() + ") FROM " + info.getTable()); - if (rs.next()) { - if (primaryType == int.class) { - int v = rs.getInt(1) / info.allocationSize; - if (v > info.primaryValue.get()) info.primaryValue.set(v); - } else { - long v = rs.getLong(1) / info.allocationSize; - if (v > info.primaryValue.get()) info.primaryValue.set(v); - } - } - rs.close(); - stmt.close(); - if (info.distributeTables != null) { - for (final Class t : info.distributeTables) { - EntityInfo infox = loadEntityInfo(t); - stmt = conn.createStatement(); - rs = stmt.executeQuery("SELECT MAX(" + info.getPrimarySQLColumn() + ") FROM " + infox.getTable()); // 必须是同一字段名 - if (rs.next()) { - if (primaryType == int.class) { - int v = rs.getInt(1) / info.allocationSize; - if (v > info.primaryValue.get()) info.primaryValue.set(v); - } else { - long v = rs.getLong(1) / info.allocationSize; - if (v > info.primaryValue.get()) info.primaryValue.set(v); - } - } - rs.close(); - stmt.close(); - } - } - info.initedPrimaryValue = true; - } - } - } - if (writeListener == null) { - for (final T value : values) { - int i = 0; - if (distributed) info.createPrimaryValue(value); - for (Attribute attr : attrs) { - prestmt.setObject(++i, attr.get(value)); - } - prestmt.addBatch(); - } - } else { - char[] sqlchars = sql.toCharArray(); - sqls = new String[values.length]; - CharSequence[] ps = new CharSequence[attrs.length]; - int index = 0; - for (final T value : values) { - int i = 0; - if (distributed) info.createPrimaryValue(value); - for (Attribute attr : attrs) { - Object a = attr.get(value); - ps[i] = formatToString(a); - prestmt.setObject(++i, a); - } - prestmt.addBatch(); - //----------------------------- - StringBuilder sb = new StringBuilder(128); - i = 0; - for (char ch : sqlchars) { - if (ch == '?') { - sb.append(ps[i++]); - } else { - sb.append(ch); - } - } - sqls[index++] = sb.toString(); - } - } - prestmt.executeBatch(); - if (writeListener != null) writeListener.insert(sqls); - if (info.autoGenerated) { - ResultSet set = prestmt.getGeneratedKeys(); - int i = -1; - while (set.next()) { - if (primaryType == int.class) { - primary.set(values[++i], set.getInt(1)); - } else if (primaryType == long.class) { - primary.set(values[++i], set.getLong(1)); - } else { - primary.set(values[++i], set.getObject(1)); - } - } - set.close(); - } - prestmt.close(); - //------------------------------------------------------------ - if (debug.get()) { - char[] sqlchars = sql.toCharArray(); - for (final T value : values) { - //----------------------------- - StringBuilder sb = new StringBuilder(128); - int i = 0; - for (char ch : sqlchars) { - if (ch == '?') { - Object obj = attrs[i++].get(value); - if (obj != null && obj.getClass().isArray()) { - sb.append("'[length=").append(java.lang.reflect.Array.getLength(obj)).append("]'"); - } else { - sb.append(formatToString(obj)); - } - } else { - sb.append(ch); - } - } - logger.finest(info.getType().getSimpleName() + " insert sql=" + sb.toString().replaceAll("(\r|\n)", "\\n")); - } - } - } - final EntityCache cache = info.getCache(); - if (cache != null) { - for (final T value : values) { - cache.insert(value); - } - if (cacheListener != null) cacheListener.insertCache(info.getType(), values); - } - } catch (SQLException e) { - throw new RuntimeException(e); - } - } - - public void insertCache(Class clazz, T... values) { - if (values.length == 0) return; - final EntityInfo info = loadEntityInfo(clazz); - final EntityCache cache = info.getCache(); - if (cache == null) return; - for (T value : values) { - cache.insert(value); - } - } - - //-------------------------deleteCache-------------------------- - /** - * 删除对象, 必须是Entity对象 - * - * @param Entity类泛型 - * @param values Entity对象 - */ - @Override - public void delete(T... values) { - if (values.length == 0) return; - final EntityInfo info = loadEntityInfo((Class) values[0].getClass()); - if (info.isVirtualEntity()) { - delete(null, info, values); - return; - } - Connection conn = createWriteSQLConnection(); - try { - delete(conn, info, values); - } finally { - closeSQLConnection(conn); - } - } - - @Override - public void delete(final CompletionHandler handler, final T... values) { - delete(values); - if (handler != null) handler.completed(null, values); - } - - private void delete(final Connection conn, final EntityInfo info, T... values) { - if (values.length == 0) return; - final Attribute primary = info.getPrimary(); - Serializable[] ids = new Serializable[values.length]; - int i = 0; - for (final T value : values) { - ids[i++] = (Serializable) primary.get(value); - } - delete(conn, info, ids); - } - - @Override - public void delete(Class clazz, Serializable... ids) { - final EntityInfo info = loadEntityInfo(clazz); - if (info.isVirtualEntity()) { - delete(null, info, ids); - return; - } - Connection conn = createWriteSQLConnection(); - try { - delete(conn, info, ids); - } finally { - closeSQLConnection(conn); - } - } - - @Override - public void delete(final CompletionHandler handler, final Class clazz, final Serializable... ids) { - delete(clazz, ids); - if (handler != null) handler.completed(null, ids); - } - - private void delete(final Connection conn, final EntityInfo info, Serializable... keys) { - if (keys.length == 0) return; - try { - if (!info.isVirtualEntity()) { - String sql = "DELETE FROM " + info.getTable() + " WHERE " + info.getPrimarySQLColumn() + " IN " + formatToString(keys); - if (debug.get()) logger.finest(info.getType().getSimpleName() + " delete sql=" + sql); - final Statement stmt = conn.createStatement(); - stmt.execute(sql); - stmt.close(); - if (writeListener != null) writeListener.delete(sql); - } - //------------------------------------ - final EntityCache cache = info.getCache(); - if (cache == null) return; - for (Serializable key : keys) { - cache.delete(key); - } - if (cacheListener != null) cacheListener.deleteCache(info.getType(), keys); - } catch (SQLException e) { - throw new RuntimeException(e); - } - } - - @Override - public void delete(Class clazz, FilterNode node) { - final EntityInfo info = loadEntityInfo(clazz); - if (info.isVirtualEntity()) { - delete(null, info, node); - return; - } - Connection conn = createWriteSQLConnection(); - try { - delete(conn, info, node); - } finally { - closeSQLConnection(conn); - } - } - - @Override - public void delete(final CompletionHandler handler, final Class clazz, final FilterNode node) { - delete(clazz, node); - if (handler != null) handler.completed(null, node); - } - - private void delete(final Connection conn, final EntityInfo info, final FilterNode node) { - try { - if (!info.isVirtualEntity()) { - Map joinTabalis = node.getJoinTabalis(); - CharSequence join = node.createSQLJoin(this, joinTabalis, info); - CharSequence where = node.createSQLExpress(info, joinTabalis); - String sql = "DELETE " + (this.readPool.isMysql() ? "a" : "") + " FROM " + info.getTable() + " a" + (join == null ? "" : join) + ((where == null || where.length() == 0) ? "" : (" WHERE " + where)); - if (debug.get()) logger.finest(info.getType().getSimpleName() + " delete sql=" + sql); - final Statement stmt = conn.createStatement(); - stmt.execute(sql); - stmt.close(); - if (writeListener != null) writeListener.delete(sql); - } - //------------------------------------ - final EntityCache cache = info.getCache(); - if (cache == null) return; - Serializable[] ids = cache.delete(node); - if (cacheListener != null) cacheListener.deleteCache(info.getType(), ids); - } catch (SQLException e) { - throw new RuntimeException(e); - } - } - - public void deleteCache(Class clazz, Serializable... ids) { - if (ids.length == 0) return; - final EntityInfo info = loadEntityInfo(clazz); - final EntityCache cache = info.getCache(); - if (cache == null) return; - for (Serializable id : ids) { - cache.delete(id); - } - } - - //------------------------update--------------------------- - /** - * 更新对象, 必须是Entity对象 - * - * @param Entity类泛型 - * @param values Entity对象 - */ - @Override - public void update(T... values) { - if (values.length == 0) return; - final EntityInfo info = loadEntityInfo((Class) values[0].getClass()); - if (info.isVirtualEntity()) { - update(null, info, values); - return; - } - Connection conn = createWriteSQLConnection(); - try { - update(conn, info, values); - } finally { - closeSQLConnection(conn); - } - } - - @Override - public void update(final CompletionHandler handler, final T... values) { - update(values); - if (handler != null) handler.completed(null, values); - } - - private void update(final Connection conn, final EntityInfo info, T... values) { - try { - Class clazz = info.getType(); - if (!info.isVirtualEntity()) { - if (debug.get()) logger.finest(clazz.getSimpleName() + " update sql=" + info.updateSQL); - final Attribute primary = info.getPrimary(); - final PreparedStatement prestmt = conn.prepareStatement(info.updateSQL); - Attribute[] attrs = info.updateAttributes; - String[] sqls = null; - if (writeListener == null) { - for (final T value : values) { - int i = 0; - for (Attribute attr : attrs) { - prestmt.setObject(++i, attr.get(value)); - } - prestmt.setObject(++i, primary.get(value)); - prestmt.addBatch(); - } - } else { - char[] sqlchars = info.updateSQL.toCharArray(); - sqls = new String[values.length]; - CharSequence[] ps = new CharSequence[attrs.length]; - int index = 0; - for (final T value : values) { - int i = 0; - for (Attribute attr : attrs) { - Object a = attr.get(value); - ps[i] = formatToString(a); - prestmt.setObject(++i, a); - } - prestmt.setObject(++i, primary.get(value)); - prestmt.addBatch(); - //----------------------------- - StringBuilder sb = new StringBuilder(128); - i = 0; - for (char ch : sqlchars) { - if (ch == '?') { - sb.append(ps[i++]); - } else { - sb.append(ch); - } - } - sqls[index++] = sb.toString(); - } - } - prestmt.executeBatch(); - prestmt.close(); - if (writeListener != null) writeListener.update(sqls); - } - //--------------------------------------------------- - final EntityCache cache = info.getCache(); - if (cache == null) return; - for (final T value : values) { - cache.update(value); - } - if (cacheListener != null) cacheListener.updateCache(clazz, values); - } catch (SQLException e) { - throw new RuntimeException(e); - } - } - - /** - * 根据主键值更新对象的column对应的值, 必须是Entity Class - * - * @param Entity类的泛型 - * @param clazz Entity类 - * @param id 主键值 - * @param column 过滤字段名 - * @param value 过滤字段值 - */ - @Override - public void updateColumn(Class clazz, Serializable id, String column, Serializable value) { - final EntityInfo info = loadEntityInfo(clazz); - if (info.isVirtualEntity()) { - updateColumn(null, info, id, column, value); - return; - } - Connection conn = createWriteSQLConnection(); - try { - updateColumn(conn, info, id, column, value); - } finally { - closeSQLConnection(conn); - } - } - - @Override - public void updateColumn(final CompletionHandler handler, final Class clazz, final Serializable id, final String column, final Serializable value) { - updateColumn(clazz, id, column, value); - if (handler != null) handler.completed(null, id); - } - - private void updateColumn(Connection conn, final EntityInfo info, Serializable id, String column, Serializable value) { - try { - if (!info.isVirtualEntity()) { - String sql = "UPDATE " + info.getTable() + " SET " + info.getSQLColumn(null, column) + " = " - + formatToString(value) + " WHERE " + info.getPrimarySQLColumn() + " = " + formatToString(id); - if (debug.get()) logger.finest(info.getType().getSimpleName() + " update sql=" + sql); - final Statement stmt = conn.createStatement(); - stmt.execute(sql); - stmt.close(); - if (writeListener != null) writeListener.update(sql); - } - //--------------------------------------------------- - final EntityCache cache = info.getCache(); - if (cache == null) return; - T rs = cache.update(id, info.getAttribute(column), value); - if (cacheListener != null) cacheListener.updateCache(info.getType(), rs); - } catch (SQLException e) { - throw new RuntimeException(e); - } finally { - if (conn != null) closeSQLConnection(conn); - } - } - - /** - * 根据主键值给对象的column对应的值+incvalue, 必须是Entity Class - * 等价SQL: UPDATE {clazz} SET {column} = {column} + {incvalue} WHERE {primary} = {id} - * - * @param Entity类的泛型 - * @param clazz Entity类 - * @param id 主键值 - * @param column 字段名 - * @param incvalue 字段加值 - */ - @Override - public void updateColumnIncrement(Class clazz, Serializable id, String column, long incvalue) { - final EntityInfo info = loadEntityInfo(clazz); - if (info.isVirtualEntity()) { - updateColumnIncrement(null, info, id, column, incvalue); - return; - } - Connection conn = createWriteSQLConnection(); - try { - updateColumnIncrement(conn, info, id, column, incvalue); - } finally { - closeSQLConnection(conn); - } - } - - @Override - public void updateColumnIncrement(final CompletionHandler handler, final Class clazz, final Serializable id, final String column, long incvalue) { - updateColumnIncrement(clazz, id, column, incvalue); - if (handler != null) handler.completed(null, id); - } - - private void updateColumnIncrement(Connection conn, final EntityInfo info, Serializable id, String column, long incvalue) { - try { - if (!info.isVirtualEntity()) { - String col = info.getSQLColumn(null, column); - String sql = "UPDATE " + info.getTable() + " SET " + col + " = " + col + " + (" + incvalue - + ") WHERE " + info.getPrimarySQLColumn() + " = " + formatToString(id); - if (debug.get()) logger.finest(info.getType().getSimpleName() + " update sql=" + sql); - final Statement stmt = conn.createStatement(); - stmt.execute(sql); - stmt.close(); - if (writeListener != null) writeListener.update(sql); - } - //--------------------------------------------------- - final EntityCache cache = info.getCache(); - if (cache == null) return; - Attribute attr = info.getAttribute(column); - T value = cache.updateColumnIncrement(id, attr, incvalue); - if (value != null && cacheListener != null) cacheListener.updateCache(info.getType(), value); - } catch (SQLException e) { - throw new RuntimeException(e); - } finally { - if (conn != null) closeSQLConnection(conn); - } - } - - /** - * 根据主键值给对象的column对应的值 & andvalue, 必须是Entity Class - * 等价SQL: UPDATE {clazz} SET {column} = {column} & {incvalue} WHERE {primary} = {id} - * - * @param Entity类的泛型 - * @param clazz Entity类 - * @param id 主键值 - * @param column 字段名 - * @param andvalue 字段与值 - */ - @Override - public void updateColumnAnd(Class clazz, Serializable id, String column, long andvalue) { - final EntityInfo info = loadEntityInfo(clazz); - if (info.isVirtualEntity()) { - updateColumnAnd(null, info, id, column, andvalue); - return; - } - Connection conn = createWriteSQLConnection(); - try { - updateColumnAnd(conn, info, id, column, andvalue); - } finally { - closeSQLConnection(conn); - } - } - - @Override - public void updateColumnAnd(final CompletionHandler handler, final Class clazz, final Serializable id, final String column, long incvalue) { - updateColumnAnd(clazz, id, column, incvalue); - if (handler != null) handler.completed(null, id); - } - - private void updateColumnAnd(Connection conn, final EntityInfo info, Serializable id, String column, long andvalue) { - try { - if (!info.isVirtualEntity()) { - String col = info.getSQLColumn(null, column); - String sql = "UPDATE " + info.getTable() + " SET " + col + " = " + col + " & (" + andvalue - + ") WHERE " + info.getPrimarySQLColumn() + " = " + formatToString(id); - if (debug.get()) logger.finest(info.getType().getSimpleName() + " update sql=" + sql); - final Statement stmt = conn.createStatement(); - stmt.execute(sql); - stmt.close(); - if (writeListener != null) writeListener.update(sql); - } - //--------------------------------------------------- - final EntityCache cache = info.getCache(); - if (cache == null) return; - Attribute attr = info.getAttribute(column); - T value = cache.updateColumnAnd(id, attr, andvalue); - if (value != null && cacheListener != null) cacheListener.updateCache(info.getType(), value); - } catch (SQLException e) { - throw new RuntimeException(e); - } finally { - if (conn != null) closeSQLConnection(conn); - } - } - - /** - * 根据主键值给对象的column对应的值 | andvalue, 必须是Entity Class - * 等价SQL: UPDATE {clazz} SET {column} = {column} | {incvalue} WHERE {primary} = {id} - * - * @param Entity类的泛型 - * @param clazz Entity类 - * @param id 主键值 - * @param column 字段名 - * @param orvalue 字段或值 - */ - @Override - public void updateColumnOr(Class clazz, Serializable id, String column, long orvalue) { - final EntityInfo info = loadEntityInfo(clazz); - if (info.isVirtualEntity()) { - updateColumnOr(null, info, id, column, orvalue); - return; - } - Connection conn = createWriteSQLConnection(); - try { - updateColumnOr(conn, info, id, column, orvalue); - } finally { - closeSQLConnection(conn); - } - } - - @Override - public void updateColumnOr(final CompletionHandler handler, final Class clazz, final Serializable id, final String column, long incvalue) { - updateColumnOr(clazz, id, column, incvalue); - if (handler != null) handler.completed(null, id); - } - - private void updateColumnOr(Connection conn, final EntityInfo info, Serializable id, String column, long orvalue) { - try { - if (!info.isVirtualEntity()) { - String col = info.getSQLColumn(null, column); - String sql = "UPDATE " + info.getTable() + " SET " + col + " = " + col + " | (" + orvalue - + ") WHERE " + info.getPrimarySQLColumn() + " = " + formatToString(id); - if (debug.get()) logger.finest(info.getType().getSimpleName() + " update sql=" + sql); - final Statement stmt = conn.createStatement(); - stmt.execute(sql); - stmt.close(); - if (writeListener != null) writeListener.update(sql); - } - //--------------------------------------------------- - final EntityCache cache = info.getCache(); - if (cache == null) return; - Attribute attr = info.getAttribute(column); - T value = cache.updateColumnOr(id, attr, orvalue); - if (value != null && cacheListener != null) cacheListener.updateCache(info.getType(), value); - } catch (SQLException e) { - throw new RuntimeException(e); - } finally { - if (conn != null) closeSQLConnection(conn); - } - } - - /** - * 更新对象指定的一些字段, 必须是Entity对象 - * - * @param Entity类的泛型 - * @param value Entity对象 - * @param columns 需要更新的字段 - */ - @Override - public void updateColumns(final T value, final String... columns) { - final EntityInfo info = loadEntityInfo((Class) value.getClass()); - if (info.isVirtualEntity()) { - updateColumns(null, info, value, columns); - return; - } - Connection conn = createWriteSQLConnection(); - try { - updateColumns(conn, info, value, columns); - } finally { - closeSQLConnection(conn); - } - } - - @Override - public void updateColumns(final CompletionHandler handler, final T value, final String... columns) { - updateColumns(value, columns); - if (handler != null) handler.completed(null, value); - } - - private void updateColumns(final Connection conn, final EntityInfo info, final T value, final String... columns) { - if (value == null || columns.length < 1) return; - try { - final Class clazz = (Class) value.getClass(); - StringBuilder setsql = new StringBuilder(); - final Serializable id = info.getPrimary().get(value); - final List> attrs = new ArrayList<>(); - final boolean virtual = info.isVirtualEntity(); - for (String col : columns) { - Attribute attr = info.getUpdateAttribute(col); - if (attr == null) continue; - attrs.add(attr); - if (!virtual) { - if (setsql.length() > 0) setsql.append(", "); - setsql.append(info.getSQLColumn(null, col)).append(" = ").append(formatToString(attr.get(value))); - } - } - if (!virtual) { - String sql = "UPDATE " + info.getTable() + " SET " + setsql + " WHERE " + info.getPrimarySQLColumn() + " = " + formatToString(id); - if (debug.get()) logger.finest(value.getClass().getSimpleName() + ": " + sql); - final Statement stmt = conn.createStatement(); - stmt.execute(sql); - stmt.close(); - if (writeListener != null) writeListener.update(sql); - } - //--------------------------------------------------- - final EntityCache cache = info.getCache(); - if (cache == null) return; - T rs = cache.update(value, attrs); - if (cacheListener != null) cacheListener.updateCache(clazz, rs); - } catch (SQLException e) { - throw new RuntimeException(e); - } - } - - public void updateCache(Class clazz, T... values) { - if (values.length == 0) return; - final EntityInfo info = loadEntityInfo(clazz); - final EntityCache cache = info.getCache(); - if (cache == null) return; - for (T value : values) { - cache.update(value); - } - } - - public void reloadCache(Class clazz, Serializable... ids) { - final EntityInfo info = loadEntityInfo(clazz); - final EntityCache cache = info.getCache(); - if (cache == null) return; - String column = info.getPrimary().field(); - for (Serializable id : ids) { - Sheet sheet = querySheet(false, true, clazz, null, FLIPPER_ONE, FilterNode.create(column, id)); - T value = sheet.isEmpty() ? null : sheet.list().get(0); - if (value != null) cache.update(value); - } - } - - //-----------------------getNumberResult----------------------------- - @Override - public Number getNumberResult(final Class entityClass, final FilterFunc func, final String column) { - return getNumberResult(entityClass, func, column, (FilterNode) null); - } - - @Override - public void getNumberResult(final CompletionHandler handler, final Class entityClass, final FilterFunc func, final String column) { - Number rs = getNumberResult(entityClass, func, column); - if (handler != null) handler.completed(rs, column); - } - - @Override - public Number getNumberResult(final Class entityClass, final FilterFunc func, final String column, FilterBean bean) { - return getNumberResult(entityClass, func, column, FilterNodeBean.createFilterNode(bean)); - } - - @Override - public void getNumberResult(final CompletionHandler handler, final Class entityClass, final FilterFunc func, final String column, final FilterBean bean) { - getNumberResult(handler, entityClass, func, column, FilterNodeBean.createFilterNode(bean)); - } - - @Override - public Number getNumberResult(final Class entityClass, final FilterFunc func, final String column, final FilterNode node) { - final Connection conn = createReadSQLConnection(); - try { - final EntityInfo info = loadEntityInfo(entityClass); - final EntityCache cache = info.getCache(); - if (cache != null && (info.isVirtualEntity() || cache.isFullLoaded())) { - if (node == null || node.isCacheUseable(this)) { - return cache.getNumberResult(func, column, node); - } - } - final Map joinTabalis = node == null ? null : node.getJoinTabalis(); - final CharSequence join = node == null ? null : node.createSQLJoin(this, joinTabalis, info); - final CharSequence where = node == null ? null : node.createSQLExpress(info, joinTabalis); - final String sql = "SELECT " + func.getColumn((column == null || column.isEmpty() ? "*" : ("a." + column))) + " FROM " + info.getTable() + " a" - + (join == null ? "" : join) + ((where == null || where.length() == 0) ? "" : (" WHERE " + where)); - if (debug.get() && info.isLoggable(Level.FINEST)) logger.finest(entityClass.getSimpleName() + " single sql=" + sql); - final PreparedStatement prestmt = conn.prepareStatement(sql); - Number rs = null; - ResultSet set = prestmt.executeQuery(); - if (set.next()) { - rs = (Number) set.getObject(1); - } - set.close(); - prestmt.close(); - return rs; - } catch (SQLException e) { - throw new RuntimeException(e); - } finally { - if (conn != null) closeSQLConnection(conn); - } - } - - @Override - public void getNumberResult(final CompletionHandler handler, final Class entityClass, final FilterFunc func, final String column, final FilterNode node) { - Number rs = getNumberResult(entityClass, func, column, node); - if (handler != null) handler.completed(rs, node); - } - - //-----------------------queryColumnMap----------------------------- - @Override - public Map queryColumnMap(final Class entityClass, final String keyColumn, FilterFunc func, final String funcColumn) { - return queryColumnMap(entityClass, keyColumn, func, funcColumn, (FilterNode) null); - } - - @Override - public void queryColumnMap(final CompletionHandler, String> handler, final Class entityClass, final String keyColumn, final FilterFunc func, final String funcColumn) { - Map map = queryColumnMap(entityClass, keyColumn, func, funcColumn); - if (handler != null) handler.completed(map, funcColumn); - } - - @Override - public Map queryColumnMap(final Class entityClass, final String keyColumn, FilterFunc func, final String funcColumn, FilterBean bean) { - return queryColumnMap(entityClass, keyColumn, func, funcColumn, FilterNodeBean.createFilterNode(bean)); - } - - @Override - public void queryColumnMap(final CompletionHandler, FilterNode> handler, final Class entityClass, final String keyColumn, final FilterFunc func, final String funcColumn, final FilterBean bean) { - queryColumnMap(handler, entityClass, keyColumn, func, funcColumn, FilterNodeBean.createFilterNode(bean)); - } - - @Override - public Map queryColumnMap(final Class entityClass, final String keyColumn, final FilterFunc func, final String funcColumn, FilterNode node) { - final Connection conn = createReadSQLConnection(); - try { - final EntityInfo info = loadEntityInfo(entityClass); - final EntityCache cache = info.getCache(); - if (cache != null && (info.isVirtualEntity() || cache.isFullLoaded())) { - if (node == null || node.isCacheUseable(this)) { - return cache.queryColumnMap(keyColumn, func, funcColumn, node); - } - } - final String sqlkey = info.getSQLColumn(null, keyColumn); - final Map joinTabalis = node == null ? null : node.getJoinTabalis(); - final CharSequence join = node == null ? null : node.createSQLJoin(this, joinTabalis, info); - final CharSequence where = node == null ? null : node.createSQLExpress(info, joinTabalis); - final String sql = "SELECT a." + sqlkey + ", " + func.getColumn((funcColumn == null || funcColumn.isEmpty() ? "*" : ("a." + funcColumn))) - + " FROM " + info.getTable() + " a" + (join == null ? "" : join) + ((where == null || where.length() == 0) ? "" : (" WHERE " + where)) + " GROUP BY a." + sqlkey; - if (debug.get() && info.isLoggable(Level.FINEST)) logger.finest(entityClass.getSimpleName() + " single sql=" + sql); - final PreparedStatement prestmt = conn.prepareStatement(sql); - Map rs = new LinkedHashMap<>(); - ResultSet set = prestmt.executeQuery(); - ResultSetMetaData rsd = set.getMetaData(); - boolean smallint = rsd.getColumnType(1) == Types.SMALLINT; - while (set.next()) { - rs.put((K) (smallint ? set.getShort(1) : set.getObject(1)), (N) set.getObject(2)); - } - set.close(); - prestmt.close(); - return rs; - } catch (SQLException e) { - throw new RuntimeException(e); - } finally { - if (conn != null) closeSQLConnection(conn); - } - } - - @Override - public void queryColumnMap(final CompletionHandler, FilterNode> handler, final Class entityClass, final String keyColumn, final FilterFunc func, final String funcColumn, final FilterNode node) { - Map map = queryColumnMap(entityClass, keyColumn, func, funcColumn, node); - if (handler != null) handler.completed(map, node); - } - - //-----------------------find---------------------------- - /** - * 根据主键获取对象 - * - * @param Entity类的泛型 - * @param clazz Entity类 - * @param pk 主键值 - * @return Entity对象 - */ - @Override - public T find(Class clazz, Serializable pk) { - return find(clazz, (SelectColumn) null, pk); - } - - @Override - public void find(final CompletionHandler handler, final Class clazz, final Serializable pk) { - T rs = find(clazz, pk); - if (handler != null) handler.completed(rs, pk); - } - - @Override - public T find(Class clazz, final SelectColumn selects, Serializable pk) { - final EntityInfo info = loadEntityInfo(clazz); - final EntityCache cache = info.getCache(); - if (cache != null && cache.isFullLoaded()) return cache.find(selects, pk); - - final Connection conn = createReadSQLConnection(); - try { - final SelectColumn sels = selects; - final String sql = "SELECT * FROM " + info.getTable() + " WHERE " + info.getPrimarySQLColumn() + " = " + formatToString(pk); - if (debug.get() && info.isLoggable(Level.FINEST)) logger.finest(clazz.getSimpleName() + " find sql=" + sql); - final PreparedStatement ps = conn.prepareStatement(sql, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY); - final ResultSet set = ps.executeQuery(); - T rs = set.next() ? info.getValue(sels, set) : null; - set.close(); - ps.close(); - return rs; - } catch (Exception ex) { - throw new RuntimeException(ex); - } finally { - closeSQLConnection(conn); - } - } - - @Override - public void find(final CompletionHandler handler, final Class clazz, final SelectColumn selects, final Serializable pk) { - T rs = find(clazz, selects, pk); - if (handler != null) handler.completed(rs, pk); - } - - @Override - public T find(final Class clazz, final String column, final Serializable key) { - return find(clazz, null, FilterNode.create(column, key)); - } - - @Override - public void find(final CompletionHandler handler, final Class clazz, final String column, final Serializable key) { - T rs = find(clazz, column, key); - if (handler != null) handler.completed(rs, key); - } - - @Override - public T find(final Class clazz, final FilterBean bean) { - return find(clazz, null, FilterNodeBean.createFilterNode(bean)); - } - - @Override - public void find(final CompletionHandler handler, final Class clazz, final FilterBean bean) { - FilterNode node = FilterNodeBean.createFilterNode(bean); - T rs = find(clazz, node); - if (handler != null) handler.completed(rs, node); - } - - @Override - public T find(final Class clazz, final FilterNode node) { - return find(clazz, null, node); - } - - @Override - public void find(final CompletionHandler handler, final Class clazz, final FilterNode node) { - T rs = find(clazz, node); - if (handler != null) handler.completed(rs, node); - } - - @Override - public T find(final Class clazz, final SelectColumn selects, final FilterBean bean) { - return find(clazz, selects, FilterNodeBean.createFilterNode(bean)); - } - - @Override - public void find(final CompletionHandler handler, final Class clazz, final SelectColumn selects, final FilterBean bean) { - FilterNode node = FilterNodeBean.createFilterNode(bean); - T rs = find(clazz, selects, node); - if (handler != null) handler.completed(rs, node); - } - - @Override - public T find(final Class clazz, final SelectColumn selects, final FilterNode node) { - final EntityInfo info = loadEntityInfo(clazz); - final EntityCache cache = info.getCache(); - if (cache != null && cache.isFullLoaded() && (node == null || node.isCacheUseable(this))) return cache.find(selects, node); - - final Connection conn = createReadSQLConnection(); - try { - final SelectColumn sels = selects; - final Map joinTabalis = node == null ? null : node.getJoinTabalis(); - final CharSequence join = node == null ? null : node.createSQLJoin(this, joinTabalis, info); - final CharSequence where = node == null ? null : node.createSQLExpress(info, joinTabalis); - final String sql = "SELECT a.* FROM " + info.getTable() + " a" + (join == null ? "" : join) + ((where == null || where.length() == 0) ? "" : (" WHERE " + where)); - if (debug.get() && info.isLoggable(Level.FINEST)) logger.finest(clazz.getSimpleName() + " find sql=" + sql); - final PreparedStatement ps = conn.prepareStatement(sql, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY); - final ResultSet set = ps.executeQuery(); - T rs = set.next() ? info.getValue(sels, set) : null; - set.close(); - ps.close(); - return rs; - } catch (Exception ex) { - throw new RuntimeException(ex); - } finally { - closeSQLConnection(conn); - } - } - - @Override - public void find(final CompletionHandler handler, final Class clazz, final SelectColumn selects, final FilterNode node) { - T rs = find(clazz, selects, node); - if (handler != null) handler.completed(rs, node); - } - - @Override - public boolean exists(Class clazz, Serializable pk) { - final EntityInfo info = loadEntityInfo(clazz); - final EntityCache cache = info.getCache(); - if (cache != null && cache.isFullLoaded()) return cache.exists(pk); - - final Connection conn = createReadSQLConnection(); - try { - final String sql = "SELECT COUNT(*) FROM " + info.getTable() + " WHERE " + info.getPrimarySQLColumn() + " = " + formatToString(pk); - if (debug.get() && info.isLoggable(Level.FINEST)) logger.finest(clazz.getSimpleName() + " exists sql=" + sql); - final PreparedStatement ps = conn.prepareStatement(sql, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY); - final ResultSet set = ps.executeQuery(); - boolean rs = set.next() ? (set.getInt(1) > 0) : false; - set.close(); - ps.close(); - return rs; - } catch (Exception ex) { - throw new RuntimeException(ex); - } finally { - closeSQLConnection(conn); - } - } - - @Override - public void exists(final CompletionHandler handler, final Class clazz, final Serializable pk) { - boolean rs = exists(clazz, pk); - if (handler != null) handler.completed(rs, pk); - } - - @Override - public boolean exists(final Class clazz, final FilterBean bean) { - return exists(clazz, FilterNodeBean.createFilterNode(bean)); - } - - @Override - public void exists(final CompletionHandler handler, final Class clazz, final FilterBean bean) { - FilterNode node = FilterNodeBean.createFilterNode(bean); - boolean rs = exists(clazz, node); - if (handler != null) handler.completed(rs, node); - } - - @Override - public boolean exists(final Class clazz, final FilterNode node) { - final EntityInfo info = loadEntityInfo(clazz); - final EntityCache cache = info.getCache(); - if (cache != null && cache.isFullLoaded() && (node == null || node.isCacheUseable(this))) return cache.exists(node); - - final Connection conn = createReadSQLConnection(); - try { - final Map joinTabalis = node == null ? null : node.getJoinTabalis(); - final CharSequence join = node == null ? null : node.createSQLJoin(this, joinTabalis, info); - final CharSequence where = node == null ? null : node.createSQLExpress(info, joinTabalis); - final String sql = "SELECT COUNT(" + info.getPrimarySQLColumn("a") + ") FROM " + info.getTable() + " a" + (join == null ? "" : join) + ((where == null || where.length() == 0) ? "" : (" WHERE " + where)); - if (debug.get() && info.isLoggable(Level.FINEST)) logger.finest(clazz.getSimpleName() + " exists sql=" + sql); - final PreparedStatement ps = conn.prepareStatement(sql, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY); - final ResultSet set = ps.executeQuery(); - boolean rs = set.next() ? (set.getInt(1) > 0) : false; - set.close(); - ps.close(); - return rs; - } catch (Exception ex) { - throw new RuntimeException(ex); - } finally { - closeSQLConnection(conn); - } - } - - @Override - public void exists(final CompletionHandler handler, final Class clazz, final FilterNode node) { - boolean rs = exists(clazz, node); - if (handler != null) handler.completed(rs, node); - } - - //-----------------------list set---------------------------- - @Override - public HashSet queryColumnSet(String selectedColumn, Class clazz, String column, Serializable key) { - return queryColumnSet(selectedColumn, clazz, FilterNode.create(column, key)); - } - - @Override - public void queryColumnSet(final CompletionHandler, Serializable> handler, final String selectedColumn, final Class clazz, final String column, final Serializable key) { - HashSet rs = queryColumnSet(selectedColumn, clazz, column, key); - if (handler != null) handler.completed(rs, key); - } - - @Override - public HashSet queryColumnSet(final String selectedColumn, final Class clazz, final FilterBean bean) { - return new LinkedHashSet<>(queryColumnList(selectedColumn, clazz, bean)); - } - - @Override - public void queryColumnSet(final CompletionHandler, FilterNode> handler, final String selectedColumn, final Class clazz, final FilterBean bean) { - FilterNode node = FilterNodeBean.createFilterNode(bean); - HashSet rs = queryColumnSet(selectedColumn, clazz, node); - if (handler != null) handler.completed(rs, node); - } - - @Override - public HashSet queryColumnSet(String selectedColumn, Class clazz, FilterNode node) { - return new LinkedHashSet<>(queryColumnList(selectedColumn, clazz, node)); - } - - @Override - public void queryColumnSet(final CompletionHandler, FilterNode> handler, final String selectedColumn, final Class clazz, final FilterNode node) { - HashSet rs = queryColumnSet(selectedColumn, clazz, node); - if (handler != null) handler.completed(rs, node); - } - - @Override - public List queryColumnList(final String selectedColumn, final Class clazz, final String column, final Serializable key) { - return queryColumnList(selectedColumn, clazz, FilterNode.create(column, key)); - } - - @Override - public void queryColumnList(final CompletionHandler, Serializable> handler, final String selectedColumn, final Class clazz, final String column, final Serializable key) { - List rs = queryColumnList(selectedColumn, clazz, column, key); - if (handler != null) handler.completed(rs, key); - } - - @Override - public List queryColumnList(final String selectedColumn, final Class clazz, final FilterBean bean) { - return (List) queryColumnSheet(selectedColumn, clazz, null, bean).list(true); - } - - @Override - public void queryColumnList(final CompletionHandler, FilterNode> handler, final String selectedColumn, final Class clazz, final FilterBean bean) { - final FilterNode node = FilterNodeBean.createFilterNode(bean); - List rs = queryColumnList(selectedColumn, clazz, node); - if (handler != null) handler.completed(rs, node); - } - - @Override - public List queryColumnList(final String selectedColumn, final Class clazz, final FilterNode node) { - return (List) queryColumnSheet(selectedColumn, clazz, null, node).list(true); - } - - @Override - public void queryColumnList(final CompletionHandler, FilterNode> handler, final String selectedColumn, final Class clazz, final FilterNode node) { - List rs = queryColumnList(selectedColumn, clazz, node); - if (handler != null) handler.completed(rs, node); - } - - /** - * 根据指定参数查询对象某个字段的集合 - *

- * @param Entity类的泛型 - * @param 字段值的类型 - * @param selectedColumn 字段名 - * @param clazz Entity类 - * @param flipper 翻页对象 - * @param bean 过滤Bean - * @return 字段集合 - */ - @Override - public Sheet queryColumnSheet(final String selectedColumn, Class clazz, final Flipper flipper, final FilterBean bean) { - return queryColumnSheet(selectedColumn, clazz, flipper, FilterNodeBean.createFilterNode(bean)); - } - - @Override - public void queryColumnSheet(final CompletionHandler, FilterNode> handler, final String selectedColumn, final Class clazz, final Flipper flipper, final FilterBean bean) { - final FilterNode node = FilterNodeBean.createFilterNode(bean); - Sheet rs = queryColumnSheet(selectedColumn, clazz, flipper, node); - if (handler != null) handler.completed(rs, node); - } - - @Override - public Sheet queryColumnSheet(final String selectedColumn, final Class clazz, final Flipper flipper, final FilterNode node) { - Sheet sheet = querySheet(true, true, clazz, SelectColumn.createIncludes(selectedColumn), flipper, node); - final Sheet rs = new Sheet<>(); - if (sheet.isEmpty()) return rs; - rs.setTotal(sheet.getTotal()); - final EntityInfo info = loadEntityInfo(clazz); - final Attribute selected = (Attribute) info.getAttribute(selectedColumn); - final List list = new ArrayList<>(); - for (T t : sheet.getRows()) { - list.add(selected.get(t)); - } - rs.setRows(list); - return rs; - } - - @Override - public void queryColumnSheet(final CompletionHandler, FilterNode> handler, final String selectedColumn, final Class clazz, final Flipper flipper, final FilterNode node) { - Sheet rs = queryColumnSheet(selectedColumn, clazz, flipper, node); - if (handler != null) handler.completed(rs, node); - } - - private Map formatMap(final Class clazz, final Collection list) { - Map map = new LinkedHashMap<>(); - if (list == null || list.isEmpty()) return map; - final Attribute attr = (Attribute) loadEntityInfo(clazz).getPrimary(); - for (T t : list) { - map.put(attr.get(t), t); - } - return map; - } - - /** - * 根据指定字段值查询对象集合 - * - * @param Entity类的泛型 - * @param clazz Entity类 - * @param column 过滤字段名 - * @param key 过滤字段值 - * @return Entity对象的集合 - */ - @Override - public List queryList(final Class clazz, final String column, final Serializable key) { - return queryList(clazz, FilterNode.create(column, key)); - } - - @Override - public void queryList(final CompletionHandler, Serializable> handler, final Class clazz, final String column, final Serializable key) { - List rs = queryList(clazz, column, key); - if (handler != null) handler.completed(rs, key); - } - - /** - * 根据过滤对象FilterBean查询对象集合 - * - * @param Entity类的泛型 - * @param clazz Entity类 - * @param bean 过滤Bean - * @return Entity对象集合 - */ - @Override - public List queryList(final Class clazz, final FilterBean bean) { - return queryList(clazz, (SelectColumn) null, bean); - } - - @Override - public void queryList(final CompletionHandler, FilterNode> handler, final Class clazz, final FilterBean bean) { - FilterNode node = FilterNodeBean.createFilterNode(bean); - List rs = queryList(clazz, node); - if (handler != null) handler.completed(rs, node); - } - - @Override - public List queryList(final Class clazz, final FilterNode node) { - return queryList(clazz, (SelectColumn) null, node); - } - - @Override - public void queryList(final CompletionHandler, FilterNode> handler, final Class clazz, final FilterNode node) { - List rs = queryList(clazz, node); - if (handler != null) handler.completed(rs, node); - } - - /** - * 根据过滤对象FilterBean查询对象集合, 对象只填充或排除SelectField指定的字段 - * - * @param Entity类的泛型 - * @param clazz Entity类 - * @param selects 收集的字段 - * @param bean 过滤Bean - * @return Entity对象的集合 - */ - @Override - public List queryList(final Class clazz, final SelectColumn selects, final FilterBean bean) { - return queryList(clazz, selects, (Flipper) null, bean); - } - - @Override - public void queryList(final CompletionHandler, FilterNode> handler, final Class clazz, final SelectColumn selects, final FilterBean bean) { - FilterNode node = FilterNodeBean.createFilterNode(bean); - List rs = queryList(clazz, selects, node); - if (handler != null) handler.completed(rs, node); - } - - @Override - public List queryList(final Class clazz, final SelectColumn selects, final FilterNode node) { - return queryList(clazz, selects, (Flipper) null, node); - } - - @Override - public void queryList(final CompletionHandler, FilterNode> handler, final Class clazz, final SelectColumn selects, final FilterNode node) { - List rs = queryList(clazz, selects, node); - if (handler != null) handler.completed(rs, node); - } - - @Override - public List queryList(final Class clazz, final Flipper flipper, final String column, final Serializable key) { - return queryList(clazz, flipper, FilterNode.create(column, key)); - } - - @Override - public void queryList(final CompletionHandler, Serializable> handler, final Class clazz, final Flipper flipper, final String column, final Serializable key) { - List rs = queryList(clazz, flipper, column, key); - if (handler != null) handler.completed(rs, key); - } - - @Override - public List queryList(final Class clazz, final Flipper flipper, final FilterBean bean) { - return queryList(clazz, null, flipper, bean); - } - - @Override - public void queryList(final CompletionHandler, FilterNode> handler, final Class clazz, final Flipper flipper, final FilterBean bean) { - FilterNode node = FilterNodeBean.createFilterNode(bean); - List rs = queryList(clazz, flipper, node); - if (handler != null) handler.completed(rs, node); - } - - @Override - public List queryList(final Class clazz, final Flipper flipper, final FilterNode node) { - return queryList(clazz, null, flipper, node); - } - - @Override - public void queryList(final CompletionHandler, FilterNode> handler, final Class clazz, final Flipper flipper, final FilterNode node) { - List rs = queryList(clazz, flipper, node); - if (handler != null) handler.completed(rs, node); - } - - @Override - public List queryList(final Class clazz, final SelectColumn selects, final Flipper flipper, final FilterBean bean) { - return querySheet(true, false, clazz, selects, flipper, FilterNodeBean.createFilterNode(bean)).list(true); - } - - @Override - public void queryList(final CompletionHandler, FilterNode> handler, final Class clazz, final SelectColumn selects, final Flipper flipper, final FilterBean bean) { - FilterNode node = FilterNodeBean.createFilterNode(bean); - List rs = queryList(clazz, selects, flipper, node); - if (handler != null) handler.completed(rs, node); - } - - @Override - public List queryList(final Class clazz, final SelectColumn selects, final Flipper flipper, final FilterNode node) { - return querySheet(true, false, clazz, selects, flipper, node).list(true); - } - - @Override - public void queryList(final CompletionHandler, FilterNode> handler, final Class clazz, final SelectColumn selects, final Flipper flipper, final FilterNode node) { - List rs = queryList(clazz, selects, flipper, node); - if (handler != null) handler.completed(rs, node); - } - - //-----------------------sheet---------------------------- - /** - * 根据过滤对象FilterBean和翻页对象Flipper查询一页的数据 - * - * @param Entity类的泛型 - * @param clazz Entity类 - * @param flipper 翻页对象 - * @param bean 过滤Bean - * @return Entity对象的集合 - */ - @Override - public Sheet querySheet(final Class clazz, final Flipper flipper, final FilterBean bean) { - return querySheet(clazz, null, flipper, bean); - } - - @Override - public void querySheet(final CompletionHandler, FilterNode> handler, final Class clazz, final Flipper flipper, final FilterBean bean) { - FilterNode node = FilterNodeBean.createFilterNode(bean); - Sheet rs = querySheet(clazz, flipper, node); - if (handler != null) handler.completed(rs, node); - } - - @Override - public Sheet querySheet(final Class clazz, final Flipper flipper, final FilterNode node) { - return querySheet(clazz, null, flipper, node); - } - - @Override - public void querySheet(final CompletionHandler, FilterNode> handler, final Class clazz, final Flipper flipper, final FilterNode node) { - Sheet rs = querySheet(clazz, flipper, node); - if (handler != null) handler.completed(rs, node); - } - - /** - * 根据过滤对象FilterBean和翻页对象Flipper查询一页的数据, 对象只填充或排除SelectField指定的字段 - * - * @param Entity类的泛型 - * @param clazz Entity类 - * @param selects 收集的字段集合 - * @param flipper 翻页对象 - * @param bean 过滤Bean - * @return Entity对象的集合 - */ - @Override - public Sheet querySheet(final Class clazz, final SelectColumn selects, final Flipper flipper, final FilterBean bean) { - return querySheet(true, true, clazz, selects, flipper, FilterNodeBean.createFilterNode(bean)); - } - - @Override - public void querySheet(final CompletionHandler, FilterNode> handler, final Class clazz, final SelectColumn selects, final Flipper flipper, final FilterBean bean) { - FilterNode node = FilterNodeBean.createFilterNode(bean); - Sheet rs = querySheet(clazz, selects, flipper, node); - if (handler != null) handler.completed(rs, node); - } - - @Override - public Sheet querySheet(final Class clazz, final SelectColumn selects, final Flipper flipper, final FilterNode node) { - return querySheet(true, true, clazz, selects, flipper, node); - } - - @Override - public void querySheet(final CompletionHandler, FilterNode> handler, final Class clazz, final SelectColumn selects, final Flipper flipper, final FilterNode node) { - Sheet rs = querySheet(clazz, selects, flipper, node); - if (handler != null) handler.completed(rs, node); - } - - private Sheet querySheet(final boolean readcache, final boolean needtotal, final Class clazz, final SelectColumn selects, final Flipper flipper, final FilterNode node) { - final EntityInfo info = loadEntityInfo(clazz); - final EntityCache cache = info.getCache(); - if (readcache && cache != null) { - if (node == null || node.isCacheUseable(this)) { - if (debug.get() && info.isLoggable(Level.FINEST)) logger.finest(clazz.getSimpleName() + " cache query predicate = " + (node == null ? null : node.createPredicate(cache))); - Sheet sheet = cache.querySheet(needtotal, selects, flipper, node); - if (!sheet.isEmpty() || info.isVirtualEntity() || cache.isFullLoaded()) return sheet; - } - } - final Connection conn = createReadSQLConnection(); - try { - final SelectColumn sels = selects; - final List list = new ArrayList(); - final Map joinTabalis = node == null ? null : node.getJoinTabalis(); - final CharSequence join = node == null ? null : node.createSQLJoin(this, joinTabalis, info); - final CharSequence where = node == null ? null : node.createSQLExpress(info, joinTabalis); - final String sql = "SELECT a.* FROM " + info.getTable() + " a" + (join == null ? "" : join) - + ((where == null || where.length() == 0) ? "" : (" WHERE " + where)) + info.createSQLOrderby(flipper); - if (debug.get() && info.isLoggable(Level.FINEST)) - logger.finest(clazz.getSimpleName() + " query sql=" + sql + (flipper == null ? "" : (" LIMIT " + flipper.index() + "," + flipper.getSize()))); - final PreparedStatement ps = conn.prepareStatement(sql, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY); - final ResultSet set = ps.executeQuery(); - if (flipper != null && flipper.index() > 0) set.absolute(flipper.index()); - final int limit = flipper == null ? Integer.MAX_VALUE : flipper.getSize(); - int i = 0; - while (set.next()) { - i++; - list.add(info.getValue(sels, set)); - if (limit <= i) break; - } - long total = list.size(); - if (needtotal && flipper != null) { - set.last(); - total = set.getRow(); - } - set.close(); - ps.close(); - return new Sheet<>(total, list); - } catch (Exception ex) { - throw new RuntimeException(ex); - } finally { - closeSQLConnection(conn); - } - } - - @Override - public final void directQuery(String sql, Consumer consumer) { - final Connection conn = createReadSQLConnection(); - try { - if (debug.get()) logger.finest("direct query sql=" + sql); - final PreparedStatement ps = conn.prepareStatement(sql, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY); - final ResultSet set = ps.executeQuery(); - consumer.accept(set); - set.close(); - ps.close(); - } catch (Exception ex) { - throw new RuntimeException(ex); - } finally { - closeSQLConnection(conn); - } - } - -} diff --git a/src/main/java/org/redkale/source/DataSQLListener.java b/src/main/java/org/redkale/source/DataSQLListener.java deleted file mode 100644 index 0d5295a5a..000000000 --- a/src/main/java/org/redkale/source/DataSQLListener.java +++ /dev/null @@ -1,21 +0,0 @@ -/* - * 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.source; - -/** - * @Resource(name = "property.datasource.nodeid") - * - *

详情见: http://www.redkale.org - * @author zhangjx - */ -public interface DataSQLListener { - - public void insert(String... sqls); - - public void update(String... sqls); - - public void delete(String... sqls); -} diff --git a/src/main/java/org/redkale/source/DataSource.java b/src/main/java/org/redkale/source/DataSource.java deleted file mode 100644 index 6dc600c90..000000000 --- a/src/main/java/org/redkale/source/DataSource.java +++ /dev/null @@ -1,325 +0,0 @@ -/* - * 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.source; - -import java.io.*; -import java.nio.channels.*; -import java.sql.*; -import java.util.*; -import java.util.function.*; -import org.redkale.util.*; - -/** - * - *

- * 详情见: http://www.redkale.org - * - * @author zhangjx - */ -@SuppressWarnings("unchecked") -public interface DataSource { - - //----------------------insert----------------------------- - /** - * 新增对象, 必须是Entity对象 - * - * @param 泛型 - * @param values Entity对象 - */ - public void insert(final T... values); - - //----------------------异步版--------------------------------- - public void insert(final CompletionHandler handler, final T... values); - - //-------------------------delete-------------------------- - /** - * 删除对象, 必须是Entity对象 - * - * @param 泛型 - * @param values Entity对象 - */ - public void delete(final T... values); - - /** - * 根据主键值删除数据 - * 等价SQL: DELETE FROM WHERE {primary} IN {ids} - * - * @param Entity类的泛型 - * @param clazz Entity类 - * @param ids 主键值 - */ - public void delete(final Class clazz, final Serializable... ids); - - public void delete(final Class clazz, final FilterNode node); - - //----------------------异步版--------------------------------- - public void delete(final CompletionHandler handler, final T... values); - - public void delete(final CompletionHandler handler, final Class clazz, final Serializable... ids); - - public void delete(final CompletionHandler handler, final Class clazz, final FilterNode node); - - //------------------------update--------------------------- - /** - * 更新对象, 必须是Entity对象 - * - * @param 泛型 - * @param values Entity对象 - */ - public void update(final T... values); - - public void updateColumn(final Class clazz, final Serializable id, final String column, final Serializable value); - - public void updateColumnIncrement(final Class clazz, final Serializable id, final String column, long incvalue); - - public void updateColumnAnd(final Class clazz, final Serializable id, final String column, long incvalue); - - public void updateColumnOr(final Class clazz, final Serializable id, final String column, long incvalue); - - public void updateColumns(final T value, final String... columns); - - //----------------------异步版--------------------------------- - public void update(final CompletionHandler handler, final T... values); - - public void updateColumn(final CompletionHandler handler, final Class clazz, final Serializable id, final String column, final Serializable value); - - public void updateColumnIncrement(final CompletionHandler handler, final Class clazz, final Serializable id, final String column, long incvalue); - - public void updateColumnAnd(final CompletionHandler handler, final Class clazz, final Serializable id, final String column, long incvalue); - - public void updateColumnOr(final CompletionHandler handler, final Class clazz, final Serializable id, final String column, long incvalue); - - public void updateColumns(final CompletionHandler handler, final T value, final String... columns); - - //-----------------------getXXXXResult----------------------------- - public Number getNumberResult(final Class entityClass, final FilterFunc func, final String column); - - public Number getNumberResult(final Class entityClass, final FilterFunc func, final String column, final FilterBean bean); - - public Number getNumberResult(final Class entityClass, final FilterFunc func, final String column, final FilterNode node); - - public Map queryColumnMap(final Class entityClass, final String keyColumn, final FilterFunc func, final String funcColumn); - - public Map queryColumnMap(final Class entityClass, final String keyColumn, final FilterFunc func, final String funcColumn, final FilterBean bean); - - public Map queryColumnMap(final Class entityClass, final String keyColumn, final FilterFunc func, final String funcColumn, final FilterNode node); - - //----------------------异步版--------------------------------- - public void getNumberResult(final CompletionHandler handler, final Class entityClass, final FilterFunc func, final String column); - - public void getNumberResult(final CompletionHandler handler, final Class entityClass, final FilterFunc func, final String column, final FilterBean bean); - - public void getNumberResult(final CompletionHandler handler, final Class entityClass, final FilterFunc func, final String column, final FilterNode node); - - public void queryColumnMap(final CompletionHandler, String> handler, final Class entityClass, final String keyColumn, final FilterFunc func, final String funcColumn); - - public void queryColumnMap(final CompletionHandler, FilterNode> handler, final Class entityClass, final String keyColumn, final FilterFunc func, final String funcColumn, final FilterBean bean); - - public void queryColumnMap(final CompletionHandler, FilterNode> handler, final Class entityClass, final String keyColumn, final FilterFunc func, final String funcColumn, final FilterNode node); - - //-----------------------find---------------------------- - /** - * 根据主键获取对象 - * - * @param 泛型 - * @param clazz Entity类 - * @param pk 主键值 - * @return Entity对象 - */ - public T find(final Class clazz, final Serializable pk); - - public T find(final Class clazz, final SelectColumn selects, final Serializable pk); - - public T find(final Class clazz, final String column, final Serializable key); - - public T find(final Class clazz, final FilterBean bean); - - public T find(final Class clazz, final FilterNode node); - - public T find(final Class clazz, final SelectColumn selects, final FilterBean bean); - - public T find(final Class clazz, final SelectColumn selects, final FilterNode node); - - public boolean exists(final Class clazz, final Serializable pk); - - public boolean exists(final Class clazz, final FilterBean bean); - - public boolean exists(final Class clazz, final FilterNode node); - - //----------------------异步版--------------------------------- - public void find(final CompletionHandler handler, final Class clazz, final Serializable pk); - - public void find(final CompletionHandler handler, final Class clazz, final SelectColumn selects, final Serializable pk); - - public void find(final CompletionHandler handler, final Class clazz, final String column, final Serializable key); - - public void find(final CompletionHandler handler, final Class clazz, final FilterBean bean); - - public void find(final CompletionHandler handler, final Class clazz, final FilterNode node); - - public void find(final CompletionHandler handler, final Class clazz, final SelectColumn selects, final FilterBean bean); - - public void find(final CompletionHandler handler, final Class clazz, final SelectColumn selects, final FilterNode node); - - public void exists(final CompletionHandler handler, final Class clazz, final Serializable pk); - - public void exists(final CompletionHandler handler, final Class clazz, final FilterBean bean); - - public void exists(final CompletionHandler handler, final Class clazz, final FilterNode node); - - //-----------------------list set---------------------------- - /** - * 根据指定字段值查询对象某个字段的集合 - * - * @param Entity泛型 - * @param 字段类型 - * @param selectedColumn 字段名 - * @param clazz Entity类 - * @param column 过滤字段名 - * @param key 过滤字段值 - * @return 字段值的集合 - */ - public HashSet queryColumnSet(final String selectedColumn, final Class clazz, final String column, final Serializable key); - - public HashSet queryColumnSet(final String selectedColumn, final Class clazz, final FilterBean bean); - - public HashSet queryColumnSet(final String selectedColumn, final Class clazz, final FilterNode node); - - public List queryColumnList(final String selectedColumn, final Class clazz, final String column, final Serializable key); - - public List queryColumnList(final String selectedColumn, final Class clazz, final FilterBean bean); - - public List queryColumnList(final String selectedColumn, final Class clazz, final FilterNode node); - - //----------------------异步版--------------------------------- - public void queryColumnSet(final CompletionHandler, Serializable> handler, final String selectedColumn, final Class clazz, final String column, final Serializable key); - - public void queryColumnSet(final CompletionHandler, FilterNode> handler, final String selectedColumn, final Class clazz, final FilterBean bean); - - public void queryColumnSet(final CompletionHandler, FilterNode> handler, final String selectedColumn, final Class clazz, final FilterNode node); - - public void queryColumnList(final CompletionHandler, Serializable> handler, final String selectedColumn, final Class clazz, final String column, final Serializable key); - - public void queryColumnList(final CompletionHandler, FilterNode> handler, final String selectedColumn, final Class clazz, final FilterBean bean); - - public void queryColumnList(final CompletionHandler, FilterNode> handler, final String selectedColumn, final Class clazz, final FilterNode node); - - /** - * 根据指定参数查询对象某个字段的集合 - * - * @param Entity泛型 - * @param 字段类型 - * @param selectedColumn 字段名 - * @param clazz Entity类 - * @param flipper 翻页对象 - * @param bean 过滤Bean - * @return 结果集合 - */ - public Sheet queryColumnSheet(final String selectedColumn, final Class clazz, final Flipper flipper, final FilterBean bean); - - public Sheet queryColumnSheet(final String selectedColumn, final Class clazz, final Flipper flipper, final FilterNode node); - - //----------------------异步版--------------------------------- - public void queryColumnSheet(final CompletionHandler, FilterNode> handler, final String selectedColumn, final Class clazz, final Flipper flipper, final FilterBean bean); - - public void queryColumnSheet(final CompletionHandler, FilterNode> handler, final String selectedColumn, final Class clazz, final Flipper flipper, final FilterNode node); - - /** - * 根据指定字段值查询对象集合 - * - * @param Entity泛型 - * @param clazz Entity类 - * @param column 过滤字段名 - * @param key 过滤字段值 - * @return Entity的List - */ - public List queryList(final Class clazz, final String column, final Serializable key); - - public List queryList(final Class clazz, final FilterBean bean); - - public List queryList(final Class clazz, final FilterNode node); - - public List queryList(final Class clazz, final SelectColumn selects, final FilterBean bean); - - public List queryList(final Class clazz, final SelectColumn selects, final FilterNode node); - - public List queryList(final Class clazz, final Flipper flipper, final String column, final Serializable key); - - public List queryList(final Class clazz, final Flipper flipper, final FilterBean bean); - - public List queryList(final Class clazz, final Flipper flipper, final FilterNode node); - - public List queryList(final Class clazz, final SelectColumn selects, final Flipper flipper, final FilterBean bean); - - public List queryList(final Class clazz, final SelectColumn selects, final Flipper flipper, final FilterNode node); - - //----------------------异步版--------------------------------- - public void queryList(final CompletionHandler, Serializable> handler, final Class clazz, final String column, final Serializable key); - - public void queryList(final CompletionHandler, FilterNode> handler, final Class clazz, final FilterBean bean); - - public void queryList(final CompletionHandler, FilterNode> handler, final Class clazz, final FilterNode node); - - public void queryList(final CompletionHandler, FilterNode> handler, final Class clazz, final SelectColumn selects, final FilterBean bean); - - public void queryList(final CompletionHandler, FilterNode> handler, final Class clazz, final SelectColumn selects, final FilterNode node); - - public void queryList(final CompletionHandler, Serializable> handler, final Class clazz, final Flipper flipper, final String column, final Serializable key); - - public void queryList(final CompletionHandler, FilterNode> handler, final Class clazz, final Flipper flipper, final FilterBean bean); - - public void queryList(final CompletionHandler, FilterNode> handler, final Class clazz, final Flipper flipper, final FilterNode node); - - public void queryList(final CompletionHandler, FilterNode> handler, final Class clazz, final SelectColumn selects, final Flipper flipper, final FilterBean bean); - - public void queryList(final CompletionHandler, FilterNode> handler, final Class clazz, final SelectColumn selects, final Flipper flipper, final FilterNode node); - - //-----------------------sheet---------------------------- - /** - * 根据指定参数查询对象某个对象的集合页 - *

- * @param Entity泛型 - * @param clazz Entity类 - * @param flipper 翻页对象 - * @param bean 过滤Bean - * @return Entity的Sheet - */ - public Sheet querySheet(final Class clazz, final Flipper flipper, final FilterBean bean); - - public Sheet querySheet(final Class clazz, final Flipper flipper, final FilterNode node); - - public Sheet querySheet(final Class clazz, final SelectColumn selects, final Flipper flipper, final FilterBean bean); - - public Sheet querySheet(final Class clazz, final SelectColumn selects, final Flipper flipper, final FilterNode node); - - //----------------------异步版--------------------------------- - public void querySheet(final CompletionHandler, FilterNode> handler, final Class clazz, final Flipper flipper, final FilterBean bean); - - public void querySheet(final CompletionHandler, FilterNode> handler, final Class clazz, final Flipper flipper, final FilterNode node); - - public void querySheet(final CompletionHandler, FilterNode> handler, final Class clazz, final SelectColumn selects, final Flipper flipper, final FilterBean bean); - - public void querySheet(final CompletionHandler, FilterNode> handler, final Class clazz, final SelectColumn selects, final Flipper flipper, final FilterNode node); - - //-----------------------direct---------------------------- - /** - * 直接本地执行SQL语句进行查询,远程模式不可用 - * 通常用于复杂的关联查询 - * - * @param sql SQL语句 - * @param consumer 回调函数 - */ - public void directQuery(String sql, final Consumer consumer); - - /** - * 直接本地执行SQL语句进行增删改操作,远程模式不可用 - * 通常用于复杂的更新操作 - * - * @param sqls SQL语句 - * @return 结果数组 - */ - public int[] directExecute(String... sqls); -} diff --git a/src/main/java/org/redkale/source/DistributeGenerator.java b/src/main/java/org/redkale/source/DistributeGenerator.java deleted file mode 100644 index 849767df0..000000000 --- a/src/main/java/org/redkale/source/DistributeGenerator.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * 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.source; - -import java.lang.annotation.*; -import static java.lang.annotation.ElementType.*; -import static java.lang.annotation.RetentionPolicy.RUNTIME; - -/** - * - *

详情见: http://www.redkale.org - * @author zhangjx - */ -@Target({FIELD}) -@Retention(RUNTIME) -public @interface DistributeGenerator { - - long initialValue() default 1; - - /** - * 如果allocationSize的值小于或等于1,则主键不会加上nodeid - * - * @return allocationSize - */ - int allocationSize() default 1000; -} diff --git a/src/main/java/org/redkale/source/DistributeTables.java b/src/main/java/org/redkale/source/DistributeTables.java deleted file mode 100644 index 35e280f91..000000000 --- a/src/main/java/org/redkale/source/DistributeTables.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * 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.source; - -import java.lang.annotation.*; -import static java.lang.annotation.ElementType.TYPE; -import static java.lang.annotation.RetentionPolicy.RUNTIME; - -/** - * 当使用DistributeGenerator控制主键值时, 如果表A与表AHistory使用同一主键时, 就需要将表A的class标记: - *

- *  @DistributeTables({AHistory.class})
- *  public class A {
- *  }
- * 
- * 这样DistributeGenerator将从A、B表中取最大值来初始化主键值。 常见场景就是表B是数据表A对应的历史表 - * - *

- * 详情见: http://www.redkale.org - * - * @author zhangjx - */ -@Target({TYPE}) -@Retention(RUNTIME) -public @interface DistributeTables { - - Class[] value(); -} diff --git a/src/main/java/org/redkale/source/EntityCache.java b/src/main/java/org/redkale/source/EntityCache.java deleted file mode 100644 index 5d0c0a8c0..000000000 --- a/src/main/java/org/redkale/source/EntityCache.java +++ /dev/null @@ -1,657 +0,0 @@ -/* - * 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.source; - -import java.io.*; -import java.util.*; -import java.util.concurrent.*; -import java.util.function.*; -import java.util.logging.*; -import java.util.stream.Stream; -import javax.persistence.Transient; -import static org.redkale.source.FilterFunc.*; -import java.util.stream.*; -import org.redkale.util.*; - -/** - * - *

- * 详情见: http://www.redkale.org - * - * @author zhangjx - * @param Entity类的泛型 - */ -@SuppressWarnings("unchecked") -public final class EntityCache { - - private static final Logger logger = Logger.getLogger(EntityCache.class.getName()); - - private final ConcurrentHashMap map = new ConcurrentHashMap(); - - private final Collection list = new ConcurrentLinkedQueue(); // CopyOnWriteArrayList 插入慢、查询快; 10w数据插入需要3.2秒; ConcurrentLinkedQueue 插入快、查询慢;10w数据查询需要 0.062秒, 查询慢40%; - - private final Map> sortComparators = new ConcurrentHashMap<>(); - - private final Class type; - - private final boolean needcopy; - - private final Creator creator; - - private final Attribute primary; - - private final Reproduce reproduce; - - private volatile boolean fullloaded; - - final EntityInfo info; - - public EntityCache(final EntityInfo info) { - this.info = info; - this.type = info.getType(); - this.creator = info.getCreator(); - this.primary = info.primary; - this.needcopy = true; - this.reproduce = Reproduce.create(type, type, (m) -> { - try { - return type.getDeclaredField(m).getAnnotation(Transient.class) == null; - } catch (Exception e) { - return true; - } - }); - } - - public void fullLoad(List all) { - if (all == null) return; - clear(); - all.stream().filter(x -> x != null).forEach(x -> { - this.map.put(this.primary.get(x), x); - }); - this.list.addAll(all); - this.fullloaded = true; - } - - public Class getType() { - return type; - } - - public void clear() { - this.fullloaded = false; - this.list.clear(); - this.map.clear(); - } - - public boolean isFullLoaded() { - return fullloaded; - } - - public T find(Serializable id) { - if (id == null) return null; - T rs = map.get(id); - return rs == null ? null : (needcopy ? reproduce.copy(this.creator.create(), rs) : rs); - } - - public T find(final SelectColumn selects, final Serializable id) { - if (id == null) return null; - T rs = map.get(id); - if (rs == null) return null; - if (selects == null) return (needcopy ? reproduce.copy(this.creator.create(), rs) : rs); - T t = this.creator.create(); - for (Attribute attr : this.info.attributes) { - if (selects.test(attr.field())) attr.set(t, attr.get(rs)); - } - return t; - } - - public T find(final SelectColumn selects, FilterNode node) { - final Predicate filter = node == null ? null : node.createPredicate(this); - Stream stream = this.list.stream(); - if (filter != null) stream = stream.filter(filter); - Optional opt = stream.findFirst(); - if (!opt.isPresent()) return null; - if (selects == null) return (needcopy ? reproduce.copy(this.creator.create(), opt.get()) : opt.get()); - T rs = opt.get(); - T t = this.creator.create(); - for (Attribute attr : this.info.attributes) { - if (selects.test(attr.field())) attr.set(t, attr.get(rs)); - } - return t; - } - - public boolean exists(Serializable id) { - if (id == null) return false; - final Class atype = this.primary.type(); - if (id.getClass() != atype && id instanceof Number) { - if (atype == int.class || atype == Integer.class) { - id = ((Number) id).intValue(); - } else if (atype == long.class || atype == Long.class) { - id = ((Number) id).longValue(); - } else if (atype == short.class || atype == Short.class) { - id = ((Number) id).shortValue(); - } else if (atype == float.class || atype == Float.class) { - id = ((Number) id).floatValue(); - } else if (atype == byte.class || atype == Byte.class) { - id = ((Number) id).byteValue(); - } else if (atype == double.class || atype == Double.class) { - id = ((Number) id).doubleValue(); - } - } - return this.map.containsKey(id); - } - - public boolean exists(FilterNode node) { - final Predicate filter = node == null ? null : node.createPredicate(this); - Stream stream = this.list.stream(); - if (filter != null) stream = stream.filter(filter); - return stream.findFirst().isPresent(); - } - - public boolean exists(final Predicate filter) { - return (filter != null) && this.list.stream().filter(filter).findFirst().isPresent(); - } - - public Map queryColumnMap(final String keyColumn, final FilterFunc func, final String funcColumn, FilterNode node) { - final Attribute keyAttr = info.getAttribute(keyColumn); - final Predicate filter = node == null ? null : node.createPredicate(this); - final Attribute funcAttr = funcColumn == null ? null : info.getAttribute(funcColumn); - Stream stream = this.list.stream(); - if (filter != null) stream = stream.filter(filter); - Collector collector = null; - final Class valtype = funcAttr == null ? null : funcAttr.type(); - switch (func) { - case AVG: - if (valtype == float.class || valtype == Float.class || valtype == double.class || valtype == Double.class) { - collector = (Collector) Collectors.averagingDouble((T t) -> ((Number) funcAttr.get(t)).doubleValue()); - } else { - collector = (Collector) Collectors.averagingLong((T t) -> ((Number) funcAttr.get(t)).longValue()); - } - break; - case COUNT: collector = (Collector) Collectors.counting(); - break; - case DISTINCTCOUNT: - collector = (Collector) Collectors.mapping((t) -> funcAttr.get(t), Collectors.toSet()); - break; - case MAX: - case MIN: - Comparator comp = (o1, o2) -> o1 == null ? (o2 == null ? 0 : -1) : ((Comparable) funcAttr.get(o1)).compareTo(funcAttr.get(o2)); - collector = (Collector) ((func == MAX) ? Collectors.maxBy(comp) : Collectors.minBy(comp)); - break; - case SUM: - if (valtype == float.class || valtype == Float.class || valtype == double.class || valtype == Double.class) { - collector = (Collector) Collectors.summingDouble((T t) -> ((Number) funcAttr.get(t)).doubleValue()); - } else { - collector = (Collector) Collectors.summingLong((T t) -> ((Number) funcAttr.get(t)).longValue()); - } - break; - } - Map rs = stream.collect(Collectors.groupingBy(t -> keyAttr.get(t), LinkedHashMap::new, collector)); - if (func == MAX || func == MIN) { - Map rs2 = new LinkedHashMap(); - rs.forEach((x, y) -> { - if (((Optional) y).isPresent()) rs2.put(x, funcAttr.get((T) ((Optional) y).get())); - }); - rs = rs2; - } else if (func == DISTINCTCOUNT) { - Map rs2 = new LinkedHashMap(); - rs.forEach((x, y) -> rs2.put(x, ((Set) y).size())); - rs = rs2; - } - return rs; - } - - public Number getNumberResult(final FilterFunc func, final String column, FilterNode node) { - final Attribute attr = column == null ? null : info.getAttribute(column); - final Predicate filter = node == null ? null : node.createPredicate(this); - Stream stream = this.list.stream(); - if (filter != null) stream = stream.filter(filter); - switch (func) { - case AVG: - if (attr.type() == int.class || attr.type() == Integer.class) { - return (int) stream.mapToInt(x -> (Integer) attr.get(x)).average().orElse(0); - } else if (attr.type() == long.class || attr.type() == Long.class) { - return (long) stream.mapToLong(x -> (Long) attr.get(x)).average().orElse(0); - } else if (attr.type() == short.class || attr.type() == Short.class) { - return (short) stream.mapToInt(x -> ((Short) attr.get(x)).intValue()).average().orElse(0); - } else if (attr.type() == float.class || attr.type() == Float.class) { - return (float) stream.mapToDouble(x -> ((Float) attr.get(x)).doubleValue()).average().orElse(0); - } else if (attr.type() == double.class || attr.type() == Double.class) { - return stream.mapToDouble(x -> (Double) attr.get(x)).average().orElse(0); - } - throw new RuntimeException("getNumberResult error(type:" + type + ", attr.declaringClass: " + attr.declaringClass() + ", attr.field: " + attr.field() + ", attr.type: " + attr.type()); - case COUNT: return stream.count(); - case DISTINCTCOUNT: return stream.map(x -> attr.get(x)).distinct().count(); - - case MAX: - if (attr.type() == int.class || attr.type() == Integer.class) { - return stream.mapToInt(x -> (Integer) attr.get(x)).max().orElse(0); - } else if (attr.type() == long.class || attr.type() == Long.class) { - return stream.mapToLong(x -> (Long) attr.get(x)).max().orElse(0); - } else if (attr.type() == short.class || attr.type() == Short.class) { - return (short) stream.mapToInt(x -> ((Short) attr.get(x)).intValue()).max().orElse(0); - } else if (attr.type() == float.class || attr.type() == Float.class) { - return (float) stream.mapToDouble(x -> ((Float) attr.get(x)).doubleValue()).max().orElse(0); - } else if (attr.type() == double.class || attr.type() == Double.class) { - return stream.mapToDouble(x -> (Double) attr.get(x)).max().orElse(0); - } - 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) { - return stream.mapToInt(x -> (Integer) attr.get(x)).min().orElse(0); - } else if (attr.type() == long.class || attr.type() == Long.class) { - return stream.mapToLong(x -> (Long) attr.get(x)).min().orElse(0); - } else if (attr.type() == short.class || attr.type() == Short.class) { - return (short) stream.mapToInt(x -> ((Short) attr.get(x)).intValue()).min().orElse(0); - } else if (attr.type() == float.class || attr.type() == Float.class) { - return (float) stream.mapToDouble(x -> ((Float) attr.get(x)).doubleValue()).min().orElse(0); - } else if (attr.type() == double.class || attr.type() == Double.class) { - return stream.mapToDouble(x -> (Double) attr.get(x)).min().orElse(0); - } - 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(); - } 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) { - return (float) stream.mapToDouble(x -> ((Float) attr.get(x)).doubleValue()).sum(); - } else if (attr.type() == double.class || attr.type() == Double.class) { - return stream.mapToDouble(x -> (Double) attr.get(x)).sum(); - } - throw new RuntimeException("getNumberResult error(type:" + type + ", attr.declaringClass: " + attr.declaringClass() + ", attr.field: " + attr.field() + ", attr.type: " + attr.type()); - } - return -1; - } - - public Sheet querySheet(final SelectColumn selects, final Flipper flipper, final FilterNode node) { - return querySheet(true, selects, flipper, node); - } - - public Sheet querySheet(final boolean needtotal, final SelectColumn selects, final Flipper flipper, FilterNode node) { - final Predicate filter = node == null ? null : node.createPredicate(this); - final Comparator comparator = createComparator(flipper); - long total = 0; - if (needtotal) { - Stream stream = this.list.stream(); - if (filter != null) stream = stream.filter(filter); - total = stream.count(); - } - if (needtotal && total == 0) return new Sheet<>(); - Stream stream = this.list.stream(); - if (filter != null) stream = stream.filter(filter); - if (comparator != null) stream = stream.sorted(comparator); - if (flipper != null) stream = stream.skip(flipper.index()).limit(flipper.getSize()); - final List rs = new ArrayList<>(); - if (selects == null) { - Consumer action = x -> rs.add(needcopy ? reproduce.copy(creator.create(), x) : x); - if (comparator != null) { - stream.forEachOrdered(action); - } else { - stream.forEach(action); - } - } else { - final List> attrs = new ArrayList<>(); - info.forEachAttribute((k, v) -> { - if (selects.test(k)) attrs.add(v); - }); - Consumer action = x -> { - final T item = creator.create(); - for (Attribute attr : attrs) { - attr.set(item, attr.get(x)); - } - rs.add(item); - }; - if (comparator != null) { - stream.forEachOrdered(action); - } else { - stream.forEach(action); - } - } - if (!needtotal) total = rs.size(); - return new Sheet<>(total, rs); - } - - public void insert(T value) { - if (value == null) return; - final T rs = reproduce.copy(this.creator.create(), value); //确保同一主键值的map与list中的对象必须共用。 - T old = this.map.put(this.primary.get(rs), rs); - if (old == null) { - this.list.add(rs); - } else { - logger.log(Level.WARNING, "cache repeat insert data: " + value); - } - } - - public void delete(final Serializable id) { - if (id == null) return; - final T rs = this.map.remove(id); - if (rs != null) this.list.remove(rs); - } - - public Serializable[] delete(final FilterNode node) { - if (node == null || this.list.isEmpty()) return new Serializable[0]; - Object[] rms = this.list.stream().filter(node.createPredicate(this)).toArray(); - Serializable[] ids = new Serializable[rms.length]; - int i = -1; - for (Object o : rms) { - final T t = (T) o; - ids[++i] = this.primary.get(t); - this.map.remove(ids[i]); - this.list.remove(t); - } - return ids; - } - - public void update(final T value) { - if (value == null) return; - T rs = this.map.get(this.primary.get(value)); - if (rs == null) return; - this.reproduce.copy(rs, value); - } - - public T update(final T value, Collection> attrs) { - if (value == null) return value; - T rs = this.map.get(this.primary.get(value)); - if (rs == null) return rs; - for (Attribute attr : attrs) { - attr.set(rs, attr.get(value)); - } - return rs; - } - - public T update(final Serializable id, Attribute attr, final V fieldValue) { - if (id == null) return null; - T rs = this.map.get(id); - if (rs != null) attr.set(rs, fieldValue); - return rs; - } - - public T updateColumnOr(final Serializable id, Attribute attr, final long orvalue) { - if (id == null) return null; - T rs = this.map.get(id); - if (rs == null) return rs; - Number numb = (Number) attr.get(rs); - return updateColumnIncrAndOr(attr, rs, (numb == null) ? orvalue : (numb.longValue() | orvalue)); - } - - public T updateColumnAnd(final Serializable id, Attribute attr, final long andvalue) { - if (id == null) return null; - T rs = this.map.get(id); - if (rs == null) return rs; - Number numb = (Number) attr.get(rs); - return updateColumnIncrAndOr(attr, rs, (numb == null) ? 0 : (numb.longValue() & andvalue)); - } - - public T updateColumnIncrement(final Serializable id, Attribute attr, final long incvalue) { - if (id == null) return null; - T rs = this.map.get(id); - if (rs == null) return rs; - Number numb = (Number) attr.get(rs); - return updateColumnIncrAndOr(attr, rs, (numb == null) ? incvalue : (numb.longValue() + incvalue)); - } - - private T updateColumnIncrAndOr(Attribute attr, final T rs, Number numb) { - final Class ft = attr.type(); - if (ft == int.class || ft == Integer.class) { - numb = numb.intValue(); - } else if (ft == long.class || ft == Long.class) { - numb = numb.longValue(); - } else if (ft == short.class || ft == Short.class) { - numb = numb.shortValue(); - } else if (ft == float.class || ft == Float.class) { - numb = numb.floatValue(); - } else if (ft == double.class || ft == Double.class) { - numb = numb.doubleValue(); - } else if (ft == byte.class || ft == Byte.class) { - numb = numb.byteValue(); - } - attr.set(rs, (V) numb); - return rs; - } - - public Attribute getAttribute(String fieldname) { - return info.getAttribute(fieldname); - } - - //------------------------------------------------------------------------------------------------------------------------------- - protected Comparator createComparator(Flipper flipper) { - if (flipper == null || flipper.getSort() == null || flipper.getSort().isEmpty()) return null; - final String sort = flipper.getSort(); - Comparator comparator = this.sortComparators.get(sort); - if (comparator != null) return comparator; - for (String item : sort.split(",")) { - if (item.trim().isEmpty()) continue; - String[] sub = item.trim().split("\\s+"); - int pos = sub[0].indexOf('('); - Attribute attr; - if (pos <= 0) { - attr = getAttribute(sub[0]); - } else { //含SQL函数 - int pos2 = sub[0].lastIndexOf(')'); - final Attribute pattr = getAttribute(sub[0].substring(pos + 1, pos2)); - final String func = sub[0].substring(0, pos); - if ("ABS".equalsIgnoreCase(func)) { - if (pattr.type() == int.class || pattr.type() == Integer.class) { - attr = new Attribute() { - - @Override - public Class type() { - return pattr.type(); - } - - @Override - public Class declaringClass() { - return pattr.declaringClass(); - } - - @Override - public String field() { - return pattr.field(); - } - - @Override - public Serializable get(T obj) { - return Math.abs(((Number) pattr.get(obj)).intValue()); - } - - @Override - public void set(T obj, Serializable value) { - pattr.set(obj, value); - } - }; - } else if (pattr.type() == long.class || pattr.type() == Long.class) { - attr = new Attribute() { - - @Override - public Class type() { - return pattr.type(); - } - - @Override - public Class declaringClass() { - return pattr.declaringClass(); - } - - @Override - public String field() { - return pattr.field(); - } - - @Override - public Serializable get(T obj) { - return Math.abs(((Number) pattr.get(obj)).longValue()); - } - - @Override - public void set(T obj, Serializable value) { - pattr.set(obj, value); - } - }; - } else if (pattr.type() == float.class || pattr.type() == Float.class) { - attr = new Attribute() { - - @Override - public Class type() { - return pattr.type(); - } - - @Override - public Class declaringClass() { - return pattr.declaringClass(); - } - - @Override - public String field() { - return pattr.field(); - } - - @Override - public Serializable get(T obj) { - return Math.abs(((Number) pattr.get(obj)).floatValue()); - } - - @Override - public void set(T obj, Serializable value) { - pattr.set(obj, value); - } - }; - } else if (pattr.type() == double.class || pattr.type() == Double.class) { - attr = new Attribute() { - - @Override - public Class type() { - return pattr.type(); - } - - @Override - public Class declaringClass() { - return pattr.declaringClass(); - } - - @Override - public String field() { - return pattr.field(); - } - - @Override - public Serializable get(T obj) { - return Math.abs(((Number) pattr.get(obj)).doubleValue()); - } - - @Override - public void set(T obj, Serializable value) { - pattr.set(obj, value); - } - }; - } else { - throw new RuntimeException("Flipper not supported sort illegal type by ABS (" + flipper.getSort() + ")"); - } - } else if (func.isEmpty()) { - attr = pattr; - } else { - throw new RuntimeException("Flipper not supported sort illegal function (" + flipper.getSort() + ")"); - } - } - Comparator c = (sub.length > 1 && sub[1].equalsIgnoreCase("DESC")) ? (T o1, T o2) -> { - Comparable c1 = (Comparable) attr.get(o1); - Comparable c2 = (Comparable) attr.get(o2); - return c2 == null ? -1 : c2.compareTo(c1); - } : (T o1, T o2) -> { - Comparable c1 = (Comparable) attr.get(o1); - Comparable c2 = (Comparable) attr.get(o2); - return c1 == null ? -1 : c1.compareTo(c2); - }; - - if (comparator == null) { - comparator = c; - } else { - comparator = comparator.thenComparing(c); - } - } - this.sortComparators.put(sort, comparator); - return comparator; - } - - private static class UniqueSequence implements Serializable { - - private final Serializable[] value; - - public UniqueSequence(Serializable[] val) { - this.value = val; - } - - @Override - public int hashCode() { - return Arrays.deepHashCode(this.value); - } - - @Override - public boolean equals(Object obj) { - if (obj == null) return false; - if (getClass() != obj.getClass()) return false; - final UniqueSequence other = (UniqueSequence) obj; - if (value.length != other.value.length) return false; - for (int i = 0; i < value.length; i++) { - if (!value[i].equals(other.value[i])) return false; - } - return true; - } - - } - - private static interface UniqueAttribute extends Predicate { - - public Serializable getValue(T bean); - - @Override - public boolean test(FilterNode node); - - public static UniqueAttribute create(final Attribute[] attributes) { - if (attributes.length == 1) { - final Attribute attribute = attributes[0]; - return new UniqueAttribute() { - - @Override - public Serializable getValue(T bean) { - return attribute.get(bean); - } - - @Override - public boolean test(FilterNode node) { - if (node == null || node.isOr()) return false; - if (!attribute.field().equals(node.column)) return false; - if (node.nodes == null) return true; - for (FilterNode n : node.nodes) { - if (!test(n)) return false; - } - return true; - } - }; - } else { - return new UniqueAttribute() { - - @Override - public Serializable getValue(T bean) { - final Serializable[] rs = new Serializable[attributes.length]; - for (int i = 0; i < rs.length; i++) { - rs[i] = attributes[i].get(bean); - } - return new UniqueSequence(rs); - } - - @Override - public boolean test(FilterNode node) { - return true; - } - }; - } - } - } - -} diff --git a/src/main/java/org/redkale/source/EntityInfo.java b/src/main/java/org/redkale/source/EntityInfo.java deleted file mode 100644 index fd000655d..000000000 --- a/src/main/java/org/redkale/source/EntityInfo.java +++ /dev/null @@ -1,381 +0,0 @@ -/* - * 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.source; - -import com.sun.istack.internal.logging.Logger; -import java.io.Serializable; -import java.lang.reflect.*; -import java.sql.*; -import java.util.*; -import java.util.concurrent.*; -import java.util.concurrent.atomic.AtomicLong; -import java.util.function.*; -import java.util.logging.*; -import javax.persistence.*; -import org.redkale.util.*; - -/** - * - *

- * 详情见: http://www.redkale.org - * - * @author zhangjx - * @param Entity类的泛型 - */ -@SuppressWarnings("unchecked") -public final class EntityInfo { - - private static final ConcurrentHashMap entityInfos = new ConcurrentHashMap<>(); - - private static final Logger logger = Logger.getLogger(EntityInfo.class); - - //Entity类的类名 - private final Class type; - - //类对应的数据表名, 如果是VirtualEntity 类, 则该字段为null - private final String table; - - private final Creator creator; - - //主键 - final Attribute primary; - - private final EntityCache cache; - - //key是field的name, 不是sql字段。 - //存放所有与数据库对应的字段, 包括主键 - private final HashMap> attributeMap = new HashMap<>(); - - final Attribute[] attributes; - - //key是field的name, value是Column的别名,即数据库表的字段名 - //只有field.name 与 Column.name不同才存放在aliasmap里. - private final Map aliasmap; - - private final Map> updateAttributeMap = new HashMap<>(); - - final String containSQL; //用于反向LIKE使用 - - final String notcontainSQL; //用于反向LIKE使用 - - final String querySQL; - - private final Attribute[] queryAttributes; //数据库中所有字段 - - final String insertSQL; - - final Attribute[] insertAttributes; //数据库中所有可新增字段 - - final String updateSQL; - - final Attribute[] updateAttributes; //数据库中所有可更新字段 - - final String deleteSQL; - - private final int logLevel; - - private final Map sortOrderbySqls = new ConcurrentHashMap<>(); - - //---------------------计算主键值---------------------------- - private final int nodeid; - - final Class[] distributeTables; - - final boolean autoGenerated; - - final boolean distributed; - - boolean initedPrimaryValue = false; - - final AtomicLong primaryValue = new AtomicLong(0); - - final int allocationSize; - //------------------------------------------------------------ - - public static EntityInfo load(Class clazz, final int nodeid, final boolean cacheForbidden, final Properties conf, - Function fullloader) { - EntityInfo rs = entityInfos.get(clazz); - if (rs != null) return rs; - synchronized (entityInfos) { - rs = entityInfos.get(clazz); - if (rs == null) { - if (nodeid < 0) throw new IllegalArgumentException("nodeid(" + nodeid + ") is illegal"); - rs = new EntityInfo(clazz, nodeid, cacheForbidden, conf); - entityInfos.put(clazz, rs); - AutoLoad auto = clazz.getAnnotation(AutoLoad.class); - if (rs.cache != null && auto != null && auto.value()) { - if (fullloader == null) throw new IllegalArgumentException(clazz.getName() + " auto loader is illegal"); - rs.cache.fullLoad(fullloader.apply(clazz)); - } - } - return rs; - } - } - - static EntityInfo get(Class clazz) { - return entityInfos.get(clazz); - } - - private EntityInfo(Class type, int nodeid, final boolean cacheForbidden, Properties conf) { - this.type = type; - //--------------------------------------------- - this.nodeid = nodeid >= 0 ? nodeid : 0; - DistributeTables dt = type.getAnnotation(DistributeTables.class); - this.distributeTables = dt == null ? null : dt.value(); - - LogLevel ll = type.getAnnotation(LogLevel.class); - this.logLevel = ll == null ? Integer.MIN_VALUE : Level.parse(ll.value()).intValue(); - //--------------------------------------------- - Table t = type.getAnnotation(Table.class); - if (type.getAnnotation(VirtualEntity.class) != null) { - this.table = null; - } else { - this.table = (t == null) ? type.getSimpleName().toLowerCase() : (t.catalog().isEmpty()) ? t.name() : (t.catalog() + '.' + t.name()); - } - this.creator = Creator.create(type); - Attribute idAttr0 = null; - Map aliasmap0 = null; - Class cltmp = type; - Set fields = new HashSet<>(); - List> queryattrs = new ArrayList<>(); - List insertcols = new ArrayList<>(); - List> insertattrs = new ArrayList<>(); - List updatecols = new ArrayList<>(); - List> updateattrs = new ArrayList<>(); - boolean auto = false; - boolean sqldistribute = false; - int allocationSize0 = 0; - - do { - for (Field field : cltmp.getDeclaredFields()) { - if (Modifier.isStatic(field.getModifiers())) continue; - if (Modifier.isFinal(field.getModifiers())) continue; - if (field.getAnnotation(Transient.class) != null) continue; - if (fields.contains(field.getName())) continue; - final String fieldname = field.getName(); - final Column col = field.getAnnotation(Column.class); - final String sqlfield = col == null || col.name().isEmpty() ? fieldname : col.name(); - if (!fieldname.equals(sqlfield)) { - if (aliasmap0 == null) aliasmap0 = new HashMap<>(); - aliasmap0.put(fieldname, sqlfield); - } - Attribute attr; - try { - attr = Attribute.create(cltmp, field); - } catch (RuntimeException e) { - continue; - } - if (field.getAnnotation(javax.persistence.Id.class) != null && idAttr0 == null) { - idAttr0 = attr; - GeneratedValue gv = field.getAnnotation(GeneratedValue.class); - auto = gv != null; -// if (gv != null && gv.strategy() != GenerationType.IDENTITY) { -// throw new RuntimeException(cltmp.getName() + "'s @ID primary not a GenerationType.IDENTITY"); -// } - DistributeGenerator dg = field.getAnnotation(DistributeGenerator.class); - if (dg != null) { - if (!field.getType().isPrimitive()) throw new RuntimeException(cltmp.getName() + "'s @" + DistributeGenerator.class.getSimpleName() + " primary must be primitive class type field"); - sqldistribute = true; - auto = false; - allocationSize0 = dg.allocationSize(); - primaryValue.set(dg.initialValue()); - } - if (!auto) { - insertcols.add(sqlfield); - insertattrs.add(attr); - } - } else { - if (col == null || col.insertable()) { - insertcols.add(sqlfield); - insertattrs.add(attr); - } - if (col == null || col.updatable()) { - updatecols.add(sqlfield); - updateattrs.add(attr); - updateAttributeMap.put(fieldname, attr); - } - } - queryattrs.add(attr); - fields.add(fieldname); - attributeMap.put(fieldname, attr); - } - } while ((cltmp = cltmp.getSuperclass()) != Object.class); - this.primary = idAttr0; - this.aliasmap = aliasmap0; - this.attributes = attributeMap.values().toArray(new Attribute[attributeMap.size()]); - this.queryAttributes = queryattrs.toArray(new Attribute[queryattrs.size()]); - this.insertAttributes = insertattrs.toArray(new Attribute[insertattrs.size()]); - this.updateAttributes = updateattrs.toArray(new Attribute[updateattrs.size()]); - if (table != null) { - StringBuilder insertsb = new StringBuilder(); - StringBuilder insertsb2 = new StringBuilder(); - for (String col : insertcols) { - if (insertsb.length() > 0) insertsb.append(','); - insertsb.append(col); - if (insertsb2.length() > 0) insertsb2.append(','); - insertsb2.append('?'); - } - this.insertSQL = "INSERT INTO " + table + "(" + insertsb + ") VALUES(" + insertsb2 + ")"; - StringBuilder updatesb = new StringBuilder(); - for (String col : updatecols) { - if (updatesb.length() > 0) updatesb.append(", "); - updatesb.append(col).append(" = ?"); - } - this.updateSQL = "UPDATE " + table + " SET " + updatesb + " WHERE " + getPrimarySQLColumn(null) + " = ?"; - this.deleteSQL = "DELETE FROM " + table + " WHERE " + getPrimarySQLColumn(null) + " = ?"; - this.querySQL = "SELECT * FROM " + table + " WHERE " + getPrimarySQLColumn(null) + " = ?"; - } else { - this.insertSQL = null; - this.updateSQL = null; - this.deleteSQL = null; - this.querySQL = null; - } - this.autoGenerated = auto; - this.distributed = sqldistribute; - this.allocationSize = allocationSize0; - //----------------cache-------------- - Cacheable c = type.getAnnotation(Cacheable.class); - if (this.table == null || (!cacheForbidden && c != null && c.value())) { - this.cache = new EntityCache<>(this); - } else { - this.cache = null; - } - if (conf == null) conf = new Properties(); - this.containSQL = conf.getProperty("contain-sql-template", "LOCATE(${keystr}, ${column}) > 0"); - this.notcontainSQL = conf.getProperty("notcontain-sql-template", "LOCATE(${keystr}, ${column}) = 0"); - } - - public void createPrimaryValue(T src) { - long v = allocationSize > 1 ? (primaryValue.incrementAndGet() * allocationSize + nodeid) : primaryValue.incrementAndGet(); - if (primary.type() == int.class || primary.type() == Integer.class) { - getPrimary().set(src, (Integer) ((Long) v).intValue()); - } else { - getPrimary().set(src, v); - } - } - - public EntityCache getCache() { - return cache; - } - - public boolean isCacheFullLoaded() { - return cache != null && cache.isFullLoaded(); - } - - public Creator getCreator() { - return creator; - } - - public Class getType() { - return type; - } - - /** - * 是否虚拟类 - * - * @return 是否虚拟类 - */ - public boolean isVirtualEntity() { - return table == null; - } - - public String getTable() { - return table; - } - - public Attribute getPrimary() { - return this.primary; - } - - public void forEachAttribute(BiConsumer> action) { - this.attributeMap.forEach(action); - } - - public Attribute getAttribute(String fieldname) { - if (fieldname == null) return null; - return this.attributeMap.get(fieldname); - } - - public Attribute getUpdateAttribute(String fieldname) { - return this.updateAttributeMap.get(fieldname); - } - - public boolean isNoAlias() { - return this.aliasmap == null; - } - - protected String createSQLOrderby(Flipper flipper) { - if (flipper == null || flipper.getSort() == null || flipper.getSort().isEmpty()) return ""; - final String sort = flipper.getSort(); - String sql = this.sortOrderbySqls.get(sort); - if (sql != null) return sql; - final StringBuilder sb = new StringBuilder(); - sb.append(" ORDER BY "); - if (isNoAlias()) { - sb.append(sort); - } else { - boolean flag = false; - for (String item : sort.split(",")) { - if (item.isEmpty()) continue; - String[] sub = item.split("\\s+"); - if (flag) sb.append(','); - if (sub.length < 2 || sub[1].equalsIgnoreCase("ASC")) { - sb.append(getSQLColumn("a", sub[0])).append(" ASC"); - } else { - sb.append(getSQLColumn("a", sub[0])).append(" DESC"); - } - flag = true; - } - } - sql = sb.toString(); - this.sortOrderbySqls.put(sort, sql); - return sql; - } - - //根据field字段名获取数据库对应的字段名 - public String getSQLColumn(String tabalis, String fieldname) { - return this.aliasmap == null ? (tabalis == null ? fieldname : (tabalis + '.' + fieldname)) - : (tabalis == null ? aliasmap.getOrDefault(fieldname, fieldname) : (tabalis + '.' + aliasmap.getOrDefault(fieldname, fieldname))); - } - - public String getPrimarySQLColumn() { - return getSQLColumn(null, this.primary.field()); - } - - //数据库字段名 - public String getPrimarySQLColumn(String tabalis) { - return getSQLColumn(tabalis, this.primary.field()); - } - - protected Map> getAttributes() { - return attributeMap; - } - - public boolean isLoggable(Level l) { - return l.intValue() >= this.logLevel; - } - - protected T getValue(final SelectColumn sels, final ResultSet set) throws SQLException { - T obj = creator.create(); - for (Attribute attr : queryAttributes) { - if (sels == null || sels.test(attr.field())) { - Serializable o = (Serializable) set.getObject(this.getSQLColumn(null, attr.field())); - if (o != null) { - Class t = attr.type(); - if (t == short.class) { - o = ((Number) o).shortValue(); - } else if (t == long.class) { - o = ((Number) o).longValue(); - } else if (t == int.class) { - o = ((Number) o).intValue(); - } - } - attr.set(obj, o); - } - } - return obj; - } -} diff --git a/src/main/java/org/redkale/source/FilterBean.java b/src/main/java/org/redkale/source/FilterBean.java deleted file mode 100644 index de72030bd..000000000 --- a/src/main/java/org/redkale/source/FilterBean.java +++ /dev/null @@ -1,16 +0,0 @@ -/* - * 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.source; - -/** - * - *

详情见: http://www.redkale.org - * @author zhangjx - */ -public interface FilterBean { - -} diff --git a/src/main/java/org/redkale/source/FilterColumn.java b/src/main/java/org/redkale/source/FilterColumn.java deleted file mode 100644 index dd6de780b..000000000 --- a/src/main/java/org/redkale/source/FilterColumn.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * 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.source; - -import java.lang.annotation.*; -import static java.lang.annotation.ElementType.FIELD; -import static java.lang.annotation.RetentionPolicy.RUNTIME; - -/** - * - *

- * 详情见: http://www.redkale.org - * - * @author zhangjx - */ -@Inherited -@Documented -@Target({FIELD}) -@Retention(RUNTIME) -public @interface FilterColumn { - - /** - * 对应Entity Class中字段的名称, 而不是SQL字段名称 - * - * @return 字段名 - */ - String name() default ""; - - /** - * 当字段类型是Number时, 如果值>=least() 则需要过滤, 否则跳过该字段 - * - * @return 最小可过滤值 - */ - long least() default 1; - - /** - * express的默认值根据字段类型的不同而不同: - * 数组 --> IN - * Range --> Between - * 其他 --> = - * - * @return 字段表达式 - */ - FilterExpress express() default FilterExpress.EQUAL; - -} diff --git a/src/main/java/org/redkale/source/FilterExpress.java b/src/main/java/org/redkale/source/FilterExpress.java deleted file mode 100644 index ceca71bcc..000000000 --- a/src/main/java/org/redkale/source/FilterExpress.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * 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.source; - -/** - * - *

- * 详情见: http://www.redkale.org - * - * @author zhangjx - */ -public enum FilterExpress { - - EQUAL("="), - NOTEQUAL("<>"), - GREATERTHAN(">"), - LESSTHAN("<"), - GREATERTHANOREQUALTO(">="), - LESSTHANOREQUALTO("<="), - - STARTSWITH("LIKE"), - NOTSTARTSWITH("NOT LIKE"), - ENDSWITH("LIKE"), - NOTENDSWITH("NOT LIKE"), - - LIKE("LIKE"), - NOTLIKE("NOT LIKE"), - IGNORECASELIKE("LIKE"), //不区分大小写的 LIKE - IGNORECASENOTLIKE("NOT LIKE"), //不区分大小写的 NOT LIKE - - CONTAIN("CONTAIN"), //包含, 相当于反向LIKE - NOTCONTAIN("NOT CONTAIN"), //不包含, 相当于反向LIKE - IGNORECASECONTAIN("CONTAIN"), //不区分大小写的 CONTAIN - IGNORECASENOTCONTAIN("NOT CONTAIN"), //不区分大小写的 NOT CONTAIN - - BETWEEN("BETWEEN"), - NOTBETWEEN("NOT BETWEEN"), - IN("IN"), - NOTIN("NOT IN"), - ISNULL("IS NULL"), - ISNOTNULL("IS NOT NULL"), - OPAND("&"), //与运算 > 0 - OPOR("|"), //或运算 > 0 - OPANDNO("&"), //与运算 == 0 - FV_MOD("%"), //取模运算,需要与FilterValue配合使用 - FV_DIV("DIV"), //整除运算,需要与FilterValue配合使用 - AND("AND"), - OR("OR"); - - private final String value; - - private FilterExpress(String v) { - this.value = v; - } - - public String value() { - return value; - } - -} diff --git a/src/main/java/org/redkale/source/FilterFunc.java b/src/main/java/org/redkale/source/FilterFunc.java deleted file mode 100644 index 0f1e689ca..000000000 --- a/src/main/java/org/redkale/source/FilterFunc.java +++ /dev/null @@ -1,25 +0,0 @@ -/* - * 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.source; - -/** - * - *

详情见: http://www.redkale.org - * @author zhangjx - */ -public enum FilterFunc { - AVG, - COUNT, - DISTINCTCOUNT, - MAX, - MIN, - SUM; - - public String getColumn(String col) { - if (this == DISTINCTCOUNT) return "COUNT(DISTINCT " + col + ")"; - return this.name() + "(" + col + ")"; - } -} diff --git a/src/main/java/org/redkale/source/FilterGroup.java b/src/main/java/org/redkale/source/FilterGroup.java deleted file mode 100644 index 315fc1d61..000000000 --- a/src/main/java/org/redkale/source/FilterGroup.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * 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.source; - -import static java.lang.annotation.RetentionPolicy.RUNTIME; -import static java.lang.annotation.ElementType.FIELD; -import java.lang.annotation.*; - -/** - * 默认情况下FilterBean下的过滤字段之间是AND关系。 - * 当需要使用OR或AND OR组合过滤查询时需要使用 FilterGroup。 - * FilterGroup 的value 必须是[OR]或者[AND]开头, 多级需要用点.分隔。 (注: 暂时不支持多级) - * 示例一: - *

- * public class TestFilterBean implements FilterBean {
- *
- *      private int id;
- *
- *      @FilterGroup("[OR]g1")
- *      private String desc;
- *
- *      @FilterGroup("[OR]g1")
- *      private String name;
- * }
- * 
- * 转换的SQL语句为: WHERE id = ? AND (desc = ? OR name = ?) - * - * 示例二: - *
- * public class TestFilterBean implements FilterBean {
- *
- *      private int id;
- *
- *      @FilterGroup("[OR]g1.[AND]subg1")
- *      @FilterColumn(express = LIKE)
- *      private String desc;
- *
- *      @FilterGroup("[OR]g1.[AND]subg1")
- *      @FilterColumn(express = LIKE)
- *      private String name;
- *
- *      @FilterGroup("[OR]g1.[OR]subg2")
- *      private int age;
- *
- *      @FilterGroup("[OR]g1.[OR]subg2")
- *      private int birthday;
- * }
- * 
- * 转换的SQL语句为: WHERE id = ? AND ((desc LIKE ? AND name LIKE ?) OR (age = ? OR birthday = ?)) - * 因为默认是AND关系, @FilterGroup("") 等价于 @FilterGroup("[AND]") - * 所以示例二的@FilterGroup("[OR]g1.[AND]subg1") 可以简化为 @FilterGroup("[OR]g1") - */ -/** - *

- * 详情见: http://www.redkale.org - * - * @author zhangjx - */ -@Inherited -@Documented -@Target({FIELD}) -@Retention(RUNTIME) -public @interface FilterGroup { - - String value() default "[AND]"; -} diff --git a/src/main/java/org/redkale/source/FilterJoinColumn.java b/src/main/java/org/redkale/source/FilterJoinColumn.java deleted file mode 100644 index 9cd57bc9e..000000000 --- a/src/main/java/org/redkale/source/FilterJoinColumn.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * 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.source; - -import java.lang.annotation.*; -import static java.lang.annotation.ElementType.FIELD; -import static java.lang.annotation.RetentionPolicy.RUNTIME; - -/** - * - *

- * 详情见: http://www.redkale.org - * - * @author zhangjx - */ -@Inherited -@Documented -@Target({FIELD}) -@Retention(RUNTIME) -public @interface FilterJoinColumn { - - /** - * 关联表 通常join表默认别名为b/c/d/...自增, 被join表默认别名为a - * - * @return 关联表 - */ - Class table(); - - /** - * - * 多个关联字段, 默认使用join表(b)的主键, join表与被join表(a)的字段必须一样 - * 例如: SELECT a.* FROM user a INNER JOIN record b ON a.userid = b.userid AND a.usertype = b.usertype - * 那么注解为: @FilterJoinColumn(table = Record.class, columns = {"userid", "usertype"}) - * - * @return 关联字段 - */ - String[] columns(); -} diff --git a/src/main/java/org/redkale/source/FilterJoinNode.java b/src/main/java/org/redkale/source/FilterJoinNode.java deleted file mode 100644 index 80a374896..000000000 --- a/src/main/java/org/redkale/source/FilterJoinNode.java +++ /dev/null @@ -1,316 +0,0 @@ -/* - * 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.source; - -import java.io.*; -import java.util.*; -import java.util.concurrent.atomic.*; -import java.util.function.*; -import org.redkale.util.*; - -/** - * - *

详情见: http://www.redkale.org - * @author zhangjx - */ -public class FilterJoinNode extends FilterNode { - - private Class joinClass; - - private EntityInfo joinEntity; //在调用 createSQLJoin 和 isCacheUseable 时会注入 - - private String[] joinColumns; - - public FilterJoinNode() { - } - - protected FilterJoinNode(Class joinClass, String[] joinColumns, String column, Serializable value) { - this(joinClass, joinColumns, column, null, value); - } - - protected FilterJoinNode(Class joinClass, String[] joinColumns, String column, FilterExpress express, Serializable value) { - Objects.requireNonNull(joinClass); - Objects.requireNonNull(joinColumns); - this.joinClass = joinClass; - this.joinColumns = joinColumns; - this.column = column; - this.express = express; - this.value = value; - } - - protected FilterJoinNode(FilterJoinNode node) { - this(node.joinClass, node.joinColumns, node.column, node.express, node.value); - this.joinEntity = node.joinEntity; - this.or = node.or; - this.nodes = node.nodes; - } - - public static FilterJoinNode create(Class joinClass, String joinColumn, String column, Serializable value) { - return new FilterJoinNode(joinClass, new String[]{joinColumn}, column, value); - } - - public static FilterJoinNode create(Class joinClass, String joinColumn, String column, FilterExpress express, Serializable value) { - return new FilterJoinNode(joinClass, new String[]{joinColumn}, column, express, value); - } - - public static FilterJoinNode create(Class joinClass, String[] joinColumns, String column, Serializable value) { - return new FilterJoinNode(joinClass, joinColumns, column, value); - } - - public static FilterJoinNode create(Class joinClass, String[] joinColumns, String column, FilterExpress express, Serializable value) { - return new FilterJoinNode(joinClass, joinColumns, column, express, value); - } - - @Override - protected FilterNode any(final FilterNode node0, boolean signor) { - Objects.requireNonNull(node0); - if (!(node0 instanceof FilterJoinNode)) { - throw new IllegalArgumentException(this + (signor ? " or " : " and ") + " a node but " + String.valueOf(node0) + "is not a " + FilterJoinNode.class.getSimpleName()); - } - final FilterJoinNode node = (FilterJoinNode) node0; - if (this.nodes == null) { - this.nodes = new FilterNode[]{node}; - this.or = signor; - return this; - } - if (or == signor || this.column == null) { - FilterNode[] newsiblings = new FilterNode[nodes.length + 1]; - System.arraycopy(nodes, 0, newsiblings, 0, nodes.length); - newsiblings[nodes.length] = node; - this.nodes = newsiblings; - if (this.column == null) this.or = signor; - return this; - } - this.nodes = new FilterNode[]{new FilterJoinNode(node), node}; - this.column = null; - this.express = null; - this.value = null; - this.joinClass = null; - this.joinEntity = null; - this.joinColumns = null; - this.or = signor; - return this; - } - - @Override - protected CharSequence createSQLExpress(final EntityInfo info, final Map joinTabalis) { - return super.createSQLExpress(this.joinEntity == null ? info : this.joinEntity, joinTabalis); - } - - @Override - protected Predicate createPredicate(final EntityCache cache) { - if (column == null && this.nodes == null) return null; - final EntityCache joinCache = this.joinEntity.getCache(); - final AtomicBoolean more = new AtomicBoolean(); - Predicate filter = createJoinPredicate(more); - Predicate rs = null; - if (filter == null && !more.get()) return rs; - if (filter != null) { - final Predicate inner = filter; - rs = new Predicate() { - - @Override - public boolean test(final T t) { - Predicate joinPredicate = null; - for (String joinColumn : joinColumns) { - final Serializable key = cache.getAttribute(joinColumn).get(t); - final Attribute joinAttr = joinCache.getAttribute(joinColumn); - Predicate p = (E e) -> key.equals(joinAttr.get(e)); - joinPredicate = joinPredicate == null ? p : joinPredicate.and(p); - } - return joinCache.exists(inner.and(joinPredicate)); - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append(" #-- ON ").append(joinColumns[0]).append("=").append(joinClass == null ? "null" : joinClass.getSimpleName()).append(".").append(joinColumns[0]); - for (int i = 1; i < joinColumns.length; i++) { - sb.append(" AND ").append(joinColumns[i]).append("=").append(joinClass == null ? "null" : joinClass.getSimpleName()).append(".").append(joinColumns[i]); - } - sb.append(" --# ").append(inner.toString()); - return sb.toString(); - } - }; - } - if (more.get()) { //存在不同Class的关联表 - if (this.nodes != null) { - for (FilterNode node : this.nodes) { - if (((FilterJoinNode) node).joinClass == this.joinClass) continue; - Predicate f = node.createPredicate(cache); - if (f == null) continue; - final Predicate one = rs; - final Predicate two = f; - rs = (rs == null) ? f : (or ? new Predicate() { - - @Override - public boolean test(T t) { - return one.test(t) || two.test(t); - } - - @Override - public String toString() { - return "(" + one + " OR " + two + ")"; - } - } : new Predicate() { - - @Override - public boolean test(T t) { - return one.test(t) && two.test(t); - } - - @Override - public String toString() { - return "(" + one + " AND " + two + ")"; - } - }); - } - } - } - return rs; - } - - private Predicate createJoinPredicate(final AtomicBoolean more) { - if (column == null && this.nodes == null) return null; - final EntityCache joinCache = this.joinEntity.getCache(); - Predicate filter = createElementPredicate(joinCache, true); - if (this.nodes != null) { - for (FilterNode node : this.nodes) { - if (((FilterJoinNode) node).joinClass != this.joinClass) { - more.set(true); - continue; - } - Predicate f = ((FilterJoinNode) node).createJoinPredicate(more); - if (f == null) continue; - final Predicate one = filter; - final Predicate two = f; - filter = (filter == null) ? f : (or ? new Predicate() { - - @Override - public boolean test(E t) { - return one.test(t) || two.test(t); - } - - @Override - public String toString() { - return "(" + one + " OR " + two + ")"; - } - } : new Predicate() { - - @Override - public boolean test(E t) { - return one.test(t) && two.test(t); - } - - @Override - public String toString() { - return "(" + one + " AND " + two + ")"; - } - }); - } - } - return filter; - } - - @Override - protected CharSequence createSQLJoin(final Function func, final Map joinTabalis, final EntityInfo info) { - boolean morejoin = false; - if (this.joinEntity == null) { - if (this.joinClass != null) this.joinEntity = func.apply(this.joinClass); - if (this.nodes != null) { - for (FilterNode node : this.nodes) { - if (node instanceof FilterJoinNode) { - FilterJoinNode joinNode = ((FilterJoinNode) node); - if (joinNode.joinClass != null) { - joinNode.joinEntity = func.apply(joinNode.joinClass); - if (this.joinClass != null && this.joinClass != joinNode.joinClass) morejoin = true; - } - } - } - } - } - StringBuilder sb = new StringBuilder(); - if (this.joinClass != null) { - sb.append(createElementSQLJoin(joinTabalis, info, this)); - } - if (morejoin) { - Set set = new HashSet<>(); - if (this.joinClass != null) set.add(this.joinClass); - for (FilterNode node : this.nodes) { - if (node instanceof FilterJoinNode) { - FilterJoinNode joinNode = ((FilterJoinNode) node); - if (!set.contains(joinNode.joinClass)) { - CharSequence cs = createElementSQLJoin(joinTabalis, info, joinNode); - if (cs != null) { - sb.append(cs); - set.add(joinNode.joinClass); - } - } - } - } - } - return sb; - } - - private static CharSequence createElementSQLJoin(final Map joinTabalis, final EntityInfo info, final FilterJoinNode node) { - if (node.joinClass == null) return null; - StringBuilder sb = new StringBuilder(); - String[] joinColumns = node.joinColumns; - sb.append(" INNER JOIN ").append(node.joinEntity.getTable()).append(" ").append(joinTabalis.get(node.joinClass)) - .append(" ON ").append(info.getSQLColumn("a", joinColumns[0])).append(" = ").append(node.joinEntity.getSQLColumn(joinTabalis.get(node.joinClass), joinColumns[0])); - for (int i = 1; i < joinColumns.length; i++) { - sb.append(" AND ").append(info.getSQLColumn("a", joinColumns[i])).append(" = ").append(node.joinEntity.getSQLColumn(joinTabalis.get(node.joinClass), joinColumns[i])); - } - return sb; - } - - @Override - protected boolean isCacheUseable(final Function entityApplyer) { - if (this.joinEntity == null) this.joinEntity = entityApplyer.apply(this.joinClass); - if (!this.joinEntity.isCacheFullLoaded()) return false; - if (this.nodes == null) return true; - for (FilterNode node : this.nodes) { - if (!node.isCacheUseable(entityApplyer)) return false; - } - return true; - } - - @Override - protected void putJoinTabalis(Map map) { - if (this.joinClass != null && !map.containsKey(this.joinClass)) map.put(joinClass, String.valueOf((char) ('b' + map.size()))); - if (this.nodes == null) return; - for (FilterNode node : this.nodes) { - node.putJoinTabalis(map); - } - } - - @Override - protected final boolean isjoin() { - return true; - } - - @Override - public String toString() { - return toString(joinClass == null ? null : joinClass.getSimpleName()).toString(); - } - - public Class getJoinClass() { - return joinClass; - } - - public void setJoinClass(Class joinClass) { - this.joinClass = joinClass; - } - - public String[] getJoinColumns() { - return joinColumns; - } - - public void setJoinColumns(String[] joinColumns) { - this.joinColumns = joinColumns; - } - -} diff --git a/src/main/java/org/redkale/source/FilterNode.java b/src/main/java/org/redkale/source/FilterNode.java deleted file mode 100644 index fecb95135..000000000 --- a/src/main/java/org/redkale/source/FilterNode.java +++ /dev/null @@ -1,1256 +0,0 @@ -/* - * 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.source; - -import java.io.Serializable; -import java.lang.reflect.Array; -import java.util.*; -import java.util.function.*; -import static org.redkale.source.FilterExpress.*; -import org.redkale.util.Attribute; - -/** - * 注意: 在调用 createSQLExpress 之前必须先调用 createSQLJoin 在调用 createPredicate 之前必须先调用 isCacheUseable - *

- *

- * 详情见: http://www.redkale.org - * - * @author zhangjx - */ -public class FilterNode { - - protected String column; - - protected FilterExpress express; - - protected Serializable value; - - //---------------------------------------------- - protected boolean or; - - protected FilterNode[] nodes; - - public FilterNode() { - } - - protected FilterNode(String col, FilterExpress exp, Serializable val) { - Objects.requireNonNull(col); - if (exp == null) { - if (val instanceof Range) { - exp = FilterExpress.BETWEEN; - } else if (val instanceof Collection) { - exp = FilterExpress.IN; - } else if (val != null && val.getClass().isArray()) { - exp = FilterExpress.IN; - } else { - exp = FilterExpress.EQUAL; - } - } - this.column = col; - this.express = exp; - this.value = val; - } - - public final FilterNode and(FilterNode node) { - return any(node, false); - } - - public final FilterNode and(String column, Serializable value) { - return and(column, null, value); - } - - public final FilterNode and(String column, FilterExpress express, Serializable value) { - return and(new FilterNode(column, express, value)); - } - - public final FilterNode or(FilterNode node) { - return any(node, true); - } - - public final FilterNode or(String column, Serializable value) { - return or(column, null, value); - } - - public final FilterNode or(String column, FilterExpress express, Serializable value) { - return or(new FilterNode(column, express, value)); - } - - protected FilterNode any(FilterNode node, boolean signor) { - Objects.requireNonNull(node); - if (this.column == null) { - this.column = node.column; - this.express = node.express; - this.value = node.value; - return this; - } - if (this.nodes == null) { - this.nodes = new FilterNode[]{node}; - this.or = signor; - return this; - } - if (or == signor) { - FilterNode[] newsiblings = new FilterNode[nodes.length + 1]; - System.arraycopy(nodes, 0, newsiblings, 0, nodes.length); - newsiblings[nodes.length] = node; - this.nodes = newsiblings; - return this; - } - FilterNode newnode = new FilterNode(this.column, this.express, this.value); - newnode.or = this.or; - newnode.nodes = this.nodes; - this.nodes = new FilterNode[]{newnode, node}; - this.column = null; - this.express = null; - this.or = signor; - this.value = null; - return this; - } - - /** - * 该方法需要重载 - * - * @param Entity类的泛型 - * @param func EntityInfo的加载器 - * @param joinTabalis 关联表集合 - * @param info Entity类的EntityInfo - * @return SQL的join语句 不存在返回null - */ - protected CharSequence createSQLJoin(final Function func, final Map joinTabalis, final EntityInfo info) { - if (joinTabalis == null || this.nodes == null) return null; - StringBuilder sb = null; - for (FilterNode node : this.nodes) { - CharSequence cs = node.createSQLJoin(func, joinTabalis, info); - if (cs == null) continue; - if (sb == null) sb = new StringBuilder(); - sb.append(cs); - } - return sb; - } - - /** - * 该方法需要重载 - * - * @return 是否存在关联表 - */ - protected boolean isjoin() { - if (this.nodes == null) return false; - for (FilterNode node : this.nodes) { - if (node.isjoin()) return true; - } - return false; - } - - protected final Map getJoinTabalis() { - if (!isjoin()) return null; - Map map = new HashMap<>(); - putJoinTabalis(map); - return map; - } - - protected void putJoinTabalis(Map map) { - if (this.nodes == null) return; - for (FilterNode node : this.nodes) { - node.putJoinTabalis(map); - } - } - - /** - * 该方法需要重载 - * - * @param entityApplyer EntityInfo的加载器 - * @return 是否可以使用缓存 - */ - protected boolean isCacheUseable(final Function entityApplyer) { - if (this.nodes == null) return true; - for (FilterNode node : this.nodes) { - if (!node.isCacheUseable(entityApplyer)) return false; - } - return true; - } - - /** - * 该方法需要重载 - * - * @param Entity类的泛型 - * @param joinTabalis 关联表的集合 - * @param info EntityInfo - * @return JOIN的SQL语句 - */ - protected CharSequence createSQLExpress(final EntityInfo info, final Map joinTabalis) { - CharSequence sb0 = this.column == null || info == null ? null : createElementSQLExpress(info, joinTabalis == null ? null : joinTabalis.get(info.getType())); - if (this.nodes == null) return sb0; - final StringBuilder rs = new StringBuilder(); - rs.append('('); - boolean more = false; - if (sb0 != null && sb0.length() > 2) { - more = true; - rs.append(sb0); - } - for (FilterNode node : this.nodes) { - CharSequence f = node.createSQLExpress(info, joinTabalis); - if (f == null || f.length() < 3) continue; - if (more) rs.append(or ? " OR " : " AND "); - rs.append(f); - more = true; - } - rs.append(')'); - if (rs.length() < 5) return null; - return rs; - } - - public static FilterNode create(String column, Serializable value) { - return create(column, null, value); - } - - public static FilterNode create(String column, FilterExpress express, Serializable value) { - return new FilterNode(column, express, value); - } - - protected final CharSequence createElementSQLExpress(final EntityInfo info, String talis) { - if (column == null) return null; - if (talis == null) talis = "a"; - if (express == ISNULL || express == ISNOTNULL) { - return new StringBuilder().append(info.getSQLColumn(talis, column)).append(' ').append(express.value()); - } - Object val0 = getValue(); - if (val0 == null) return null; - if (express == FV_MOD || express == FV_DIV) { - FilterValue fv = (FilterValue) val0; - return new StringBuilder().append(info.getSQLColumn(talis, column)).append(' ').append(express.value()).append(' ').append(fv.getOptvalue()) - .append(' ').append(fv.getExpress().value()).append(' ').append(fv.getDestvalue()); - } - CharSequence val = formatToString(express, val0); - if (val == null) return null; - StringBuilder sb = new StringBuilder(32); - if (express == CONTAIN) return info.containSQL.replace("${column}", info.getSQLColumn(talis, column)).replace("${keystr}", val); - if (express == IGNORECASECONTAIN) return info.containSQL.replace("${column}", "LOWER(" + info.getSQLColumn(talis, column) + ")").replace("${keystr}", val); - if (express == NOTCONTAIN) return info.notcontainSQL.replace("${column}", info.getSQLColumn(talis, column)).replace("${keystr}", val); - if (express == IGNORECASENOTCONTAIN) return info.notcontainSQL.replace("${column}", "LOWER(" + info.getSQLColumn(talis, column) + ")").replace("${keystr}", val); - - if (express == IGNORECASELIKE || express == IGNORECASENOTLIKE) { - sb.append("LOWER(").append(info.getSQLColumn(talis, column)).append(')'); - } else { - sb.append(info.getSQLColumn(talis, column)); - } - sb.append(' '); - switch (express) { - case OPAND: - case OPOR: - sb.append(express.value()).append(' ').append(val).append(" > 0"); - break; - case OPANDNO: - sb.append(express.value()).append(' ').append(val).append(" = 0"); - break; - default: - sb.append(express.value()).append(' ').append(val); - break; - } - return sb; - } - - protected Predicate createPredicate(final EntityCache cache) { - if (cache == null || (column == null && this.nodes == null)) return null; - Predicate filter = createElementPredicate(cache, false); - if (this.nodes == null) return filter; - for (FilterNode node : this.nodes) { - Predicate f = node.createPredicate(cache); - if (f == null) continue; - final Predicate one = filter; - final Predicate two = f; - filter = (filter == null) ? f : (or ? new Predicate() { - - @Override - public boolean test(T t) { - return one.test(t) || two.test(t); - } - - @Override - public String toString() { - return "(" + one + " OR " + two + ")"; - } - } : new Predicate() { - - @Override - public boolean test(T t) { - return one.test(t) && two.test(t); - } - - @Override - public String toString() { - return "(" + one + " AND " + two + ")"; - } - }); - } - return filter; - } - - protected final Predicate createElementPredicate(final EntityCache cache, final boolean join) { - if (column == null) return null; - return createElementPredicate(cache, join, cache.getAttribute(column)); - } - - @SuppressWarnings("unchecked") - protected final Predicate createElementPredicate(final EntityCache cache, final boolean join, final Attribute attr) { - if (attr == null) return null; - final String field = join ? (cache.getType().getSimpleName() + "." + attr.field()) : attr.field(); - if (express == ISNULL) return new Predicate() { - - @Override - public boolean test(T t) { - return attr.get(t) == null; - } - - @Override - public String toString() { - return field + " = null"; - } - }; - if (express == ISNOTNULL) return new Predicate() { - - @Override - public boolean test(T t) { - return attr.get(t) != null; - } - - @Override - public String toString() { - return field + " != null"; - } - }; - if (attr == null) return null; - Serializable val0 = getValue(); - if (val0 == null) return null; - - final Class atype = attr.type(); - final Class valtype = val0.getClass(); - if (atype != valtype && val0 instanceof Number) { - if (atype == int.class || atype == Integer.class) { - val0 = ((Number) val0).intValue(); - } else if (atype == long.class || atype == Long.class) { - val0 = ((Number) val0).longValue(); - } else if (atype == short.class || atype == Short.class) { - val0 = ((Number) val0).shortValue(); - } else if (atype == float.class || atype == Float.class) { - val0 = ((Number) val0).floatValue(); - } else if (atype == byte.class || atype == Byte.class) { - val0 = ((Number) val0).byteValue(); - } else if (atype == double.class || atype == Double.class) { - val0 = ((Number) val0).doubleValue(); - } - } else if (valtype.isArray()) { - final int len = Array.getLength(val0); - if (len == 0 && express == NOTIN) return null; - final Class compType = valtype.getComponentType(); - if (atype != compType && len > 0) { - if (!compType.isPrimitive() && Number.class.isAssignableFrom(compType)) throw new RuntimeException("param(" + val0 + ") type not match " + atype + " for column " + column); - if (atype == int.class || atype == Integer.class) { - int[] vs = new int[len]; - for (int i = 0; i < len; i++) { - vs[i] = ((Number) Array.get(val0, i)).intValue(); - } - val0 = vs; - } else if (atype == long.class || atype == Long.class) { - long[] vs = new long[len]; - for (int i = 0; i < len; i++) { - vs[i] = ((Number) Array.get(val0, i)).longValue(); - } - val0 = vs; - } else if (atype == short.class || atype == Short.class) { - short[] vs = new short[len]; - for (int i = 0; i < len; i++) { - vs[i] = ((Number) Array.get(val0, i)).shortValue(); - } - val0 = vs; - } else if (atype == float.class || atype == Float.class) { - float[] vs = new float[len]; - for (int i = 0; i < len; i++) { - vs[i] = ((Number) Array.get(val0, i)).floatValue(); - } - val0 = vs; - } else if (atype == byte.class || atype == Byte.class) { - byte[] vs = new byte[len]; - for (int i = 0; i < len; i++) { - vs[i] = ((Number) Array.get(val0, i)).byteValue(); - } - val0 = vs; - } else if (atype == double.class || atype == Double.class) { - double[] vs = new double[len]; - for (int i = 0; i < len; i++) { - vs[i] = ((Number) Array.get(val0, i)).doubleValue(); - } - val0 = vs; - } - } - } else if (val0 instanceof Collection) { - final Collection collection = (Collection) val0; - if (collection.isEmpty() && express == NOTIN) return null; - if (!collection.isEmpty()) { - Iterator it = collection.iterator(); - it.hasNext(); - Class fs = it.next().getClass(); - Class pfs = fs; - if (fs == Integer.class) { - pfs = int.class; - } else if (fs == Long.class) { - pfs = long.class; - } else if (fs == Short.class) { - pfs = short.class; - } else if (fs == Float.class) { - pfs = float.class; - } else if (fs == Byte.class) { - pfs = byte.class; - } else if (fs == Double.class) { - pfs = double.class; - } - if (Number.class.isAssignableFrom(fs) && atype != fs && atype != pfs) { //需要转换 - ArrayList list = new ArrayList(collection.size()); - if (atype == int.class || atype == Integer.class) { - for (Number num : (Collection) collection) { - list.add(num.intValue()); - } - } else if (atype == long.class || atype == Long.class) { - for (Number num : (Collection) collection) { - list.add(num.longValue()); - } - } else if (atype == short.class || atype == Short.class) { - for (Number num : (Collection) collection) { - list.add(num.shortValue()); - } - } else if (atype == float.class || atype == Float.class) { - for (Number num : (Collection) collection) { - list.add(num.floatValue()); - } - } else if (atype == byte.class || atype == Byte.class) { - for (Number num : (Collection) collection) { - list.add(num.byteValue()); - } - } else if (atype == double.class || atype == Double.class) { - for (Number num : (Collection) collection) { - list.add(num.doubleValue()); - } - } - val0 = list; - } - } - } - final Serializable val = val0; - switch (express) { - case EQUAL: - return new Predicate() { - - @Override - public boolean test(T t) { - return val.equals(attr.get(t)); - } - - @Override - public String toString() { - return field + ' ' + express.value() + ' ' + formatToString(val); - } - }; - case NOTEQUAL: - return new Predicate() { - - @Override - public boolean test(T t) { - return !val.equals(attr.get(t)); - } - - @Override - public String toString() { - return field + ' ' + express.value() + ' ' + formatToString(val); - } - }; - case GREATERTHAN: - return new Predicate() { - - @Override - public boolean test(T t) { - return ((Number) attr.get(t)).longValue() > ((Number) val).longValue(); - } - - @Override - public String toString() { - return field + ' ' + express.value() + ' ' + val; - } - }; - case LESSTHAN: - return new Predicate() { - - @Override - public boolean test(T t) { - return ((Number) attr.get(t)).longValue() < ((Number) val).longValue(); - } - - @Override - public String toString() { - return field + ' ' + express.value() + ' ' + val; - } - }; - case GREATERTHANOREQUALTO: - return new Predicate() { - - @Override - public boolean test(T t) { - return ((Number) attr.get(t)).longValue() >= ((Number) val).longValue(); - } - - @Override - public String toString() { - return field + ' ' + express.value() + ' ' + val; - } - }; - case LESSTHANOREQUALTO: - return new Predicate() { - - @Override - public boolean test(T t) { - return ((Number) attr.get(t)).longValue() <= ((Number) val).longValue(); - } - - @Override - public String toString() { - return field + ' ' + express.value() + ' ' + val; - } - }; - - case OPAND: - return new Predicate() { - - @Override - public boolean test(T t) { - return (((Number) attr.get(t)).longValue() & ((Number) val).longValue()) > 0; - } - - @Override - public String toString() { - return field + " & " + val + " > 0"; - } - }; - case FV_MOD: - FilterValue fv0 = (FilterValue) val; - switch (fv0.getExpress()) { - case EQUAL: - return new Predicate() { - - @Override - public boolean test(T t) { - return (((Number) attr.get(t)).longValue() % fv0.getOptvalue().longValue()) == fv0.getDestvalue().longValue(); - } - - @Override - public String toString() { - return field + " " + express.value() + " " + fv0.getOptvalue() + " " + fv0.getExpress().value() + " " + fv0.getDestvalue(); - } - }; - case NOTEQUAL: - return new Predicate() { - - @Override - public boolean test(T t) { - return (((Number) attr.get(t)).longValue() % fv0.getOptvalue().longValue()) != fv0.getDestvalue().longValue(); - } - - @Override - public String toString() { - return field + " " + express.value() + " " + fv0.getOptvalue() + " " + fv0.getExpress().value() + " " + fv0.getDestvalue(); - } - }; - case GREATERTHAN: - return new Predicate() { - - @Override - public boolean test(T t) { - return (((Number) attr.get(t)).longValue() % fv0.getOptvalue().longValue()) > fv0.getDestvalue().longValue(); - } - - @Override - public String toString() { - return field + " " + express.value() + " " + fv0.getOptvalue() + " " + fv0.getExpress().value() + " " + fv0.getDestvalue(); - } - }; - case LESSTHAN: - return new Predicate() { - - @Override - public boolean test(T t) { - return (((Number) attr.get(t)).longValue() % fv0.getOptvalue().longValue()) < fv0.getDestvalue().longValue(); - } - - @Override - public String toString() { - return field + " " + express.value() + " " + fv0.getOptvalue() + " " + fv0.getExpress().value() + " " + fv0.getDestvalue(); - } - }; - case GREATERTHANOREQUALTO: - return new Predicate() { - - @Override - public boolean test(T t) { - return (((Number) attr.get(t)).longValue() % fv0.getOptvalue().longValue()) >= fv0.getDestvalue().longValue(); - } - - @Override - public String toString() { - return field + " " + express.value() + " " + fv0.getOptvalue() + " " + fv0.getExpress().value() + " " + fv0.getDestvalue(); - } - }; - case LESSTHANOREQUALTO: - return new Predicate() { - - @Override - public boolean test(T t) { - return (((Number) attr.get(t)).longValue() % fv0.getOptvalue().longValue()) <= fv0.getDestvalue().longValue(); - } - - @Override - public String toString() { - return field + " " + express.value() + " " + fv0.getOptvalue() + " " + fv0.getExpress().value() + " " + fv0.getDestvalue(); - } - }; - default: - throw new RuntimeException("(" + fv0 + ")'s express illegal, must be =, !=, <, >, <=, >="); - } - case FV_DIV: - FilterValue fv1 = (FilterValue) val; - switch (fv1.getExpress()) { - case EQUAL: - return new Predicate() { - - @Override - public boolean test(T t) { - return (((Number) attr.get(t)).longValue() / fv1.getOptvalue().longValue()) == fv1.getDestvalue().longValue(); - } - - @Override - public String toString() { - return field + " " + express.value() + " " + fv1.getOptvalue() + " " + fv1.getExpress().value() + " " + fv1.getDestvalue(); - } - }; - case NOTEQUAL: - return new Predicate() { - - @Override - public boolean test(T t) { - return (((Number) attr.get(t)).longValue() / fv1.getOptvalue().longValue()) != fv1.getDestvalue().longValue(); - } - - @Override - public String toString() { - return field + " " + express.value() + " " + fv1.getOptvalue() + " " + fv1.getExpress().value() + " " + fv1.getDestvalue(); - } - }; - case GREATERTHAN: - return new Predicate() { - - @Override - public boolean test(T t) { - return (((Number) attr.get(t)).longValue() / fv1.getOptvalue().longValue()) > fv1.getDestvalue().longValue(); - } - - @Override - public String toString() { - return field + " " + express.value() + " " + fv1.getOptvalue() + " " + fv1.getExpress().value() + " " + fv1.getDestvalue(); - } - }; - case LESSTHAN: - return new Predicate() { - - @Override - public boolean test(T t) { - return (((Number) attr.get(t)).longValue() / fv1.getOptvalue().longValue()) < fv1.getDestvalue().longValue(); - } - - @Override - public String toString() { - return field + " " + express.value() + " " + fv1.getOptvalue() + " " + fv1.getExpress().value() + " " + fv1.getDestvalue(); - } - }; - case GREATERTHANOREQUALTO: - return new Predicate() { - - @Override - public boolean test(T t) { - return (((Number) attr.get(t)).longValue() / fv1.getOptvalue().longValue()) >= fv1.getDestvalue().longValue(); - } - - @Override - public String toString() { - return field + " " + express.value() + " " + fv1.getOptvalue() + " " + fv1.getExpress().value() + " " + fv1.getDestvalue(); - } - }; - case LESSTHANOREQUALTO: - return new Predicate() { - - @Override - public boolean test(T t) { - return (((Number) attr.get(t)).longValue() / fv1.getOptvalue().longValue()) <= fv1.getDestvalue().longValue(); - } - - @Override - public String toString() { - return field + " " + express.value() + " " + fv1.getOptvalue() + " " + fv1.getExpress().value() + " " + fv1.getDestvalue(); - } - }; - default: - throw new RuntimeException("(" + fv1 + ")'s express illegal, must be =, !=, <, >, <=, >="); - } - case OPOR: - return new Predicate() { - - @Override - public boolean test(T t) { - return (((Number) attr.get(t)).longValue() | ((Number) val).longValue()) > 0; - } - - @Override - public String toString() { - return field + " | " + val + " > 0"; - } - }; - case OPANDNO: - return new Predicate() { - - @Override - public boolean test(T t) { - return (((Number) attr.get(t)).longValue() & ((Number) val).longValue()) == 0; - } - - @Override - public String toString() { - return field + " & " + val + " = 0"; - } - }; - case LIKE: - return new Predicate() { - - @Override - public boolean test(T t) { - Object rs = attr.get(t); - return rs != null && rs.toString().contains(val.toString()); - } - - @Override - public String toString() { - return field + ' ' + express.value() + ' ' + formatToString(val); - } - }; - case STARTSWITH: - return new Predicate() { - - @Override - public boolean test(T t) { - Object rs = attr.get(t); - return rs != null && rs.toString().startsWith(val.toString()); - } - - @Override - public String toString() { - return field + " STARTSWITH " + formatToString(val); - } - }; - case ENDSWITH: - return new Predicate() { - - @Override - public boolean test(T t) { - Object rs = attr.get(t); - return rs != null && rs.toString().endsWith(val.toString()); - } - - @Override - public String toString() { - return field + " ENDSWITH " + formatToString(val); - } - }; - case IGNORECASELIKE: - final String valstr = val.toString().toLowerCase(); - return new Predicate() { - - @Override - public boolean test(T t) { - Object rs = attr.get(t); - return rs != null && rs.toString().toLowerCase().contains(valstr); - } - - @Override - public String toString() { - return "LOWER(" + field + ") " + express.value() + ' ' + formatToString(valstr); - } - }; - case NOTSTARTSWITH: - return new Predicate() { - - @Override - public boolean test(T t) { - Object rs = attr.get(t); - return rs == null || !rs.toString().startsWith(val.toString()); - } - - @Override - public String toString() { - return field + " NOT STARTSWITH " + formatToString(val); - } - }; - case NOTENDSWITH: - return new Predicate() { - - @Override - public boolean test(T t) { - Object rs = attr.get(t); - return rs == null || !rs.toString().endsWith(val.toString()); - } - - @Override - public String toString() { - return field + " NOT ENDSWITH " + formatToString(val); - } - }; - case IGNORECASENOTLIKE: - final String valstr2 = val.toString().toLowerCase(); - return new Predicate() { - - @Override - public boolean test(T t) { - Object rs = attr.get(t); - return rs == null || !rs.toString().toLowerCase().contains(valstr2); - } - - @Override - public String toString() { - return "LOWER(" + field + ") " + express.value() + ' ' + formatToString(valstr2); - } - }; - case CONTAIN: - return new Predicate() { - - @Override - public boolean test(T t) { - Object rs = attr.get(t); - return rs != null && val.toString().contains(rs.toString()); - } - - @Override - public String toString() { - return "" + formatToString(val) + ' ' + express.value() + ' ' + field; - } - }; - case IGNORECASECONTAIN: - final String valstr3 = val.toString().toLowerCase(); - return new Predicate() { - - @Override - public boolean test(T t) { - Object rs = attr.get(t); - return rs != null && valstr3.contains(rs.toString().toLowerCase()); - } - - @Override - public String toString() { - return "" + formatToString(valstr3) + express.value() + ' ' + "LOWER(" + field + ") "; - } - }; - case NOTCONTAIN: - return new Predicate() { - - @Override - public boolean test(T t) { - Object rs = attr.get(t); - return rs == null || !val.toString().contains(rs.toString()); - } - - @Override - public String toString() { - return "" + formatToString(val) + ' ' + express.value() + ' ' + field; - } - }; - case IGNORECASENOTCONTAIN: - final String valstr4 = val.toString().toLowerCase(); - return new Predicate() { - - @Override - public boolean test(T t) { - Object rs = attr.get(t); - return rs == null || !valstr4.contains(rs.toString().toLowerCase()); - } - - @Override - public String toString() { - return "" + formatToString(valstr4) + express.value() + ' ' + "LOWER(" + field + ") "; - } - }; - case BETWEEN: - case NOTBETWEEN: - Range range = (Range) val; - final Comparable min = range.getMin(); - final Comparable max = range.getMax(); - if (express == BETWEEN) return new Predicate() { - - @Override - public boolean test(T t) { - Comparable rs = (Comparable) attr.get(t); - if (rs == null) return false; - if (min != null && min.compareTo(rs) >= 0) return false; - return !(max != null && max.compareTo(rs) <= 0); - } - - @Override - public String toString() { - return field + " BETWEEN " + min + " AND " + max; - } - }; - if (express == NOTBETWEEN) return new Predicate() { - - @Override - public boolean test(T t) { - Comparable rs = (Comparable) attr.get(t); - if (rs == null) return true; - if (min != null && min.compareTo(rs) >= 0) return true; - return (max != null && max.compareTo(rs) <= 0); - } - - @Override - public String toString() { - return field + " NOT BETWEEN " + min + " AND " + max; - } - }; - return null; - case IN: - case NOTIN: - Predicate filter; - if (val instanceof Collection) { - Collection array = (Collection) val; - if (array.isEmpty()) { //express 只会是 IN - filter = new Predicate() { - - @Override - public boolean test(T t) { - return false; - } - - @Override - public String toString() { - return field + ' ' + express.value() + " []"; - } - }; - } else { - filter = new Predicate() { - - @Override - public boolean test(T t) { - Object rs = attr.get(t); - return rs != null && array.contains(rs); - } - - @Override - public String toString() { - return field + ' ' + express.value() + ' ' + val; - } - }; - } - } else { - Class type = val.getClass(); - if (Array.getLength(val) == 0) {//express 只会是 IN - filter = new Predicate() { - - @Override - public boolean test(T t) { - return false; - } - - @Override - public String toString() { - return field + ' ' + express.value() + " []"; - } - }; - } else if (type == int[].class) { - filter = new Predicate() { - - @Override - public boolean test(T t) { - Object rs = attr.get(t); - if (rs == null) return false; - int k = (int) rs; - for (int v : (int[]) val) { - if (v == k) return true; - } - return false; - } - - @Override - public String toString() { - return field + ' ' + express.value() + ' ' + Arrays.toString((int[]) val); - } - }; - } else if (type == short[].class) { - filter = new Predicate() { - - @Override - public boolean test(T t) { - Object rs = attr.get(t); - if (rs == null) return false; - short k = (short) rs; - for (short v : (short[]) val) { - if (v == k) return true; - } - return false; - } - - @Override - public String toString() { - return field + ' ' + express.value() + ' ' + Arrays.toString((short[]) val); - } - }; - } else if (type == long[].class) { - filter = new Predicate() { - - @Override - public boolean test(T t) { - Object rs = attr.get(t); - if (rs == null) return false; - long k = (long) rs; - for (long v : (long[]) val) { - if (v == k) return true; - } - return false; - } - - @Override - public String toString() { - return field + ' ' + express.value() + ' ' + Arrays.toString((long[]) val); - } - }; - } else if (type == float[].class) { - filter = new Predicate() { - - @Override - public boolean test(T t) { - Object rs = attr.get(t); - if (rs == null) return false; - float k = (float) rs; - for (float v : (float[]) val) { - if (v == k) return true; - } - return false; - } - - @Override - public String toString() { - return field + ' ' + express.value() + ' ' + Arrays.toString((float[]) val); - } - }; - } else if (type == double[].class) { - filter = new Predicate() { - - @Override - public boolean test(T t) { - Object rs = attr.get(t); - if (rs == null) return false; - double k = (double) rs; - for (double v : (double[]) val) { - if (v == k) return true; - } - return false; - } - - @Override - public String toString() { - return field + ' ' + express.value() + ' ' + Arrays.toString((double[]) val); - } - }; - } else { - filter = new Predicate() { - - @Override - public boolean test(T t) { - Object rs = attr.get(t); - if (rs == null) return false; - for (Object v : (Object[]) val) { - if (rs.equals(v)) return true; - } - return false; - } - - @Override - public String toString() { - return field + ' ' + express.value() + ' ' + Arrays.toString((Object[]) val); - } - }; - } - } - if (express == NOTIN) { - final Predicate filter2 = filter; - filter = new Predicate() { - - @Override - public boolean test(T t) { - return !filter2.test(t); - } - - @Override - public String toString() { - return filter2.toString(); - } - }; - } - return filter; - } - return null; - } - - @Override - public String toString() { - return toString(null).toString(); - } - - protected StringBuilder toString(final String prefix) { - StringBuilder sb = new StringBuilder(); - StringBuilder element = toElementString(prefix); - boolean more = element.length() > 0 && this.nodes != null; - if (more) sb.append('('); - sb.append(element); - if (this.nodes != null) { - for (FilterNode node : this.nodes) { - String s = node.toString(); - if (s.length() < 1) continue; - if (sb.length() > 1) sb.append(or ? " OR " : " AND "); - sb.append(s); - } - } - if (more) sb.append(')'); - return sb; - } - - protected final StringBuilder toElementString(final String prefix) { - StringBuilder sb = new StringBuilder(); - if (column != null) { - String col = prefix == null ? column : (prefix + "." + column); - Serializable ev = getValue(); - if (express == ISNULL || express == ISNOTNULL) { - sb.append(col).append(' ').append(express.value()); - } else if (ev != null) { - boolean lower = (express == IGNORECASELIKE || express == IGNORECASENOTLIKE || express == IGNORECASECONTAIN || express == IGNORECASENOTCONTAIN); - sb.append(lower ? ("LOWER(" + col + ')') : col).append(' ').append(express.value()).append(' ').append(formatToString(express, ev)); - } - } - return sb; - } - - protected static CharSequence formatToString(Object value) { - CharSequence sb = formatToString(null, value); - return sb == null ? null : sb.toString(); - } - - private static CharSequence formatToString(FilterExpress express, Object value) { - if (value == null) return null; - if (value instanceof Number) return String.valueOf(value); - if (value instanceof CharSequence) { - if (express == LIKE || express == NOTLIKE) { - value = "%" + value + '%'; - } else if (express == STARTSWITH || express == NOTSTARTSWITH) { - value = value + "%"; - } else if (express == ENDSWITH || express == NOTENDSWITH) { - value = "%" + value; - } else if (express == IGNORECASELIKE || express == IGNORECASENOTLIKE) { - value = "%" + value.toString().toLowerCase() + '%'; - } else if (express == IGNORECASECONTAIN || express == IGNORECASENOTCONTAIN) { - value = value.toString().toLowerCase(); - } - return new StringBuilder().append('\'').append(value.toString().replace("'", "\\'")).append('\''); - } else if (value instanceof Range) { - Range range = (Range) value; - boolean rangestring = range.getClass() == Range.StringRange.class; - StringBuilder sb = new StringBuilder(); - if (rangestring) { - sb.append('\'').append(range.getMin().toString().replace("'", "\\'")).append('\''); - } else { - sb.append(range.getMin()); - } - sb.append(" AND "); - if (rangestring) { - sb.append('\'').append(range.getMax().toString().replace("'", "\\'")).append('\''); - } else { - sb.append(range.getMax()); - } - return sb; - } else if (value.getClass().isArray()) { - int len = Array.getLength(value); - if (len == 0) return express == NOTIN ? null : new StringBuilder("(NULL)"); - if (len == 1) { - Object firstval = Array.get(value, 0); - if (firstval != null && firstval.getClass().isArray()) return formatToString(express, firstval); - } - StringBuilder sb = new StringBuilder(); - sb.append('('); - for (int i = 0; i < len; i++) { - Object o = Array.get(value, i); - if (sb.length() > 1) sb.append(','); - if (o instanceof CharSequence) { - sb.append('\'').append(o.toString().replace("'", "\\'")).append('\''); - } else { - sb.append(o); - } - } - return sb.append(')'); - } else if (value instanceof Collection) { - Collection c = (Collection) value; - if (c.isEmpty()) return express == NOTIN ? null : new StringBuilder("(NULL)"); - StringBuilder sb = new StringBuilder(); - sb.append('('); - for (Object o : c) { - if (sb.length() > 1) sb.append(','); - if (o instanceof CharSequence) { - sb.append('\'').append(o.toString().replace("'", "\\'")).append('\''); - } else { - sb.append(o); - } - } - return sb.append(')'); - } - return String.valueOf(value); - } - - public final Serializable getValue() { - return value; - } - - public final void setValue(Serializable value) { - this.value = value; - } - - public final boolean isOr() { - return or; - } - - public final void setOr(boolean or) { - this.or = or; - } - - public final String getColumn() { - return column; - } - - public final void setColumn(String column) { - this.column = column; - } - - public final FilterExpress getExpress() { - return express; - } - - public final void setExpress(FilterExpress express) { - this.express = express; - } - - public final FilterNode[] getNodes() { - return nodes; - } - - public final void setNodes(FilterNode[] nodes) { - this.nodes = nodes; - } - -} diff --git a/src/main/java/org/redkale/source/FilterNodeBean.java b/src/main/java/org/redkale/source/FilterNodeBean.java deleted file mode 100644 index 277c41741..000000000 --- a/src/main/java/org/redkale/source/FilterNodeBean.java +++ /dev/null @@ -1,356 +0,0 @@ -/* - * 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.source; - -import java.io.*; -import java.lang.reflect.*; -import java.util.*; -import java.util.concurrent.*; -import javax.persistence.*; -import static org.redkale.source.FilterExpress.*; -import org.redkale.util.*; - -/** - * - *

- * 详情见: http://www.redkale.org - * - * @author zhangjx - */ -public final class FilterNodeBean implements Comparable> { - - private static final ConcurrentHashMap beanodes = new ConcurrentHashMap<>(); - - private Attribute beanAttr; - - private String column; - - private FilterExpress express; - - private boolean or; - - private FilterNodeBean[] nodeBeans; - - //-----------------join table-------------------------- - private Class joinClass; - - private String[] joinColumns; - - //---------------------------------------------------- - private long least; - - private boolean string; - - private boolean number; - - public FilterNodeBean(FilterNodeBean bean) { - this.beanAttr = bean == null ? null : bean.beanAttr; - this.column = bean == null ? null : bean.column; - this.express = bean == null ? null : bean.express; - this.joinClass = bean == null ? null : bean.joinClass; - this.joinColumns = bean == null ? null : bean.joinColumns; - this.least = bean == null ? 1 : bean.least; - this.string = bean == null ? false : bean.string; - this.number = bean == null ? false : bean.number; - this.or = bean == null ? false : bean.or; - this.nodeBeans = bean == null ? null : bean.nodeBeans; - } - - private FilterNodeBean(final FilterJoinColumn joinCol, final FilterColumn filterCol, final Attribute attr) { - this.beanAttr = attr; - this.joinClass = joinCol == null ? null : joinCol.table(); - this.joinColumns = joinCol == null ? null : joinCol.columns(); - - final Class type = attr.type(); - this.column = (filterCol != null && !filterCol.name().isEmpty()) ? filterCol.name() : attr.field(); - - FilterExpress exp = filterCol == null ? null : filterCol.express(); - if (type.isArray() || Collection.class.isAssignableFrom(type)) { - if (Range.class.isAssignableFrom(type.getComponentType())) { - if (AND != exp) exp = OR; - } else if (NOTIN != exp) exp = IN; - } else if (Range.class.isAssignableFrom(type)) { - if (NOTBETWEEN != exp) exp = BETWEEN; - } - if (exp == null) exp = EQUAL; - this.express = exp; - - this.least = filterCol == null ? 1 : filterCol.least(); - this.number = (type.isPrimitive() && type != boolean.class) || Number.class.isAssignableFrom(type); - this.string = CharSequence.class.isAssignableFrom(type); - } - - private FilterNodeBean or(FilterNodeBean node) { - return any(node, true); - } - - private FilterNodeBean and(FilterNodeBean node) { - return any(node, false); - } - - private FilterNodeBean any(FilterNodeBean node, boolean signor) { - Objects.requireNonNull(node); - if (this.column == null) { - this.beanAttr = node.beanAttr; - this.column = node.column; - this.express = node.express; - this.joinClass = node.joinClass; - this.joinColumns = node.joinColumns; - this.least = node.least; - this.string = node.string; - this.number = node.number; - return this; - } - if (this.nodeBeans == null) { - this.nodeBeans = new FilterNodeBean[]{node}; - this.or = signor; - return this; - } - if (or == signor) { - FilterNodeBean[] newsiblings = new FilterNodeBean[nodeBeans.length + 1]; - System.arraycopy(nodeBeans, 0, newsiblings, 0, nodeBeans.length); - newsiblings[nodeBeans.length] = node; - this.nodeBeans = newsiblings; - return this; - } - this.nodeBeans = new FilterNodeBean[]{new FilterNodeBean(this), node}; - this.column = null; - this.or = signor; - return this; - } - - public static FilterNode createFilterNode(final FilterBean bean) { - if (bean == null) return null; - return load(bean.getClass()).create(bean); - } - - private FilterNode create(final T bean) { - if (bean == null || beanAttr == null) return null; - FilterNode node = null; - final Serializable val = beanAttr.get(bean); - if (column != null && val != null) { - boolean skip = false; - if (string && ((CharSequence) val).length() == 0) { - skip = true; - } else if (number && ((Number) val).longValue() < least) { - skip = true; - } - if (!skip) { - if (this.joinClass == null) { - node = FilterNode.create(column, express, val); - } else { - node = FilterJoinNode.create(joinClass, joinColumns, column, express, val); - } - } - } - if (this.nodeBeans == null) return node; - for (final FilterNodeBean fnb : this.nodeBeans) { - FilterNode n = fnb.create(bean); - if (n == null) continue; - node = node == null ? n : ((!(n instanceof FilterJoinNode)) ? n.any(node, or) : node.any(n, or)); - } - return node; - } - - private static FilterNodeBean createFilterNodeBean(final Class clazz) { - final Set fields = new HashSet<>(); - final Map nodemap = new LinkedHashMap(); - Class cltmp = clazz; - do { - for (final Field field : cltmp.getDeclaredFields()) { - if (Modifier.isStatic(field.getModifiers())) continue; - if (fields.contains(field.getName())) continue; - if (field.getAnnotation(Transient.class) != null) continue; - - final boolean pubmod = Modifier.isPublic(field.getModifiers()); - - char[] chars = field.getName().toCharArray(); - chars[0] = Character.toUpperCase(chars[0]); - final Class t = field.getType(); - Method getter = null; - try { - getter = cltmp.getMethod(((t == boolean.class || t == Boolean.class) ? "is" : "get") + new String(chars)); - } catch (Exception ex) { - if (!pubmod) continue; - } - fields.add(field.getName()); - - final Attribute beanAttr = pubmod ? Attribute.create(field) : Attribute.create(getter, null); - FilterNodeBean nodeBean = new FilterNodeBean(field.getAnnotation(FilterJoinColumn.class), field.getAnnotation(FilterColumn.class), beanAttr); - - //------------------------------------ - { - FilterGroup[] refs = field.getAnnotationsByType(FilterGroup.class); - String[] groups = new String[refs.length]; - for (int i = 0; i < refs.length; i++) { - groups[i] = refs[i].value(); - } - if (groups.length == 0) groups = new String[]{"[AND]"}; - for (String key : groups) { - if (!key.startsWith("[AND]") && !key.startsWith("[OR]")) { - throw new RuntimeException(field + "'s FilterGroup.value(" + key + ") illegal, must be [AND] or [OR] startsWith"); - } - FilterNodeBean node = nodemap.get(key); - if (node == null) { - nodemap.put(key, nodeBean); - } else if (nodeBean.joinClass == null && node.joinClass != null) { //非joinNode 关联 joinNode - nodemap.put(key, nodeBean.any(node, key.substring(key.lastIndexOf('.') + 1).contains("[OR]"))); - } else { - node.any(nodeBean, key.substring(key.lastIndexOf('.') + 1).contains("[OR]")); - } - } - } - } - } while ((cltmp = cltmp.getSuperclass()) != Object.class); - final Map linkes = new LinkedHashMap<>(); - nodemap.forEach((k, v) -> { - String[] keys = k.split("\\."); - LinkNode link = linkes.get(keys[0]); - if (link == null) { - linkes.put(keys[0], new LinkNode(k, v)); - } else { - link.put(keys, 0, v); - } - }); - FilterNodeBean rs = null; - for (LinkNode link : linkes.values()) { - FilterNodeBean f = link.createFilterNodeBean(); - if (f == null) continue; - rs = rs == null ? f : rs.and(f); - } - if (rs !=null && rs.nodeBeans != null) Arrays.sort(rs.nodeBeans); - return rs == null ? new FilterNodeBean(null) : rs; - } - - @Override - public int compareTo(FilterNodeBean o) { - if (this.joinClass == null && o.joinClass == null) return 0; - if (this.joinClass != null && o.joinClass != null) return 0; - return this.joinClass == null ? -1 : 1; - } - - private static class LinkNode { - - public final boolean or; - - public final String key; - - public final List beans = new ArrayList<>(); - - public final Map nexts = new LinkedHashMap<>(); - - public LinkNode(String keyString, FilterNodeBean node) { - String[] keys = keyString.split("\\."); - this.key = keys[0]; - this.or = this.key.contains("[OR]"); - put(keys, 0, node); - } - - public LinkNode(String[] keyStrings, int pos, FilterNodeBean node) { - this.key = keyStrings[pos]; - this.or = this.key.contains("[OR]"); - put(keyStrings, pos, node); - } - - public FilterNodeBean createFilterNodeBean() { - FilterNodeBean node = null; - for (FilterNodeBean bean : beans) { - node = node == null ? bean : node.any(bean, or); - } - for (LinkNode link : nexts.values()) { - FilterNodeBean f = link.createFilterNodeBean(); - if (f == null) continue; - node = node == null ? f : node.any(f, or); - } - return node; - } - - public final void put(final String[] keys, int pos, final FilterNodeBean node) { - if (keys.length == pos + 1 && this.key.equals(keys[pos])) { - this.beans.add(node); - return; - } - LinkNode link = nexts.get(keys[pos + 1]); - if (link == null) { - nexts.put(keys[pos + 1], new LinkNode(keys, pos + 1, node)); - } else { - link.put(keys, pos + 1, node); - } - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("{key = '").append(key).append("', or = ").append(or); - if (!beans.isEmpty()) { - sb.append(", beans = [\r\n"); - for (FilterNodeBean bean : this.beans) { - sb.append(" ").append(bean).append("\r\n"); - } - sb.append("]"); - } - if (!nexts.isEmpty()) { - sb.append(", nexts = [\r\n"); - for (LinkNode link : this.nexts.values()) { - sb.append(" ").append(link).append("\r\n"); - } - sb.append("]"); - } - sb.append("}"); - return sb.toString(); - } - } - - private static FilterNodeBean load(Class clazz) { - FilterNodeBean rs = beanodes.get(clazz); - if (rs != null) return rs; - synchronized (beanodes) { - rs = beanodes.get(clazz); - if (rs == null) { - rs = createFilterNodeBean(clazz); - beanodes.put(clazz, rs); - } - return rs; - } - } - - @Override - public String toString() { - return toString(joinClass == null ? null : joinClass.getSimpleName()).toString(); - } - - protected StringBuilder toString(final String prefix) { - StringBuilder sb = new StringBuilder(); - StringBuilder element = toElementString(prefix); - boolean more = element.length() > 0 && this.nodeBeans != null; - if (more) sb.append('('); - sb.append(element); - if (this.nodeBeans != null) { - for (FilterNodeBean node : this.nodeBeans) { - String s = node.toString(); - if (s.length() < 1) continue; - if (sb.length() > 1) sb.append(or ? " OR " : " AND "); - sb.append(s); - } - } - if (more) sb.append(')'); - return sb; - } - - protected final StringBuilder toElementString(final String prefix) { - StringBuilder sb = new StringBuilder(); - if (column != null) { - String col = prefix == null ? column : (prefix + "." + column); - if (express == ISNULL || express == ISNOTNULL) { - sb.append(col).append(' ').append(express.value()); - } else { - boolean lower = (express == IGNORECASELIKE || express == IGNORECASENOTLIKE || express == IGNORECASECONTAIN || express == IGNORECASENOTCONTAIN); - sb.append(lower ? ("LOWER(" + col + ')') : col).append(' ').append(express.value()).append(" ?"); - } - } - return sb; - } -} diff --git a/src/main/java/org/redkale/source/FilterValue.java b/src/main/java/org/redkale/source/FilterValue.java deleted file mode 100644 index 3c7bd642f..000000000 --- a/src/main/java/org/redkale/source/FilterValue.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * 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.source; - -/** - * FilterValue主要用于复杂的表达式, 例如: col / 10 = 3 、MOD(col, 8) > 0 这些都不是单独一个数值能表达的,因此需要FilterValue 才构建 8 、 > 、0 组合值. - * - * @author zhangjx - */ -public class FilterValue implements java.io.Serializable { - - private Number optvalue; - - private FilterExpress express; - - private Number destvalue; - - public FilterValue() { - } - - public FilterValue(Number optvalue, Number destvalue) { - this(optvalue, FilterExpress.EQUAL, destvalue); - } - - public FilterValue(Number optvalue, FilterExpress express) { - this(optvalue, express, 0); - } - - public FilterValue(Number optvalue, FilterExpress express, Number destvalue) { - this.optvalue = optvalue; - this.express = express; - this.destvalue = destvalue; - } - - public Number getOptvalue() { - return optvalue == null ? 0 : optvalue; - } - - public void setOptvalue(Number optvalue) { - this.optvalue = optvalue; - } - - public FilterExpress getExpress() { - return express == null ? FilterExpress.EQUAL : express; - } - - public void setExpress(FilterExpress express) { - this.express = express; - } - - public Number getDestvalue() { - return destvalue == null ? 0 : destvalue; - } - - public void setDestvalue(Number destvalue) { - this.destvalue = destvalue; - } - - @Override - public String toString() { - return FilterValue.class.getSimpleName() + "[optvalue=" + getOptvalue() + ", express=" + getExpress() + ", destvalue=" + getDestvalue() + "]"; - } -} diff --git a/src/main/java/org/redkale/source/Flipper.java b/src/main/java/org/redkale/source/Flipper.java deleted file mode 100644 index f81b73755..000000000 --- a/src/main/java/org/redkale/source/Flipper.java +++ /dev/null @@ -1,120 +0,0 @@ -/* - * 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.source; - -import java.io.Serializable; - -/** - * - *

- * 详情见: http://www.redkale.org - * - * @author zhangjx - */ -public final class Flipper implements Serializable { - - public static int DEFAULT_PAGESIZE = 20; - - private int size = DEFAULT_PAGESIZE; - - private int page = 1; - - private String sort = ""; - - public Flipper() { - } - - public Flipper(int pageSize) { - this.size = pageSize; - } - - public Flipper(String sortColumn) { - this.sort = sortColumn; - } - - public Flipper(int pageSize, int pageNo) { - this.size = pageSize; - this.page = pageNo; - } - - public Flipper(int pageSize, int pageNo, String sortColumn) { - this.size = pageSize; - this.page = pageNo; - this.sort = sortColumn; - } - - public void copyTo(Flipper copy) { - if (copy == null) return; - copy.page = this.page; - copy.size = this.size; - copy.sort = this.sort; - } - - public void copyFrom(Flipper copy) { - if (copy == null) return; - this.page = copy.page; - this.size = copy.size; - this.sort = copy.sort; - } - - public Flipper next() { - this.page++; - return this; - } - - @Override - @SuppressWarnings("CloneDoesntCallSuperClone") - public Flipper clone() { - return new Flipper(this.size, this.page, this.sort); - } - - public int index() { - return (getPage() - 1) * getSize(); - } - - @Override - public String toString() { - return this.getClass().getSimpleName() + "{page:" + this.page + ", size=" + this.size + ", sort=" + this.sort + "}"; - } - - public int getSize() { - return size; - } - - public void setSize(int size) { - if (size > 0) { - this.size = size; - } - } - - public int getPage() { - return page; - } - - public void setPage(int page) { - if (page >= 0) { - this.page = page; - } - } - - public String getSort() { - return sort; - } - - public Flipper putSortIfEmpty(String sort) { - if (this.sort == null || this.sort.isEmpty()) { - this.sort = sort; - } - return this; - } - - public void setSort(String sort) { - if (sort != null) { - this.sort = sort.trim(); - } - } - -} diff --git a/src/main/java/org/redkale/source/JDBCPoolSource.java b/src/main/java/org/redkale/source/JDBCPoolSource.java deleted file mode 100644 index cabd2815a..000000000 --- a/src/main/java/org/redkale/source/JDBCPoolSource.java +++ /dev/null @@ -1,260 +0,0 @@ -/* - * 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.source; - -import static org.redkale.source.DataDefaultSource.*; -import java.io.*; -import java.lang.ref.WeakReference; -import java.lang.reflect.Method; -import java.nio.file.*; -import static java.nio.file.StandardWatchEventKinds.ENTRY_MODIFY; -import java.sql.*; -import java.util.*; -import java.util.concurrent.*; -import java.util.concurrent.atomic.AtomicLong; -import java.util.logging.Level; -import javax.sql.*; - -/** - * - *

- * 详情见: http://www.redkale.org - * - * @author zhangjx - */ -public class JDBCPoolSource { - - private static final Map>>> maps = new HashMap<>(); - - private final AtomicLong usingCounter = new AtomicLong(); - - private final AtomicLong creatCounter = new AtomicLong(); - - private final AtomicLong cycleCounter = new AtomicLong(); - - private final AtomicLong saveCounter = new AtomicLong(); - - private final ConnectionPoolDataSource source; - - private final ArrayBlockingQueue queue; - - private final ConnectionEventListener listener; - - private final DataDefaultSource dataSource; - - private final String stype; // "" 或 "read" 或 "write" - - private final int max; - - private String url; - - private String user; - - private String password; - - final Properties props; - - public JDBCPoolSource(DataDefaultSource source, String stype, Properties prop) { - this.dataSource = source; - this.stype = stype; - this.props = prop; - this.source = createDataSource(prop); - this.url = prop.getProperty(JDBC_URL); - this.user = prop.getProperty(JDBC_USER); - this.password = prop.getProperty(JDBC_PWD); - this.max = Integer.decode(prop.getProperty(JDBC_CONNECTIONSMAX, "" + Runtime.getRuntime().availableProcessors() * 16)); - this.queue = new ArrayBlockingQueue<>(this.max); - this.listener = new ConnectionEventListener() { - - @Override - public void connectionClosed(ConnectionEvent event) { - PooledConnection pc = (PooledConnection) event.getSource(); - if (queue.offer(pc)) saveCounter.incrementAndGet(); - } - - @Override - public void connectionErrorOccurred(ConnectionEvent event) { - usingCounter.decrementAndGet(); - if ("08S01".equals(event.getSQLException().getSQLState())) return; //MySQL特性, 长时间连接没使用会抛出com.mysql.jdbc.exceptions.jdbc4.CommunicationsException - dataSource.logger.log(Level.WARNING, "connectionErronOccurred [" + event.getSQLException().getSQLState() + "]", event.getSQLException()); - } - }; - if (this.isOracle()) { - this.props.setProperty(JDBC_CONTAIN_SQLTEMPLATE, "INSTR(${keystr}, ${column}) > 0"); - this.props.setProperty(JDBC_NOTCONTAIN_SQLTEMPLATE, "INSTR(${keystr}, ${column}) = 0"); - } else if (this.isSqlserver()) { - this.props.setProperty(JDBC_CONTAIN_SQLTEMPLATE, "CHARINDEX(${column}, ${keystr}) > 0"); - this.props.setProperty(JDBC_NOTCONTAIN_SQLTEMPLATE, "CHARINDEX(${column}, ${keystr}) = 0"); - } - - try { - this.watch(); - } catch (Exception e) { - dataSource.logger.log(Level.WARNING, DataSource.class.getSimpleName() + " watch " + dataSource.conf + " error", e); - } - } - - final boolean isMysql() { - return source != null && source.getClass().getName().contains(".mysql."); - } - - final boolean isOracle() { - return source != null && source.getClass().getName().contains("oracle."); - } - - final boolean isSqlserver() { - return source != null && source.getClass().getName().contains(".sqlserver."); - } - - private void watch() throws IOException { - if (dataSource.conf == null || dataSource.name == null) return; - final String file = dataSource.conf.getFile(); - final File f = new File(file); - if (!f.isFile() || !f.canRead()) return; - synchronized (maps) { - AbstractMap.SimpleEntry>> entry = maps.get(file); - if (entry != null) { - entry.getValue().add(new WeakReference<>(this)); - return; - } - final WatchService watcher = f.toPath().getFileSystem().newWatchService(); - final List> list = new CopyOnWriteArrayList<>(); - Thread watchThread = new Thread() { - - @Override - public void run() { - try { - while (!this.isInterrupted()) { - final WatchKey key = watcher.take(); - Thread.sleep(3000); //防止文件正在更新过程中去读取 - final Map m = loadProperties(new FileInputStream(file)); - key.pollEvents().stream().forEach((event) -> { - if (event.kind() != ENTRY_MODIFY) return; - if (!((Path) event.context()).toFile().getName().equals(f.getName())) return; - for (WeakReference ref : list) { - JDBCPoolSource pool = ref.get(); - if (pool == null) continue; - try { - Properties property = m.get(pool.dataSource.name); - if (property == null) property = m.get(pool.dataSource.name + "." + pool.stype); - if (property != null) pool.change(property); - } catch (Exception ex) { - dataSource.logger.log(Level.INFO, event.context() + " occur error", ex); - } - } - }); - key.reset(); - } - } catch (Exception e) { - dataSource.logger.log(Level.WARNING, "DataSource watch " + file + " occur error", e); - } - } - }; - f.getParentFile().toPath().register(watcher, ENTRY_MODIFY); - watchThread.setName("DataSource-Watch-" + maps.size() + "-Thread"); - watchThread.setDaemon(true); - watchThread.start(); - dataSource.logger.log(Level.FINER, watchThread.getName() + " start watching " + file); - //----------------------------------------------------------- - list.add(new WeakReference<>(this)); - maps.put(file, new AbstractMap.SimpleEntry<>(watcher, list)); - } - } - - public void change(Properties property) { - Method seturlm; - Class clazz = source.getClass(); - String newurl = property.getProperty(JDBC_URL); - String newuser = property.getProperty(JDBC_USER); - String newpassword = property.getProperty(JDBC_PWD); - if (this.url.equals(newurl) && this.user.equals(newuser) && this.password.equals(newpassword)) return; - try { - try { - seturlm = clazz.getMethod("setUrl", String.class); - } catch (Exception e) { - seturlm = clazz.getMethod("setURL", String.class); - } - seturlm.invoke(source, newurl); - clazz.getMethod("setUser", String.class).invoke(source, newuser); - clazz.getMethod("setPassword", String.class).invoke(source, newpassword); - this.url = newurl; - this.user = newuser; - this.password = newpassword; - dataSource.logger.log(Level.INFO, DataSource.class.getSimpleName() + "(" + dataSource.name + "." + stype + ") change (" + property + ")"); - } catch (Exception e) { - dataSource.logger.log(Level.SEVERE, DataSource.class.getSimpleName() + " dynamic change JDBC (url userName password) error", e); - } - } - - public Connection poll() { - return poll(0, null); - } - - private Connection poll(final int count, SQLException e) { - if (count >= 3) { - dataSource.logger.log(Level.WARNING, "create pooled connection error", e); - throw new RuntimeException(e); - } - PooledConnection result = queue.poll(); - if (result == null) { - if (usingCounter.get() >= max) { - try { - result = queue.poll(6, TimeUnit.SECONDS); - } catch (Exception t) { - dataSource.logger.log(Level.WARNING, "take pooled connection error", t); - } - } - if (result == null) { - try { - result = source.getPooledConnection(); - result.addConnectionEventListener(listener); - usingCounter.incrementAndGet(); - } catch (SQLException ex) { - return poll(count + 1, ex); - } - creatCounter.incrementAndGet(); - } - } else { - cycleCounter.incrementAndGet(); - } - Connection conn; - try { - conn = result.getConnection(); - if (!conn.isValid(1)) { - dataSource.logger.info("sql connection is not vaild"); - usingCounter.decrementAndGet(); - return poll(0, null); - } - } catch (SQLException ex) { - if (!"08S01".equals(ex.getSQLState())) {//MySQL特性, 长时间连接没使用会抛出com.mysql.jdbc.exceptions.jdbc4.CommunicationsException - dataSource.logger.log(Level.FINER, "result.getConnection from pooled connection abort [" + ex.getSQLState() + "]", ex); - } - return poll(0, null); - } - return conn; - } - - public long getCreatCount() { - return creatCounter.longValue(); - } - - public long getCycleCount() { - return cycleCounter.longValue(); - } - - public long getSaveCount() { - return saveCounter.longValue(); - } - - public void close() { - queue.stream().forEach(x -> { - try { - x.close(); - } catch (Exception e) { - } - }); - } -} diff --git a/src/main/java/org/redkale/source/Range.java b/src/main/java/org/redkale/source/Range.java deleted file mode 100644 index 21ebee142..000000000 --- a/src/main/java/org/redkale/source/Range.java +++ /dev/null @@ -1,325 +0,0 @@ -/* - * 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.source; - -import java.util.function.*; - -/** - * - *

- * 详情见: http://www.redkale.org - * - * @author zhangjx - * @param Comparable的子类型 - */ -public interface Range extends java.io.Serializable, Predicate { - - public E getMin(); - - public E getMax(); - - public static final class ByteRange implements Range { - - private Byte min = Byte.MIN_VALUE; - - private Byte max = Byte.MAX_VALUE; - - public ByteRange() { - } - - public ByteRange(Byte min, Byte max) { - if (min != null) this.min = min; - if (max != null) this.max = max; - } - - @Override - public Byte getMin() { - return min; - } - - @Override - public Byte getMax() { - return max; - } - - public void setMin(Byte min) { - if (min != null) this.min = min; - } - - public void setMax(Byte max) { - if (max != null) this.max = max; - } - - @Override - public boolean test(Byte t) { - return t >= min && t <= max; - } - - @Override - public String toString() { - return "{min:" + min + ", max:" + max + "}"; - } - - } - - public static final class ShortRange implements Range { - - private Short min = Short.MIN_VALUE; - - private Short max = Short.MAX_VALUE; - - public ShortRange() { - } - - public ShortRange(Short min, Short max) { - if (min != null) this.min = min; - if (max != null) this.max = max; - } - - @Override - public Short getMin() { - return min; - } - - @Override - public Short getMax() { - return max; - } - - public void setMin(Short min) { - if (min != null) this.min = min; - } - - public void setMax(Short max) { - if (max != null) this.max = max; - } - - @Override - public boolean test(Short t) { - return t >= min && t <= max; - } - - @Override - public String toString() { - return "{min:" + min + ", max:" + max + "}"; - } - } - - public static final class IntRange implements Range { - - private Integer min = Integer.MIN_VALUE; - - private Integer max = Integer.MAX_VALUE; - - public IntRange() { - } - - public IntRange(Integer min, Integer max) { - if (min != null) this.min = min; - if (max != null) this.max = max; - } - - @Override - public Integer getMin() { - return min; - } - - @Override - public Integer getMax() { - return max; - } - - public void setMin(Integer min) { - if (min != null) this.min = min; - } - - public void setMax(Integer max) { - if (max != null) this.max = max; - } - - @Override - public boolean test(Integer t) { - return t >= min && t <= max; - } - - @Override - public String toString() { - return "{min:" + min + ", max:" + max + "}"; - } - } - - public static final class LongRange implements Range { - - private Long min = Long.MIN_VALUE; - - private Long max = Long.MAX_VALUE; - - public LongRange() { - } - - public LongRange(Long min, Long max) { - if (min != null) this.min = min; - if (max != null) this.max = max; - } - - @Override - public Long getMin() { - return min; - } - - @Override - public Long getMax() { - return max; - } - - public void setMin(Long min) { - if (min != null) this.min = min; - } - - public void setMax(Long max) { - if (max != null) this.max = max; - } - - @Override - public boolean test(Long t) { - return t >= min && t <= max; - } - - @Override - public String toString() { - return "{min:" + min + ", max:" + max + "}"; - } - } - - public static final class FloatRange implements Range { - - private Float min = Float.MIN_VALUE; - - private Float max = Float.MAX_VALUE; - - public FloatRange() { - } - - public FloatRange(Float min, Float max) { - if (min != null) this.min = min; - if (max != null) this.max = max; - } - - @Override - public Float getMin() { - return min; - } - - @Override - public Float getMax() { - return max; - } - - public void setMin(Float min) { - if (min != null) this.min = min; - } - - public void setMax(Float max) { - if (max != null) this.max = max; - } - - @Override - public boolean test(Float t) { - return t >= min && t <= max; - } - - @Override - public String toString() { - return "{min:" + min + ", max:" + max + "}"; - } - } - - public static final class DoubleRange implements Range { - - private Double min = Double.MIN_VALUE; - - private Double max = Double.MAX_VALUE; - - public DoubleRange() { - } - - public DoubleRange(Double min, Double max) { - if (min != null) this.min = min; - if (max != null) this.max = max; - } - - @Override - public Double getMin() { - return min; - } - - @Override - public Double getMax() { - return max; - } - - public void setMin(Double min) { - if (min != null) this.min = min; - } - - public void setMax(Double max) { - if (max != null) this.max = max; - } - - @Override - public boolean test(Double t) { - return t >= min && t <= max; - } - - @Override - public String toString() { - return "{min:" + min + ", max:" + max + "}"; - } - } - - public static final class StringRange implements Range { - - private String min = ""; - - private String max = ""; - - public StringRange() { - } - - public StringRange(String min, String max) { - this.min = min; - this.max = max; - } - - @Override - public String getMin() { - return min; - } - - @Override - public String getMax() { - return max; - } - - public void setMin(String min) { - if (min != null) this.min = min; - } - - public void setMax(String max) { - if (max != null) this.max = max; - } - - @Override - public boolean test(String t) { - return t.compareTo(min) >= 0 && t.compareTo(max) <= 0; - } - - @Override - public String toString() { - return "{min:'" + min + "', max:'" + max + "'}"; - } - } -} diff --git a/src/main/java/org/redkale/source/VirtualEntity.java b/src/main/java/org/redkale/source/VirtualEntity.java deleted file mode 100644 index df6c09ace..000000000 --- a/src/main/java/org/redkale/source/VirtualEntity.java +++ /dev/null @@ -1,24 +0,0 @@ -/* - * 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.source; - -import java.lang.annotation.*; -import static java.lang.annotation.ElementType.TYPE; -import static java.lang.annotation.RetentionPolicy.RUNTIME; - -/** - * - *

- * 详情见: http://www.redkale.org - * - * @author zhangjx - */ -@Documented -@Target(TYPE) -@Retention(RUNTIME) -public @interface VirtualEntity { - -} diff --git a/src/main/java/org/redkale/source/package-info.java b/src/main/java/org/redkale/source/package-info.java deleted file mode 100644 index 47fa2d01a..000000000 --- a/src/main/java/org/redkale/source/package-info.java +++ /dev/null @@ -1,4 +0,0 @@ -/** - * 数据源(数据库、缓存)操作包 - */ -package org.redkale.source; diff --git a/src/main/java/org/redkale/util/AnyValue.java b/src/main/java/org/redkale/util/AnyValue.java deleted file mode 100644 index 275e49dee..000000000 --- a/src/main/java/org/redkale/util/AnyValue.java +++ /dev/null @@ -1,446 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ -package org.redkale.util; - -import java.lang.reflect.Array; -import java.util.*; -import java.util.function.BiPredicate; - -/** - * 该类提供类似JSONObject的数据结构,主要用于读取xml配置文件和http-header存储 - * - *

详情见: http://www.redkale.org - * @author zhangjx - */ -@SuppressWarnings("unchecked") -public abstract class AnyValue { - - /** - * 可读写的AnyValue默认实现类 - * - *

详情见: http://www.redkale.org - * @author zhangjx - */ - @SuppressWarnings("unchecked") - public static final class DefaultAnyValue extends AnyValue { - - public static final BiPredicate EQUALS = new BiPredicate() { //为了兼容Android - @Override - public boolean test(String name1, String name2) { - return name1.equals(name2); - } - }; - - public static final BiPredicate EQUALSIGNORE = new BiPredicate() { //为了兼容Android - @Override - public boolean test(String name1, String name2) { - return name1.equalsIgnoreCase(name2); - } - }; - - private final BiPredicate predicate; - - private Entry[] stringValues = new Entry[0]; - - private Entry[] entityValues = new Entry[0]; - - public static final DefaultAnyValue create() { - return new DefaultAnyValue(); - } - - public static final DefaultAnyValue create(String name, String value) { - DefaultAnyValue conf = new DefaultAnyValue(); - conf.addValue(name, value); - return conf; - } - - public static final DefaultAnyValue create(String name, AnyValue value) { - DefaultAnyValue conf = new DefaultAnyValue(); - conf.addValue(name, value); - return conf; - } - - public DefaultAnyValue() { - this(false); - } - - public DefaultAnyValue(boolean ignoreCase) { - this.predicate = ignoreCase ? EQUALSIGNORE : EQUALS; - } - - public DefaultAnyValue(BiPredicate predicate) { - this.predicate = predicate; - } - - public DefaultAnyValue duplicate() { - DefaultAnyValue rs = new DefaultAnyValue(this.predicate); - rs.stringValues = this.stringValues; - rs.entityValues = this.entityValues; - return rs; - } - - public DefaultAnyValue addAll(final AnyValue av) { - if (av == null) return this; - if (av instanceof DefaultAnyValue) { - final DefaultAnyValue adv = (DefaultAnyValue) av; - if (adv.stringValues != null) { - for (Entry en : adv.stringValues) { - this.addValue(en.name, en.value); - } - } - if (adv.entityValues != null) { - for (Entry en : adv.entityValues) { - this.addValue(en.name, en.value); - } - } - } else { - final Entry[] strings = av.getStringEntrys(); - if (strings != null) { - for (Entry en : strings) { - this.addValue(en.name, en.value); - } - } - final Entry[] anys = av.getAnyEntrys(); - if (anys != null) { - for (Entry en : anys) { - this.addValue(en.name, en.value); - } - } - } - return this; - } - - public DefaultAnyValue setAll(final AnyValue av) { - if (av == null) return this; - if (av instanceof DefaultAnyValue) { - final DefaultAnyValue adv = (DefaultAnyValue) av; - if (adv.stringValues != null) { - for (Entry en : adv.stringValues) { - this.setValue(en.name, en.value); - } - } - if (adv.entityValues != null) { - for (Entry en : adv.entityValues) { - this.setValue(en.name, en.value); - } - } - } else { - final Entry[] strings = av.getStringEntrys(); - if (strings != null) { - for (Entry en : strings) { - this.setValue(en.name, en.value); - } - } - final Entry[] anys = av.getAnyEntrys(); - if (anys != null) { - for (Entry en : anys) { - this.setValue(en.name, en.value); - } - } - } - return this; - } - - @Override - public Entry[] getStringEntrys() { - return stringValues; - } - - @Override - public Entry[] getAnyEntrys() { - return entityValues; - } - - @Override - public String[] getNames() { - Set set = new LinkedHashSet<>(); - for (Entry en : this.stringValues) { - set.add(en.name); - } - for (Entry en : this.entityValues) { - set.add(en.name); - } - return set.toArray(new String[set.size()]); - } - - @Override - public String[] getValues(String... names) { - return Entry.getValues(this.predicate, String.class, this.stringValues, names); - } - - @Override - public AnyValue[] getAnyValues(String... names) { - return Entry.getValues(this.predicate, AnyValue.class, this.entityValues, names); - } - - @Override - public String toString() { - return toString(0); - } - - public DefaultAnyValue clear() { - this.stringValues = new Entry[0]; - this.entityValues = new Entry[0]; - return this; - } - - public DefaultAnyValue setValue(String name, String value) { - if (name == null) return this; - if (getValue(name) == null) { - this.addValue(name, value); - } else { - for (Entry en : this.stringValues) { - if (predicate.test(en.name, name)) { - en.value = value; - return this; - } - } - } - return this; - } - - public DefaultAnyValue setValue(String name, AnyValue value) { - if (name == null) return this; - if (getValue(name) == null) { - this.addValue(name, value); - } else { - for (Entry en : this.entityValues) { - if (predicate.test(en.name, name)) { - en.value = value; - return this; - } - } - } - return this; - } - - public DefaultAnyValue addValue(String name, String value) { - if (name == null) return this; - int len = this.stringValues.length; - Entry[] news = new Entry[len + 1]; - System.arraycopy(this.stringValues, 0, news, 0, len); - news[len] = new Entry(name, value); - this.stringValues = news; - return this; - } - - public DefaultAnyValue addValue(String name, AnyValue value) { - if (name == null || value == null) return this; - int len = this.entityValues.length; - Entry[] news = new Entry[len + 1]; - System.arraycopy(this.entityValues, 0, news, 0, len); - news[len] = new Entry(name, value); - this.entityValues = news; - return this; - } - - @Override - public AnyValue getAnyValue(String name) { - for (Entry en : this.entityValues) { - if (predicate.test(en.name, name)) { - return en.value; - } - } - return null; - } - - @Override - public String getValue(String name) { - for (Entry en : this.stringValues) { - if (predicate.test(en.name, name)) { - return en.value; - } - } - return null; - } - - @Override - public String[] getValues(String name) { - return Entry.getValues(this.predicate, String.class, this.stringValues, name); - } - - @Override - public AnyValue[] getAnyValues(String name) { - return Entry.getValues(this.predicate, AnyValue.class, this.entityValues, name); - } - - } - - public static final class Entry { - - public final String name; - - T value; - - public Entry(String name0, T value0) { - this.name = name0; - this.value = value0; - } - - public T getValue() { - return value; - } - - static T[] getValues(BiPredicate comparison, Class clazz, Entry[] entitys, String name) { - int len = 0; - for (Entry en : entitys) { - if (comparison.test(en.name, name)) { - ++len; - } - } - if (len == 0) return (T[]) Array.newInstance(clazz, len); - T[] rs = (T[]) Array.newInstance(clazz, len); - int i = 0; - for (Entry en : entitys) { - if (comparison.test(en.name, name)) { - rs[i++] = en.value; - } - } - return rs; - } - - static T[] getValues(BiPredicate comparison, Class clazz, Entry[] entitys, String... names) { - int len = 0; - for (Entry en : entitys) { - for (String name : names) { - if (comparison.test(en.name, name)) { - ++len; - break; - } - } - } - if (len == 0) return (T[]) Array.newInstance(clazz, len); - T[] rs = (T[]) Array.newInstance(clazz, len); - int i = 0; - for (Entry en : entitys) { - for (String name : names) { - if (comparison.test(en.name, name)) { - rs[i++] = en.value; - break; - } - } - } - return rs; - } - } - - public static AnyValue create() { - return new DefaultAnyValue(); - } - - protected String toString(int len) { - if (len < 0) len = 0; - char[] chars = new char[len]; - Arrays.fill(chars, ' '); - final String space = new String(chars); - StringBuilder sb = new StringBuilder(); - sb.append("{\r\n"); - for (Entry en : getStringEntrys()) { - sb.append(space).append(" '").append(en.name).append("': '").append(en.value).append("',\r\n"); - } - for (Entry en : getAnyEntrys()) { - sb.append(space).append(" '").append(en.name).append("': '").append(en.value.toString(len + 4)).append("',\r\n"); - } - sb.append(space).append('}'); - return sb.toString(); - } - - public abstract Entry[] getStringEntrys(); - - public abstract Entry[] getAnyEntrys(); - - public abstract String[] getNames(); - - public abstract String[] getValues(String name); - - public abstract String[] getValues(String... names); - - public abstract AnyValue[] getAnyValues(String name); - - public abstract AnyValue[] getAnyValues(String... names); - - public abstract AnyValue getAnyValue(String name); - - public abstract String getValue(String name); - - public boolean getBoolValue(String name) { - return Boolean.parseBoolean(getValue(name)); - } - - public boolean getBoolValue(String name, boolean defaultValue) { - String value = getValue(name); - return value == null ? defaultValue : Boolean.parseBoolean(value); - } - - public byte getByteValue(String name) { - return Byte.parseByte(getValue(name)); - } - - public byte getByteValue(String name, byte defaultValue) { - String value = getValue(name); - return value == null ? defaultValue : Byte.decode(value); - } - - public char getCharValue(String name) { - return getValue(name).charAt(0); - } - - public char getCharValue(String name, char defaultValue) { - String value = getValue(name); - return value == null || value.length() == 0 ? defaultValue : value.charAt(0); - } - - public short getShortValue(String name) { - return Short.decode(getValue(name)); - } - - public short getShortValue(String name, short defaultValue) { - String value = getValue(name); - return value == null ? defaultValue : Short.decode(value); - } - - public int getIntValue(String name) { - return Integer.decode(getValue(name)); - } - - public int getIntValue(String name, int defaultValue) { - String value = getValue(name); - return value == null ? defaultValue : Integer.decode(value); - } - - public long getLongValue(String name) { - return Long.decode(getValue(name)); - } - - public long getLongValue(String name, long defaultValue) { - String value = getValue(name); - return value == null ? defaultValue : Long.decode(value); - } - - public float getFloatValue(String name) { - return Float.parseFloat(getValue(name)); - } - - public float getFloatValue(String name, float defaultValue) { - String value = getValue(name); - return value == null ? defaultValue : Float.parseFloat(value); - } - - public double getDoubleValue(String name) { - return Double.parseDouble(getValue(name)); - } - - public double getDoubleValue(String name, double defaultValue) { - String value = getValue(name); - return value == null ? defaultValue : Double.parseDouble(value); - } - - public String getValue(String name, String defaultValue) { - String value = getValue(name); - return value == null ? defaultValue : value; - } - -} diff --git a/src/main/java/org/redkale/util/AsmMethodVisitor.java b/src/main/java/org/redkale/util/AsmMethodVisitor.java deleted file mode 100644 index 4ce456855..000000000 --- a/src/main/java/org/redkale/util/AsmMethodVisitor.java +++ /dev/null @@ -1,152 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ -package org.redkale.util; - -import java.util.*; -import jdk.internal.org.objectweb.asm.*; - -/** - * MethodVisitor 的调试类 - * - *

详情见: http://www.redkale.org - * @author zhangjx - */ -public class AsmMethodVisitor { - - private final MethodVisitor visitor; - - private boolean debug = false; - - public AsmMethodVisitor setDebug(boolean d) { - debug = d; - return this; - } - - private final Map labels = new LinkedHashMap(); - - private static final String[] opcodes = new String[200]; //0 -18 - - static { - try { - for (java.lang.reflect.Field field : Opcodes.class.getFields()) { - String name = field.getName(); - if (name.startsWith("ASM")) continue; - if (name.startsWith("V1_")) continue; - if (name.startsWith("ACC_")) continue; - if (name.startsWith("T_")) continue; - if (name.startsWith("H_")) continue; - if (name.startsWith("F_")) continue; - if (field.getType() != int.class) continue; - opcodes[(int) (Integer) field.get(null)] = name; - } - } catch (Exception ex) { - throw new RuntimeException(ex); //不可能会发生 - } - } - - public AsmMethodVisitor(MethodVisitor visitor) { - //super(Opcodes.ASM5, visitor); - this.visitor = visitor; - } - - public AnnotationVisitor visitParameterAnnotation(int i, String string, boolean bln) { - AnnotationVisitor av = visitor.visitParameterAnnotation(i, string, bln); - if (debug) System.out.println("mv.visitParameterAnnotation(" + i + ", \"" + string + "\", " + bln + ");"); - return av; - } - - public AnnotationVisitor visitAnnotation(String desc, boolean flag) { - AnnotationVisitor av = visitor.visitAnnotation(desc, flag); - if (debug) System.out.println("mv.visitAnnotation(\"" + desc + "\", " + flag + ");"); - return av; - } - - public void visitParameter(String name, int access) { - visitor.visitParameter(name, access); - if (debug) System.out.println("mv.visitParameter(" + name + ", " + access + ");"); - } - - public void visitVarInsn(int opcode, int var) { - visitor.visitVarInsn(opcode, var); - if (debug) System.out.println("mv.visitVarInsn(" + opcodes[opcode] + ", " + var + ");"); - } - - public void visitJumpInsn(int opcode, Label var) { //调用此方法的 ClassWriter 必须由 COMPUTE_FRAMES 构建 - visitor.visitJumpInsn(opcode, var); - if (debug) { - Integer index = labels.get(var); - if (index == null) { - index = labels.size(); - labels.put(var, index); - System.out.println("Label l" + index + " = new Label();"); - } - System.out.println("mv.visitJumpInsn(" + opcodes[opcode] + ", l" + index + ");"); - } - } - - public void visitCode() { - visitor.visitCode(); - if (debug) System.out.println("mv.visitCode();"); - } - - public void visitLabel(Label var) { - visitor.visitLabel(var); - if (debug) { - Integer index = labels.get(var); - if (index == null) { - index = labels.size(); - labels.put(var, index); - System.out.println("Label l" + index + " = new Label();"); - } - System.out.println("mv.visitLabel(l" + index + ");"); - } - } - - public void visitMethodInsn(int opcode, String owner, String name, String desc, boolean itf) { - visitor.visitMethodInsn(opcode, owner, name, desc, itf); - if (debug) System.out.println("mv.visitMethodInsn(" + opcodes[opcode] + ", \"" + owner + "\", \"" + name + "\", \"" + desc + "\", " + itf + ");"); - } - - public void visitFieldInsn(int opcode, String owner, String name, String desc) { - visitor.visitFieldInsn(opcode, owner, name, desc); - if (debug) System.out.println("mv.visitFieldInsn(" + opcodes[opcode] + ", \"" + owner + "\", \"" + name + "\", \"" + desc + "\");"); - } - - public void visitTypeInsn(int opcode, String type) { - visitor.visitTypeInsn(opcode, type); - if (debug) System.out.println("mv.visitTypeInsn(" + opcodes[opcode] + ", \"" + type + "\");"); - } - - public void visitInsn(int opcode) { - visitor.visitInsn(opcode); - if (debug) System.out.println("mv.visitInsn(" + opcodes[opcode] + ");"); - } - - public void visitIntInsn(int opcode, int value) { - visitor.visitIntInsn(opcode, value); - if (debug) System.out.println("mv.visitIntInsn(" + opcodes[opcode] + ", " + value + ");"); - } - - public void visitIincInsn(int opcode, int value) { - visitor.visitIincInsn(opcode, value); - if (debug) System.out.println("mv.visitIincInsn(" + opcode + ", " + value + ");"); - } - - public void visitLdcInsn(Object o) { - visitor.visitLdcInsn(o); - if (debug) System.out.println("mv.visitLdcInsn(" + o + ");"); - } - - public void visitMaxs(int maxStack, int maxLocals) { - visitor.visitMaxs(maxStack, maxLocals); - if (debug) System.out.println("mv.visitMaxs(" + maxStack + ", " + maxLocals + ");"); - } - - public void visitEnd() { - visitor.visitEnd(); - if (debug) System.out.println("mv.visitEnd();\r\n\r\n\r\n"); - } -} diff --git a/src/main/java/org/redkale/util/Attribute.java b/src/main/java/org/redkale/util/Attribute.java deleted file mode 100644 index 49c252655..000000000 --- a/src/main/java/org/redkale/util/Attribute.java +++ /dev/null @@ -1,555 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ -package org.redkale.util; - -import java.util.ArrayList; -import java.util.List; -import jdk.internal.org.objectweb.asm.*; -import static jdk.internal.org.objectweb.asm.Opcodes.*; - -/** - * 该类实现动态映射一个JavaBean类中成员对应的getter、setter方法; 代替低效的反射实现方式。 - *

- *  public class Record {
- *
- *      private String name;
- *
- *      public String getName() {
- *          return name;
- *      }
- *
- *      public void setName(String name) {
- *          this.name = name;
- *      }
- *  }
- * 
- * 获取name的 Attribute : - *
- *  Attribute<Record, String> nameAction = Attribute.create(Record.class.getDeclaredField("name"));
- * 
- * 等价于: - *
- *  Attribute<Record, String> nameAction = new Attribute<Record, String>() {
- *
- *      @Override
- *      public String field() {
- *          return "name";
- *      }
- *
- *      @Override
- *      public String get(Record obj) {
- *          return obj.getName();
- *      }
- *
- *      @Override
- *      public void set(Record obj, String value) {
- *          obj.setName(value);
- *      }
- *
- *      @Override
- *      public Class type() {
- *          return String.class;
- *      }
- *
- *      @Override
- *      public Class declaringClass() {
- *          return Record.class;
- *      }
- *  };
- * 
- *

- * 映射Field时,field必须满足以下条件之一:
- * 1、field属性是public且非final
- * 2、至少存在对应的getter、setter方法中的一个
- * 当不存在getter方法时,get操作固定返回null
- * 当不存在setter方法时,set操作为空方法
- * - *

- * 详情见: http://www.redkale.org - * - * @author zhangjx - * @param 字段依附的类 - * @param 字段的数据类型 - */ -public interface Attribute { - - /** - * 返回字段的数据类型 - * - * @return 字段的数据类型 - */ - public Class type(); - - /** - * 返回字段依附的类名 - * - * @return 依附的类名 - */ - public Class declaringClass(); - - /** - * 返回字段名 - * - * @return 字段名 - */ - public String field(); - - /** - * 获取指定对象的该字段的值 - * - * @param obj 指定对象 - * @return 字段的值 - */ - public F get(T obj); - - /** - * 给指定对象的该字段赋值 - * - * @param obj 指定对象 - * @param value 字段新值 - */ - public void set(T obj, F value); - - /** - * 根据一个Field生成 Attribute 对象。 - * - * @param 依附类的类型 - * @param 字段类型 - * @param field 字段,如果该字段不存在则抛异常 - * @return Attribute对象 - */ - @SuppressWarnings("unchecked") - public static Attribute create(final java.lang.reflect.Field field) { - return create((Class) field.getDeclaringClass(), field.getName(), field, null, null); - } - - /** - * 根据一个Field和field的别名生成 Attribute 对象。 - * - * @param 依附类的类型 - * @param 字段类型 - * @param fieldalias 别名 - * @param field 字段,如果该字段不存在则抛异常 - * @return Attribute对象 - */ - @SuppressWarnings("unchecked") - public static Attribute create(String fieldalias, final java.lang.reflect.Field field) { - return create((Class) field.getDeclaringClass(), fieldalias, field, null, null); - } - - /** - * 根据一个Class和field真实名称生成 Attribute 对象。 - * - * @param 依附类的类型 - * @param 字段类型 - * @param clazz 指定依附的类 - * @param fieldname 字段名,如果该字段不存在则抛异常 - * @return Attribute对象 - */ - public static Attribute create(Class clazz, final String fieldname) { - try { - return create(clazz, fieldname, clazz.getDeclaredField(fieldname), null, null); - } catch (NoSuchFieldException | SecurityException ex) { - throw new RuntimeException(ex); - } - } - - /** - * 根据一个Class和Field生成 Attribute 对象。 - * - * @param 依附类的类型 - * @param 字段类型 - * @param clazz 指定依附的类 - * @param field 字段,如果该字段不存在则抛异常 - * @return Attribute对象 - */ - public static Attribute create(Class clazz, final java.lang.reflect.Field field) { - return create(clazz, field.getName(), field); - } - - /** - * 根据一个Class、field别名和Field生成 Attribute 对象。 - * - * @param 依附类的类型 - * @param 字段类型 - * @param clazz 指定依附的类 - * @param fieldalias 字段别名 - * @param field 字段,如果该字段不存在则抛异常 - * @return Attribute对象 - */ - public static Attribute create(Class clazz, final String fieldalias, final java.lang.reflect.Field field) { - return create(clazz, fieldalias, field, null, null); - } - - /** - * 根据一个getter和setter方法生成 Attribute 对象。 - * tgetter、setter不能同时为null - * - * @param 依附类的类型 - * @param 字段类型 - * @param getter getter方法 - * @param setter setter方法 - * @return Attribute对象 - */ - @SuppressWarnings("unchecked") - public static Attribute create(final java.lang.reflect.Method getter, final java.lang.reflect.Method setter) { - return create((Class) (getter == null ? setter.getDeclaringClass() : getter.getDeclaringClass()), null, null, getter, setter); - } - - /** - * 根据Class、getter和setter方法生成 Attribute 对象。 - * tgetter、setter不能同时为null - * - * @param 依附类的类型 - * @param 字段类型 - * @param clazz 指定依附的类 - * @param getter getter方法 - * @param setter setter方法 - * @return Attribute对象 - */ - public static Attribute create(Class clazz, final java.lang.reflect.Method getter, final java.lang.reflect.Method setter) { - return create(clazz, null, null, getter, setter); - } - - /** - * 根据Class生成getter、setter方法都存在的字段对应的 Attribute 对象数组。 - * - * @param 依附类的类型 - * @param clazz 指定依附的类 - * @return Attribute对象数组 - */ - public static Attribute[] create(Class clazz) { - List> list = new ArrayList<>(); - for(java.lang.reflect.Field field : clazz.getFields()){ - if(java.lang.reflect.Modifier.isStatic(field.getModifiers())) continue; - if(java.lang.reflect.Modifier.isFinal(field.getModifiers())) continue; - list.add(create(clazz, field)); - } - for(java.lang.reflect.Method setter : clazz.getDeclaredMethods()){ - if(java.lang.reflect.Modifier.isStatic(setter.getModifiers())) continue; - if(!setter.getName().startsWith("set")) continue; - if(setter.getReturnType() != void.class) continue; - if(setter.getParameterCount() != 1) continue; - Class t = setter.getParameterTypes()[0]; - String prefix = t == boolean.class || t == Boolean.class ? "is" : "get"; - java.lang.reflect.Method getter = null; - try { - clazz.getMethod(setter.getName().replaceFirst("set", prefix)); - } catch (Exception e){ - continue; - } - list.add(create(clazz, getter, setter)); - } - return list.toArray(new Attribute[list.size()]); - } - - /** - * 根据Class生成getter方法对应的 Attribute 对象数组。 - * - * @param 依附类的类型 - * @param clazz 指定依附的类 - * @return Attribute对象数组 - */ - public static Attribute[] createGetters(Class clazz) { - List> list = new ArrayList<>(); - for(java.lang.reflect.Field field : clazz.getFields()){ - if(java.lang.reflect.Modifier.isStatic(field.getModifiers())) continue; - if(java.lang.reflect.Modifier.isFinal(field.getModifiers())) continue; - list.add(create(clazz, field)); - } - for(java.lang.reflect.Method method : clazz.getDeclaredMethods()){ - if(java.lang.reflect.Modifier.isStatic(method.getModifiers())) continue; - if(!method.getName().startsWith("get") && !method.getName().startsWith("is")) continue; - if(method.getReturnType() == void.class) continue; - if(method.getParameterCount() != 0) continue; - list.add(create(clazz, method, null)); - } - return list.toArray(new Attribute[list.size()]); - } - - /** - * 根据Class生成setter方法对应的 Attribute 对象数组。 - * - * @param 依附类的类型 - * @param clazz 指定依附的类 - * @return Attribute对象数组 - */ - public static Attribute[] createSetters(Class clazz) { - List> list = new ArrayList<>(); - for(java.lang.reflect.Field field : clazz.getFields()){ - if(java.lang.reflect.Modifier.isStatic(field.getModifiers())) continue; - if(java.lang.reflect.Modifier.isFinal(field.getModifiers())) continue; - list.add(create(clazz, field)); - } - for(java.lang.reflect.Method method : clazz.getDeclaredMethods()){ - if(java.lang.reflect.Modifier.isStatic(method.getModifiers())) continue; - if(!method.getName().startsWith("set")) continue; - if(method.getReturnType() != void.class) continue; - if(method.getParameterCount() != 1) continue; - list.add(create(clazz, null, method)); - } - return list.toArray(new Attribute[list.size()]); - } - - /** - * 根据Class、字段别名、getter和setter方法生成 Attribute 对象。 - * tgetter、setter不能同时为null - * - * @param 依附类的类型 - * @param 字段类型 - * @param clazz 指定依附的类 - * @param fieldalias 字段别名 - * @param getter getter方法 - * @param setter setter方法 - * @return Attribute对象 - */ - public static Attribute create(Class clazz, final String fieldalias, final java.lang.reflect.Method getter, final java.lang.reflect.Method setter) { - return create(clazz, fieldalias, null, getter, setter); - } - - /** - * 根据Class、字段别名、Field、getter和setter方法生成 Attribute 对象。 - * Field、tgetter、setter不能同时为null - * - * @param 依附类的类型 - * @param 字段类型 - * @param clazz 指定依附的类 - * @param fieldalias 字段别名 - * @param field 字段 - * @param getter getter方法 - * @param setter setter方法 - * @return Attribute对象 - */ - @SuppressWarnings("unchecked") - public static Attribute create(final Class clazz, String fieldalias, final java.lang.reflect.Field field, java.lang.reflect.Method getter, java.lang.reflect.Method setter) { - if (fieldalias != null && fieldalias.isEmpty()) fieldalias = null; - int mod = field == null ? java.lang.reflect.Modifier.STATIC : field.getModifiers(); - if (field != null && !java.lang.reflect.Modifier.isStatic(mod) && !java.lang.reflect.Modifier.isPublic(mod)) { - Class t = field.getType(); - char[] fs = field.getName().toCharArray(); - fs[0] = Character.toUpperCase(fs[0]); - String mn = new String(fs); - if (getter == null) { - String prefix = t == boolean.class || t == Boolean.class ? "is" : "get"; - try { - getter = clazz.getMethod(prefix + mn); - } catch (Exception ex) { - } - } - if (setter == null) { - try { - setter = clazz.getMethod("set" + mn, field.getType()); - } catch (Exception ex) { - } - } - } - final java.lang.reflect.Field tfield = field == null ? null : (!java.lang.reflect.Modifier.isPublic(mod) || java.lang.reflect.Modifier.isStatic(mod) ? null : field); - final java.lang.reflect.Method tgetter = getter; - final java.lang.reflect.Method tsetter = setter; - if (fieldalias == null) { - if (field != null) { - fieldalias = field.getName(); - } else { - String s; - if (getter != null) { - s = getter.getName().substring(getter.getName().startsWith("is") ? 2 : 3); - } else { - s = setter.getName().substring(3); - } - char[] d = s.toCharArray(); - if (d.length < 2 || Character.isLowerCase(d[1])) { - d[0] = Character.toLowerCase(d[0]); - } - fieldalias = new String(d); - } - } - if (tgetter == null && tsetter == null && tfield == null) { - throw new RuntimeException("[" + clazz + "]have no public field or setter or getter"); - } - final String fieldname = fieldalias; - Class column; - if (tfield != null) { // public tfield - column = tfield.getType(); - } else if (tgetter != null) { - column = tgetter.getReturnType(); - } else { // tsetter != null - column = tsetter.getParameterTypes()[0]; - } - final Class pcolumn = column; - if (column.isPrimitive()) column = java.lang.reflect.Array.get(java.lang.reflect.Array.newInstance(column, 1), 0).getClass(); - final String supDynName = Attribute.class.getName().replace('.', '/'); - final String interName = clazz.getName().replace('.', '/'); - final String columnName = column.getName().replace('.', '/'); - final String interDesc = Type.getDescriptor(clazz); - final String columnDesc = Type.getDescriptor(column); - - ClassLoader loader = Attribute.class.getClassLoader(); - String newDynName = supDynName + "_Dyn_" + clazz.getSimpleName() + "_" - + fieldname.substring(fieldname.indexOf('.') + 1) + "_" + pcolumn.getSimpleName().replace("[]", "Array"); - if (String.class.getClassLoader() != clazz.getClassLoader()) { - loader = clazz.getClassLoader(); - newDynName = interName + "_Dyn" + Attribute.class.getSimpleName() + "_" - + fieldname.substring(fieldname.indexOf('.') + 1) + "_" + pcolumn.getSimpleName().replace("[]", "Array"); - } - try { - return (Attribute) Class.forName(newDynName.replace('/', '.')).newInstance(); - } catch (Throwable ex) { - } - //--------------------------------------------------- - final ClassWriter cw = new ClassWriter(0); - MethodVisitor mv; - - cw.visit(V1_8, ACC_PUBLIC + ACC_FINAL + ACC_SUPER, newDynName, "Ljava/lang/Object;L" + supDynName + "<" + interDesc + columnDesc + ">;", "java/lang/Object", new String[]{supDynName}); - - { //构造方法 - mv = cw.visitMethod(ACC_PUBLIC, "", "()V", null, null); - mv.visitVarInsn(ALOAD, 0); - mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "", "()V", false); - mv.visitInsn(RETURN); - mv.visitMaxs(1, 1); - mv.visitEnd(); - } - - { //field 方法 - mv = cw.visitMethod(ACC_PUBLIC, "field", "()Ljava/lang/String;", null, null); - mv.visitLdcInsn(fieldname); - mv.visitInsn(ARETURN); - mv.visitMaxs(1, 1); - mv.visitEnd(); - } - { //type 方法 - mv = cw.visitMethod(ACC_PUBLIC, "type", "()Ljava/lang/Class;", null, null); - if (pcolumn == boolean.class) { - mv.visitFieldInsn(GETSTATIC, "java/lang/Boolean", "TYPE", "Ljava/lang/Class;"); - } else if (pcolumn == byte.class) { - mv.visitFieldInsn(GETSTATIC, "java/lang/Byte", "TYPE", "Ljava/lang/Class;"); - } else if (pcolumn == char.class) { - mv.visitFieldInsn(GETSTATIC, "java/lang/Character", "TYPE", "Ljava/lang/Class;"); - } else if (pcolumn == short.class) { - mv.visitFieldInsn(GETSTATIC, "java/lang/Short", "TYPE", "Ljava/lang/Class;"); - } else if (pcolumn == int.class) { - mv.visitFieldInsn(GETSTATIC, "java/lang/Integer", "TYPE", "Ljava/lang/Class;"); - } else if (pcolumn == float.class) { - mv.visitFieldInsn(GETSTATIC, "java/lang/Float", "TYPE", "Ljava/lang/Class;"); - } else if (pcolumn == long.class) { - mv.visitFieldInsn(GETSTATIC, "java/lang/Long", "TYPE", "Ljava/lang/Class;"); - } else if (pcolumn == double.class) { - mv.visitFieldInsn(GETSTATIC, "java/lang/Double", "TYPE", "Ljava/lang/Class;"); - } else { - mv.visitLdcInsn(Type.getType(pcolumn)); - } - mv.visitInsn(ARETURN); - mv.visitMaxs(1, 1); - mv.visitEnd(); - } - { //declaringClass 方法 - mv = cw.visitMethod(ACC_PUBLIC, "declaringClass", "()Ljava/lang/Class;", null, null); - mv.visitLdcInsn(Type.getType(clazz)); - mv.visitInsn(ARETURN); - mv.visitMaxs(1, 1); - mv.visitEnd(); - } - { //get 方法 - mv = cw.visitMethod(ACC_PUBLIC, "get", "(" + interDesc + ")" + columnDesc, null, null); - int m = 1; - if (tgetter == null) { - if (tfield == null) { - mv.visitInsn(ACONST_NULL); - } else { //public tfield - mv.visitVarInsn(ALOAD, 1); - mv.visitFieldInsn(GETFIELD, interName, tfield.getName(), Type.getDescriptor(pcolumn)); - if (pcolumn != column) { - mv.visitMethodInsn(INVOKESTATIC, columnName, "valueOf", "(" + Type.getDescriptor(pcolumn) + ")" + columnDesc, false); - m = 2; - } - } - } else { - mv.visitVarInsn(ALOAD, 1); - mv.visitMethodInsn(INVOKEVIRTUAL, interName, tgetter.getName(), Type.getMethodDescriptor(tgetter), false); - if (pcolumn != column) { - mv.visitMethodInsn(INVOKESTATIC, columnName, "valueOf", "(" + Type.getDescriptor(pcolumn) + ")" + columnDesc, false); - m = 2; - } - } - mv.visitInsn(ARETURN); - mv.visitMaxs(m, 2); - mv.visitEnd(); - } - { //set 方法 - mv = cw.visitMethod(ACC_PUBLIC, "set", "(" + interDesc + columnDesc + ")V", null, null); - int m = 2; - if (tsetter == null) { - if (tfield == null || java.lang.reflect.Modifier.isFinal(tfield.getModifiers())) { - m = 0; - } else { //public tfield - mv.visitVarInsn(ALOAD, 1); - mv.visitVarInsn(ALOAD, 2); - if (pcolumn != column) { - try { - java.lang.reflect.Method pm = column.getMethod(pcolumn.getSimpleName() + "Value"); - mv.visitMethodInsn(INVOKEVIRTUAL, columnName, pm.getName(), Type.getMethodDescriptor(pm), false); - m = 3; - } catch (Exception ex) { - throw new RuntimeException(ex); //不可能会发生 - } - } - mv.visitFieldInsn(PUTFIELD, interName, tfield.getName(), Type.getDescriptor(pcolumn)); - } - } else { - mv.visitVarInsn(ALOAD, 1); - mv.visitVarInsn(ALOAD, 2); - if (pcolumn != column) { - try { - java.lang.reflect.Method pm = column.getMethod(pcolumn.getSimpleName() + "Value"); - mv.visitMethodInsn(INVOKEVIRTUAL, columnName, pm.getName(), Type.getMethodDescriptor(pm), false); - m = 3; - } catch (Exception ex) { - throw new RuntimeException(ex); //不可能会发生 - } - } - mv.visitMethodInsn(INVOKEVIRTUAL, interName, tsetter.getName(), Type.getMethodDescriptor(tsetter), false); - } - mv.visitInsn(RETURN); - mv.visitMaxs(m, 3); - mv.visitEnd(); - } - { //虚拟get - mv = cw.visitMethod(ACC_PUBLIC + ACC_BRIDGE + ACC_SYNTHETIC, "get", "(Ljava/lang/Object;)Ljava/lang/Object;", null, null); - mv.visitVarInsn(ALOAD, 0); - mv.visitVarInsn(ALOAD, 1); - mv.visitTypeInsn(CHECKCAST, interName); - mv.visitMethodInsn(INVOKEVIRTUAL, newDynName, "get", "(" + interDesc + ")" + columnDesc, false); - mv.visitInsn(ARETURN); - mv.visitMaxs(2, 2); - mv.visitEnd(); - } - {//虚拟set - mv = cw.visitMethod(ACC_PUBLIC + ACC_BRIDGE + ACC_SYNTHETIC, "set", "(Ljava/lang/Object;Ljava/lang/Object;)V", null, null); - mv.visitVarInsn(ALOAD, 0); - mv.visitVarInsn(ALOAD, 1); - mv.visitTypeInsn(CHECKCAST, interName); - mv.visitVarInsn(ALOAD, 2); - mv.visitTypeInsn(CHECKCAST, columnName); - mv.visitMethodInsn(INVOKEVIRTUAL, newDynName, "set", "(" + interDesc + columnDesc + ")V", false); - mv.visitInsn(RETURN); - mv.visitMaxs(3, 3); - mv.visitEnd(); - } - cw.visitEnd(); - - byte[] bytes = cw.toByteArray(); - Class creatorClazz = (Class) new ClassLoader(loader) { - public final Class loadClass(String name, byte[] b) { - return defineClass(name, b, 0, b.length); - } - }.loadClass(newDynName.replace('/', '.'), bytes); - try { - return creatorClazz.newInstance(); - } catch (Exception ex) { - throw new RuntimeException(ex); - } - } -} diff --git a/src/main/java/org/redkale/util/AutoLoad.java b/src/main/java/org/redkale/util/AutoLoad.java deleted file mode 100644 index 7c399325b..000000000 --- a/src/main/java/org/redkale/util/AutoLoad.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ -package org.redkale.util; - -import java.lang.annotation.*; -import static java.lang.annotation.ElementType.TYPE; -import static java.lang.annotation.RetentionPolicy.RUNTIME; - -/** - * 自动加载。 使用场景: - * 1、被标记为@AutoLoad(false)的Service类不会被自动加载 - * 2、被标记为@AutoLoad(false)的Servlet类不会被自动加载 - * 3、被标记为@AutoLoad且同时被标记为@javax.persistence.Cacheable的Entity类在被DataSource初始化时需要将Entity类对应的表数据全量加载进缓存中。 - * - *

详情见: http://www.redkale.org - * @author zhangjx - */ -@Documented -@Target({TYPE}) -@Retention(RUNTIME) -public @interface AutoLoad { - - boolean value() default true; -} diff --git a/src/main/java/org/redkale/util/ByteArray.java b/src/main/java/org/redkale/util/ByteArray.java deleted file mode 100644 index 861faf3f1..000000000 --- a/src/main/java/org/redkale/util/ByteArray.java +++ /dev/null @@ -1,194 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ -package org.redkale.util; - -import java.nio.*; -import java.nio.charset.*; -import java.util.*; - -/** - * 简单的byte[]操作类。 - * - *

- * 详情见: http://www.redkale.org - * - * @author zhangjx - */ -public final class ByteArray { - - private byte[] content; - - private int count; - - public ByteArray() { - this(1024); - } - - public ByteArray(int size) { - content = new byte[Math.max(128, size)]; - } - - public void clear() { - this.count = 0; - } - - public int find(byte value) { - return find(0, value); - } - - public boolean equal(final byte[] bytes) { - if (bytes == null || count != bytes.length) return false; - for (int i = 0; i < count; i++) { - if (content[i] != bytes[i]) return false; - } - return true; - } - - public boolean isEmpty() { - return count == 0; - } - - public int size() { - return count; - } - - public byte get(int index) { - return content[index]; - } - - public byte getLastByte() { - return content[count - 1]; - } - - public void copyTo(byte[] buf) { - System.arraycopy(this.content, 0, buf, 0, count); - } - - public byte[] directBytes() { - return content; - } - - public byte[] getBytes() { - return Arrays.copyOf(content, count); - } - - public byte[] getBytesAndClear() { - byte[] bs = Arrays.copyOf(content, count); - clear(); - return bs; - } - - public int find(int offset, char value) { - return find(offset, (byte) value); - } - - public int find(int offset, byte value) { - return find(offset, -1, value); - } - - public int find(int offset, int limit, char value) { - return find(offset, limit, (byte) value); - } - - public int find(int offset, int limit, byte value) { - byte[] bytes = this.content; - int end = limit > 0 ? limit : count; - for (int i = offset; i < end; i++) { - if (bytes[i] == value) return i; - } - return -1; - } - - public void removeLastByte() { - if (count > 0) count--; - } - - public void writeInt(int value) { - write((byte) (value >> 24 & 0xFF), (byte) (value >> 16 & 0xFF), (byte) (value >> 8 & 0xFF), (byte) (value & 0xFF)); - } - - public void write(byte value) { - if (count >= content.length - 1) { - byte[] ns = new byte[content.length + 8]; - System.arraycopy(content, 0, ns, 0, count); - this.content = ns; - } - content[count++] = value; - } - - public void write(byte... values) { - if (count >= content.length - values.length) { - byte[] ns = new byte[content.length + values.length]; - System.arraycopy(content, 0, ns, 0, count); - this.content = ns; - } - System.arraycopy(content, count, values, 0, values.length); - count += values.length; - } - - public void write(ByteBuffer buffer, int len) { - if (len < 1) return; - if (count >= content.length - len) { - byte[] ns = new byte[content.length + len]; - System.arraycopy(content, 0, ns, 0, count); - this.content = ns; - } - buffer.get(content, count, len); - count += len; - } - - @Override - public String toString() { - return new String(content, 0, count); - } - - public String toString(final Charset charset) { - return toString(0, count, charset); - } - - public String toStringAndClear(final Charset charset) { - String str = toString(0, count, charset); - clear(); - return str; - } - - public String toString(final int offset, int len, final Charset charset) { - if (charset == null) return new String(Utility.decodeUTF8(content, offset, len)); - return new String(content, offset, len, charset); - } - - public String toDecodeString(final int offset, int len, final Charset charset) { - int index = offset; - for (int i = offset; i < (offset + len); i++) { - switch (content[i]) { - case '+': - content[index] = ' '; - break; - case '%': - content[index] = (byte) ((hexBit(content[++i]) * 16 + hexBit(content[++i]))); - break; - default: - content[index] = content[i]; - break; - } - index++; - } - for (int i = index + 1; i < (offset + len); i++) { - content[i] = ' '; - } - len = index - offset; - if (charset == null) return new String(Utility.decodeUTF8(content, offset, len)); - return new String(content, offset, len, charset); - } - - private static int hexBit(byte b) { - if ('0' <= b && '9' >= b) return b - '0'; - if ('a' <= b && 'z' >= b) return b - 'a' + 10; - if ('A' <= b && 'Z' >= b) return b - 'A' + 10; - return b; - } - -} diff --git a/src/main/java/org/redkale/util/Creator.java b/src/main/java/org/redkale/util/Creator.java deleted file mode 100644 index cd317cb62..000000000 --- a/src/main/java/org/redkale/util/Creator.java +++ /dev/null @@ -1,358 +0,0 @@ -/* - * To change this template, choose Tools | Templates - * and open the template in the editor. - */ -package org.redkale.util; - -import java.beans.*; -import java.io.*; -import java.lang.annotation.*; -import static java.lang.annotation.ElementType.*; -import static java.lang.annotation.RetentionPolicy.RUNTIME; -import java.lang.reflect.*; -import java.net.*; -import java.util.*; -import jdk.internal.org.objectweb.asm.*; -import jdk.internal.org.objectweb.asm.Type; -import static jdk.internal.org.objectweb.asm.Opcodes.*; - -/** - *

- * 实现一个类的构造方法。 代替低效的反射实现方式。 不支持数组类。 - * 常见的无参数的构造函数类都可以自动生成Creator, 对应自定义的类可以提供一个静态构建Creator方法。 - * 例如: - *

- * public class Record {
- *
- *    private final int id;
- *
- *    private String name;
- *
- *    Record(int id, String name) {
- *        this.id = id;
- *        this.name = name;
- *    }
- *
- *    private static Creator createCreator() {
- *        return new Creator<Record>() {
- *            @Override
- *            @ConstructorParameters({"id", "name"})
- *            public Record create(Object... params) {
- *                if(params[0] == null) params[0] = 0;
- *                return new Record((Integer) params[0], (String) params[1]);
- *            }
- *         };
- *    }
- * }
- * 
- * - * 或者: - *
- * public class Record {
- *
- *    private final int id;
- *
- *    private String name;
- *
- *    @java.beans.ConstructorProperties({"id", "name"})
- *    public Record(int id, String name) {
- *        this.id = id;
- *        this.name = name;
- *    }
- * }
- * 
- * - *

- * 详情见: http://www.redkale.org - * - * @author zhangjx - * @param 构建对象的数据类型 - */ -public interface Creator { - - /** - * 该注解只用于Creator.create方法上, 与 java.beans.ConstructorProperties 类似。 - * - */ - @Documented - @Target({METHOD}) - @Retention(RUNTIME) - public static @interface ConstructorParameters { - - String[] value(); - } - - /** - * 创建对象 - * - * @param params 构造函数的参数 - * @return 构建的对象 - */ - public T create(Object... params); - - /** - * 根据指定的class采用ASM技术生产Creator。 - * - * @param 构建类的数据类型 - * @param clazz 构建类 - * @return Creator对象 - */ - @SuppressWarnings("unchecked") - public static Creator create(Class clazz) { - if (clazz.isAssignableFrom(ArrayList.class)) { - clazz = (Class) ArrayList.class; - } else if (clazz.isAssignableFrom(HashMap.class)) { - clazz = (Class) HashMap.class; - } else if (clazz.isAssignableFrom(HashSet.class)) { - clazz = (Class) HashSet.class; - } - if (clazz.isInterface() || Modifier.isAbstract(clazz.getModifiers())) { - throw new RuntimeException("[" + clazz + "] is a interface or abstract class, cannot create it's Creator."); - } - for (final Method method : clazz.getDeclaredMethods()) { - if (!Modifier.isStatic(method.getModifiers())) continue; - if (method.getParameterTypes().length != 0) continue; - if (method.getReturnType() != Creator.class) continue; - try { - method.setAccessible(true); - return (Creator) method.invoke(null); - } catch (Exception e) { - throw new RuntimeException(e); - } - } - final String supDynName = Creator.class.getName().replace('.', '/'); - final String interName = clazz.getName().replace('.', '/'); - final String interDesc = Type.getDescriptor(clazz); - ClassLoader loader = Creator.class.getClassLoader(); - String newDynName = supDynName + "_" + clazz.getSimpleName() + "_" + (System.currentTimeMillis() % 10000); - if (String.class.getClassLoader() != clazz.getClassLoader()) { - loader = clazz.getClassLoader(); - newDynName = interName + "_Dyn" + Creator.class.getSimpleName(); - } - try { - return (Creator) Class.forName(newDynName.replace('/', '.')).newInstance(); - } catch (Exception ex) { - } - Constructor constructor0 = null; - for (Constructor c : clazz.getConstructors()) { //优先找public 的构造函数 - if (c.getParameterCount() == 0) { - constructor0 = c; - break; - } - } - if (constructor0 == null) {//其次找非private带ConstructorProperties的构造函数 - for (Constructor c : clazz.getDeclaredConstructors()) { - if (Modifier.isPrivate(c.getModifiers())) continue; - if (c.getAnnotation(ConstructorProperties.class) != null) { - constructor0 = c; - break; - } - } - } - if (constructor0 == null) {//再次找非private且带-parameters编译项的构造函数 java 8以上才支持 - for (Constructor c : clazz.getDeclaredConstructors()) { - if (Modifier.isPrivate(c.getModifiers())) continue; - Parameter[] params = c.getParameters(); - if (params.length == 0) continue; - boolean flag = true; - for (Parameter param : params) { - try { - clazz.getDeclaredField(param.getName()); - } catch (Exception e) { - flag = false; - break; - } - } - if (flag) { - constructor0 = c; - break; - } - } - } - if (constructor0 == null) {//最后找非private的空构造函数 - for (Constructor c : clazz.getDeclaredConstructors()) { - if (Modifier.isPrivate(c.getModifiers())) continue; - if (c.getParameterCount() == 0) { - constructor0 = c; - break; - } - } - } - final Constructor constructor = constructor0; - if (constructor == null) throw new RuntimeException("[" + clazz + "] have no public or java.beans.ConstructorProperties-Annotation constructor."); - //------------------------------------------------------------- - ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES); - FieldVisitor fv; - MethodVisitor mv; - AnnotationVisitor av0; - cw.visit(V1_8, ACC_PUBLIC + ACC_FINAL + ACC_SUPER, newDynName, "Ljava/lang/Object;L" + supDynName + "<" + interDesc + ">;", "java/lang/Object", new String[]{supDynName}); - - {//构造方法 - mv = cw.visitMethod(ACC_PUBLIC, "", "()V", null, null); - mv.visitVarInsn(ALOAD, 0); - mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "", "()V", false); - mv.visitInsn(RETURN); - mv.visitMaxs(1, 1); - mv.visitEnd(); - } - {//create 方法 - mv = cw.visitMethod(ACC_PUBLIC + ACC_VARARGS, "create", "([Ljava/lang/Object;)L" + interName + ";", null, null); - ConstructorProperties cps = constructor.getAnnotation(ConstructorProperties.class); - String[] cparams = cps == null ? null : cps.value(); - if (cparams == null && constructor.getParameterCount() > 0) { // java 8 以上版本才支持的 -parameters 编译项 - Parameter[] params = constructor.getParameters(); - String[] ss = new String[params.length]; - for (int i = 0; i < ss.length; i++) { - try { - clazz.getDeclaredField(params[i].getName()); - } catch (Exception e) { //没有该字段,直接退出 - ss = null; - break; - } - ss[i] = params[i].getName(); - } - cparams = ss; - } - if (cparams != null) { - av0 = mv.visitAnnotation(Type.getDescriptor(ConstructorParameters.class), true); - AnnotationVisitor av1 = av0.visitArray("value"); - for (String n : cparams) { - av1.visit(null, n); - } - av1.visitEnd(); - av0.visitEnd(); - } - final Class[] paramTypes = constructor.getParameterTypes(); - final int[] iconsts = {ICONST_0, ICONST_1, ICONST_2, ICONST_3, ICONST_4, ICONST_5}; - { //有Primitive数据类型且值为null的参数需要赋默认值 - for (int i = 0; i < paramTypes.length; i++) { - final Class pt = paramTypes[i]; - if (!pt.isPrimitive()) continue; - mv.visitVarInsn(ALOAD, 1); - if (i < 6) { - mv.visitInsn(iconsts[i]); - } else { - mv.visitIntInsn(BIPUSH, i); - } - mv.visitInsn(AALOAD); - Label lab = new Label(); - mv.visitJumpInsn(IFNONNULL, lab); - mv.visitVarInsn(ALOAD, 1); - if (i < 6) { - mv.visitInsn(iconsts[i]); - } else { - mv.visitIntInsn(BIPUSH, i); - } - if (pt == int.class) { - mv.visitInsn(ICONST_0); - mv.visitMethodInsn(INVOKESTATIC, "java/lang/Integer", "valueOf", "(I)Ljava/lang/Integer;", false); - } else if (pt == long.class) { - mv.visitInsn(LCONST_0); - mv.visitMethodInsn(INVOKESTATIC, "java/lang/Long", "valueOf", "(J)Ljava/lang/Long;", false); - } else if (pt == boolean.class) { - mv.visitFieldInsn(GETSTATIC, "java/lang/Boolean", "FALSE", "Ljava/lang/Boolean;"); - } else if (pt == short.class) { - mv.visitInsn(ICONST_0); - mv.visitMethodInsn(INVOKESTATIC, "java/lang/Short", "valueOf", "(S)Ljava/lang/Short;", false); - } else if (pt == float.class) { - mv.visitInsn(FCONST_0); - mv.visitMethodInsn(INVOKESTATIC, "java/lang/Float", "valueOf", "(F)Ljava/lang/Float;", false); - } else if (pt == byte.class) { - mv.visitInsn(ICONST_0); - mv.visitMethodInsn(INVOKESTATIC, "java/lang/Byte", "valueOf", "(B)Ljava/lang/Byte;", false); - } else if (pt == double.class) { - mv.visitInsn(DCONST_0); - mv.visitMethodInsn(INVOKESTATIC, "java/lang/Double", "valueOf", "(D)Ljava/lang/Double;", false); - } else if (pt == char.class) { - mv.visitInsn(ICONST_0); - mv.visitMethodInsn(INVOKESTATIC, "java/lang/Character", "valueOf", "(C)Ljava/lang/Character;", false); - } - mv.visitInsn(AASTORE); - mv.visitLabel(lab); - } - } - mv.visitTypeInsn(NEW, interName); - mv.visitInsn(DUP); - //--------------------------------------- - { - for (int i = 0; i < paramTypes.length; i++) { - mv.visitVarInsn(ALOAD, 1); - if (i < 6) { - mv.visitInsn(iconsts[i]); - } else { - mv.visitIntInsn(BIPUSH, i); - } - mv.visitInsn(AALOAD); - final Class ct = paramTypes[i]; - if (ct.isPrimitive()) { - final Class bigct = Array.get(Array.newInstance(ct, 1), 0).getClass(); - mv.visitTypeInsn(CHECKCAST, bigct.getName().replace('.', '/')); - try { - Method pm = bigct.getMethod(ct.getSimpleName() + "Value"); - mv.visitMethodInsn(INVOKEVIRTUAL, bigct.getName().replace('.', '/'), pm.getName(), Type.getMethodDescriptor(pm), false); - } catch (Exception ex) { - throw new RuntimeException(ex); //不可能会发生 - } - } else { - mv.visitTypeInsn(CHECKCAST, ct.getName().replace('.', '/')); - } - } - } - //--------------------------------------- - mv.visitMethodInsn(INVOKESPECIAL, interName, "", Type.getConstructorDescriptor(constructor), false); - mv.visitInsn(ARETURN); - mv.visitMaxs((paramTypes.length > 0 ? (paramTypes.length + 3) : 2), 2); - mv.visitEnd(); - } - { //虚拟 create 方法 - mv = cw.visitMethod(ACC_PUBLIC + ACC_BRIDGE + ACC_VARARGS + ACC_SYNTHETIC, "create", "([Ljava/lang/Object;)Ljava/lang/Object;", null, null); - mv.visitVarInsn(ALOAD, 0); - mv.visitVarInsn(ALOAD, 1); - mv.visitMethodInsn(INVOKEVIRTUAL, newDynName, "create", "([Ljava/lang/Object;)" + interDesc, false); - mv.visitInsn(ARETURN); - mv.visitMaxs(2, 2); - mv.visitEnd(); - } - cw.visitEnd(); - final byte[] bytes = cw.toByteArray(); - final boolean ispub = Modifier.isPublic(constructor.getModifiers()); - Class resultClazz = null; - if (loader instanceof URLClassLoader && !ispub) { - try { - final URLClassLoader urlLoader = (URLClassLoader) loader; - final URL url = new URL("memclass", "localhost", -1, "/" + newDynName.replace('/', '.') + "/", new URLStreamHandler() { - @Override - protected URLConnection openConnection(URL u) throws IOException { - return new URLConnection(u) { - @Override - public void connect() throws IOException { - } - - @Override - public InputStream getInputStream() throws IOException { - return new ByteArrayInputStream(bytes); - } - }; - } - }); - Method addURLMethod = URLClassLoader.class.getDeclaredMethod("addURL", URL.class); - addURLMethod.setAccessible(true); - addURLMethod.invoke(urlLoader, url); - resultClazz = urlLoader.loadClass(newDynName.replace('/', '.')); - } catch (Throwable t) { //异常无需理会, 使用下一种loader方式 - t.printStackTrace(); - } - } - if (!ispub && resultClazz == null) throw new RuntimeException("[" + clazz + "] have no public or java.beans.ConstructorProperties-Annotation constructor."); - try { - if (resultClazz == null) resultClazz = new ClassLoader(loader) { - public final Class loadClass(String name, byte[] b) { - return defineClass(name, b, 0, b.length); - } - }.loadClass(newDynName.replace('/', '.'), bytes); - return (Creator) resultClazz.newInstance(); - } catch (Exception ex) { - throw new RuntimeException(ex); - } - } -} diff --git a/src/main/java/org/redkale/util/DLong.java b/src/main/java/org/redkale/util/DLong.java deleted file mode 100644 index d3714f044..000000000 --- a/src/main/java/org/redkale/util/DLong.java +++ /dev/null @@ -1,119 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ -package org.redkale.util; - -import java.nio.*; -import java.util.*; - -/** - * 16bytes数据结构 - * 注意: 为了提高性能, DLong中的bytes是直接返回, 不得对bytes的内容进行修改。 - * - *

- * 详情见: http://www.redkale.org - * - * @author zhangjx - */ -public final class DLong extends Number implements Comparable { - - public static final DLong ZERO = new DLong(new byte[16]); - - protected final byte[] value; - - protected DLong(long v1, long v2) { //暂时不用 - this.value = new byte[]{(byte) (v1 >> 56), (byte) (v1 >> 48), (byte) (v1 >> 40), (byte) (v1 >> 32), - (byte) (v1 >> 24), (byte) (v1 >> 16), (byte) (v1 >> 8), (byte) v1, (byte) (v2 >> 56), (byte) (v2 >> 48), (byte) (v2 >> 40), (byte) (v2 >> 32), - (byte) (v2 >> 24), (byte) (v2 >> 16), (byte) (v2 >> 8), (byte) v2}; - } - - protected DLong(byte[] bytes) { - if (bytes == null || bytes.length != 16) throw new NumberFormatException("Not 16 length bytes"); - this.value = bytes; - } - - public byte[] getBytes() { - return Arrays.copyOf(value, value.length); - } - - public byte[] directBytes() { - return value; - } - - public static DLong create(byte[] bytes) { - return new DLong(bytes); - } - - public static DLong read(ByteBuffer buffer) { - byte[] bs = new byte[16]; - buffer.get(bs); - return new DLong(bs); - } - - public static ByteBuffer write(ByteBuffer buffer, DLong dlong) { - buffer.put(dlong.value); - return buffer; - } - - public boolean equals(byte[] bytes) { - return Arrays.equals(this.value, bytes); - } - - @Override - public boolean equals(Object obj) { - if (obj == null) return false; - if (getClass() != obj.getClass()) return false; - final DLong other = (DLong) obj; - return Arrays.equals(this.value, other.value); - } - - @Override - public int hashCode() { - return Arrays.hashCode(value); - } - - @Override - public String toString() { - if (this == ZERO) return "0"; - return new String(Utility.binToHex(value)); - } - - @Override - public int intValue() { - return ((value[12] & 0xff) << 24) | ((value[113] & 0xff) << 16) | ((value[14] & 0xff) << 8) | (value[15] & 0xff); - } - - @Override - public long longValue() { - return ((((long) value[8] & 0xff) << 56) - | (((long) value[9] & 0xff) << 48) - | (((long) value[10] & 0xff) << 40) - | (((long) value[11] & 0xff) << 32) - | (((long) value[12] & 0xff) << 24) - | (((long) value[13] & 0xff) << 16) - | (((long) value[14] & 0xff) << 8) - | (((long) value[15] & 0xff))); - } - - @Override - public float floatValue() { - return (float) longValue(); - } - - @Override - public double doubleValue() { - return (double) longValue(); - } - - @Override - public int compareTo(DLong o) { - if (o == null) return 1; - for (int i = 0; i < value.length; i++) { - if (this.value[i] != o.value[i]) return this.value[i] - o.value[i]; - } - return 0; - } - -} diff --git a/src/main/java/org/redkale/util/LogLevel.java b/src/main/java/org/redkale/util/LogLevel.java deleted file mode 100644 index de2ee27bf..000000000 --- a/src/main/java/org/redkale/util/LogLevel.java +++ /dev/null @@ -1,25 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ -package org.redkale.util; - -import java.lang.annotation.*; -import static java.lang.annotation.ElementType.TYPE; -import static java.lang.annotation.RetentionPolicy.RUNTIME; - -/** - * 被标记的日志级别以上的才会被记录 - * - *

详情见: http://www.redkale.org - * @author zhangjx - */ -@Inherited -@Documented -@Target({TYPE}) -@Retention(RUNTIME) -public @interface LogLevel { - - String value(); -} diff --git a/src/main/java/org/redkale/util/ObjectPool.java b/src/main/java/org/redkale/util/ObjectPool.java deleted file mode 100644 index a7636a4ae..000000000 --- a/src/main/java/org/redkale/util/ObjectPool.java +++ /dev/null @@ -1,102 +0,0 @@ -/* - * To change this template, choose Tools | Templates - * and open the template in the editor. - */ -package org.redkale.util; - -import java.util.*; -import java.util.concurrent.*; -import java.util.concurrent.atomic.*; -import java.util.function.*; -import java.util.logging.*; - -/** - * - *

- * 详情见: http://www.redkale.org - * - * @author zhangjx - * @param 对象池元素的数据类型 - */ -public final class ObjectPool implements Supplier { - - private static final Logger logger = Logger.getLogger(ObjectPool.class.getSimpleName()); - - private final boolean debug; - - private final Queue queue; - - private Creator creator; - - private final Consumer prepare; - - private final Predicate recycler; - - private final AtomicLong creatCounter; - - private final AtomicLong cycleCounter; - - public ObjectPool(Class clazz, Consumer prepare, Predicate recycler) { - this(2, clazz, prepare, recycler); - } - - public ObjectPool(int max, Class clazz, Consumer prepare, Predicate recycler) { - this(max, Creator.create(clazz), prepare, recycler); - } - - public ObjectPool(Creator creator, Consumer prepare, Predicate recycler) { - this(2, creator, prepare, recycler); - } - - public ObjectPool(int max, Creator creator, Consumer prepare, Predicate recycler) { - this(null, null, max, creator, prepare, recycler); - } - - public ObjectPool(AtomicLong creatCounter, AtomicLong cycleCounter, int max, Creator creator, Consumer prepare, Predicate recycler) { - this.creatCounter = creatCounter; - this.cycleCounter = cycleCounter; - this.creator = creator; - this.prepare = prepare; - this.recycler = recycler; - this.queue = new LinkedBlockingQueue<>(Math.max(Runtime.getRuntime().availableProcessors() * 2, max)); - this.debug = logger.isLoggable(Level.FINER); - } - - public void setCreator(Creator creator) { - this.creator = creator; - } - - @Override - public T get() { - T result = queue.poll(); - if (result == null) { - if (creatCounter != null) creatCounter.incrementAndGet(); - result = this.creator.create(); - } - if (prepare != null) prepare.accept(result); - return result; - } - - public void offer(final T e) { - if (e != null && recycler.test(e)) { - if (cycleCounter != null) cycleCounter.incrementAndGet(); - if (debug) { - for (T t : queue) { - if (t == e) { - logger.log(Level.WARNING, "[" + Thread.currentThread().getName() + "] repeat offer the same object(" + e + ")", new Exception()); - return; - } - } - } - queue.offer(e); - } - } - - public long getCreatCount() { - return creatCounter.longValue(); - } - - public long getCycleCount() { - return cycleCounter.longValue(); - } -} diff --git a/src/main/java/org/redkale/util/Reproduce.java b/src/main/java/org/redkale/util/Reproduce.java deleted file mode 100644 index 99199f8b8..000000000 --- a/src/main/java/org/redkale/util/Reproduce.java +++ /dev/null @@ -1,141 +0,0 @@ -package org.redkale.util; - -import java.lang.reflect.Modifier; -import java.util.function.Predicate; -import static jdk.internal.org.objectweb.asm.Opcodes.*; -import jdk.internal.org.objectweb.asm.*; - -/** - * - *

- * 详情见: http://www.redkale.org - * - * @author zhangjx - * @param 目标对象的数据类型 - * @param 源对象的数据类型 - */ -public interface Reproduce { - - public D copy(D dest, S src); - - public static Reproduce create(final Class destClass, final Class srcClass) { - return create(destClass, srcClass, null); - } - - @SuppressWarnings("unchecked") - public static Reproduce create(final Class destClass, final Class srcClass, final Predicate columnPredicate) { - // ------------------------------------------------------------------------------ - final String supDynName = Reproduce.class.getName().replace('.', '/'); - final String destName = destClass.getName().replace('.', '/'); - final String srcName = srcClass.getName().replace('.', '/'); - final String destDesc = Type.getDescriptor(destClass); - final String srcDesc = Type.getDescriptor(srcClass); - String newDynName = supDynName + "Dyn_" + destClass.getSimpleName() + "_" + srcClass.getSimpleName(); - ClassLoader loader = Reproduce.class.getClassLoader(); - if (String.class.getClassLoader() != destClass.getClassLoader()) { - loader = destClass.getClassLoader(); - newDynName = destName + "_Dyn" + Reproduce.class.getSimpleName() + "_" + srcClass.getSimpleName(); - } - try { - return (Reproduce) Class.forName(newDynName.replace('/', '.')).newInstance(); - } catch (Exception ex) { - } - // ------------------------------------------------------------------------------ - ClassWriter cw = new ClassWriter(0); - FieldVisitor fv; - MethodVisitor mv; - AnnotationVisitor av0; - - cw.visit(V1_8, ACC_PUBLIC + ACC_FINAL + ACC_SUPER, newDynName, "Ljava/lang/Object;L" + supDynName + "<" + destDesc + srcDesc + ">;", "java/lang/Object", new String[]{supDynName}); - - { // 构造函数 - mv = (cw.visitMethod(ACC_PUBLIC, "", "()V", null, null)); - //mv.setDebug(true); - mv.visitVarInsn(ALOAD, 0); - mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "", "()V", false); - mv.visitInsn(RETURN); - mv.visitMaxs(1, 1); - mv.visitEnd(); - } - { - mv = (cw.visitMethod(ACC_PUBLIC, "copy", "(" + destDesc + srcDesc + ")" + destDesc, null, null)); - //mv.setDebug(true); - - for (java.lang.reflect.Field field : srcClass.getFields()) { - if (Modifier.isStatic(field.getModifiers())) continue; - if (Modifier.isFinal(field.getModifiers())) continue; - if (!Modifier.isPublic(field.getModifiers())) continue; - final String fname = field.getName(); - try { - if (!field.getType().equals(destClass.getField(fname).getType())) continue; - if (!columnPredicate.test(fname)) continue; - } catch (Exception e) { - continue; - } - mv.visitVarInsn(ALOAD, 1); - mv.visitVarInsn(ALOAD, 2); - String td = Type.getDescriptor(field.getType()); - mv.visitFieldInsn(GETFIELD, srcName, fname, td); - mv.visitFieldInsn(PUTFIELD, destName, fname, td); - } - - for (java.lang.reflect.Method getter : srcClass.getMethods()) { - if (Modifier.isStatic(getter.getModifiers())) continue; - if (getter.getParameterTypes().length > 0) continue; //为了兼容android 而不使用 getParameterCount() - if ("getClass".equals(getter.getName())) continue; - if (!getter.getName().startsWith("get") && !getter.getName().startsWith("is")) continue; - java.lang.reflect.Method setter; - boolean is = getter.getName().startsWith("is"); - try { - setter = destClass.getMethod(getter.getName().replaceFirst(is ? "is" : "get", "set"), getter.getReturnType()); - if (columnPredicate != null) { - String col = setter.getName().substring(3); - if (col.length() < 2 || Character.isLowerCase(col.charAt(1))) { - char[] cs = col.toCharArray(); - cs[0] = Character.toLowerCase(cs[0]); - col = new String(cs); - } - if (!columnPredicate.test(col)) continue; - } - } catch (Exception e) { - continue; - } - mv.visitVarInsn(ALOAD, 1); - mv.visitVarInsn(ALOAD, 2); - mv.visitMethodInsn(INVOKEVIRTUAL, srcName, getter.getName(), Type.getMethodDescriptor(getter), false); - mv.visitMethodInsn(INVOKEVIRTUAL, destName, setter.getName(), Type.getMethodDescriptor(setter), false); - } - mv.visitVarInsn(ALOAD, 1); - mv.visitInsn(ARETURN); - mv.visitMaxs(3, 3); - mv.visitEnd(); - } - { - mv = (cw.visitMethod(ACC_PUBLIC + ACC_BRIDGE + ACC_SYNTHETIC, "copy", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", null, null)); - //mv.setDebug(true); - mv.visitVarInsn(ALOAD, 0); - mv.visitVarInsn(ALOAD, 1); - mv.visitTypeInsn(CHECKCAST, destName); - mv.visitVarInsn(ALOAD, 2); - mv.visitTypeInsn(CHECKCAST, srcName); - mv.visitMethodInsn(INVOKEVIRTUAL, newDynName, "copy", "(" + destDesc + srcDesc + ")" + destDesc, false); - mv.visitInsn(ARETURN); - mv.visitMaxs(3, 3); - mv.visitEnd(); - } - cw.visitEnd(); - // ------------------------------------------------------------------------------ - byte[] bytes = cw.toByteArray(); - Class creatorClazz = new ClassLoader(loader) { - public final Class loadClass(String name, byte[] b) { - return defineClass(name, b, 0, b.length); - } - }.loadClass(newDynName.replace('/', '.'), bytes); - try { - return (Reproduce) creatorClazz.newInstance(); - } catch (Exception ex) { - throw new RuntimeException(ex); - } - } - -} diff --git a/src/main/java/org/redkale/util/ResourceFactory.java b/src/main/java/org/redkale/util/ResourceFactory.java deleted file mode 100644 index 3aafaad14..000000000 --- a/src/main/java/org/redkale/util/ResourceFactory.java +++ /dev/null @@ -1,451 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ -package org.redkale.util; - -import java.lang.ref.*; -import java.lang.reflect.*; -import java.util.*; -import java.util.concurrent.*; -import java.util.logging.*; -import java.util.regex.*; -import javax.annotation.*; - -/** - * 如果Resource(name = "$") 表示资源name采用所属对象的name - * - *

- * 详情见: http://www.redkale.org - * - * @author zhangjx - */ -@SuppressWarnings("unchecked") -public final class ResourceFactory { - - public static final String RESOURCE_PARENT_NAME = "$"; - - private static final Logger logger = Logger.getLogger(ResourceFactory.class.getSimpleName()); - - private final ResourceFactory parent; - - private static final ResourceFactory instance = new ResourceFactory(null); - - private final ConcurrentHashMap loadermap = new ConcurrentHashMap(); - - private final ConcurrentHashMap> store = new ConcurrentHashMap(); - - private ResourceFactory(ResourceFactory parent) { - this.parent = parent; - } - - public static ResourceFactory root() { - return instance; - } - - public ResourceFactory createChild() { - return new ResourceFactory(this); - } - - public void release() { - this.store.clear(); - } - - public A register(final Class clazz, final A rs) { - return register(true, clazz, rs); - } - - public A register(final boolean autoSync, final Class clazz, final A rs) { - return register(autoSync, "", clazz, rs); - } - - public A register(final A rs) { - return register(true, rs); - } - - public A register(final boolean autoSync, final A rs) { - if (rs == null) return null; - return (A) register(autoSync, "", rs.getClass(), rs); - } - - public void add(final Type clazz, final ResourceLoader rs) { - if (clazz == null || rs == null) return; - loadermap.put(clazz, rs); - } - - public void register(final String name, final boolean value) { - register(true, name, boolean.class, value); - } - - public void register(final boolean autoSync, final String name, final boolean value) { - register(autoSync, name, boolean.class, value); - } - - public void register(final String name, final byte value) { - register(true, name, byte.class, value); - } - - public void register(final boolean autoSync, final String name, final byte value) { - register(autoSync, name, byte.class, value); - } - - public void register(final String name, final short value) { - register(true, name, short.class, value); - } - - public void register(final boolean autoSync, final String name, final short value) { - register(autoSync, name, short.class, value); - } - - public void register(final String name, final int value) { - register(true, name, int.class, value); - } - - public void register(final boolean autoSync, final String name, final int value) { - register(autoSync, name, int.class, value); - } - - public void register(final String name, final float value) { - register(true, name, float.class, value); - } - - public void register(final boolean autoSync, final String name, final float value) { - register(autoSync, name, float.class, value); - } - - public void register(final String name, final long value) { - register(true, name, long.class, value); - } - - public void register(final boolean autoSync, final String name, final long value) { - register(autoSync, name, long.class, value); - } - - public void register(final String name, final double value) { - register(true, name, double.class, value); - } - - public void register(final boolean autoSync, final String name, final double value) { - register(autoSync, name, double.class, value); - } - - public A register(final String name, final A rs) { - return register(true, name, rs); - } - - public A register(final boolean autoSync, final String name, final A rs) { - final Class claz = rs.getClass(); - ResourceType rtype = claz.getAnnotation(ResourceType.class); - if (rtype == null) { - return (A) register(autoSync, name, claz, rs); - } else { - A old = null; - for (Class cl : rtype.value()) { - A t = (A) register(autoSync, name, cl, rs); - if (t != null) old = t; - } - return old; - } - } - - public A register(final String name, final Class clazz, final A rs) { - return register(true, name, clazz, rs); - } - - public A register(final String name, final Type clazz, final A rs) { - return register(true, name, clazz, rs); - } - - public A register(final boolean autoSync, final String name, final Type clazz, final A rs) { - ConcurrentHashMap map = this.store.get(clazz); - if (map == null) { - ConcurrentHashMap sub = new ConcurrentHashMap(); - sub.put(name, new ResourceEntry(rs)); - store.put(clazz, sub); - return null; - } else { - ResourceEntry re = map.get(name); - if (re == null) { - map.put(name, new ResourceEntry(rs)); - } else { - map.put(name, new ResourceEntry(rs, re.elements, autoSync)); - } - return re == null ? null : (A) re.value; - } - } - - public A find(Class clazz) { - return find("", clazz); - } - - public A find(String name, Type clazz) { - ResourceEntry re = findEntry(name, clazz); - return re == null ? null : (A) re.value; - } - - private ResourceEntry findEntry(String name, Type clazz) { - Map map = this.store.get(clazz); - if (map != null) { - ResourceEntry re = map.get(name); - if (re != null) return re; - } - if (parent != null) return parent.findEntry(name, clazz); - return null; - } - - public List query(Class clazz) { - return query(new ArrayList(), clazz); - } - - public List query(Type clazz) { - return query(new ArrayList(), clazz); - } - - private List query(final List list, Type clazz) { - Map map = this.store.get(clazz); - if (map != null) { - for (ResourceEntry re : map.values()) { - if (re.value != null) list.add((A) re.value); - } - } - if (parent != null) query(list, clazz); - return list; - } - - public A find(String name, Class clazz) { - ResourceEntry re = findEntry(name, clazz); - return re == null ? null : re.value; - } - - private ResourceEntry findEntry(String name, Class clazz) { - Map map = this.store.get(clazz); - if (map != null) { - ResourceEntry rs = map.get(name); - if (rs != null) return rs; - } - if (parent != null) return parent.findEntry(name, clazz); - return null; - } - - public A findChild(final String name, final Class clazz) { - A rs = find(name, clazz); - if (rs != null) return rs; - for (Map.Entry> en : this.store.entrySet()) { //不用forEach为兼容JDK 6 - if (!(en.getKey() instanceof Class)) continue; - if (!clazz.isAssignableFrom((Class) en.getKey())) continue; - ResourceEntry v = en.getValue().get(name); - if (v != null) return (A) v.value; - } - return null; - } - - //Map无法保证ResourceEntry的自动同步, 暂时不提供该功能 - @Deprecated - private Map find(final Pattern reg, Class clazz, A exclude) { - Map result = new LinkedHashMap(); - load(reg, clazz, exclude, result); - return result; - } - - private void load(final Pattern reg, Class clazz, final A exclude, final Map result) { - ConcurrentHashMap map = this.store.get(clazz); - if (map != null) { - for (Map.Entry en : map.entrySet()) { // 不用forEach为兼容JDK 6 - String x = en.getKey(); - ResourceEntry re = en.getValue(); - if (re == null) continue; - Object y = re.value; - if (y != exclude && reg.matcher(x).find() && result.get(x) == null) result.put(x, (A) y); - } - } - if (parent != null) parent.load(reg, clazz, exclude, result); - } - - public boolean inject(final Object src) { - return inject(src, null); - } - - public boolean inject(final Object src, final T attachment) { - return inject(src, attachment, new ArrayList()); - } - - private boolean inject(final Object src, final T attachment, final List list) { - if (src == null) return false; - try { - list.add(src); - Class clazz = src.getClass(); - do { - for (Field field : clazz.getDeclaredFields()) { - if (Modifier.isStatic(field.getModifiers())) continue; - field.setAccessible(true); - final Class classtype = field.getType(); - final Type genctype = field.getGenericType(); - Resource rc = field.getAnnotation(Resource.class); - if (rc == null) { - boolean flag = true; - Object ns = field.get(src); - for (Object o : list) { - if (o == ns) { - flag = false; - break; - } - } - if (ns == null) continue; - if (ns.getClass().isPrimitive() || ns.getClass().isArray() || ns.getClass().getName().startsWith("java")) continue; - if (flag) this.inject(ns, attachment, list); - continue; - } - if (Modifier.isFinal(field.getModifiers())) continue; - String tname = rc.name(); - if (tname.contains(RESOURCE_PARENT_NAME)) { - try { - Resource res = src.getClass().getAnnotation(Resource.class); - if (res == null) { - String srcname = (String) src.getClass().getMethod("name").invoke(src); - tname = tname.replace(RESOURCE_PARENT_NAME, srcname); - } else { - tname = res.name(); - } - } catch (Exception e) { // 获取src中的name()方法的值, 异常则忽略 - logger.log(Level.SEVERE, src.getClass().getName() + " not found @Resource on Class or [public String name()] method", e); - } - } - final String rcname = tname; - ResourceEntry re = findEntry(rcname, genctype); - if (re == null) { -// if (Map.class.isAssignableFrom(classtype)) { -// Map map = find(Pattern.compile(rcname.isEmpty() ? ".*" : rcname), (Class) ((ParameterizedType) field.getGenericType()).getActualTypeArguments()[1], src); -// if (map != null) re = new ResourceEntry(map); -// } else - if (rcname.startsWith("property.")) { - re = findEntry(rcname, String.class); - } else { - re = findEntry(rcname, classtype); - } - } - if (re == null) { - ResourceLoader it = findLoader(field.getGenericType(), field); - if (it != null) { - it.load(this, src, rcname, field, attachment); - re = findEntry(rcname, genctype); - } - } - if (re == null) { - register(rcname, genctype, null); //自动注入null的值 - re = findEntry(rcname, genctype); - } - if (re == null) continue; - re.elements.add(new ResourceElement<>(src, field)); - - Object rs = re.value; - if (rs != null && !rs.getClass().isPrimitive() && classtype.isPrimitive()) { - if (classtype == int.class) { - rs = Integer.decode(rs.toString()); - } else if (classtype == long.class) { - rs = Long.decode(rs.toString()); - } else if (classtype == short.class) { - rs = Short.decode(rs.toString()); - } else if (classtype == boolean.class) { - rs = "true".equalsIgnoreCase(rs.toString()); - } else if (classtype == byte.class) { - rs = Byte.decode(rs.toString()); - } else if (classtype == float.class) { - rs = Float.parseFloat(rs.toString()); - } else if (classtype == double.class) { - rs = Double.parseDouble(rs.toString()); - } - } - if (rs != null) field.set(src, rs); - } - } while ((clazz = clazz.getSuperclass()) != Object.class); - return true; - } catch (Exception ex) { - logger.log(Level.SEVERE, "inject " + src + " error", ex); - return false; - } - } - - private ResourceLoader findLoader(Type ft, Field field) { - ResourceLoader it = this.loadermap.get(ft); - if (it != null) return it; - Class c = field.getType(); - for (Map.Entry en : this.loadermap.entrySet()) { - Type t = en.getKey(); - if (t == ft) return en.getValue(); - if (t instanceof Class && (((Class) t)).isAssignableFrom(c)) return en.getValue(); - } - return parent == null ? null : parent.findLoader(ft, field); - } - - private static class ResourceEntry { - - public final T value; - - public final List elements; - - public ResourceEntry(T value) { - this.value = value; - this.elements = new CopyOnWriteArrayList<>(); - } - - public ResourceEntry(T value, final List elements, boolean sync) { - this.value = value; - this.elements = elements == null ? new CopyOnWriteArrayList<>() : elements; - if (sync && elements != null && !elements.isEmpty()) { - - for (ResourceElement element : elements) { - Object dest = element.dest.get(); - if (dest == null) continue; - Object rs = value; - final Class classtype = element.fieldType; - if (rs != null && !rs.getClass().isPrimitive() && classtype.isPrimitive()) { - if (classtype == int.class) { - rs = Integer.decode(rs.toString()); - } else if (classtype == long.class) { - rs = Long.decode(rs.toString()); - } else if (classtype == short.class) { - rs = Short.decode(rs.toString()); - } else if (classtype == boolean.class) { - rs = "true".equalsIgnoreCase(rs.toString()); - } else if (classtype == byte.class) { - rs = Byte.decode(rs.toString()); - } else if (classtype == float.class) { - rs = Float.parseFloat(rs.toString()); - } else if (classtype == double.class) { - rs = Double.parseDouble(rs.toString()); - } - } - if (rs == null && classtype.isPrimitive()) rs = Array.get(Array.newInstance(classtype, 1), 0); - try { - element.field.set(dest, rs); - } catch (Exception e) { - e.printStackTrace(); - } - } - } - } - } - - private static class ResourceElement { - - public final WeakReference dest; - - public final Field field; - - public final Class fieldType; - - public ResourceElement(T dest, Field field) { - this.dest = new WeakReference(dest); - this.field = field; - this.fieldType = field.getType(); - } - } - - @FunctionalInterface - public static interface ResourceLoader { - - public void load(ResourceFactory factory, Object src, String resourceName, Field field, Object attachment); - } - -} diff --git a/src/main/java/org/redkale/util/ResourceType.java b/src/main/java/org/redkale/util/ResourceType.java deleted file mode 100644 index 3cb19031c..000000000 --- a/src/main/java/org/redkale/util/ResourceType.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ -package org.redkale.util; - -import java.lang.annotation.*; -import static java.lang.annotation.ElementType.TYPE; -import static java.lang.annotation.RetentionPolicy.RUNTIME; - -/** - * 显式的指明资源类型 - *

- * 详情见: http://www.redkale.org - * - * @author zhangjx - */ -@Inherited -@Documented -@Target({TYPE}) -@Retention(RUNTIME) -public @interface ResourceType { - - Class[] value(); -} diff --git a/src/main/java/org/redkale/util/SelectColumn.java b/src/main/java/org/redkale/util/SelectColumn.java deleted file mode 100644 index a1bbfaa77..000000000 --- a/src/main/java/org/redkale/util/SelectColumn.java +++ /dev/null @@ -1,139 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ -package org.redkale.util; - -import java.util.*; -import java.util.function.*; -import java.util.regex.*; - -/** - * - *

- * 详情见: http://www.redkale.org - * - * @author zhangjx - */ -public class SelectColumn implements Predicate { - - private Pattern[] patterns; - - private String[] columns; - - private boolean excludable; //是否排除 - - public SelectColumn() { - } - - protected SelectColumn(final String[] columns0, final boolean excludable) { - this.excludable = excludable; - final int len = columns0.length; - if (len < 1) return; - Pattern[] regs = null; - String[] cols = null; - int regcount = 0; - int colcount = 0; - for (String col : columns0) { - boolean reg = false; - for (int i = 0; i < col.length(); i++) { - char ch = col.charAt(i); - if (ch == '^' || ch == '$' || ch == '*' || ch == '?' || ch == '+' || ch == '[' || ch == '(') { - reg = true; - break; - } - } - if (reg) { - if (regs == null) regs = new Pattern[len]; - regs[regcount++] = Pattern.compile(col); - } else { - if (cols == null) cols = new String[len]; - cols[colcount++] = col; - } - } - if (regs != null) { - if (regcount == len) { - this.patterns = regs; - } else { - this.patterns = Arrays.copyOf(regs, regcount); - } - } - if (cols != null) { - if (colcount == len) { - this.columns = cols; - } else { - this.columns = Arrays.copyOf(cols, colcount); - } - } - } - - /** - * class中的字段名 - * - * @param columns 包含的字段名集合 - * @return SelectColumn - */ - public static SelectColumn createIncludes(String... columns) { - return new SelectColumn(columns, false); - } - - /** - * class中的字段名 - * - * @param columns 排除的字段名集合 - * @return SelectColumn - */ - public static SelectColumn createExcludes(String... columns) { - return new SelectColumn(columns, true); - } - - @Override - public boolean test(final String column) { - if (this.columns != null) { - for (String col : this.columns) { - if (col.equalsIgnoreCase(column)) return !excludable; - } - } - if (this.patterns != null) { - for (Pattern reg : this.patterns) { - if (reg.matcher(column).find()) return !excludable; - } - } - return excludable; - } - - public String[] getColumns() { - return columns; - } - - public void setColumns(String[] columns) { - this.columns = columns; - } - - public boolean isExcludable() { - return excludable; - } - - public void setExcludable(boolean excludable) { - this.excludable = excludable; - } - - public Pattern[] getPatterns() { - return patterns; - } - - public void setPatterns(Pattern[] patterns) { - this.patterns = patterns; - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append(getClass().getSimpleName()).append("{excludable=").append(excludable); - if (columns != null) sb.append(", columns=").append(Arrays.toString(columns)); - if (patterns != null) sb.append(", patterns=").append(Arrays.toString(patterns)); - return sb.append('}').toString(); - } - -} diff --git a/src/main/java/org/redkale/util/Sheet.java b/src/main/java/org/redkale/util/Sheet.java deleted file mode 100644 index 51319510e..000000000 --- a/src/main/java/org/redkale/util/Sheet.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ -package org.redkale.util; - -import java.util.*; - -/** - * 页集合。 结构由一个total总数和一个List列表组合而成。 - * - *

- * 详情见: http://www.redkale.org - * - * @author zhangjx - * @param 集合元素的数据类型 - */ -@SuppressWarnings("unchecked") -public class Sheet implements java.io.Serializable { - - private long total = -1; - - private Collection rows; - - public Sheet() { - super(); - } - - public Sheet(int total, Collection data) { - this((long) total, data); - } - - public Sheet(long total, Collection data) { - this.total = total; - this.rows = (Collection) data; - } - - public static Sheet asSheet(Collection data) { - return data == null ? new Sheet() : new Sheet(data.size(), data); - } - - public Sheet copyTo(Sheet copy) { - if (copy == null) return copy; - copy.total = this.total; - if (this.getRows() != null) { - copy.setRows(new ArrayList(this.getRows())); - } else { - copy.rows = null; - } - return copy; - } - - /** - * 判断数据列表是否为空 - * - * @return 是否为空 - */ - public boolean isEmpty() { - return this.rows == null || this.rows.isEmpty(); - } - - @Override - public String toString() { - return "Sheet[total=" + this.total + ", rows=" + this.rows + "]"; - } - - public long getTotal() { - return this.total; - } - - public void setTotal(long total) { - this.total = total; - } - - public Collection getRows() { - return this.rows; - } - - public List list() { - return list(false); - } - - public List list(boolean created) { - if (this.rows == null) return created ? new ArrayList() : null; - return (this.rows instanceof List) ? (List) this.rows : new ArrayList(this.rows); - } - - public void setRows(Collection data) { - this.rows = (Collection) data; - } -} diff --git a/src/main/java/org/redkale/util/TypeToken.java b/src/main/java/org/redkale/util/TypeToken.java deleted file mode 100644 index 1d5f5c806..000000000 --- a/src/main/java/org/redkale/util/TypeToken.java +++ /dev/null @@ -1,192 +0,0 @@ -/* - * To change this template, choose Tools | Templates - * and open the template in the editor. - */ -package org.redkale.util; - -import java.lang.reflect.Type; -import java.lang.reflect.*; -import java.util.*; -import jdk.internal.org.objectweb.asm.*; -import static jdk.internal.org.objectweb.asm.Opcodes.*; - -/** - * - * 获取泛型的Type类 - * - *

- * 详情见: http://www.redkale.org - * - * @author zhangjx - * @param 泛型 - */ -public abstract class TypeToken { - - private final Type type; - - public TypeToken() { - type = ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0]; - } - - public final Type getType() { - return type; - } - - /** - * 判断Type是否能确定最终的class, 是则返回true,存在通配符或者不确定类型则返回false。 - * 例如: Map< String, String > 返回 ture; Map< ? extends Serializable, String > 返回false; - * - * @param type Type对象 - * @return 是否可反解析 - */ - public final static boolean isClassType(final Type type) { - if (type instanceof Class) return true; - if (type instanceof WildcardType) return false; - if (type instanceof TypeVariable) return false; - if (type instanceof GenericArrayType) return isClassType(((GenericArrayType) type).getGenericComponentType()); - if (!(type instanceof ParameterizedType)) return false; //只能是null了 - final ParameterizedType ptype = (ParameterizedType) type; - if (ptype.getOwnerType() != null && !isClassType(ptype.getOwnerType())) return false; - if (!isClassType(ptype.getRawType())) return false; - for (Type t : ptype.getActualTypeArguments()) { - if (!isClassType(t)) return false; - } - return true; - } - - /** - * 动态创建 ParameterizedType - * - * @param ownerType0 ParameterizedType 的 ownerType - * @param rawType0 ParameterizedType 的 rawType - * @param actualTypeArguments0 ParameterizedType 的 actualTypeArguments - * @return Type - */ - public static Type createParameterizedType(final Type ownerType0, final Type rawType0, final Type... actualTypeArguments0) { - if (ownerType0 == null && rawType0 instanceof Class) { - int count = 0; - for (Type t : actualTypeArguments0) { - if (isClassType(t)) count++; - } - if (count == actualTypeArguments0.length) return createParameterizedType((Class) rawType0, actualTypeArguments0); - } - return new ParameterizedType() { - private final Class rawType = (Class) rawType0; - - private final Type ownerType = ownerType0; - - private final Type[] actualTypeArguments = actualTypeArguments0; - - @Override - public Type[] getActualTypeArguments() { - return actualTypeArguments.clone(); - } - - @Override - public Type getRawType() { - return rawType; - } - - @Override - public Type getOwnerType() { - return ownerType; - } - - @Override - public int hashCode() { - return Arrays.hashCode(actualTypeArguments) ^ Objects.hashCode(rawType) ^ Objects.hashCode(ownerType); - } - - @Override - public boolean equals(Object o) { - if (!(o instanceof ParameterizedType)) return false; - final ParameterizedType that = (ParameterizedType) o; - if (this == that) return true; - return Objects.equals(ownerType, that.getOwnerType()) - && Objects.equals(rawType, that.getRawType()) - && Arrays.equals(actualTypeArguments, that.getActualTypeArguments()); - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - if (ownerType != null) sb.append((ownerType instanceof Class) ? (((Class) ownerType).getName()) : ownerType.toString()).append("."); - sb.append(rawType.getName()); - - if (actualTypeArguments != null && actualTypeArguments.length > 0) { - sb.append("<"); - boolean first = true; - for (Type t : actualTypeArguments) { - if (!first) sb.append(", "); - sb.append(t); - first = false; - } - sb.append(">"); - } - return sb.toString(); - } - }; - } - - private static Type createParameterizedType(final Class rawType, final Type... actualTypeArguments) { - ClassLoader loader = TypeToken.class.getClassLoader(); - String newDynName = TypeToken.class.getName().replace('.', '/') + "_Dyn" + System.currentTimeMillis(); - for (;;) { - try { - Class.forName(newDynName.replace('/', '.')); - newDynName = TypeToken.class.getName().replace('.', '/') + "_Dyn" + Math.abs(System.nanoTime()); - } catch (Exception ex) { //异常说明类不存在 - break; - } - } - ClassWriter cw = new ClassWriter(0); - FieldVisitor fv; - MethodVisitor mv; - cw.visit(V1_8, ACC_PUBLIC + ACC_FINAL + ACC_SUPER, newDynName, null, "java/lang/Object", null); - String rawTypeDesc = jdk.internal.org.objectweb.asm.Type.getDescriptor(rawType); - StringBuilder sb = new StringBuilder(); - sb.append(rawTypeDesc.substring(0, rawTypeDesc.length() - 1)).append('<'); - for (Type c : actualTypeArguments) { - sb.append(getClassTypeDescriptor(c)); - } - sb.append(">;"); - { - fv = cw.visitField(ACC_PUBLIC, "field", rawTypeDesc, sb.toString(), null); - fv.visitEnd(); - } - {//构造方法 - mv = cw.visitMethod(ACC_PUBLIC, "", "()V", null, null); - mv.visitVarInsn(ALOAD, 0); - mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "", "()V", false); - mv.visitInsn(RETURN); - mv.visitMaxs(1, 1); - mv.visitEnd(); - } - cw.visitEnd(); - byte[] bytes = cw.toByteArray(); - Class newClazz = new ClassLoader(loader) { - public final Class loadClass(String name, byte[] b) { - return defineClass(name, b, 0, b.length); - } - }.loadClass(newDynName.replace('/', '.'), bytes); - try { - return newClazz.getField("field").getGenericType(); - } catch (Exception ex) { - throw new RuntimeException(ex); - } - } - - private static CharSequence getClassTypeDescriptor(Type type) { - if (!isClassType(type)) throw new IllegalArgumentException(type + " not a class type"); - if (type instanceof Class) return jdk.internal.org.objectweb.asm.Type.getDescriptor((Class) type); - final ParameterizedType pt = (ParameterizedType) type; - CharSequence rawTypeDesc = getClassTypeDescriptor(pt.getRawType()); - StringBuilder sb = new StringBuilder(); - sb.append(rawTypeDesc.subSequence(0, rawTypeDesc.length() - 1)).append('<'); - for (Type c : pt.getActualTypeArguments()) { - sb.append(getClassTypeDescriptor(c)); - } - sb.append(">;"); - return sb; - } -} diff --git a/src/main/java/org/redkale/util/Utility.java b/src/main/java/org/redkale/util/Utility.java deleted file mode 100644 index 304c9a251..000000000 --- a/src/main/java/org/redkale/util/Utility.java +++ /dev/null @@ -1,578 +0,0 @@ -/* - * To change this template, choose Tools | Templates - * and open the template in the editor. - */ -package org.redkale.util; - -import java.io.*; -import java.lang.reflect.Field; -import java.net.*; -import java.nio.ByteBuffer; -import java.nio.charset.*; -import java.time.*; -import java.util.*; -import javax.net.ssl.*; - -/** - * - *

- * 详情见: http://www.redkale.org - * - * @author zhangjx - */ -public final class Utility { - - private static final int zoneRawOffset = TimeZone.getDefault().getRawOffset(); - - private static final String format = "%1$tY-%1$tm-%1$td %1$tH:%1$tM:%1$tS.%tL"; - - private static final Charset UTF_8 = Charset.forName("UTF-8"); - - private static final char hex[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'}; - - private static final sun.misc.Unsafe UNSAFE; - - private static final long strvaloffset; - - private static final long sbvaloffset; - - private static final javax.net.ssl.SSLContext DEFAULTSSL_CONTEXT; - - static { - sun.misc.Unsafe usafe = null; - long fd1 = 0L; - long fd2 = 0L; - try { - Field f = String.class.getDeclaredField("value"); - if (f.getType() == char[].class) { //JDK9及以上不再是char[] - Field safeField = sun.misc.Unsafe.class.getDeclaredField("theUnsafe"); - safeField.setAccessible(true); - usafe = (sun.misc.Unsafe) safeField.get(null); - fd1 = usafe.objectFieldOffset(f); - fd2 = usafe.objectFieldOffset(StringBuilder.class.getSuperclass().getDeclaredField("value")); - } - } catch (Exception e) { - throw new RuntimeException(e); //不可能会发生 - } - UNSAFE = usafe; - strvaloffset = fd1; - sbvaloffset = fd2; - - try { - DEFAULTSSL_CONTEXT = javax.net.ssl.SSLContext.getInstance("SSL"); - DEFAULTSSL_CONTEXT.init(null, new javax.net.ssl.TrustManager[]{new javax.net.ssl.X509TrustManager() { - @Override - public java.security.cert.X509Certificate[] getAcceptedIssuers() { - return null; - } - - @Override - public void checkServerTrusted(java.security.cert.X509Certificate[] certs, String authType) throws java.security.cert.CertificateException { - } - - @Override - public void checkClientTrusted(java.security.cert.X509Certificate[] certs, String authType) throws java.security.cert.CertificateException { - } - }}, null); - } catch (Exception e) { - throw new RuntimeException(e); //不可能会发生 - } - } - - private Utility() { - } - - public static String now() { - return String.format(format, System.currentTimeMillis()); - } - - public static void println(String string, ByteBuffer buffer) { - if (buffer == null || !buffer.hasRemaining()) return; - byte[] bytes = new byte[buffer.remaining()]; - buffer.get(bytes); - buffer.flip(); - println(string, bytes); - } - - public static void println(String string, byte... bytes) { - if (bytes == null) return; - StringBuilder sb = new StringBuilder(); - if (string != null) sb.append(string); - sb.append(bytes.length).append(".["); - boolean last = false; - for (byte b : bytes) { - if (last) sb.append(','); - int v = b & 0xff; - if (v < 16) sb.append('0'); - sb.append(Integer.toHexString(v)); - last = true; - } - sb.append(']'); - (System.out).println(sb); - } - - /** - * 返回本机的第一个内网IPv4地址, 没有则返回null - * - * @return IPv4地址 - */ - public static InetAddress localInetAddress() { - InetAddress back = null; - try { - Enumeration nifs = NetworkInterface.getNetworkInterfaces(); - while (nifs.hasMoreElements()) { - NetworkInterface nif = nifs.nextElement(); - if (!nif.isUp()) continue; - Enumeration eis = nif.getInetAddresses(); - while (eis.hasMoreElements()) { - InetAddress ia = eis.nextElement(); - if (ia.isLoopbackAddress()) back = ia; - if (ia.isSiteLocalAddress()) return ia; - } - } - } catch (Exception e) { - e.printStackTrace(); - } - return back; - } - - /** - * 获取当天凌晨零点的格林时间 - * - * @return 毫秒数 - */ - public static long midnight() { - return midnight(System.currentTimeMillis()); - } - - /** - * 获取指定时间当天凌晨零点的格林时间 - * - * @param time 指定时间 - * @return 毫秒数 - */ - public static long midnight(long time) { - return (time + zoneRawOffset) / 86400000 * 86400000 - zoneRawOffset; - } - - /** - * 获取当天20151231格式的int值 - * - * @return 20151231格式的int值 - */ - public static int today() { - java.time.LocalDate today = java.time.LocalDate.now(); - return today.getYear() * 10000 + today.getMonthValue() * 100 + today.getDayOfMonth(); - } - - /** - * 获取时间点所在星期的周一 - * - * @param time 指定时间 - * @return 毫秒数 - */ - public static long monday(long time) { - ZoneId zid = ZoneId.systemDefault(); - Instant instant = Instant.ofEpochMilli(time); - LocalDate ld = instant.atZone(zid).toLocalDate(); - ld = ld.minusDays(ld.getDayOfWeek().getValue() - 1); - return ld.atStartOfDay(zid).toInstant().toEpochMilli(); - } - - /** - * 获取时间点所在星期的周日 - * - * @param time 指定时间 - * @return 毫秒数 - */ - public static long sunday(long time) { - ZoneId zid = ZoneId.systemDefault(); - Instant instant = Instant.ofEpochMilli(time); - LocalDate ld = instant.atZone(zid).toLocalDate(); - ld = ld.plusDays(7 - ld.getDayOfWeek().getValue()); - return ld.atStartOfDay(zid).toInstant().toEpochMilli(); - } - - /** - * 获取时间点所在月份的1号 - * - * @param time 指定时间 - * @return 毫秒数 - */ - public static long monthFirstDay(long time) { - ZoneId zid = ZoneId.systemDefault(); - Instant instant = Instant.ofEpochMilli(time); - LocalDate ld = instant.atZone(zid).toLocalDate().withDayOfMonth(1); - return ld.atStartOfDay(zid).toInstant().toEpochMilli(); - } - - public static String binToHexString(byte[] bytes) { - return new String(binToHex(bytes)); - } - - public static char[] binToHex(byte[] bytes) { - return binToHex(bytes, 0, bytes.length); - } - - public static String binToHexString(byte[] bytes, int offset, int len) { - return new String(binToHex(bytes, offset, len)); - } - - public static char[] binToHex(byte[] bytes, int offset, int len) { - final char[] sb = new char[len * 2]; - final int end = offset + len; - int index = 0; - final char[] hexs = hex; - for (int i = offset; i < end; i++) { - byte b = bytes[i]; - sb[index++] = (hexs[((b >> 4) & 0xF)]); - sb[index++] = hexs[((b) & 0xF)]; - } - return sb; - } - - public static byte[] hexToBin(CharSequence src) { - return hexToBin(src, 0, src.length()); - } - - public static byte[] hexToBin(CharSequence src, int offset, int len) { - final int size = (len + 1) / 2; - final byte[] bytes = new byte[size]; - final int end = offset + len; - String digits = "0123456789abcdef"; - for (int i = 0; i < size; i++) { - int ch1 = src.charAt(offset + i * 2); - if ('A' <= ch1 && 'F' >= ch1) ch1 = ch1 - 'A' + 'a'; - int ch2 = src.charAt(offset + i * 2 + 1); - if ('A' <= ch2 && 'F' >= ch2) ch2 = ch2 - 'A' + 'a'; - int pos1 = digits.indexOf(ch1); - if (pos1 < 0) throw new NumberFormatException(); - int pos2 = digits.indexOf(ch2); - if (pos2 < 0) throw new NumberFormatException(); - bytes[i] = (byte) (pos1 * 0x10 + pos2); - } - return bytes; - } - - public static byte[] hexToBin(String str) { - return hexToBin(charArray(str)); - } - - public static byte[] hexToBin(char[] src) { - return hexToBin(src, 0, src.length); - } - - public static byte[] hexToBin(char[] src, int offset, int len) { - final int size = (len + 1) / 2; - final byte[] bytes = new byte[size]; - final int end = offset + len; - String digits = "0123456789abcdef"; - for (int i = 0; i < size; i++) { - int ch1 = src[offset + i * 2]; - if ('A' <= ch1 && 'F' >= ch1) ch1 = ch1 - 'A' + 'a'; - int ch2 = src[offset + i * 2 + 1]; - if ('A' <= ch2 && 'F' >= ch2) ch2 = ch2 - 'A' + 'a'; - int pos1 = digits.indexOf(ch1); - if (pos1 < 0) throw new NumberFormatException(); - int pos2 = digits.indexOf(ch2); - if (pos2 < 0) throw new NumberFormatException(); - bytes[i] = (byte) (pos1 * 0x10 + pos2); - } - return bytes; - } - - //----------------------------------------------------------------------------- - public static char[] decodeUTF8(final byte[] array) { - return decodeUTF8(array, 0, array.length); - } - - public static char[] decodeUTF8(final byte[] array, final int start, final int len) { - byte b; - int size = len; - final byte[] bytes = array; - final int limit = start + len; - for (int i = start; i < limit; i++) { - b = bytes[i]; - if ((b >> 5) == -2) { - size--; - } else if ((b >> 4) == -2) { - size -= 2; - } - } - final char[] text = new char[size]; - size = 0; - for (int i = start; i < limit;) { - b = bytes[i++]; - if (b >= 0) { - text[size++] = (char) b; - } else if ((b >> 5) == -2) { - text[size++] = (char) (((b << 6) ^ bytes[i++]) ^ (((byte) 0xC0 << 6) ^ ((byte) 0x80))); - } else if ((b >> 4) == -2) { - text[size++] = (char) ((b << 12) ^ (bytes[i++] << 6) ^ (bytes[i++] ^ (((byte) 0xE0 << 12) ^ ((byte) 0x80 << 6) ^ ((byte) 0x80)))); - } - } - return text; - } - - public static byte[] encodeUTF8(final String value) { - if (value == null) return new byte[0]; - if (UNSAFE == null) return encodeUTF8(value.toCharArray()); - return encodeUTF8((char[]) UNSAFE.getObject(value, strvaloffset)); - } - - public static byte[] encodeUTF8(final char[] array) { - return encodeUTF8(array, 0, array.length); - } - - public static byte[] encodeUTF8(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]; - if (c < 0x80) { - size++; - } else if (c < 0x800) { - size += 2; - } else { - size += 3; - } - } - final byte[] bytes = new byte[size]; - size = 0; - for (int i = start; i < limit; i++) { - c = chars[i]; - if (c < 0x80) { - bytes[size++] = (byte) c; - } else if (c < 0x800) { - bytes[size++] = (byte) (0xc0 | (c >> 6)); - bytes[size++] = (byte) (0x80 | (c & 0x3f)); - } else { - bytes[size++] = (byte) (0xe0 | ((c >> 12))); - bytes[size++] = (byte) (0x80 | ((c >> 6) & 0x3f)); - bytes[size++] = (byte) (0x80 | (c & 0x3f)); - } - } - return bytes; - } - - public static char[] charArray(String value) { - if (value == null) return null; - if (UNSAFE == null) return value.toCharArray(); - return (char[]) UNSAFE.getObject(value, strvaloffset); - } - - public static char[] charArray(StringBuilder value) { - if (value == null) return null; - if (UNSAFE == null) return value.toString().toCharArray(); - return (char[]) UNSAFE.getObject(value, sbvaloffset); - } - - public static ByteBuffer encodeUTF8(final ByteBuffer buffer, final char[] array) { - return encodeUTF8(buffer, array, 0, array.length); - } - - public static ByteBuffer encodeUTF8(final ByteBuffer buffer, int bytesLength, final char[] array) { - return encodeUTF8(buffer, bytesLength, array, 0, array.length); - } - - public static int encodeUTF8Length(String value) { - if (value == null) return -1; - if (UNSAFE == null) return encodeUTF8Length(value.toCharArray()); - return encodeUTF8Length((char[]) UNSAFE.getObject(value, strvaloffset)); - } - - public static int encodeUTF8Length(final char[] text) { - return encodeUTF8Length(text, 0, text.length); - } - - public 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; - } - - /** - * 将两个数字组装成一个long - * - * @param high 高位值 - * @param low 低位值 - * @return long值 - */ - public static long merge(int high, int low) { - return (0L + high) << 32 | low; - } - - public static ByteBuffer encodeUTF8(final ByteBuffer buffer, final char[] text, final int start, final int len) { - return encodeUTF8(buffer, encodeUTF8Length(text, start, len), text, start, len); - } - - public static ByteBuffer encodeUTF8(final ByteBuffer buffer, int bytesLength, final char[] text, final int start, final int len) { - char c; - char[] chars = text; - final int limit = start + len; - int remain = buffer.remaining(); - final ByteBuffer buffer2 = remain >= bytesLength ? null : ByteBuffer.allocate(bytesLength - remain + 3); //最差情况buffer最后两byte没有填充 - ByteBuffer buf = buffer; - for (int i = start; i < limit; i++) { - c = chars[i]; - if (c < 0x80) { - if (buf.remaining() < 1) buf = buffer2; - buf.put((byte) c); - } else if (c < 0x800) { - if (buf.remaining() < 2) buf = buffer2; - buf.put((byte) (0xc0 | (c >> 6))); - buf.put((byte) (0x80 | (c & 0x3f))); - } else { - if (buf.remaining() < 3) buf = buffer2; - buf.put((byte) (0xe0 | ((c >> 12)))); - buf.put((byte) (0x80 | ((c >> 6) & 0x3f))); - buf.put((byte) (0x80 | (c & 0x3f))); - } - } - if (buffer2 != null) buffer2.flip(); - return buffer2; - } - - //----------------------------------------------------------------------------- - public static javax.net.ssl.SSLContext getDefaultSSLContext() { - return DEFAULTSSL_CONTEXT; - } - - public static Socket createDefaultSSLSocket(InetSocketAddress address) throws IOException { - return createDefaultSSLSocket(address.getAddress(), address.getPort()); - } - - public static Socket createDefaultSSLSocket(InetAddress host, int port) throws IOException { - Socket socket = DEFAULTSSL_CONTEXT.getSocketFactory().createSocket(host, port); - - return socket; - } - - public static String postHttpContent(String url) throws IOException { - return remoteHttpContent(null, "POST", url, null, null).toString("UTF-8"); - } - - public static String postHttpContent(String url, String body) throws IOException { - return remoteHttpContent(null, "POST", url, null, body).toString("UTF-8"); - } - - public static String postHttpContent(String url, Map headers, String body) throws IOException { - return remoteHttpContent(null, "POST", url, headers, body).toString("UTF-8"); - } - - public static String postHttpContent(SSLContext ctx, String url) throws IOException { - return remoteHttpContent(ctx, "POST", url, null, null).toString("UTF-8"); - } - - public static String postHttpContent(SSLContext ctx, String url, String body) throws IOException { - return remoteHttpContent(ctx, "POST", url, null, body).toString("UTF-8"); - } - - public static String postHttpContent(SSLContext ctx, String url, Map headers, String body) throws IOException { - return remoteHttpContent(ctx, "POST", url, headers, body).toString("UTF-8"); - } - - public static byte[] postHttpBytesContent(String url) throws IOException { - return remoteHttpContent(null, "POST", url, null, null).toByteArray(); - } - - public static byte[] postHttpBytesContent(SSLContext ctx, String url) throws IOException { - return remoteHttpContent(ctx, "POST", url, null, null).toByteArray(); - } - - public static byte[] postHttpBytesContent(String url, Map headers, String body) throws IOException { - return remoteHttpContent(null, "POST", url, headers, body).toByteArray(); - } - - public static byte[] postHttpBytesContent(SSLContext ctx, String url, Map headers, String body) throws IOException { - return remoteHttpContent(ctx, "POST", url, headers, body).toByteArray(); - } - - public static String getHttpContent(String url) throws IOException { - return remoteHttpContent(null, "GET", url, null, null).toString("UTF-8"); - } - - public static String getHttpContent(SSLContext ctx, String url) throws IOException { - return remoteHttpContent(ctx, "GET", url, null, null).toString("UTF-8"); - } - - public static String getHttpContent(SSLContext ctx, String url, Map headers, String body) throws IOException { - return remoteHttpContent(ctx, "GET", url, headers, body).toString("UTF-8"); - } - - public static String getHttpContent(String url, Map headers, String body) throws IOException { - return remoteHttpContent(null, "GET", url, headers, body).toString("UTF-8"); - } - - public static byte[] getHttpBytesContent(String url) throws IOException { - return remoteHttpContent(null, "GET", url, null, null).toByteArray(); - } - - public static byte[] getHttpBytesContent(SSLContext ctx, String url) throws IOException { - return remoteHttpContent(ctx, "GET", url, null, null).toByteArray(); - } - - public static byte[] getHttpBytesContent(String url, Map headers, String body) throws IOException { - return remoteHttpContent(null, "GET", url, headers, body).toByteArray(); - } - - public static byte[] getHttpBytesContent(SSLContext ctx, String url, Map headers, String body) throws IOException { - return remoteHttpContent(ctx, "GET", url, headers, body).toByteArray(); - } - - protected static ByteArrayOutputStream remoteHttpContent(SSLContext ctx, String method, String url, Map headers, String body) throws IOException { - HttpURLConnection conn = (HttpURLConnection) new URL(url).openConnection(); - conn.setConnectTimeout(3000); - conn.setReadTimeout(3000); - if (conn instanceof HttpsURLConnection) ((HttpsURLConnection) conn).setSSLSocketFactory((ctx == null ? DEFAULTSSL_CONTEXT : ctx).getSocketFactory()); - conn.setRequestMethod(method); - if (headers != null) { - for (Map.Entry en : headers.entrySet()) { //不用forEach是为了兼容JDK 6 - conn.setRequestProperty(en.getKey(), en.getValue()); - } - } - if (body != null) { - conn.setDoInput(true); - conn.setDoOutput(true); - conn.getOutputStream().write(body.getBytes(UTF_8)); - } - conn.connect(); - int rs = conn.getResponseCode(); - if (rs == 301 || rs == 302) { - String newurl = conn.getHeaderField("Location"); - conn.disconnect(); - return remoteHttpContent(ctx, method, newurl, headers, body); - } - InputStream in = conn.getInputStream(); - ByteArrayOutputStream out = new ByteArrayOutputStream(1024); - byte[] bytes = new byte[1024]; - int pos; - while ((pos = in.read(bytes)) != -1) { - out.write(bytes, 0, pos); - } - conn.disconnect(); - return out; - } - - public static String read(InputStream in) throws IOException { - return read(in, "UTF-8"); - } - - public static String read(InputStream in, String charsetName) throws IOException { - ByteArrayOutputStream out = new ByteArrayOutputStream(1024); - byte[] bytes = new byte[1024]; - int pos; - while ((pos = in.read(bytes)) != -1) { - out.write(bytes, 0, pos); - } - return charsetName == null ? out.toString() : out.toString(charsetName); - } -} diff --git a/src/main/java/org/redkale/util/package-info.java b/src/main/java/org/redkale/util/package-info.java deleted file mode 100644 index 27728cf6c..000000000 --- a/src/main/java/org/redkale/util/package-info.java +++ /dev/null @@ -1,4 +0,0 @@ -/** - * RedKale工具包 - */ -package org.redkale.util; diff --git a/src/main/java/org/redkale/watch/WatchFactory.java b/src/main/java/org/redkale/watch/WatchFactory.java deleted file mode 100644 index 6d491636e..000000000 --- a/src/main/java/org/redkale/watch/WatchFactory.java +++ /dev/null @@ -1,100 +0,0 @@ -/* - * 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.watch; - -import java.lang.ref.WeakReference; -import java.lang.reflect.*; -import java.util.*; -import java.util.concurrent.CopyOnWriteArrayList; -import java.util.function.LongSupplier; - -/** - * - *

详情见: http://www.redkale.org - * @author zhangjx - */ -public final class WatchFactory { - - private static final WatchFactory instance = new WatchFactory(null); - - private final List> beans = new CopyOnWriteArrayList<>(); - - private final WatchFactory parent; - - private WatchFactory(WatchFactory parent) { - this.parent = parent; - } - - public void register(WatchNode bean) { - if (bean != null) beans.add(new WeakReference<>(bean)); - } - - public static WatchFactory root() { - return instance; - } - - public WatchFactory createChild() { - return new WatchFactory(this); - } - - public WatchNumber createWatchNumber(String name) { - return createWatchNumber(name, "", false, 0); - } - - public WatchNumber createWatchNumber(String name, boolean interval) { - return createWatchNumber(name, "", interval, 0); - } - - public WatchNumber createWatchNumber(String name, String description) { - return createWatchNumber(name, description, false, 0); - } - - public WatchNumber createWatchNumber(String name, String description, long v) { - return createWatchNumber(name, description, false, 0); - } - - public WatchNumber createWatchNumber(String name, String description, boolean interval) { - return createWatchNumber(name, description, interval, 0); - } - - public WatchNumber createWatchNumber(String name, String description, boolean interval, long v) { - WatchNumber bean = new WatchNumber(name, description, interval, v); - register(bean); - return bean; - } - - public void register(String name, LongSupplier supplier) { - register(name, "", supplier); - } - - public void register(String name, String description, LongSupplier supplier) { - register(new WatchSupplier(name, description, supplier)); - } - - public boolean inject(final Object src) { - return inject(src, new ArrayList<>()); - } - - private boolean inject(final Object src, final List list) { - if (src == null) return false; - try { - list.add(src); - Class clazz = src.getClass(); - do { - for (Field field : clazz.getDeclaredFields()) { - if (Modifier.isFinal(field.getModifiers())) continue; - field.setAccessible(true); - final Class type = field.getType(); - Watchable wo = field.getAnnotation(Watchable.class); - - } - } while ((clazz = clazz.getSuperclass()) != Object.class); - return true; - } catch (Exception ex) { - return false; - } - } -} diff --git a/src/main/java/org/redkale/watch/WatchNode.java b/src/main/java/org/redkale/watch/WatchNode.java deleted file mode 100644 index f7dffc461..000000000 --- a/src/main/java/org/redkale/watch/WatchNode.java +++ /dev/null @@ -1,22 +0,0 @@ -/* - * 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.watch; - -/** - * - *

详情见: http://www.redkale.org - * @author zhangjx - */ -public interface WatchNode { - - public String getName(); - - public String getDescription(); - - public long getValue(); - - public boolean isInterval(); -} diff --git a/src/main/java/org/redkale/watch/WatchNumber.java b/src/main/java/org/redkale/watch/WatchNumber.java deleted file mode 100644 index bd45ae97f..000000000 --- a/src/main/java/org/redkale/watch/WatchNumber.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * 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.watch; - -import java.beans.*; -import java.util.concurrent.atomic.*; - -/** - * - *

详情见: http://www.redkale.org - * @author zhangjx - */ -public final class WatchNumber extends AtomicLong implements WatchNode { - - private final boolean interval; - - private final String name; - - private final String description; - - @ConstructorProperties({"name", "description", "interval", "value"}) - protected WatchNumber(String name, String description, boolean interval, long value) { - this.name = name; - this.description = description; - this.interval = interval; - this.set(value); - } - - @Override - public String getName() { - return name; - } - - @Override - public String getDescription() { - return description; - } - - @Override - public long getValue() { - return super.longValue(); - } - - @Override - public boolean isInterval() { - return interval; - } - -} diff --git a/src/main/java/org/redkale/watch/WatchSupplier.java b/src/main/java/org/redkale/watch/WatchSupplier.java deleted file mode 100644 index 6cbf515c9..000000000 --- a/src/main/java/org/redkale/watch/WatchSupplier.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * 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.watch; - -import java.util.function.LongSupplier; - -/** - * - *

详情见: http://www.redkale.org - * @author zhangjx - */ -public final class WatchSupplier implements WatchNode { - - private final String name; - - private final String description; - - private final LongSupplier supplier; - - WatchSupplier(String name, String description, LongSupplier supplier) { - this.name = name; - this.description = description; - this.supplier = supplier; - } - - @Override - public String getName() { - return this.name; - } - - @Override - public String getDescription() { - return this.description; - } - - @Override - public long getValue() { - return supplier == null ? Long.MIN_VALUE : supplier.getAsLong(); - } - - @Override - public boolean isInterval() { - return false; - } -} diff --git a/src/main/java/org/redkale/watch/Watchable.java b/src/main/java/org/redkale/watch/Watchable.java deleted file mode 100644 index fcf1e3bc6..000000000 --- a/src/main/java/org/redkale/watch/Watchable.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * 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.watch; - -import java.lang.annotation.*; -import static java.lang.annotation.ElementType.FIELD; -import static java.lang.annotation.RetentionPolicy.RUNTIME; - -/** - * 该注解只能放在field类型为Collection, Map, 或者java.util.concurrent.atomic.AtomicXXX的Number类); - * - *

- * 详情见: http://www.redkale.org - * - * @author zhangjx - */ -@Inherited -@Documented -@Target({FIELD}) -@Retention(RUNTIME) -public @interface Watchable { - - String name(); - - String description() default ""; - - /** - * 该值指明是不是只收集阶段数据, 而且被注解的字段只能被赋予java.util.concurrent.atomic.AtomicXXX的Number类型字段。 - * 例如收集每分钟的注册用户数, 就需要将interval设置true。 - * - * @return 是否收集 - */ - boolean interval() default false; -} diff --git a/src/main/java/org/redkale/watch/package-info.java b/src/main/java/org/redkale/watch/package-info.java deleted file mode 100644 index 85f884f16..000000000 --- a/src/main/java/org/redkale/watch/package-info.java +++ /dev/null @@ -1,4 +0,0 @@ -/** - * 提供RedKale服务的监控、动态部署、数据收集功能 - */ -package org.redkale.watch; diff --git a/src/test/java/META-INF/persistence.xml b/src/test/java/META-INF/persistence.xml deleted file mode 100644 index eba70637b..000000000 --- a/src/test/java/META-INF/persistence.xml +++ /dev/null @@ -1,14 +0,0 @@ - - - - false - ALL - NONE - - - - - - - - diff --git a/src/test/java/org/redkale/source/FilterNodeTest.java b/src/test/java/org/redkale/source/FilterNodeTest.java deleted file mode 100644 index 02b524aef..000000000 --- a/src/test/java/org/redkale/source/FilterNodeTest.java +++ /dev/null @@ -1,303 +0,0 @@ -/* - * 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.source; - -import org.redkale.util.AutoLoad; -import static org.redkale.source.FilterExpress.*; -import java.util.*; -import java.util.function.*; -import javax.persistence.*; -import org.redkale.convert.json.*; - -/** - * - * @author zhangjx - */ -public class FilterNodeTest { - - public static void main(String[] args) throws Exception { - final Properties props = new Properties(); - final Function fullloader = (Class t) -> new ArrayList(); - final Function func = (Class t) -> EntityInfo.load(t, 0, false, props, fullloader); - final EntityInfo carEntity = EntityInfo.load(CarTestTable.class, 0, false, props, (t) -> CarTestTable.createList()); - final EntityInfo userEntity = EntityInfo.load(UserTestTable.class, 0, false, props, (t) -> UserTestTable.createList()); - final EntityInfo typeEntity = EntityInfo.load(CarTypeTestTable.class, 0, false, props, (t) -> CarTypeTestTable.createList()); - - final CarTestBean bean = new CarTestBean(); - bean.carid = 70002; - bean.username = "用户1"; - bean.createtime = 500; - bean.typename = "法拉利"; - FilterNode joinNode1 = FilterJoinNode.create(UserTestTable.class, new String[]{"userid", "username"}, "username", LIKE, bean.username) - .or(FilterJoinNode.create(UserTestTable.class, new String[]{"userid", "username"}, "createtime", GREATERTHAN, bean.createtime)); - FilterNode joinNode2 = FilterJoinNode.create(CarTypeTestTable.class, "cartype", "typename", LIKE, bean.typename); - FilterNode node = CarTestBean.caridTransient() ? (joinNode2.or(joinNode1)) : FilterNode.create("carid", GREATERTHAN, bean.carid).and(joinNode1).or(joinNode2); - FilterNode beanNode = FilterNodeBean.createFilterNode(bean); - System.out.println("node.string = " + node); - System.out.println("bean.string = " + beanNode); - Map nodeJoinTabalis = node.getJoinTabalis(); - Map beanJoinTabalis = beanNode.getJoinTabalis(); - CharSequence nodeJoinsql = node.createSQLJoin(func, nodeJoinTabalis, carEntity); - CharSequence beanJoinsql = beanNode.createSQLJoin(func, beanJoinTabalis, carEntity); - CharSequence nodeWhere = node.createSQLExpress(carEntity, nodeJoinTabalis); - CharSequence beanWhere = beanNode.createSQLExpress(carEntity, beanJoinTabalis); - System.out.println("node.sql = SELECT a.* FROM " + CarTestTable.class.getSimpleName().toLowerCase() + " a" + (nodeJoinsql == null ? "" : nodeJoinsql) + " WHERE " + nodeWhere); - System.out.println("bean.sql = SELECT a.* FROM " + CarTestTable.class.getSimpleName().toLowerCase() + " a" + (beanJoinsql == null ? "" : beanJoinsql) + " WHERE " + beanWhere); - assert node.isCacheUseable(func) : "isCacheUseable 应该是true"; - assert beanNode.isCacheUseable(func) : "isCacheUseable 应该是true"; - System.out.println("node.Predicate = " + node.createPredicate(carEntity.getCache())); - System.out.println("bean.Predicate = " + beanNode.createPredicate(carEntity.getCache())); - System.out.println("node.sheet = " + carEntity.getCache().querySheet(null, new Flipper(), node)); - System.out.println("bean.sheet = " + carEntity.getCache().querySheet(null, new Flipper(), beanNode)); - } - - public static class CarTestBean implements FilterBean { - - @FilterGroup("[OR].[AND]a") - @FilterColumn(express = GREATERTHAN) - @Transient - public long carid; - - @FilterGroup("[OR].[AND]a.[OR]c") - @FilterColumn(express = LIKE) - @FilterJoinColumn(table = UserTestTable.class, columns = {"userid", "username"}) - public String username; - - @FilterGroup("[OR].[AND]a.[OR]c") - @FilterColumn(express = GREATERTHAN) - @FilterJoinColumn(table = UserTestTable.class, columns = {"userid", "username"}) - public long createtime; - - @FilterGroup("[OR]") - @FilterColumn(express = LIKE) - @FilterJoinColumn(table = CarTypeTestTable.class, columns = {"cartype"}) - public String typename; - - @Override - public String toString() { - return JsonConvert.root().convertTo(this); - } - - public static boolean caridTransient() { - try { - return CarTestBean.class.getDeclaredField("carid").getAnnotation(Transient.class) != null; - } catch (Exception e) { - e.printStackTrace(); - return true; - } - } - } - - @AutoLoad - @Cacheable - public static class CarTestTable { - - public static List createList() { - List list = new ArrayList<>(); - - list.add(new CarTestTable(70001, 101, 1000011, "我的车")); - list.add(new CarTestTable(70002, 102, 1000012, "我的车")); - list.add(new CarTestTable(70003, 103, 1000013, "我的车")); - list.add(new CarTestTable(70004, 104, 1000014, "我的车")); - list.add(new CarTestTable(70005, 105, 1000015, "我的车")); - - list.add(new CarTestTable(70201, 201, 1000031, "我的车")); - list.add(new CarTestTable(70202, 202, 1000032, "我的车")); - list.add(new CarTestTable(70203, 203, 1000033, "我的车")); - list.add(new CarTestTable(70204, 204, 1000034, "我的车")); - list.add(new CarTestTable(70205, 205, 1000035, "我的车")); - list.add(new CarTestTable(70505, 301, 1008000, "我的车")); - - return list; - } - - @Id - private long carid; - - private int cartype; - - private int userid; - - private String username; - - private String cartitle; - - public CarTestTable() { - - } - - public CarTestTable(long carid, int cartype, int userid, String cartitle) { - this.carid = carid; - this.cartype = cartype; - this.userid = userid; - this.username = "用户" + userid % 1000; - this.cartitle = cartitle; - } - - public long getCarid() { - return carid; - } - - public void setCarid(long carid) { - this.carid = carid; - } - - public int getUserid() { - return userid; - } - - public void setUserid(int userid) { - this.userid = userid; - } - - public String getCartitle() { - return cartitle; - } - - public void setCartitle(String cartitle) { - this.cartitle = cartitle; - } - - public int getCartype() { - return cartype; - } - - public void setCartype(int cartype) { - this.cartype = cartype; - } - - public String getUsername() { - return username; - } - - public void setUsername(String username) { - this.username = username; - } - - @Override - public String toString() { - return JsonConvert.root().convertTo(this); - } - - } - - @AutoLoad - @Cacheable - public static class CarTypeTestTable { - - public static List createList() { - List list = new ArrayList<>(); - list.add(new CarTypeTestTable(101, "奥迪A1")); - list.add(new CarTypeTestTable(102, "奥迪A2")); - list.add(new CarTypeTestTable(103, "奥迪A3")); - list.add(new CarTypeTestTable(104, "奥迪A4")); - list.add(new CarTypeTestTable(105, "奥迪A5")); - list.add(new CarTypeTestTable(201, "奔驰S1")); - list.add(new CarTypeTestTable(202, "奔驰S2")); - list.add(new CarTypeTestTable(203, "奔驰S3")); - list.add(new CarTypeTestTable(204, "奔驰S4")); - list.add(new CarTypeTestTable(205, "奔驰S5")); - list.add(new CarTypeTestTable(301, "法拉利")); - return list; - } - - @Id - private int cartype; - - private String typename; - - public CarTypeTestTable() { - - } - - public CarTypeTestTable(int cartype, String typename) { - this.cartype = cartype; - this.typename = typename; - } - - @Override - public String toString() { - return JsonConvert.root().convertTo(this); - } - - public int getCartype() { - return cartype; - } - - public void setCartype(int cartype) { - this.cartype = cartype; - } - - public String getTypename() { - return typename; - } - - public void setTypename(String typename) { - this.typename = typename; - } - - } - - @AutoLoad - @Cacheable - public static class UserTestTable { - - public static List createList() { - List list = new ArrayList<>(); - for (int i = 11; i <= 50; i++) { - list.add(new UserTestTable(1000000 + i, "用户" + i, i * 20)); - } - list.add(new UserTestTable(1008000, "车主A", 20)); - return list; - } - - @Id - private int userid; - - private String username; - - private long createtime; - - public UserTestTable() { - } - - public UserTestTable(int userid, String username, long createtime) { - this.userid = userid; - this.username = username; - this.createtime = createtime; - } - - @Override - public String toString() { - return JsonConvert.root().convertTo(this); - } - - public int getUserid() { - return userid; - } - - public void setUserid(int userid) { - this.userid = userid; - } - - public String getUsername() { - return username; - } - - public void setUsername(String username) { - this.username = username; - } - - public long getCreatetime() { - return createtime; - } - - public void setCreatetime(long createtime) { - this.createtime = createtime; - } - - } -} diff --git a/src/test/java/org/redkale/test/convert/BasedEntity.java b/src/test/java/org/redkale/test/convert/BasedEntity.java deleted file mode 100644 index d1dc3867c..000000000 --- a/src/test/java/org/redkale/test/convert/BasedEntity.java +++ /dev/null @@ -1,21 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ -package org.redkale.test.convert; - -import java.io.Serializable; -import org.redkale.convert.json.*; - -/** - * - * @author zhangjx - */ -public abstract class BasedEntity implements Serializable { - - @Override - public String toString() { - return JsonConvert.root().convertTo(this); - } -} diff --git a/src/test/java/org/redkale/test/convert/BsonTestMain.java b/src/test/java/org/redkale/test/convert/BsonTestMain.java deleted file mode 100644 index c94834392..000000000 --- a/src/test/java/org/redkale/test/convert/BsonTestMain.java +++ /dev/null @@ -1,89 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ -package org.redkale.test.convert; - -import java.io.*; -import org.redkale.convert.bson.BsonByteBufferWriter; -import org.redkale.convert.bson.BsonFactory; -import org.redkale.util.Utility; -import org.redkale.convert.bson.BsonConvert; -import java.nio.*; -import java.util.Arrays; -import org.redkale.convert.json.*; - -/** - * - * @author zhangjx - */ -public class BsonTestMain { - - public static void main(String[] args) throws Exception { - Serializable[] sers = new Serializable[]{"aaa", 4}; - final BsonConvert convert = BsonFactory.root().getConvert(); - byte[] bytes = convert.convertTo(sers); - Utility.println("---", bytes); - Serializable[] a = convert.convertFrom(Serializable[].class, bytes); - System.out.println(Arrays.toString(a)); - main2(args); - main3(args); - main4(args); - } - - public static void main2(String[] args) throws Exception { - final BsonConvert convert = BsonFactory.root().getConvert(); - SimpleChildEntity entry = SimpleChildEntity.create(); - byte[] bytes = convert.convertTo(SimpleEntity.class, entry); - System.out.println("长度: " + bytes.length); - BsonByteBufferWriter writer = convert.pollBsonWriter(() -> ByteBuffer.allocate(1)); - convert.convertTo(writer, SimpleEntity.class, entry); - ByteBuffer[] buffers = writer.toBuffers(); - int len = 0; - ByteArrayOutputStream out = new ByteArrayOutputStream(); - for (ByteBuffer b : buffers) { - len += b.remaining(); - byte[] ts = new byte[b.remaining()]; - b.get(ts); - out.write(ts); - b.flip(); - } - System.out.println("长度: " + len); - SimpleChildEntity entry2 = convert.convertFrom(SimpleChildEntity.class, buffers); - System.out.println(entry); - System.out.println(entry2); - } - - public static void main3(String[] args) throws Exception { - final BsonConvert convert = BsonFactory.root().getConvert(); - SimpleChildEntity entry = SimpleChildEntity.create(); - byte[] bytes = convert.convertTo(SimpleEntity.class, entry); - Utility.println(null, bytes); - System.out.println(JsonConvert.root().convertTo(entry)); - SimpleEntity rs = convert.convertFrom(SimpleEntity.class, bytes); - System.out.println(rs.toString()); - System.out.println(JsonConvert.root().convertTo(rs)); - - ComplextEntity bean = new ComplextEntity(); - byte[] bytes2 = convert.convertTo(Object.class, bean); - final int len = bytes2.length; - BsonByteBufferWriter writer = convert.pollBsonWriter(() -> ByteBuffer.allocate(len / 2)); - convert.convertTo(writer, bean); - bytes2 = writer.toArray(); - System.out.println(convert.convertFrom(ComplextEntity.class, bytes2).toString()); - } - - public static void main4(String[] args) throws Exception { - final BsonConvert convert = BsonFactory.root().getConvert(); - SimpleChildEntity entry = SimpleChildEntity.create(); - ByteArrayOutputStream out = new ByteArrayOutputStream(); - convert.convertTo(out, SimpleEntity.class, entry); - byte[] bytes = out.toByteArray(); - Utility.println(null, bytes); - System.out.println(JsonConvert.root().convertTo(entry)); - SimpleEntity rs = convert.convertFrom(SimpleEntity.class, new ByteArrayInputStream(bytes)); - System.out.println(rs.toString()); - - } -} diff --git a/src/test/java/org/redkale/test/convert/ComplextEntity.java b/src/test/java/org/redkale/test/convert/ComplextEntity.java deleted file mode 100644 index 14f4fe11f..000000000 --- a/src/test/java/org/redkale/test/convert/ComplextEntity.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ -package org.redkale.test.convert; - -import java.util.List; -import javax.persistence.*; - -/** - * - * @author zhangjx - */ -public class ComplextEntity extends BasedEntity { - - @Id - private int userid; - - private String chname = ""; - - @Transient - private boolean flag = true; - - @Transient - private List children; - - @Transient - private SimpleEntity user; - - public int getUserid() { - return userid; - } - - public void setUserid(int userid) { - this.userid = userid; - } - - public String getChname() { - return chname; - } - - public void setChname(String chname) { - this.chname = chname; - } - - public boolean isFlag() { - return flag; - } - - public void setFlag(boolean flag) { - this.flag = flag; - } - - public List getChildren() { - return children; - } - - public void setChildren(List children) { - this.children = children; - } - - public SimpleEntity getUser() { - return user; - } - - public void setUser(SimpleEntity user) { - this.user = user; - } - -} diff --git a/src/test/java/org/redkale/test/convert/ConstructorArgsEntity.java b/src/test/java/org/redkale/test/convert/ConstructorArgsEntity.java deleted file mode 100644 index 871b3a63a..000000000 --- a/src/test/java/org/redkale/test/convert/ConstructorArgsEntity.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ -package org.redkale.test.convert; - -import java.beans.*; -import org.redkale.convert.bson.*; -import org.redkale.convert.json.*; - -/** - * 测试不存在无参数的构造函数的bean类解析 - * - * @author zhangjx - */ -public class ConstructorArgsEntity { - - private final int userid; - - private String name; - - private long createtime; - - @ConstructorProperties({"userid", "name"}) - public ConstructorArgsEntity(int userid, String name) { - this.userid = userid; - this.name = name; - } - - public static void main(String[] args) throws Exception { - final JsonConvert jsonConvert = JsonConvert.root(); - final BsonConvert bsonConvert = BsonFactory.root().getConvert(); - ConstructorArgsEntity bean = new ConstructorArgsEntity(12345678, "哈哈"); - bean.setCreatetime(System.currentTimeMillis()); - String json = jsonConvert.convertTo(bean); - System.out.println(json); - System.out.println(jsonConvert.convertFrom(ConstructorArgsEntity.class, json).toString()); - byte[] bytes = bsonConvert.convertTo(bean); - System.out.println(bsonConvert.convertFrom(ConstructorArgsEntity.class, bytes).toString()); - } - - public int getUserid() { - return userid; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public long getCreatetime() { - return createtime; - } - - public void setCreatetime(long createtime) { - this.createtime = createtime; - } - - @Override - public String toString() { - return JsonConvert.root().convertTo(this); - } -} diff --git a/src/test/java/org/redkale/test/convert/ConvertRecord.java b/src/test/java/org/redkale/test/convert/ConvertRecord.java deleted file mode 100644 index 55ac8fe35..000000000 --- a/src/test/java/org/redkale/test/convert/ConvertRecord.java +++ /dev/null @@ -1,192 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ -package org.redkale.test.convert; - - -import java.util.*; - -/** - * - * @author redkale - */ -public class ConvertRecord { - - private String aname; - - private String desc = ""; - - private int id = (int) System.currentTimeMillis(); - - private int[] integers; - - private long[] longs; - - private List strings; - - private Map map; - - public static ConvertRecord createDefault() { - ConvertRecord v = new ConvertRecord(); - v.setAname("this is name\n \"test"); - v.setId(1000000001); - v.setIntegers(new int[]{12, 34, 56, 78, 90, 123, 456, 789}); - v.setLongs(new long[]{10000012L, 10000034L, 10000056L, 10000078L, -10000090L, -100000123L, -100000456L, -100000789L}); - List list = new ArrayList<>(); - list.add("str_a"); - list.add("str_b"); - list.add("str_c"); - v.setStrings(list); - Map map = new HashMap<>(); - map.put("key_a", 111); - map.put("key_b", 222); - map.put("key_c", 333); - v.setMap(map); - return v; - } - - public static void main(String[] args) throws Exception { - final ConvertRecord entry = ConvertRecord.createDefault(); - run(ConvertRecord.class, entry); - } - - public static void run(final Class type, final T entry) throws Exception { - /** - final org.redkale.convert.json.JsonConvert convert = org.redkale.convert.json.JsonFactory.root().getConvert(); - final String entryString = convert.convertTo(entry); - convert.convertFrom(type, entryString); - System.out.println("redkale-convert: " + convert.convertTo(entry)); - - com.alibaba.fastjson.JSON.parseObject(entryString, type); - System.out.println("fastjson 1.2.7: " + com.alibaba.fastjson.JSON.toJSONString(entry)); - - final com.fasterxml.jackson.databind.ObjectMapper mapper = new com.fasterxml.jackson.databind.ObjectMapper(); - mapper.readValue(entryString, type); - System.out.println("jackson 2.7.2: " + mapper.writeValueAsString(entry)); - - final com.google.gson.Gson gson = new com.google.gson.Gson(); - gson.fromJson(entryString, type); - System.out.println("google-gson 2.4: " + gson.toJson(entry)); - - System.out.println("------------------------------------------------"); - System.out.println("组件 序列化耗时(ms) 反序列化耗时(ms)"); - final int count = 10_0000; - long s = System.currentTimeMillis(); - for (int i = 0; i < count; i++) { - convert.convertTo(entry); - } - long e = System.currentTimeMillis() - s; - System.out.print("redkale-convert " + e); - - s = System.currentTimeMillis(); - for (int i = 0; i < count; i++) { - convert.convertFrom(type, entryString); - } - e = System.currentTimeMillis() - s; - System.out.println("\t " + e); - - //---------------------------------------------------------------------------- - s = System.currentTimeMillis(); - for (int i = 0; i < count; i++) { - com.alibaba.fastjson.JSON.toJSONString(entry); - } - e = System.currentTimeMillis() - s; - System.out.print("fastjson 1.2.7 " + e); - - s = System.currentTimeMillis(); - for (int i = 0; i < count; i++) { - com.alibaba.fastjson.JSON.parseObject(entryString, type); - } - e = System.currentTimeMillis() - s; - System.out.println("\t " + e); - //---------------------------------------------------------------------------- - s = System.currentTimeMillis(); - for (int i = 0; i < count; i++) { - mapper.writeValueAsString(entry); - } - e = System.currentTimeMillis() - s; - System.out.print("jackson 2.7.2 " + e); - - s = System.currentTimeMillis(); - for (int i = 0; i < count; i++) { - mapper.readValue(entryString, type); - } - e = System.currentTimeMillis() - s; - System.out.println("\t " + e); - //---------------------------------------------------------------------------- - s = System.currentTimeMillis(); - for (int i = 0; i < count; i++) { - gson.toJson(entry); - } - e = System.currentTimeMillis() - s; - System.out.print("google-gson 2.4 " + e); - - s = System.currentTimeMillis(); - for (int i = 0; i < count; i++) { - gson.fromJson(entryString, type); - } - e = System.currentTimeMillis() - s; - System.out.println("\t " + e); - //---------------------------------------------------------------------------- - */ - } - - public String getAname() { - return aname; - } - - public void setAname(String aname) { - this.aname = aname; - } - - public String getDesc() { - return desc; - } - - public void setDesc(String desc) { - this.desc = desc; - } - - public int getId() { - return id; - } - - public void setId(int id) { - this.id = id; - } - - public int[] getIntegers() { - return integers; - } - - public void setIntegers(int[] integers) { - this.integers = integers; - } - - public long[] getLongs() { - return longs; - } - - public void setLongs(long[] longs) { - this.longs = longs; - } - - public List getStrings() { - return strings; - } - - public void setStrings(List strings) { - this.strings = strings; - } - - public Map getMap() { - return map; - } - - public void setMap(Map map) { - this.map = map; - } - -} diff --git a/src/test/java/org/redkale/test/convert/GenericEntity.java b/src/test/java/org/redkale/test/convert/GenericEntity.java deleted file mode 100644 index 04e86fa9f..000000000 --- a/src/test/java/org/redkale/test/convert/GenericEntity.java +++ /dev/null @@ -1,110 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ -package org.redkale.test.convert; - -import org.redkale.util.TypeToken; -import org.redkale.convert.json.JsonFactory; -import java.lang.reflect.*; -import java.util.*; -import org.redkale.convert.json.*; - -/** - * 支持泛型的 - * - * @author zhangjx - * @param - * @param - * @param - */ -public class GenericEntity { - - private K name; - - private List list; - - private Entry entry; - - public static void main(String[] args) throws Throwable { - GenericEntity bean = new GenericEntity<>(); - bean.setName("你好"); - List list = new ArrayList<>(); - list.add(1234567890L); - bean.setList(list); - bean.setEntry(new Entry<>("aaaa", SimpleEntity.create())); - final Type type = new TypeToken>() { - }.getType(); - JsonFactory.root().tiny(true); - String json = JsonConvert.root().convertTo(bean); - System.out.println(json); - System.out.println(JsonConvert.root().convertFrom(type, json).toString()); - } - - @Override - public String toString() { - return "{\"entry\":" + entry + ",\"list\":" + list + ",\"name\":\"" + name + "\"}"; - } - - public K getName() { - return name; - } - - public void setName(K name) { - this.name = name; - } - - public List getList() { - return list; - } - - public void setList(List list) { - this.list = list; - } - - public Entry getEntry() { - return entry; - } - - public void setEntry(Entry entry) { - this.entry = entry; - } - - public static class Entry { - - private K key; - - private V value; - - public Entry() { - } - - public Entry(K key, V value) { - this.key = key; - this.value = value; - } - - @Override - public String toString() { - return JsonConvert.root().convertTo(this); - } - - public K getKey() { - return key; - } - - public void setKey(K key) { - this.key = key; - } - - public V getValue() { - return value; - } - - public void setValue(V value) { - this.value = value; - } - - } -} diff --git a/src/test/java/org/redkale/test/convert/InnerCoderEntity.java b/src/test/java/org/redkale/test/convert/InnerCoderEntity.java deleted file mode 100644 index ba761182a..000000000 --- a/src/test/java/org/redkale/test/convert/InnerCoderEntity.java +++ /dev/null @@ -1,119 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ -package org.redkale.test.convert; - -import org.redkale.convert.*; -import org.redkale.convert.bson.*; -import org.redkale.convert.json.*; -import org.redkale.util.*; - -/** - * - * @author zhangjx - */ -public class InnerCoderEntity { - - private final String val; - - private final int id; - - private InnerCoderEntity(int id, String value) { - this.id = id; - this.val = value; - } - - public static InnerCoderEntity create(int id, String value) { - return new InnerCoderEntity(id, value); - } - - /** - * 该方法提供给Convert组件自动加载。 - * 1) 方法名可以随意。 - 2) 方法必须是static - 3)方法的参数有且只能有一个, 且必须是org.redkale.convert.ConvertFactory或子类。 - —3.1) 参数类型为org.redkale.convert.ConvertFactory 表示适合JSON和BSON。 - —3.2) 参数类型为org.redkale.convert.json.JsonFactory 表示仅适合JSON。 - —3.3) 参数类型为org.redkale.convert.bson.BsonFactory 表示仅适合BSON。 - 4)方法的返回类型必须是org.redkale.convert.Decodeable/org.redkale.convert.Encodeable/org.redkale.convert.SimpledCoder - 若返回类型不是org.redkale.convert.SimpledCoder, 就必须提供两个方法: 一个返回Decodeable 一个返回 Encodeable。 - * - * @param factory - * @return - */ - private static SimpledCoder createConvertCoder(final org.redkale.convert.ConvertFactory factory) { - return new SimpledCoder() { - - //必须与EnMember[] 顺序一致 - private final DeMember[] deMembers = new DeMember[]{ - DeMember.create(factory, InnerCoderEntity.class, "id"), - DeMember.create(factory, InnerCoderEntity.class, "val")}; - - //必须与DeMember[] 顺序一致 - private final EnMember[] enMembers = new EnMember[]{ - EnMember.create(factory, InnerCoderEntity.class, "id"), - EnMember.create(factory, InnerCoderEntity.class, "val")}; - - @Override - public void convertTo(Writer out, InnerCoderEntity value) { - if (value == null) { - out.writeObjectNull(InnerCoderEntity.class); - return; - } - out.writeObjectB(value); - for (EnMember member : enMembers) { - out.writeObjectField(member, value); - } - out.writeObjectE(value); - } - - @Override - public InnerCoderEntity convertFrom(Reader in) { - if (in.readObjectB(InnerCoderEntity.class) == null) return null; - int index = 0; - final Object[] params = new Object[deMembers.length]; - while (in.hasNext()) { - DeMember member = in.readFieldName(deMembers); //读取字段名 - in.readBlank(); //读取字段名与字段值之间的间隔符,JSON则是跳过冒号: - if (member == null) { - in.skipValue(); //跳过不存在的字段的值, 一般不会发生 - } else { - params[index++] = member.read(in); - } - } - in.readObjectE(InnerCoderEntity.class); - return InnerCoderEntity.create(params[0] == null ? 0 : (Integer) params[0], (String) params[1]); - } - }; - } - - public int getId() { - return id; - } - - public String getVal() { - return val; - } - - @Override - public String toString() { - return JsonConvert.root().convertTo(this); - } - - public static void main(String[] args) throws Exception { - InnerCoderEntity record = InnerCoderEntity.create(200, "haha"); - final JsonConvert convert = JsonConvert.root(); - String json = convert.convertTo(record); - System.out.println(json); - System.out.println(convert.convertFrom(InnerCoderEntity.class, json).toString()); - - final BsonConvert convert2 = BsonFactory.root().getConvert(); - byte[] bs = convert2.convertTo(InnerCoderEntity.class, null); - Utility.println("--", bs); - InnerCoderEntity r = convert2.convertFrom(InnerCoderEntity.class, bs); - System.out.println(r); - } - -} diff --git a/src/test/java/org/redkale/test/convert/JsonTestMain.java b/src/test/java/org/redkale/test/convert/JsonTestMain.java deleted file mode 100644 index 960abce92..000000000 --- a/src/test/java/org/redkale/test/convert/JsonTestMain.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ -package org.redkale.test.convert; - -import java.io.*; -import org.redkale.convert.json.JsonConvert; -import org.redkale.convert.json.JsonFactory; -import java.nio.*; -import java.util.*; -import org.redkale.convert.json.*; - -/** - * - * @author zhangjx - */ -public class JsonTestMain { - - public static void main(String[] args) throws Exception { - JsonFactory factory = JsonFactory.root().tiny(true); - final JsonConvert convert = JsonConvert.root(); - String json = "{\"access_token\":\"vVX2bIjN5P9TMOphDkStM96eNWapAehTuWAlVDO74aFaYxLwj2b-9-T9p_W2mfr9\",\"expires_in\":7200, \"aa\":\"\"}"; - Map map = convert.convertFrom(JsonConvert.TYPE_MAP_STRING_STRING, json); - System.out.println(map); - System.out.println(convert.convertTo(map)); - ByteBuffer[] buffers = convert.convertTo(() -> ByteBuffer.allocate(1024), map); - byte[] bs = new byte[buffers[0].remaining()]; - buffers[0].get(bs); - System.out.println(new String(bs)); - main2(args); - main3(args); - } - - public static void main2(String[] args) throws Exception { - final JsonConvert convert = JsonConvert.root(); - SimpleChildEntity entry = SimpleChildEntity.create(); - String json = convert.convertTo(SimpleEntity.class, entry); - System.out.println("长度: " + json.length()); - JsonByteBufferWriter writer = convert.pollJsonWriter(() -> ByteBuffer.allocate(1)); - convert.convertTo(writer, SimpleEntity.class, entry); - ByteBuffer[] buffers = writer.toBuffers(); - int len = 0; - ByteArrayOutputStream out = new ByteArrayOutputStream(); - for (ByteBuffer b : buffers) { - len += b.remaining(); - byte[] ts = new byte[b.remaining()]; - b.get(ts); - out.write(ts); - b.flip(); - } - System.out.println("长度: " + len); - System.out.println(json); - SimpleChildEntity entry2 = convert.convertFrom(SimpleChildEntity.class, buffers); - System.out.println(entry); - System.out.println(entry2); - } - - public static void main3(String[] args) throws Exception { - final JsonConvert convert = JsonConvert.root(); - SimpleChildEntity entry = SimpleChildEntity.create(); - ByteArrayOutputStream out = new ByteArrayOutputStream(); - convert.convertTo(out, SimpleEntity.class, entry); - String json = out.toString("UTF-8"); - System.out.println("长度: " + json.length()); - System.out.println(json); - ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); - SimpleChildEntity entry2 = convert.convertFrom(SimpleChildEntity.class, in); - System.out.println(entry); - System.out.println(entry2); - } -} diff --git a/src/test/java/org/redkale/test/convert/SimpleChildEntity.java b/src/test/java/org/redkale/test/convert/SimpleChildEntity.java deleted file mode 100644 index e96010038..000000000 --- a/src/test/java/org/redkale/test/convert/SimpleChildEntity.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ -package org.redkale.test.convert; - -import java.net.*; -import org.redkale.convert.ConvertEntity; -import java.util.*; - -/** - * - * @author zhangjx - */ -@ConvertEntity("myname") -public class SimpleChildEntity extends SimpleEntity { - - private short st = -1234; - - private String extend; - - public static SimpleChildEntity create() { - SimpleChildEntity v = new SimpleChildEntity(); - v.setName("this is name\n \"test"); - v.setId(1000000001); - v.setAddrs(new int[]{22222, 33333, 44444, 55555, 66666, 77777, 88888, 99999}); - v.setStrings(new String[]{"zzz", "yyy", "xxx"}); - List list = new ArrayList<>(); - list.add("aaaa"); - list.add("bbbb"); - list.add("cccc"); - v.setLists(list); - Map map = new HashMap<>(); - map.put("AAA", 111); - map.put("BBB", 222); - map.put("CCC", 333); - v.setMap(map); - v.setExtend("hahaha"); - v.setAddr(new InetSocketAddress("127.0.0.1", 6666)); - return v; - } - - public short getSt() { - return st; - } - - public void setSt(short st) { - this.st = st; - } - - public String getExtend() { - return extend; - } - - public void setExtend(String extend) { - this.extend = extend; - } - -} diff --git a/src/test/java/org/redkale/test/convert/SimpleEntity.java b/src/test/java/org/redkale/test/convert/SimpleEntity.java deleted file mode 100644 index 3af940b6d..000000000 --- a/src/test/java/org/redkale/test/convert/SimpleEntity.java +++ /dev/null @@ -1,137 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ -package org.redkale.test.convert; - -import java.net.*; -import org.redkale.util.Creator; -import java.util.*; -import org.redkale.convert.json.*; - -/** - * - * @author zhangjx - */ -public class SimpleEntity { - - private String name; - - private String desc = ""; - - private int id = (int) System.currentTimeMillis(); - - private int[] addrs; - - private List lists; - - private String[] strings; - - private Map map; - - private InetSocketAddress addr; - - public static SimpleEntity create() { - SimpleEntity v = new SimpleEntity(); - v.setName("this is name\n \"test"); - v.setId(1000000001); - v.setAddrs(new int[]{22222, 33333, 44444, 55555, 66666, 77777, 88888, 99999}); - v.setStrings(new String[]{"zzz", "yyy", "xxx"}); - List list = new ArrayList<>(); - list.add("aaaa"); - list.add("bbbb"); - list.add("cccc"); - v.setLists(list); - Map map = new HashMap<>(); - map.put("AAA", 111); - map.put("BBB", 222); - map.put("CCC", 333); - v.setMap(map); - v.setAddr(new InetSocketAddress("127.0.0.1", 6666)); - return v; - } - - public static void main(String[] args) throws Exception { - System.out.println(JsonConvert.root().convertTo(create())); - Creator creator = Creator.create(SimpleEntity.class); //Creator.create(10, SimpleEntity.class); - SimpleEntity entry = creator.create(); - System.out.println(entry); - for (int i = 0; i < 10000000; i++) { - creator.create(); - } - System.gc(); - Thread.sleep(2000); - System.out.println(creator.create()); - } - - @Override - public String toString() { - return JsonConvert.root().convertTo(this); - } - - public InetSocketAddress getAddr() { - return addr; - } - - public void setAddr(InetSocketAddress addr) { - this.addr = addr; - } - - public int[] getAddrs() { - return addrs; - } - - public void setAddrs(int[] addrs) { - this.addrs = addrs; - } - - public List getLists() { - return lists; - } - - public void setLists(List lists) { - this.lists = lists; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public int getId() { - return id; - } - - public void setId(int id) { - this.id = id; - } - - public Map getMap() { - return map; - } - - public void setMap(Map map) { - this.map = map; - } - - public String getDesc() { - return desc; - } - - public void setDesc(String desc) { - this.desc = desc; - } - - public String[] getStrings() { - return strings; - } - - public void setStrings(String[] strings) { - this.strings = strings; - } - -} diff --git a/src/test/java/org/redkale/test/convert/media/Image.java b/src/test/java/org/redkale/test/convert/media/Image.java deleted file mode 100644 index 14af488d6..000000000 --- a/src/test/java/org/redkale/test/convert/media/Image.java +++ /dev/null @@ -1,117 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ -package org.redkale.test.convert.media; - -/** - * - * @author redkale - */ -public class Image implements java.io.Serializable { - - private static final long serialVersionUID = 1L; - - public enum Size { - SMALL, LARGE - } - - private String uri; - - private String title; // Can be null - - private int width; - - private int height; - - private Size size; - - public Image() { - } - - public Image(String uri, String title, int width, int height, Size size) { - this.height = height; - this.title = title; - this.uri = uri; - this.width = width; - this.size = size; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - Image image = (Image) o; - - if (height != image.height) return false; - if (width != image.width) return false; - if (size != image.size) return false; - if (title != null ? !title.equals(image.title) : image.title != null) return false; - return !(uri != null ? !uri.equals(image.uri) : image.uri != null); - } - - @Override - public int hashCode() { - int result = uri != null ? uri.hashCode() : 0; - result = 31 * result + (title != null ? title.hashCode() : 0); - result = 31 * result + width; - result = 31 * result + height; - result = 31 * result + (size != null ? size.hashCode() : 0); - return result; - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("[Image "); - sb.append("uri=").append((uri)); - sb.append(", title=").append((title)); - sb.append(", width=").append(width); - sb.append(", height=").append(height); - sb.append(", size=").append(size); - sb.append("]"); - return sb.toString(); - } - - public void setUri(String uri) { - this.uri = uri; - } - - public void setTitle(String title) { - this.title = title; - } - - public void setWidth(int width) { - this.width = width; - } - - public void setHeight(int height) { - this.height = height; - } - - public void setSize(Size size) { - this.size = size; - } - - public String getUri() { - return uri; - } - - public String getTitle() { - return title; - } - - public int getWidth() { - return width; - } - - public int getHeight() { - return height; - } - - public Size getSize() { - return size; - } -} diff --git a/src/test/java/org/redkale/test/convert/media/Media.java b/src/test/java/org/redkale/test/convert/media/Media.java deleted file mode 100644 index 699d02ccf..000000000 --- a/src/test/java/org/redkale/test/convert/media/Media.java +++ /dev/null @@ -1,203 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ -package org.redkale.test.convert.media; - -import java.util.*; - -/** - * - * @author redkale - */ -public class Media implements java.io.Serializable { - - public enum Player { - JAVA, FLASH; - - } - - private String uri; - - private String title; // Can be unset. - - private int width; - - private int height; - - private String format; - - private long duration; - - private long size; - - private int bitrate; // Can be unset. - - private List persons; - - private Player player; - - private String copyright; // Can be unset. - - public Media() { - } - - public Media(String uri, String title, int width, int height, String format, long duration, long size, - int bitrate, boolean hasBitrate, List persons, Player player, String copyright) { - this.uri = uri; - this.title = title; - this.width = width; - this.height = height; - this.format = format; - this.duration = duration; - this.size = size; - this.bitrate = bitrate; - - this.persons = persons; - this.player = player; - this.copyright = copyright; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - Media media = (Media) o; - if (bitrate != media.bitrate) return false; - if (duration != media.duration) return false; - if (height != media.height) return false; - if (size != media.size) return false; - if (width != media.width) return false; - if (copyright != null ? !copyright.equals(media.copyright) : media.copyright != null) return false; - if (format != null ? !format.equals(media.format) : media.format != null) return false; - if (persons != null ? !persons.equals(media.persons) : media.persons != null) return false; - if (player != media.player) return false; - if (title != null ? !title.equals(media.title) : media.title != null) return false; - if (uri != null ? !uri.equals(media.uri) : media.uri != null) return false; - return true; - } - - @Override - public int hashCode() { - int result = uri != null ? uri.hashCode() : 0; - result = 31 * result + (title != null ? title.hashCode() : 0); - result = 31 * result + width; - result = 31 * result + height; - result = 31 * result + (format != null ? format.hashCode() : 0); - result = 31 * result + (int) (duration ^ (duration >>> 32)); - result = 31 * result + (int) (size ^ (size >>> 32)); - result = 31 * result + bitrate; - result = 31 * result + (persons != null ? persons.hashCode() : 0); - result = 31 * result + (player != null ? player.hashCode() : 0); - result = 31 * result + (copyright != null ? copyright.hashCode() : 0); - return result; - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("[Media "); - sb.append("uri=").append((uri)); - sb.append(", title=").append((title)); - sb.append(", width=").append(width); - sb.append(", height=").append(height); - sb.append(", format=").append((format)); - sb.append(", duration=").append(duration); - sb.append(", size=").append(size); - sb.append(", bitrate=").append(String.valueOf(bitrate)); - sb.append(", persons=").append((persons)); - sb.append(", player=").append(player); - sb.append(", copyright=").append((copyright)); - sb.append("]"); - return sb.toString(); - } - - public void setUri(String uri) { - this.uri = uri; - } - - public void setTitle(String title) { - this.title = title; - } - - public void setWidth(int width) { - this.width = width; - } - - public void setHeight(int height) { - this.height = height; - } - - public void setFormat(String format) { - this.format = format; - } - - public void setDuration(long duration) { - this.duration = duration; - } - - public void setSize(long size) { - this.size = size; - } - - public void setBitrate(int bitrate) { - this.bitrate = bitrate; - } - - public void setPersons(List persons) { - this.persons = persons; - } - - public void setPlayer(Player player) { - this.player = player; - } - - public void setCopyright(String copyright) { - this.copyright = copyright; - } - - public String getUri() { - return uri; - } - - public String getTitle() { - return title; - } - - public int getWidth() { - return width; - } - - public int getHeight() { - return height; - } - - public String getFormat() { - return format; - } - - public long getDuration() { - return duration; - } - - public long getSize() { - return size; - } - - public int getBitrate() { - return bitrate; - } - - public List getPersons() { - return persons; - } - - public Player getPlayer() { - return player; - } - - public String getCopyright() { - return copyright; - } -} diff --git a/src/test/java/org/redkale/test/convert/media/MediaContent.java b/src/test/java/org/redkale/test/convert/media/MediaContent.java deleted file mode 100644 index 50efeaddf..000000000 --- a/src/test/java/org/redkale/test/convert/media/MediaContent.java +++ /dev/null @@ -1,109 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ -package org.redkale.test.convert.media; - -import java.util.*; -import org.redkale.convert.json.*; -import org.redkale.test.convert.*; - -/** - * - * @author redkale - */ -public class MediaContent implements java.io.Serializable { - - private Media media; - - private List images; - - public MediaContent() { - } - - public MediaContent(Media media, List images) { - this.media = media; - this.images = images; - } - - public static void main(String[] args) throws Exception { - final MediaContent entry = MediaContent.createDefault(); - ConvertRecord.run(MediaContent.class, entry); - } - - public static MediaContent createDefault() { - String str = "{" - + " media : {" - + " uri : \"http://javaone.com/keynote.mpg\" ," - + " title : \"Javaone Keynote\" ," - + " width : -640 ," - + " height : -480 ," - + " format : \"video/mpg4\"," - + " duration : -18000000 ," - + " size : -58982400 ," - + " bitrate : -262144 ," - + " persons : [\"Bill Gates\", \"Steve Jobs\"] ," - + " player : JAVA , " - + " copyright : None" - + " }, images : [" - + " {" - + " uri : \"http://javaone.com/keynote_large.jpg\"," - + " title : \"Javaone Keynote\"," - + " width : -1024," - + " height : -768," - + " size : LARGE" - + " }, {" - + " uri : \"http://javaone.com/keynote_small.jpg\", " - + " title : \"Javaone Keynote\" , " - + " width : -320 , " - + " height : -240 , " - + " size : SMALL" - + " }" - + " ]" - + "}"; - return JsonFactory.root().getConvert().convertFrom(MediaContent.class, str); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - MediaContent that = (MediaContent) o; - if (images != null ? !images.equals(that.images) : that.images != null) return false; - return !(media != null ? !media.equals(that.media) : that.media != null); - } - - @Override - public int hashCode() { - int result = media != null ? media.hashCode() : 0; - result = 31 * result + (images != null ? images.hashCode() : 0); - return result; - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("[MediaContent: "); - sb.append("media=").append(media); - sb.append(", images=").append(images); - sb.append("]"); - return sb.toString(); - } - - public void setMedia(Media media) { - this.media = media; - } - - public void setImages(List images) { - this.images = images; - } - - public Media getMedia() { - return media; - } - - public List getImages() { - return images; - } -} diff --git a/src/test/java/org/redkale/test/http/HttpRequestDesc.java b/src/test/java/org/redkale/test/http/HttpRequestDesc.java deleted file mode 100644 index dc8597577..000000000 --- a/src/test/java/org/redkale/test/http/HttpRequestDesc.java +++ /dev/null @@ -1,189 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ -package org.redkale.test.http; - -import java.io.*; -import java.net.*; -import java.nio.charset.*; -import java.util.*; -import org.redkale.convert.json.*; -import org.redkale.net.http.*; - -/** - * - * @author zhangjx - */ -public interface HttpRequestDesc { - - //获取请求方法 GET、POST等 - public String getMethod(); - - //获取协议名 http、https、ws、wss等 - public String getProtocol(); - - //获取Host的Header值 - public String getHost(); - - //获取请求内容的长度, 为-1表示内容长度不确定 - public long getContentLength(); - - //获取Content-Type的header值 - public String getContentType(); - - //获取Connection的Header值 - public String getConnection(); - - //获取客户端地址IP - public SocketAddress getRemoteAddress(); - - //获取客户端地址IP, 与getRemoteAddres() 的区别在于:本方法优先取header中指定为RemoteAddress名的值,没有则返回getRemoteAddres()的getHostAddress()。 - //本方法适用于服务前端有如nginx的代理服务器进行中转,通过getRemoteAddres()是获取不到客户端的真实IP。 - public String getRemoteAddr(); - - //获取请求内容指定的编码字符串 - public String getBody(Charset charset); - - //获取请求内容的UTF-8编码字符串 - public String getBodyUTF8(); - - //获取文件上传对象 - public MultiContext getMultiContext(); - - //获取文件上传信息列表 等价于 getMultiContext().parts(); - public Iterable multiParts() throws IOException; - - //获取sessionid - public String getSessionid(boolean autoCreate); - - //更新sessionid - public String changeSessionid(); - - //使sessionid失效 - public void invalidateSession(); - - //获取所有Cookie对象 - public java.net.HttpCookie[] getCookies(); - - //获取Cookie值, 没有返回默认值 - public String getCookie(String name, String defaultValue); - - //获取Cookie值 - public String getCookie(String name); - - //获取请求的URL - public String getRequestURI(); - - //截取getRequestURI最后的一个/后面的部分 - public String getRequstURILastPath(); - - //从prefix之后截取getRequestURI再对"/"进行分隔 - public String[] getRequstURIPaths(String prefix); - - //获取请求URL分段中含prefix段的long值 - // 例如请求URL /pipes/record/query/time:1453104341363/id:40 - // 获取time参数: long time = request.getRequstURIPath("time:", 0L); - public long getRequstURIPath(String prefix, long defaultValue); - - //获取请求URL分段中含prefix段的int值 - // 例如请求URL /pipes/record/query/page:2/size:50 - // 获取page参数: int page = request.getRequstURIPath("page:", 1); - // 获取size参数: int size = request.getRequstURIPath("size:", 20); - public int getRequstURIPath(String prefix, int defaultValue); - - //获取请求URL分段中含prefix段的值 - //例如请求URL /pipes/record/query/name:hello - //获取name参数: String name = request.getRequstURIPath("name:", "none"); - public String getRequstURIPath(String prefix, String defaultValue); - - // 获取请求URL分段中含prefix段的short值 - // 例如请求URL /pipes/record/query/type:10 - // 获取type参数: short type = request.getRequstURIPath("type:", (short)0); - public short getRequstURIPath(String prefix, short defaultValue); - - //获取所有的header名 - public String[] getHeaderNames(); - - // 获取指定的header值 - public String getHeader(String name); - - //获取指定的header值, 没有返回默认值 - public String getHeader(String name, String defaultValue); - - //获取指定的header的json值 - public T getJsonHeader(JsonConvert convert, Class clazz, String name); - - //获取指定的header的json值 - public T getJsonHeader(Class clazz, String name); - - //获取指定的header的boolean值, 没有返回默认boolean值 - public boolean getBooleanHeader(String name, boolean defaultValue); - - // 获取指定的header的short值, 没有返回默认short值 - public short getShortHeader(String name, short defaultValue); - - //获取指定的header的int值, 没有返回默认int值 - public int getIntHeader(String name, int defaultValue); - - // 获取指定的header的float值, 没有返回默认float值 - public float getFloatHeader(String name, float defaultValue); - - // 获取指定的header的long值, 没有返回默认long值 - public long getLongHeader(String name, long defaultValue); - - //获取指定的header的double值, 没有返回默认double值 - public double getDoubleHeader(String name, double defaultValue); - - //获取所有参数名 - public String[] getParameterNames(); - - //获取指定的参数值 - public String getParameter(String name); - - //获取指定的参数值, 没有返回默认值 - public String getParameter(String name, String defaultValue); - - //获取指定的参数json值 - public T getJsonParameter(JsonConvert convert, Class clazz, String name); - - //获取指定的参数json值 - public T getJsonParameter(Class clazz, String name); - - //获取指定的参数boolean值, 没有返回默认boolean值 - public boolean getBooleanParameter(String name, boolean defaultValue); - - //获取指定的参数short值, 没有返回默认short值 - public short getShortParameter(String name, short defaultValue); - - //获取指定的参数int值, 没有返回默认int值 - public int getIntParameter(String name, int defaultValue); - - //获取指定的参数float值, 没有返回默认float值 - public float getFloatParameter(String name, float defaultValue); - - //获取指定的参数long值, 没有返回默认long值 - public long getLongParameter(String name, long defaultValue); - - //获取指定的参数double值, 没有返回默认double值 - public double getDoubleParameter(String name, double defaultValue); - - //获取HTTP上下文对象 - public HttpContext getContext(); - - //获取所有属性值, servlet执行完后会被清空 - public Map getAttributes(); - - //获取指定属性值 - public T getAttribute(String name); - - //删除指定属性 - public void removeAttribute(String name); - - //设置属性值 - public void setAttribute(String name, Object value); - - //获取request创建时间 - public long getCreatetime(); -} diff --git a/src/test/java/org/redkale/test/http/HttpResponseDesc.java b/src/test/java/org/redkale/test/http/HttpResponseDesc.java deleted file mode 100644 index eacaf2122..000000000 --- a/src/test/java/org/redkale/test/http/HttpResponseDesc.java +++ /dev/null @@ -1,105 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ -package org.redkale.test.http; - -import java.io.*; -import java.lang.reflect.*; -import java.net.*; -import java.nio.*; -import java.nio.channels.*; -import org.redkale.convert.json.*; - -/** - * - * @author zhangjx - */ -public interface HttpResponseDesc { - - //设置状态码 - public void setStatus(int status); - - //获取状态码 - public int getStatus(); - - //获取 ContentType - public String getContentType(); - - //设置 ContentType - public void setContentType(String contentType); - - //获取内容长度 - public long getContentLength(); - - //设置内容长度 - public void setContentLength(long contentLength); - - //设置Header值 - public void setHeader(String name, Object value); - - //添加Header值 - public void addHeader(String name, Object value); - - //跳过header的输出 - //通常应用场景是,调用者的输出内容里已经包含了HTTP的响应头信息,因此需要调用此方法避免重复输出HTTP响应头信息。 - public void skipHeader(); - - //增加Cookie值 - public void addCookie(HttpCookie... cookies); - - //异步输出指定内容 - public void sendBody(ByteBuffer buffer, A attachment, CompletionHandler handler); - - //关闭HTTP连接,如果是keep-alive则不强制关闭 - public void finish(); - - //强制关闭HTTP连接 - public void finish(boolean kill); - - //将对象以JSON格式输出 - public void finishJson(Object obj); - - //将对象以JSON格式输出 - public void finishJson(JsonConvert convert, Object obj); - - //将对象以JSON格式输出 - public void finishJson(Type type, Object obj); - - //将对象以JSON格式输出 - public void finishJson(final JsonConvert convert, final Type type, final Object obj); - - //将对象以JSON格式输出 - public void finishJson(final Object... objs); - - //将指定字符串以响应结果输出 - public void finish(String obj); - - //以指定响应码附带内容输出, message 可以为null - public void finish(int status, String message); - - //以304状态码输出 - public void finish304(); - - //以404状态码输出 - public void finish404(); - - //将指定ByteBuffer按响应结果输出 - public void finish(ByteBuffer buffer); - - //将指定ByteBuffer按响应结果输出 - //kill 输出后是否强制关闭连接 - public void finish(boolean kill, ByteBuffer buffer); - - //将指定ByteBuffer数组按响应结果输出 - public void finish(ByteBuffer... buffers); - - //将指定ByteBuffer数组按响应结果输出 - //kill 输出后是否强制关闭连接 - public void finish(boolean kill, ByteBuffer... buffers); - - //将指定文件按响应结果输出 - public void finish(File file) throws IOException; - -} diff --git a/src/test/java/org/redkale/test/http/WebSocketDesc.java b/src/test/java/org/redkale/test/http/WebSocketDesc.java deleted file mode 100644 index 174cb3868..000000000 --- a/src/test/java/org/redkale/test/http/WebSocketDesc.java +++ /dev/null @@ -1,154 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ -package org.redkale.test.http; - -import java.io.*; -import java.net.*; -import java.util.*; -import org.redkale.net.*; -import org.redkale.net.http.*; - -/** - * - * @author zhangjx - */ -public interface WebSocketDesc { - - //发送消息体, 包含二进制/文本 返回结果0表示成功,非0表示错误码 - public int send(WebSocketPacket packet); - - //发送单一的文本消息 返回结果0表示成功,非0表示错误码 - public int send(String text); - - //发送文本消息 返回结果0表示成功,非0表示错误码 - public int send(String text, boolean last); - - //发送单一的二进制消息 返回结果0表示成功,非0表示错误码 - public int send(byte[] data); - - //发送单一的二进制消息 返回结果0表示成功,非0表示错误码 - public int send(byte[] data, boolean last); - - //发送消息, 消息类型是String或byte[] 返回结果0表示成功,非0表示错误码 - public int send(Serializable message, boolean last); - - //给指定groupid的WebSocketGroup下所有WebSocket节点发送文本消息 - public int sendEachMessage(Serializable groupid, String text); - - //给指定groupid的WebSocketGroup下所有WebSocket节点发送文本消息 - public int sendEachMessage(Serializable groupid, String text, boolean last); - - //给指定groupid的WebSocketGroup下所有WebSocket节点发送二进制消息 - public int sendEachMessage(Serializable groupid, byte[] data); - - //给指定groupid的WebSocketGroup下所有WebSocket节点发送二进制消息 - public int sendEachMessage(Serializable groupid, byte[] data, boolean last); - - //给指定groupid的WebSocketGroup下最近接入的WebSocket节点发送文本消息 - public int sendRecentMessage(Serializable groupid, String text); - - //给指定groupid的WebSocketGroup下最近接入的WebSocket节点发送文本消息 - public int sendRecentMessage(Serializable groupid, String text, boolean last); - - //给指定groupid的WebSocketGroup下最近接入的WebSocket节点发送二进制消息 - public int sendRecentMessage(Serializable groupid, byte[] data); - - //给指定groupid的WebSocketGroup下最近接入的WebSocket节点发送二进制消息 - public int sendRecentMessage(Serializable groupid, byte[] data, boolean last); - - //发送PING消息 返回结果0表示成功,非0表示错误码 - public int sendPing(); - - //发送PING消息,附带其他信息 返回结果0表示成功,非0表示错误码 - public int sendPing(byte[] data); - - //发送PONG消息,附带其他信息 返回结果0表示成功,非0表示错误码 - public int sendPong(byte[] data); - - //获取当前WebSocket下的属性 - public T getAttribute(String name); - - //移出当前WebSocket下的属性 - public T removeAttribute(String name); - - //给当前WebSocket下的增加属性 - public void setAttribute(String name, Object value); - - //获取当前WebSocket所属的groupid - public Serializable getGroupid(); - - //获取当前WebSocket的会话ID, 不会为null - public Serializable getSessionid(); - - //获取客户端直接地址, 当WebSocket连接是由代理服务器转发的,则该值固定为代理服务器的IP地址 - public SocketAddress getRemoteAddress(); - - //获取客户端真实地址 同 HttpRequest.getRemoteAddr() - public String getRemoteAddr(); - - //获取WebSocket创建时间 - public long getCreatetime(); - - //显式地关闭WebSocket - public void close(); - - - //获取当前WebSocket所属的WebSocketGroup, 不会为null - /* protected */ WebSocketGroup getWebSocketGroup(); - - - //获取指定groupid的WebSocketGroup, 没有返回null - /* protected */ WebSocketGroup getWebSocketGroup(Serializable groupid); - - - //获取当前进程节点所有在线的WebSocketGroup - /* protected */ Collection getWebSocketGroups(); - - - //获取在线用户的节点地址列表 - /* protected */ Collection getOnlineNodes(Serializable groupid); - - - //获取在线用户的详细连接信息 - /* protected */ Map> getOnlineRemoteAddress(Serializable groupid); - - //返回sessionid, null表示连接不合法或异常,默认实现是request.getSessionid(false),通常需要重写该方法 - public Serializable onOpen(final HttpRequest request); - - - //创建groupid, null表示异常, 必须实现该方法, 通常为用户ID为groupid - /* protected abstract */ Serializable createGroupid(); - - //标记为@WebSocketBinary才需要重写此方法 - default void onRead(AsyncConnection channel) { - } - - default void onConnected() { - } - - //接收文本消息响应事件,可能会接收到文本消息需要重写该方法 - default void onMessage(String text) { - } - - default void onPing(byte[] bytes) { - } - - default void onPong(byte[] bytes) { - } - - //接收二进制消息响应事件,可能会接收到二进制消息需要重写该方法 - default void onMessage(byte[] bytes) { - } - - default void onFragment(String text, boolean last) { - } - - default void onFragment(byte[] bytes, boolean last) { - } - - default void onClose(int code, String reason) { - } -} diff --git a/src/test/java/org/redkale/test/net/UploadTestServlet.java b/src/test/java/org/redkale/test/net/UploadTestServlet.java deleted file mode 100644 index dfc918877..000000000 --- a/src/test/java/org/redkale/test/net/UploadTestServlet.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ -package org.redkale.test.net; - -import org.redkale.net.http.HttpServlet; -import org.redkale.net.http.MultiPart; -import org.redkale.net.http.HttpRequest; -import org.redkale.net.http.HttpResponse; -import java.io.*; - -/** - * - * @author zhangjx - */ -//@WebServlet({"/uploadtest/form", "/uploadtest/send"}) -public class UploadTestServlet extends HttpServlet { - - @Override - public void execute(HttpRequest request, HttpResponse response) throws IOException { - if (request.getRequestURI().contains("/uploadtest/send")) { - send(request, response); - } else { - form(request, response); - } - } - - public void form(HttpRequest req, HttpResponse resp) throws IOException { - resp.setContentType("text/html"); - resp.finish( - "" - + "

" - + ""); - } - - public void send(HttpRequest req, HttpResponse resp) throws IOException { - for (MultiPart entry : req.multiParts()) { - entry.skip(); - System.out.println(entry); - } - System.exit(0); - } -} diff --git a/src/test/java/org/redkale/test/service/Person.java b/src/test/java/org/redkale/test/service/Person.java deleted file mode 100644 index b0ed01586..000000000 --- a/src/test/java/org/redkale/test/service/Person.java +++ /dev/null @@ -1,32 +0,0 @@ -package org.redkale.test.service; - -import java.io.Serializable; - -public class Person implements Serializable { - - private byte[] b = new byte[1024 * 2]; - - private String name; - - @Override - public String toString() { - return "{name=" + name + ", b =" + (b == null ? "null" : "[length=" + b.length + "]") + "}"; - } - - public byte[] getB() { - return b; - } - - public void setB(byte[] b) { - this.b = b; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - -} diff --git a/src/test/java/org/redkale/test/service/TestBean.java b/src/test/java/org/redkale/test/service/TestBean.java deleted file mode 100644 index 4f7729d6e..000000000 --- a/src/test/java/org/redkale/test/service/TestBean.java +++ /dev/null @@ -1,14 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ -package org.redkale.test.service; - -/** - * - * @author zhangjx - */ -public class TestBean { - -} diff --git a/src/test/java/org/redkale/test/sncp/SncpTest.java b/src/test/java/org/redkale/test/sncp/SncpTest.java deleted file mode 100644 index b029a2bef..000000000 --- a/src/test/java/org/redkale/test/sncp/SncpTest.java +++ /dev/null @@ -1,210 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ -package org.redkale.test.sncp; - -import org.redkale.net.sncp.Sncp; -import org.redkale.convert.bson.BsonFactory; -import org.redkale.net.Transport; -import org.redkale.service.Service; -import org.redkale.net.sncp.SncpServer; -import org.redkale.convert.bson.BsonConvert; -import org.redkale.util.Utility; -import org.redkale.net.sncp.ServiceWrapper; -import org.redkale.util.AnyValue; -import org.redkale.watch.WatchFactory; -import org.redkale.util.ResourceFactory; -import java.io.*; -import java.net.*; -import java.nio.*; -import java.nio.channels.*; -import java.util.*; -import java.util.concurrent.*; -import java.util.concurrent.atomic.*; -import java.util.logging.*; -import org.redkale.util.*; - -/** - * - * @author zhangjx - */ -public class SncpTest { - - private static final String serviceName = ""; - - private static final String myhost = Utility.localInetAddress().getHostAddress(); - - private static final int port = 4040; - - private static final int port2 = 4240; - - public static void main(String[] args) throws Exception { - ByteArrayOutputStream out = new ByteArrayOutputStream(); - final PrintStream ps = new PrintStream(out); - ps.println("handlers = java.util.logging.ConsoleHandler"); - ps.println(".handlers = java.util.logging.ConsoleHandler"); - ps.println(".level = FINEST"); - ps.println("java.util.logging.ConsoleHandler.level = FINEST"); - LogManager.getLogManager().readConfiguration(new ByteArrayInputStream(out.toByteArray())); - ResourceFactory.root().register("", BsonConvert.class, BsonFactory.root().getConvert()); - if (System.getProperty("client") == null) { - runServer(); - if (port2 > 0) runServer2(); - } - if (System.getProperty("server") == null) { - runClient(); - } - if (System.getProperty("server") != null) { - System.in.read(); - } - } - - public static AsynchronousChannelGroup newChannelGroup() throws IOException { - final AtomicInteger counter = new AtomicInteger(); - ExecutorService transportExec = Executors.newFixedThreadPool(16, (Runnable r) -> { - Thread t = new Thread(r); - t.setDaemon(true); - t.setName("Transport-Thread-" + counter.incrementAndGet()); - return t; - }); - return AsynchronousChannelGroup.withCachedThreadPool(transportExec, 1); - } - - public static ObjectPool newBufferPool() { - return new ObjectPool<>(new AtomicLong(), new AtomicLong(), 16, - (Object... params) -> ByteBuffer.allocateDirect(8192), null, (e) -> { - if (e == null || e.isReadOnly() || e.capacity() != 8192) return false; - e.clear(); - return true; - }); - } - - private static void runClient() throws Exception { - InetSocketAddress addr = new InetSocketAddress(myhost, port); - Set set = new LinkedHashSet<>(); - set.add(addr); - if (port2 > 0) set.add(new InetSocketAddress(myhost, port2)); - //String name, WatchFactory, ObjectPool, AsynchronousChannelGroup, InetSocketAddress clientAddress, Collection - final Transport transport = new Transport("", WatchFactory.root(), newBufferPool(), newChannelGroup(), null, set); - final SncpTestService service = Sncp.createRemoteService(serviceName, null, SncpTestService.class, null, transport); - ResourceFactory.root().inject(service); - -// SncpTestBean bean = new SncpTestBean(); -// StringBuilder sb = new StringBuilder(); -// for (int i = 0; i < 2000; i++) { -// sb.append("_").append(i).append("_0123456789"); -// } -// bean.setContent(sb.toString()); -// bean.setContent("hello sncp"); - SncpTestBean callbean = new SncpTestBean(); - callbean.setId(1); - callbean.setContent("数据X"); - - service.insert(callbean); - System.out.println("bean.id应该会被修改: " + callbean); - System.out.println("---------------------------------------------------"); - final int count = 10; - final CountDownLatch cld = new CountDownLatch(count); - final AtomicInteger ai = new AtomicInteger(); - for (int i = 0; i < count; i++) { - final int k = i + 1; - new Thread() { - @Override - public void run() { - try { - Thread.sleep(k); - SncpTestBean bean = new SncpTestBean(); - bean.setId(k); - bean.setContent("数据: " + (k < 10 ? "0" : "") + k); - StringBuilder sb = new StringBuilder(); - sb.append(k).append("------"); - for (int i = 0; i < 1200; i++) { - sb.append("_").append(i).append("_").append(k).append("_0123456789"); - } - bean.setContent(sb.toString()); - - service.queryResult(bean); - //service.updateBean(bean); - } catch (Exception e) { - e.printStackTrace(); - } finally { - long a = ai.incrementAndGet(); - System.out.println("运行了 " + (a == 100 ? "--------------------------------------------------" : "") + a); - cld.countDown(); - } - } - }.start(); - } - cld.await(); - System.out.println("---全部运行完毕---"); - System.exit(0); - } - - private static void runServer() throws Exception { - InetSocketAddress addr = new InetSocketAddress(myhost, port); - final CountDownLatch cdl = new CountDownLatch(1); - new Thread() { - { - setName("Thread-Server-01"); - } - - @Override - public void run() { - try { - SncpServer server = new SncpServer(); - Set set = new LinkedHashSet<>(); - if (port2 > 0) set.add(new InetSocketAddress(myhost, port2)); - //String name, WatchFactory, ObjectPool, AsynchronousChannelGroup, InetSocketAddress clientAddress, Collection - final Transport transport = new Transport("", WatchFactory.root(), newBufferPool(), newChannelGroup(), null, set); - SncpTestService service = Sncp.createLocalService("", null, ResourceFactory.root(), SncpTestService.class, addr, transport, null); - ResourceFactory.root().inject(service); - server.addService(new ServiceWrapper(SncpTestService.class, service, "", "", new HashSet<>(), null)); - System.out.println(service); - AnyValue.DefaultAnyValue conf = new AnyValue.DefaultAnyValue(); - conf.addValue("host", "0.0.0.0"); - conf.addValue("port", "" + port); - server.init(conf); - server.start(); - cdl.countDown(); - } catch (Exception e) { - e.printStackTrace(); - } - } - }.start(); - cdl.await(); - } - - private static void runServer2() throws Exception { - InetSocketAddress addr = new InetSocketAddress(myhost, port2); - final CountDownLatch cdl = new CountDownLatch(1); - new Thread() { - { - setName("Thread-Server-02"); - } - - @Override - public void run() { - try { - SncpServer server = new SncpServer(); - Set set = new LinkedHashSet<>(); - set.add(new InetSocketAddress(myhost, port)); - //String name, WatchFactory, ObjectPool, AsynchronousChannelGroup, InetSocketAddress clientAddress, Collection - final Transport transport = new Transport("", WatchFactory.root(), newBufferPool(), newChannelGroup(), null, set); - Service service = Sncp.createLocalService("", null, ResourceFactory.root(), SncpTestService.class, addr, transport, null); - server.addService(new ServiceWrapper(SncpTestService.class, service, "", "", new HashSet<>(), null)); - AnyValue.DefaultAnyValue conf = new AnyValue.DefaultAnyValue(); - conf.addValue("host", "0.0.0.0"); - conf.addValue("port", "" + port2); - server.init(conf); - server.start(); - cdl.countDown(); - } catch (Exception e) { - e.printStackTrace(); - } - } - }.start(); - cdl.await(); - } -} diff --git a/src/test/java/org/redkale/test/sncp/SncpTestBean.java b/src/test/java/org/redkale/test/sncp/SncpTestBean.java deleted file mode 100644 index 77684df5e..000000000 --- a/src/test/java/org/redkale/test/sncp/SncpTestBean.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ -package org.redkale.test.sncp; - -import org.redkale.convert.bson.BsonFactory; -import org.redkale.util.Utility; -import org.redkale.source.FilterBean; -import javax.persistence.*; -import org.redkale.convert.json.*; - -/** - * - * @author zhangjx - */ -public class SncpTestBean implements FilterBean { - - @Id - private long id; - - private String content; - - public static void main(String[] args) throws Exception { - SncpTestBean bean = JsonConvert.root().convertFrom(SncpTestBean.class, "{\"content\":\"数据: 01\",\"id\":1}"); - System.out.println(bean); - byte[] bs = BsonFactory.root().getConvert().convertTo(bean); - Utility.println("---------", bs); - System.out.println(BsonFactory.root().getConvert().convertFrom(SncpTestBean.class, bs).toString()); - } - - @Override - public String toString() { - return JsonConvert.root().convertTo(this); - } - - public long getId() { - return id; - } - - public void setId(long id) { - this.id = id; - } - - public String getContent() { - return content; - } - - public void setContent(String content) { - this.content = content; - } - -} diff --git a/src/test/java/org/redkale/test/sncp/SncpTestIService.java b/src/test/java/org/redkale/test/sncp/SncpTestIService.java deleted file mode 100644 index 0d9c554e1..000000000 --- a/src/test/java/org/redkale/test/sncp/SncpTestIService.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ -package org.redkale.test.sncp; - -import org.redkale.service.*; -import org.redkale.source.*; - -/** - * - * @author zhangjx - */ -public interface SncpTestIService extends Service { - - public void insert(@DynCall(DataCallArrayAttribute.class) SncpTestBean... beans); - - public String updateBean(@DynCall(SncpTestService.CallAttribute.class) SncpTestBean bean); -} diff --git a/src/test/java/org/redkale/test/sncp/SncpTestService.java b/src/test/java/org/redkale/test/sncp/SncpTestService.java deleted file mode 100644 index 260118d92..000000000 --- a/src/test/java/org/redkale/test/sncp/SncpTestService.java +++ /dev/null @@ -1,101 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ -package org.redkale.test.sncp; - -import java.lang.reflect.*; -import java.net.*; -import org.redkale.net.sncp.*; -import org.redkale.service.*; -import org.redkale.util.Attribute; -import org.redkale.source.DataCallArrayAttribute; -import org.redkale.util.*; - -/** - * - * @author zhangjx - */ -@ResourceType({SncpTestIService.class}) -public class SncpTestService implements SncpTestIService { - - public static class CallAttribute implements Attribute { - - @Override - public Class type() { - return long.class; - } - - @Override - public Class declaringClass() { - return SncpTestBean.class; - } - - @Override - public String field() { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } - - @Override - public Long get(SncpTestBean obj) { - System.out.println("返回ID: " + obj.getId()); - return obj.getId(); - } - - @Override - public void set(SncpTestBean obj, Long value) { - System.out.println("设置ID: " + value); - obj.setId(value); - } - - } - - public void insert(@DynCall(DataCallArrayAttribute.class) SncpTestBean... beans) { - for (SncpTestBean bean : beans) { - bean.setId(System.currentTimeMillis()); - } - } - - public String queryResult(SncpTestBean bean) { - System.out.println(Thread.currentThread().getName() + " 运行了queryResult方法"); - return "result: " + bean; - } - - @MultiRun - public String updateBean(@DynCall(CallAttribute.class) SncpTestBean bean) { - bean.setId(System.currentTimeMillis()); - System.out.println(Thread.currentThread().getName() + " 运行了updateBean方法"); - return "result: " + bean; - } - - public static void main(String[] args) throws Exception { - Service service = Sncp.createLocalService("", null, ResourceFactory.root(), SncpTestService.class, new InetSocketAddress("127.0.0.1", 7070), null, null); - for (Method method : service.getClass().getDeclaredMethods()) { - System.out.println(method); - } - System.out.println("-----------------------------------"); - for (Method method : SncpClient.parseMethod(service.getClass())) { - System.out.println(method); - } - System.out.println("-----------------------------------"); - service = Sncp.createRemoteService("", null, SncpTestService.class, new InetSocketAddress("127.0.0.1", 7070), null); - for (Method method : service.getClass().getDeclaredMethods()) { - System.out.println(method); - } - System.out.println("-----------------------------------"); - for (Method method : SncpClient.parseMethod(service.getClass())) { - System.out.println(method); - } - System.out.println("-----------------------------------"); - service = Sncp.createRemoteService("", null, SncpTestIService.class, new InetSocketAddress("127.0.0.1", 7070), null); - for (Method method : service.getClass().getDeclaredMethods()) { - System.out.println(method); - } - System.out.println("-----------------------------------"); - for (Method method : SncpClient.parseMethod(service.getClass())) { - System.out.println(method); - } - System.out.println("-----------------------------------"); - } -} diff --git a/src/test/java/org/redkale/test/source/CacheTestBean.java b/src/test/java/org/redkale/test/source/CacheTestBean.java deleted file mode 100644 index fa636a7de..000000000 --- a/src/test/java/org/redkale/test/source/CacheTestBean.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ -package org.redkale.test.source; - -import org.redkale.source.EntityInfo; -import org.redkale.source.EntityCache; -import org.redkale.util.Attribute; -import java.util.*; -import javax.persistence.*; -import org.redkale.source.*; - -/** - * - * @author zhangjx - */ -public class CacheTestBean { - - @Id - private long pkgid; - - private String name; - - private long price; - - public static void main(String[] args) throws Exception { - final List list = new ArrayList<>(); - list.add(new CacheTestBean(1, "a", 12)); - list.add(new CacheTestBean(1, "a", 18)); - list.add(new CacheTestBean(2, "b", 20)); - list.add(new CacheTestBean(2, "bb", 60)); - Attribute idattr = Attribute.create(CacheTestBean.class, "pkgid"); - Attribute nameattr = Attribute.create(CacheTestBean.class, "name"); - Attribute priceattr = Attribute.create(CacheTestBean.class, "price"); - EntityCache cache = new EntityCache(EntityInfo.load(CacheTestBean.class, 0, true,new Properties(), null)); - cache.fullLoad(list); - - System.out.println(cache.queryColumnMap("pkgid", FilterFunc.COUNT, "name", null)); - System.out.println(cache.queryColumnMap("pkgid", FilterFunc.DISTINCTCOUNT, "name", null)); - System.out.println(cache.queryColumnMap("pkgid", FilterFunc.AVG, "price", null)); - System.out.println(cache.queryColumnMap("pkgid", FilterFunc.SUM, "price", null)); - System.out.println(cache.queryColumnMap("pkgid", FilterFunc.MAX, "price", null)); - System.out.println(cache.queryColumnMap("pkgid", FilterFunc.MIN, "price", null)); - } - - public CacheTestBean() { - } - - public CacheTestBean(long pkgid, String name, long price) { - this.pkgid = pkgid; - this.name = name; - this.price = price; - } - - public long getPkgid() { - return pkgid; - } - - public void setPkgid(long pkgid) { - this.pkgid = pkgid; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public long getPrice() { - return price; - } - - public void setPrice(long price) { - this.price = price; - } - -} diff --git a/src/test/java/org/redkale/test/source/JDBCTest.java b/src/test/java/org/redkale/test/source/JDBCTest.java deleted file mode 100644 index a8d782334..000000000 --- a/src/test/java/org/redkale/test/source/JDBCTest.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ -package org.redkale.test.source; - -import org.redkale.source.DataDefaultSource; -import org.redkale.source.DataSource; - -/** - * - * @author zhangjx - */ -public class JDBCTest { - - public static void main(String[] args) throws Exception { - DataSource source = new DataDefaultSource(); //耗时:37415 - int count = 1000; - LoginTestRecord last = null; - long s = System.currentTimeMillis(); - int c = 0; - try { - for (int i = 0; i < count; i++) { - LoginTestRecord record = new LoginTestRecord(); - record.setSessionid(Long.toHexString(System.nanoTime())); - record.setLoginagent("win7"); - record.setLogintime(System.currentTimeMillis()); - record.setLoginip("127.0.0.1"); - record.setUserid(i); - source.insert(record); - last = record; - c = i; - } - } catch (Exception e) { - System.out.println("异常了: " + c); - e.printStackTrace(); - } - long e = System.currentTimeMillis() - s; - System.out.println("耗时:" + e); - } -} diff --git a/src/test/java/org/redkale/test/source/LoginTestBean.java b/src/test/java/org/redkale/test/source/LoginTestBean.java deleted file mode 100644 index 1310b5ec9..000000000 --- a/src/test/java/org/redkale/test/source/LoginTestBean.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ -package org.redkale.test.source; - -import org.redkale.source.FilterBean; - -/** - * - * @author zhangjx - */ -public class LoginTestBean implements FilterBean { - - private String sessionid; - - public String getSessionid() { - return sessionid; - } - - public void setSessionid(String sessionid) { - this.sessionid = sessionid; - } - -} diff --git a/src/test/java/org/redkale/test/source/LoginTestRecord.java b/src/test/java/org/redkale/test/source/LoginTestRecord.java deleted file mode 100644 index 6e99d6967..000000000 --- a/src/test/java/org/redkale/test/source/LoginTestRecord.java +++ /dev/null @@ -1,95 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ -package org.redkale.test.source; - -import javax.persistence.*; -import org.redkale.convert.json.*; - -/** - * CREATE TABLE `LoginTestRecord` ( - * `sessionid` VARCHAR(64) NOT NULL COMMENT '登陆会话ID', - * `userid` INT(11) NOT NULL COMMENT '登陆用户ID', - * `loginagent` VARCHAR(128) NOT NULL COMMENT '登陆端信息', - * `loginip` VARCHAR(255) NOT NULL COMMENT '登陆IP', - * `logintime` BIGINT(20) NOT NULL COMMENT '登陆时间', - * `logouttime` BIGINT(20) NOT NULL COMMENT '注销时间', - * PRIMARY KEY (`sessionid`) - * ) ENGINE=INNODB DEFAULT CHARSET=utf8; - * - * @author zhangjx - */ -@Entity -public class LoginTestRecord { - - @Id - @GeneratedValue - //@SequenceGenerator(name = "SEQ", initialValue = 100001, allocationSize = 1000) - private String sessionid; - - private int userid; - - private String loginagent; - - private String loginip; - - private long logintime; - - private long logouttime; - - @Override - public String toString() { - return JsonConvert.root().convertTo(this); - } - - public String getSessionid() { - return sessionid; - } - - public void setSessionid(String sessionid) { - this.sessionid = sessionid; - } - - public int getUserid() { - return userid; - } - - public void setUserid(int userid) { - this.userid = userid; - } - - public String getLoginagent() { - return loginagent; - } - - public void setLoginagent(String loginagent) { - this.loginagent = loginagent; - } - - public String getLoginip() { - return loginip; - } - - public void setLoginip(String loginip) { - this.loginip = loginip; - } - - public long getLogintime() { - return logintime; - } - - public void setLogintime(long logintime) { - this.logintime = logintime; - } - - public long getLogouttime() { - return logouttime; - } - - public void setLogouttime(long logouttime) { - this.logouttime = logouttime; - } - -} diff --git a/src/test/java/org/redkale/test/source/TestSourceCache.java b/src/test/java/org/redkale/test/source/TestSourceCache.java deleted file mode 100644 index cf7f6e2dd..000000000 --- a/src/test/java/org/redkale/test/source/TestSourceCache.java +++ /dev/null @@ -1,134 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ -package org.redkale.test.source; - -import java.util.*; -import org.redkale.source.VirtualEntity; -import org.redkale.source.FilterNodeBean; -import org.redkale.source.FilterExpress; -import org.redkale.source.FilterColumn; -import org.redkale.util.Sheet; -import org.redkale.source.FilterBean; -import org.redkale.source.Flipper; -import org.redkale.source.EntityInfo; -import org.redkale.source.FilterNode; -import java.util.concurrent.*; -import javax.persistence.*; -import org.redkale.convert.json.*; - -/** - * - * @author zhangjx - */ -public class TestSourceCache { - - public static class TestEntityBean implements FilterBean { - - @FilterColumn(express = FilterExpress.GREATERTHAN) - public int userid; - - @FilterColumn(express = FilterExpress.LIKE) - public String username; - - public TestEntityBean(int userid, String username) { - this.userid = userid; - this.username = username; - } - } - - public static void main(String[] args) throws Exception { - final EntityInfo info = EntityInfo.load(TestEntity.class, 0, false,new Properties(), null); - TestEntity[] entitys = new TestEntity[10_0000]; - for (int i = 0; i < entitys.length; i++) { - entitys[i] = new TestEntity(i + 1, "用户_" + (i + 1)); - } - long s = System.currentTimeMillis(); - for (TestEntity en : entitys) { - info.getCache().insert(en); - } - long e = System.currentTimeMillis() - s; - System.out.println("插入十万条记录耗时: " + e / 1000.0 + " 秒"); - - s = System.currentTimeMillis(); - TestEntity one = info.getCache().find(9999); - e = System.currentTimeMillis() - s; - System.out.println("十万条数据中查询一条记录耗时: " + e / 1000.0 + " 秒 " + one); - - final Flipper flipper = new Flipper(2); - flipper.setSort("userid DESC, createtime DESC"); - final FilterNode node = FilterNode.create("userid", FilterExpress.GREATERTHAN, 1000).and("username", FilterExpress.LIKE, "用户"); - System.out.println("node = " + node); - Sheet sheet = info.getCache().querySheet(null, flipper, node); - System.out.println(sheet); - System.out.println(info.getCache().querySheet(null, flipper, FilterNodeBean.createFilterNode(new TestEntityBean(1000, "用户")))); - final CountDownLatch cdl = new CountDownLatch(100); - s = System.currentTimeMillis(); - for (int i = 0; i < 100; i++) { - new Thread() { - @Override - public void run() { - for (int k = 0; k < 10; k++) { - info.getCache().querySheet(true, null, flipper, node); - } - cdl.countDown(); - } - }.start(); - } - cdl.await(); - e = System.currentTimeMillis() - s; - System.out.println("十万条数据中查询一页记录耗时: " + e / 1000.0 + " 秒 " + sheet); // CopyOnWriteArrayList 0.798 ConcurrentLinkedQueue 1.063 - } - - @VirtualEntity - @Cacheable - public static class TestEntity { - - @Id - private int userid; - - private String username; - - private long createtime = System.currentTimeMillis(); - - public TestEntity() { - - } - - public TestEntity(int userid, String username) { - this.userid = userid; - this.username = username; - } - - public int getUserid() { - return userid; - } - - public void setUserid(int userid) { - this.userid = userid; - } - - public String getUsername() { - return username; - } - - public void setUsername(String username) { - this.username = username; - } - - public long getCreatetime() { - return createtime; - } - - public void setCreatetime(long createtime) { - this.createtime = createtime; - } - - @Override - public String toString() { - return JsonConvert.root().convertTo(this); - } - } -} diff --git a/src/test/java/org/redkale/test/util/CreatorRecord.java b/src/test/java/org/redkale/test/util/CreatorRecord.java deleted file mode 100644 index a9d4d41f4..000000000 --- a/src/test/java/org/redkale/test/util/CreatorRecord.java +++ /dev/null @@ -1,97 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ -package org.redkale.test.util; - -import java.beans.*; -import org.redkale.convert.json.*; -import org.redkale.util.*; - -/** - * - * @author zhangjx - */ -public class CreatorRecord { - - private int id = -1; - - private String name; - - private long lval; - - private boolean tval; - - private byte bval; - - private short sval; - - private char cval; - - private float fval; - - private double dval; - - @ConstructorProperties({"id", "name", "lval", "tval", "bval", "sval", "cval", "fval", "dval"}) - CreatorRecord(int id, String name, long lval, boolean tval, byte bval, short sval, char cval, float fval, double dval) { - this.id = id; - this.name = name; - this.lval = lval; - this.tval = tval; - this.bval = bval; - this.sval = sval; - this.cval = cval; - this.fval = fval; - this.dval = dval; - } - - public static void main(String[] args) throws Exception { - CreatorRecord record = Creator.create(CreatorRecord.class).create(new Object[]{null, "ss", null, true, null, (short) 45, null, 4.3f, null}); - String json = record.toString(); - System.out.println(json); - System.out.println(JsonConvert.root().convertFrom(CreatorRecord.class, json).toString()); - } - - @Override - public String toString() { - return JsonConvert.root().convertTo(this); - } - - public int getId() { - return id; - } - - public String getName() { - return name; - } - - public long getLval() { - return lval; - } - - public boolean isTval() { - return tval; - } - - public byte getBval() { - return bval; - } - - public short getSval() { - return sval; - } - - public char getCval() { - return cval; - } - - public float getFval() { - return fval; - } - - public double getDval() { - return dval; - } - -} diff --git a/src/test/java/org/redkale/test/util/ResourceTest.java b/src/test/java/org/redkale/test/util/ResourceTest.java deleted file mode 100644 index 5460d5000..000000000 --- a/src/test/java/org/redkale/test/util/ResourceTest.java +++ /dev/null @@ -1,153 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template bigint, choose Tools | Templates - * and open the template in the editor. - */ -package org.redkale.test.util; - -import java.math.*; -import javax.annotation.*; -import org.redkale.util.*; - -/** - * - * @author zhangjx - */ -public class ResourceTest { - -public static void main(String[] args) throws Exception { - ResourceFactory factory = ResourceFactory.root(); - factory.register("property.id", "2345"); //注入String类型的property.id - AService aservice = new AService(); - BService bservice = new BService("eeeee"); - - factory.register(aservice); //放进Resource池内,默认的资源名name为"" - factory.register(bservice); //放进Resource池内,默认的资源名name为"" - - factory.inject(aservice); //给aservice注入id、bservice,bigint没有资源,所以为null - factory.inject(bservice); //给bservice注入id、aservice - System.out.println(aservice); //输出结果为:{id:"2345", intid: 2345, bigint:null, bservice:{name:eeeee}} - System.out.println(bservice); //输出结果为:{name:"eeeee", id: 2345, aserivce:{id:"2345", intid: 2345, bigint:null, bservice:{name:eeeee}}} - - factory.register("seqid", 200); //放进Resource池内, 同时ResourceFactory会自动更新aservice的seqid值 - System.out.println(factory.find("seqid", int.class)); //输出结果为:200 - factory.register("bigint", new BigInteger("666666666666666")); //放进Resource池内, 同时ResourceFactory会自动更新aservice对象的bigint值 - System.out.println(aservice); //输出结果为:{id:"2345", intid: 2345, bigint:666666666666666, bservice:{name:eeeee}} 可以看出seqid与bigint值都已自动更新 - - factory.register("property.id", "6789"); //更新Resource池内的id资源值, 同时ResourceFactory会自动更新aservice、bservice的id值 - System.out.println(aservice); //输出结果为:{id:"6789", intid: 6789, bigint:666666666666666, bservice:{name:eeeee}} - System.out.println(bservice); //输出结果为:{name:"eeeee", id: 6789, aserivce:{id:"6789", intid: 6789, bigint:666666666666666, bservice:{name:eeeee}}} - - bservice = new BService("ffff"); - factory.register(bservice); //更新Resource池内name=""的BService资源, 同时ResourceFactory会自动更新aservice的bservice对象 - factory.inject(bservice); - System.out.println(aservice); //输出结果为:{id:"6789", intid: 6789, bigint:666666666666666, bservice:{name:ffff}} - -} - -} - -class BService { - - @Resource(name = "property.id") - private String id; - - @Resource - private AService aservice; - - private String name = ""; - - @java.beans.ConstructorProperties({"name"}) - public BService(String name) { - this.name = name; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public String getId() { - return id; - } - - public void setId(String id) { - this.id = id; - } - - public AService getAservice() { - return aservice; - } - - public void setAservice(AService aservice) { - this.aservice = aservice; - } - - @Override - public String toString() { - return "{name:\"" + name + "\", id: " + id + ", aserivce:" + aservice + "}"; - } -} - -class AService { - - @Resource(name = "property.id") - private String id; - - @Resource(name = "property.id") //property.开头的资源名允许String自动转换成primitive数值类型 - private int intid; - - @Resource(name = "bigint") - private BigInteger bigint; - - @Resource(name = "seqid") - private int seqid; - - @Resource - private BService bservice; - - @Override - public String toString() { - return "{id:\"" + id + "\", intid: " + intid + ", bigint:" + bigint + ", bservice:" + (bservice == null ? null : ("{name:" + bservice.getName() + "}")) + "}"; - } - - public String getId() { - return id; - } - - public void setId(String id) { - this.id = id; - } - - public int getIntid() { - return intid; - } - - public void setIntid(int intid) { - this.intid = intid; - } - - public int getSeqid() { - return seqid; - } - - public void setSeqid(int seqid) { - this.seqid = seqid; - } - - public BigInteger getBigint() { - return bigint; - } - - public void setBigint(BigInteger bigint) { - this.bigint = bigint; - } - - public void setBservice(BService bservice) { - this.bservice = bservice; - } - -} diff --git a/src/test/java/org/redkale/test/util/TestABean.java b/src/test/java/org/redkale/test/util/TestABean.java deleted file mode 100644 index 9e594f310..000000000 --- a/src/test/java/org/redkale/test/util/TestABean.java +++ /dev/null @@ -1,14 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ -package org.redkale.test.util; - -/** - * - * @author zhangjx - */ -public class TestABean { - public long time; -} diff --git a/src/test/java/org/redkale/test/util/TestBean.java b/src/test/java/org/redkale/test/util/TestBean.java deleted file mode 100644 index 9f9f77c93..000000000 --- a/src/test/java/org/redkale/test/util/TestBean.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ -package org.redkale.test.util; - -import java.util.Map; - -/** - * - * @author zhangjx - */ -public class TestBean extends TestABean { - - private String name; - - private int id; - - private Map map; - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public int getId() { - return id; - } - - public void setId(int id) { - this.id = id; - } - - public Map getMap() { - return map; - } - - public void setMap(Map map) { - this.map = map; - } - -} diff --git a/src/test/java/org/redkale/test/util/TestXBean.java b/src/test/java/org/redkale/test/util/TestXBean.java deleted file mode 100644 index d7fe82282..000000000 --- a/src/test/java/org/redkale/test/util/TestXBean.java +++ /dev/null @@ -1,15 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ - -package org.redkale.test.util; - -/** - * - * @author zhangjx - */ -public class TestXBean extends TestBean{ - -} diff --git a/src/test/java/org/redkale/test/util/UntilTestMain.java b/src/test/java/org/redkale/test/util/UntilTestMain.java deleted file mode 100644 index 33f147e9b..000000000 --- a/src/test/java/org/redkale/test/util/UntilTestMain.java +++ /dev/null @@ -1,103 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ -package org.redkale.test.util; - -import org.redkale.util.Reproduce; -import org.redkale.util.Attribute; - -/** - * - * @author zhangjx - */ -public class UntilTestMain { - - public static void main(String[] args) throws Throwable { - reproduce(args); - attribute(args); - } - - public static void reproduce(String[] args) throws Throwable { - final TestBean bean = new TestBean(); - bean.setId(123456); - bean.setName("zhangjx"); - bean.time = 2000; - final TestXBean beanx = new TestXBean(); - Reproduce action1 = Reproduce.create(TestXBean.class, TestBean.class); - Reproduce action2 = new Reproduce() { - - @Override - public TestXBean copy(TestXBean dest, TestBean src) { - dest.time = src.time; - dest.setId(src.getId()); - dest.setName(src.getName()); - dest.setMap(src.getMap()); - return dest; - } - }; - final int count = 1_000_000; - long s = System.nanoTime(); - for (int i = 0; i < count; i++) { - action2.copy(beanx, bean); - } - long e = System.nanoTime() - s; - System.out.println("静态Reproduce耗时: " + e); - s = System.nanoTime(); - for (int i = 0; i < count; i++) { - action1.copy(beanx, bean); - } - e = System.nanoTime() - s; - System.out.println("动态Reproduce耗时: " + e); - System.out.println(); - } - - public static void attribute(String[] args) throws Throwable { - final TestBean bean = new TestBean(); - bean.setId(123456); - bean.setName("zhangjx"); - Attribute action1 = Attribute.create(TestBean.class.getDeclaredField("name")); - Attribute action2 = new Attribute() { - - @Override - public String field() { - return "name"; - } - - @Override - public String get(TestBean obj) { - return obj.getName(); - } - - @Override - public void set(TestBean obj, String value) { - obj.setName(value); - } - - @Override - public Class type() { - return String.class; - } - - @Override - public Class declaringClass() { - return TestBean.class; - } - }; - final int count = 1_000_000; - long s = System.nanoTime(); - for (int i = 0; i < count; i++) { - action2.set(bean, "zhangjx2"); - } - long e = System.nanoTime() - s; - System.out.println("静态Attribute耗时: " + e); - s = System.nanoTime(); - for (int i = 0; i < count; i++) { - action1.set(bean, "zhangjx2"); - } - e = System.nanoTime() - s; - System.out.println("动态Attribute耗时: " + e); - System.out.println(); - } -} diff --git a/src/test/java/org/redkale/test/websocket/ChatWebSocketServlet.java b/src/test/java/org/redkale/test/websocket/ChatWebSocketServlet.java deleted file mode 100644 index ff5410646..000000000 --- a/src/test/java/org/redkale/test/websocket/ChatWebSocketServlet.java +++ /dev/null @@ -1,77 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ -package org.redkale.test.websocket; - -import org.redkale.net.http.WebServlet; -import org.redkale.net.http.WebSocketServlet; -import org.redkale.net.http.WebSocket; -import java.io.*; -import static java.lang.Thread.sleep; -import java.text.*; -import java.util.concurrent.atomic.*; -import static java.lang.Thread.sleep; -import static java.lang.Thread.sleep; -import static java.lang.Thread.sleep; - -/** - * - * @author zhangjx - */ -@WebServlet("/ws/chat") -public class ChatWebSocketServlet extends WebSocketServlet { - - private final AtomicLong counter = new AtomicLong(); - - private final AtomicLong icounter = new AtomicLong(); - - private final boolean debug; - - public ChatWebSocketServlet() { - debug = "true".equalsIgnoreCase(System.getProperty("debug", "false")); - Thread t = new Thread() { - - private final DateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); - - { - setName("Debug-ChatWebSocket-ShowCount-Thread"); - } - - @Override - public void run() { - while (true) { - try { - sleep(60 * 1000); - } catch (Exception e) { - return; - } - System.out.println(format.format(new java.util.Date()) + ": 消息总数: " + counter.get() + ",间隔消息数: " + icounter.getAndSet(0)); - } - } - }; - t.start(); - } - - @Override - protected WebSocket createWebSocket() { - - return new WebSocket() { - - @Override - public void onMessage(String text) { - icounter.incrementAndGet(); - counter.incrementAndGet(); - if (debug) System.out.println("收到消息: " + text); - super.getWebSocketGroup().getWebSockets().forEach(x -> x.send(text)); - } - - @Override - protected Serializable createGroupid() { - return ""; - } - }; - } - -} diff --git a/src/test/java/org/redkale/test/websocket/Flash843.java b/src/test/java/org/redkale/test/websocket/Flash843.java deleted file mode 100644 index bd29f8ddf..000000000 --- a/src/test/java/org/redkale/test/websocket/Flash843.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ -package org.redkale.test.websocket; - -import java.io.ByteArrayOutputStream; -import java.net.Socket; - -/** - * - * @author zhangjx - */ -public class Flash843 { - - public static void main(String[] args) throws Exception { - Socket socket = new Socket("113.105.88.229", 843); - socket.getOutputStream().write("".getBytes()); - socket.getOutputStream().flush(); - ByteArrayOutputStream out = new ByteArrayOutputStream(); - byte[] bytes = new byte[1024]; - int pos; - while ((pos = socket.getInputStream().read(bytes)) != -1) { - out.write(bytes, 0, pos); - } - System.out.println(out.toString()); - } -} diff --git a/src/test/java/org/redkale/test/websocket/VideoWebSocketServlet.java b/src/test/java/org/redkale/test/websocket/VideoWebSocketServlet.java deleted file mode 100644 index 79bec9478..000000000 --- a/src/test/java/org/redkale/test/websocket/VideoWebSocketServlet.java +++ /dev/null @@ -1,134 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ -package org.redkale.test.websocket; - -import org.redkale.net.http.WebServlet; -import org.redkale.net.http.WebSocketServlet; -import org.redkale.net.http.HttpRequest; -import org.redkale.net.http.WebSocket; -import org.redkale.net.http.HttpServer; -import org.redkale.util.TypeToken; -import org.redkale.util.AnyValue; -import java.io.*; -import java.util.*; -import java.util.concurrent.CountDownLatch; - -/** - * - * @author zhangjx - */ -@WebServlet({"/ws/listen"}) -public class VideoWebSocketServlet extends WebSocketServlet { - - private final Map sessions = new java.util.concurrent.ConcurrentHashMap<>(); - - private final Map users = new HashMap<>(); - - private static final class Entry { - - public WebSocket socket; - - public String username; - - public Serializable userid; - - } - - public VideoWebSocketServlet() { - super(); - users.put("zhangjx", "xxxx"); - } - - @Override - protected WebSocket createWebSocket() { - WebSocket socket = new WebSocket() { - - private final TypeToken> mapToken = new TypeToken>() { - }; - - private boolean repeat = false; - - @Override - public String onOpen(final HttpRequest request) { - String uri = request.getRequestURI(); - int pos = uri.indexOf("/listen/"); - uri = uri.substring(pos + "/listen/".length()); - this.repeat = sessions.get(uri) != null; - if (!this.repeat) this.repeat = users.get(uri) == null; - String sessionid = Long.toString(System.nanoTime()); - if (uri.indexOf('\'') >= 0 || uri.indexOf('"') >= 0) return null; - if (!repeat) sessionid = uri; - return sessionid; - } - - @Override - public void onConnected() { - if (repeat) { - super.close(); - } else { - Entry entry = new Entry(); - entry.userid = this.getSessionid(); - entry.username = users.get(entry.userid); - sessions.put(this.getSessionid(), entry); - StringBuilder sb = new StringBuilder(); - for (Map.Entry en : sessions.entrySet()) { - if (sb.length() > 0) sb.append(','); - sb.append("{'userid':'").append(en.getKey()).append("','username':'").append(en.getValue().username).append("'}"); - } - super.send(("{'type':'user_list','users':[" + sb + "]}").replace('\'', '"')); - String msg = ("{'type':'discover_user','user':{'userid':'" + this.getSessionid() + "','username':'" + users.get(this.getSessionid()) + "'}}").replace('\'', '"'); - super.getWebSocketGroup().getWebSockets().filter(x -> x != this).forEach(x -> { - x.send(msg); - }); - } - } - - @Override - public void onMessage(String text) { - //System.out.println("接收到消息: " + text); - super.getWebSocketGroup().getWebSockets().filter(x -> x != this).forEach(x -> { - x.send(text); - }); - } - - @Override - public void onClose(int code, String reason) { - sessions.remove(this.getSessionid()); - String msg = ("{'type':'remove_user','user':{'userid':'" + this.getSessionid() + "','username':'" + users.get(this.getSessionid()) + "'}}").replace('\'', '"'); - super.getWebSocketGroup().getWebSockets().filter(x -> x != this).forEach(x -> { - x.send(msg); - }); - } - - @Override - protected Serializable createGroupid() { - return ""; - } - }; - return socket; - } - - public static void main(String[] args) throws Throwable { - CountDownLatch cdl = new CountDownLatch(1); - AnyValue.DefaultAnyValue config = new AnyValue.DefaultAnyValue(); - config.addValue("threads", System.getProperty("threads")); - config.addValue("bufferPoolSize", System.getProperty("bufferPoolSize")); - config.addValue("responsePoolSize", System.getProperty("responsePoolSize")); - config.addValue("host", System.getProperty("host", "0.0.0.0")); - config.addValue("port", System.getProperty("port", "8070")); - config.addValue("root", System.getProperty("root", "./root3/")); - AnyValue.DefaultAnyValue resConf = new AnyValue.DefaultAnyValue(); - resConf.setValue("cacheMaxLength", "200M"); - resConf.setValue("cacheMaxItemLength", "10M"); - config.setValue("ResourceServlet", resConf); - HttpServer server = new HttpServer(); - server.addHttpServlet(new VideoWebSocketServlet(), "/pipes", null, "/listen/*"); - server.init(config); - server.start(); - cdl.await(); - } - -}