Full Code Format

This commit is contained in:
redkale
2024-05-26 08:26:36 +08:00
parent 7230be701e
commit aeeb7a3c72
723 changed files with 28775 additions and 26418 deletions

View File

@@ -17,9 +17,11 @@
<junit.version>5.7.0</junit.version> <junit.version>5.7.0</junit.version>
<maven-plugin.version>3.2.0</maven-plugin.version> <maven-plugin.version>3.2.0</maven-plugin.version>
<maven-gpg-plugin.version>3.0.1</maven-gpg-plugin.version> <maven-gpg-plugin.version>3.0.1</maven-gpg-plugin.version>
<maven-compiler-plugin.version>3.8.0</maven-compiler-plugin.version> <maven-compiler-plugin.version>3.9.0</maven-compiler-plugin.version>
<maven-surefire-plugin.version>3.0.0-M5</maven-surefire-plugin.version> <maven-surefire-plugin.version>3.0.0</maven-surefire-plugin.version>
<maven-failsafe-plugin.version>3.0.0-M5</maven-failsafe-plugin.version> <maven-failsafe-plugin.version>3.0.0</maven-failsafe-plugin.version>
<spotless-maven-plugin.version>2.43.0</spotless-maven-plugin.version>
<palantir-java-format.version>2.46.0</palantir-java-format.version>
</properties> </properties>
<dependencies> <dependencies>
@@ -167,6 +169,21 @@
</executions> </executions>
</plugin> </plugin>
<plugin>
<groupId>com.diffplug.spotless</groupId>
<artifactId>spotless-maven-plugin</artifactId>
<version>${spotless-maven-plugin.version}</version>
<configuration>
<java>
<palantirJavaFormat>
<version>${palantir-java-format.version}</version>
<style>PALANTIR</style>
<formatJavadoc>true</formatJavadoc>
</palantirJavaFormat>
</java>
</configuration>
</plugin>
</plugins> </plugins>
</build> </build>

21
pom.xml
View File

@@ -1,5 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<groupId>org.redkale</groupId> <groupId>org.redkale</groupId>
<artifactId>redkale</artifactId> <artifactId>redkale</artifactId>
@@ -19,6 +20,9 @@
<maven-compiler-plugin.version>3.9.0</maven-compiler-plugin.version> <maven-compiler-plugin.version>3.9.0</maven-compiler-plugin.version>
<maven-surefire-plugin.version>3.0.0</maven-surefire-plugin.version> <maven-surefire-plugin.version>3.0.0</maven-surefire-plugin.version>
<maven-failsafe-plugin.version>3.0.0</maven-failsafe-plugin.version> <maven-failsafe-plugin.version>3.0.0</maven-failsafe-plugin.version>
<spotless-maven-plugin.version>2.43.0</spotless-maven-plugin.version>
<palantir-java-format.version>2.46.0</palantir-java-format.version>
</properties> </properties>
<licenses> <licenses>
@@ -136,6 +140,21 @@
<artifactId>maven-failsafe-plugin</artifactId> <artifactId>maven-failsafe-plugin</artifactId>
<version>${maven-failsafe-plugin.version}</version> <version>${maven-failsafe-plugin.version}</version>
</plugin> </plugin>
<plugin>
<groupId>com.diffplug.spotless</groupId>
<artifactId>spotless-maven-plugin</artifactId>
<version>${spotless-maven-plugin.version}</version>
<configuration>
<java>
<palantirJavaFormat>
<version>${palantir-java-format.version}</version>
<style>PALANTIR</style>
<formatJavadoc>true</formatJavadoc>
</palantirJavaFormat>
</java>
</configuration>
</plugin>
</plugins> </plugins>
</build> </build>

View File

@@ -22,11 +22,8 @@ import java.lang.annotation.*;
* 值越大,优先级越高 * 值越大,优先级越高
* *
* @see org.redkale.annotation.Priority * @see org.redkale.annotation.Priority
*
* @since Common Annotations 1.2 * @since Common Annotations 1.2
*
* @deprecated replace by {@link org.redkale.annotation.Priority} * @deprecated replace by {@link org.redkale.annotation.Priority}
*
*/ */
@Deprecated(since = "2.8.0") @Deprecated(since = "2.8.0")
@Target({ElementType.TYPE}) @Target({ElementType.TYPE})

View File

@@ -9,9 +9,7 @@ import java.lang.annotation.*;
/** /**
* @since Common Annotations 1.0 * @since Common Annotations 1.0
*
* @see org.redkale.annotation.Resource * @see org.redkale.annotation.Resource
*
* @deprecated replace by {@link org.redkale.annotation.Resource} * @deprecated replace by {@link org.redkale.annotation.Resource}
*/ */
@Deprecated(since = "2.8.0") @Deprecated(since = "2.8.0")
@@ -19,21 +17,21 @@ import java.lang.annotation.*;
@Retention(RetentionPolicy.RUNTIME) @Retention(RetentionPolicy.RUNTIME)
public @interface Resource { public @interface Resource {
// /** // /**
// * AuthenticationType // * AuthenticationType
// */ // */
// @Deprecated // @Deprecated
// public enum AuthenticationType { // public enum AuthenticationType {
// /** // /**
// * @deprecated // * @deprecated
// */ // */
// CONTAINER, // CONTAINER,
// /** // /**
// * @deprecated // * @deprecated
// */ // */
// APPLICATION // APPLICATION
// } // }
// //
/** /**
* 资源名称 * 资源名称
* *
@@ -47,39 +45,39 @@ public @interface Resource {
* @return Class * @return Class
*/ */
public Class<?> type() default Object.class; public Class<?> type() default Object.class;
// //
// /** // /**
// * // *
// * @return AuthenticationType // * @return AuthenticationType
// */ // */
// @Deprecated // @Deprecated
// public AuthenticationType authenticationType() default AuthenticationType.CONTAINER; // public AuthenticationType authenticationType() default AuthenticationType.CONTAINER;
// //
// /** // /**
// * // *
// * @return boolean // * @return boolean
// */ // */
// @Deprecated // @Deprecated
// public boolean shareable() default true; // public boolean shareable() default true;
// //
// /** // /**
// * // *
// * @return String // * @return String
// */ // */
// @Deprecated // @Deprecated
// public String description() default ""; // public String description() default "";
// //
// /** // /**
// * // *
// * @return String // * @return String
// */ // */
// @Deprecated // @Deprecated
// public String mappedName() default ""; // public String mappedName() default "";
// //
// /** // /**
// * // *
// * @return String // * @return String
// */ // */
// @Deprecated // @Deprecated
// public String lookup() default ""; // public String lookup() default "";
} }

View File

@@ -1,38 +1,32 @@
/** ***************************************************************************** /**
* Copyright (c) 2008 - 2013 Oracle Corporation. All rights reserved. * ***************************************************************************** Copyright (c) 2008 - 2013 Oracle
* Corporation. All rights reserved.
* *
* This program and the accompanying materials are made available under the * <p>This program and the accompanying materials are made available under the terms of the Eclipse Public License v1.0
* terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0 * and Eclipse Distribution License v. 1.0 which accompanies this distribution. The Eclipse Public License is available
* which accompanies this distribution. * at http://www.eclipse.org/legal/epl-v10.html and the Eclipse Distribution License is available at
* 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. * http://www.eclipse.org/org/documents/edl-v10.php.
* *
* Contributors: * <p>Contributors: Linda DeMichiel - Java Persistence 2.1 Linda DeMichiel - Java Persistence 2.0
* Linda DeMichiel - Java Persistence 2.1
* Linda DeMichiel - Java Persistence 2.0
* *
***************************************************************************** */ * <p>****************************************************************************
*/
package javax.persistence; package javax.persistence;
import java.lang.annotation.*;
import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.RetentionPolicy.RUNTIME; import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.*;
/** /**
* Specifies whether an entity should be cached if caching is enabled * Specifies whether an entity should be cached if caching is enabled when the value of the <code>persistence.xml</code>
* when the value of the <code>persistence.xml</code> caching element * caching element is <code>ENABLE_SELECTIVE</code> or <code>DISABLE_SELECTIVE</code>. The value of the <code>Cacheable
* is <code>ENABLE_SELECTIVE</code> or <code>DISABLE_SELECTIVE</code>. * </code> annotation is inherited by subclasses; it can be overridden by specifying <code>Cacheable</code> on a
* The value of the <code>Cacheable</code> annotation is inherited by * subclass.
* subclasses; it can be overridden by specifying
* <code>Cacheable</code> on a subclass.
* *
* <p> * <p><code>Cacheable(false)</code> means that the entity and its state must not be cached by the provider.
* <code>Cacheable(false)</code> means that the entity and its state must
* not be cached by the provider.
* *
* @since Java Persistence 2.0 * @since Java Persistence 2.0
*
* @deprecated replace by {@link org.redkale.persistence.Cacheable} * @deprecated replace by {@link org.redkale.persistence.Cacheable}
* @see org.redkale.persistence.Cacheable * @see org.redkale.persistence.Cacheable
*/ */
@@ -61,5 +55,4 @@ public @interface Cacheable {
* @return boolean * @return boolean
*/ */
boolean direct() default false; boolean direct() default false;
} }

View File

@@ -1,29 +1,30 @@
/** ***************************************************************************** /**
* Copyright (c) 2008 - 2013 Oracle Corporation. All rights reserved. * ***************************************************************************** Copyright (c) 2008 - 2013 Oracle
* Corporation. All rights reserved.
* *
* This program and the accompanying materials are made available under the * <p>This program and the accompanying materials are made available under the terms of the Eclipse Public License v1.0
* terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0 * and Eclipse Distribution License v. 1.0 which accompanies this distribution. The Eclipse Public License is available
* which accompanies this distribution. * at http://www.eclipse.org/legal/epl-v10.html and the Eclipse Distribution License is available at
* 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. * http://www.eclipse.org/org/documents/edl-v10.php.
* *
* Contributors: * <p>Contributors: Linda DeMichiel - Java Persistence 2.1 Linda DeMichiel - Java Persistence 2.0
* Linda DeMichiel - Java Persistence 2.1
* Linda DeMichiel - Java Persistence 2.0
* *
***************************************************************************** */ * <p>****************************************************************************
*/
package javax.persistence; package javax.persistence;
import java.lang.annotation.*;
import static java.lang.annotation.ElementType.*; import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.RUNTIME; import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.*;
/** /**
* Specifies the mapped column for a persistent property or field. * Specifies the mapped column for a persistent property or field. If no <code>Column</code> annotation is specified,
* If no <code>Column</code> annotation is specified, the default values apply. * the default values apply.
* *
* <blockquote><pre> * <blockquote>
*
* <pre>
* Example 1: * Example 1:
* *
* &#064;Column(name="DESC", nullable=false, length=512) * &#064;Column(name="DESC", nullable=false, length=512)
@@ -42,13 +43,12 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME;
* &#064;Column(name="ORDER_COST", updatable=false, precision=12, scale=2) * &#064;Column(name="ORDER_COST", updatable=false, precision=12, scale=2)
* public BigDecimal getCost() { return cost; } * public BigDecimal getCost() { return cost; }
* *
* </pre></blockquote> * </pre>
* *
* </blockquote>
* *
* @since Java Persistence 1.0 * @since Java Persistence 1.0
*
* @deprecated replace by {@link org.redkale.persistence.Column} * @deprecated replace by {@link org.redkale.persistence.Column}
*
* @see org.redkale.persistence.Column * @see org.redkale.persistence.Column
*/ */
@Deprecated(since = "2.8.0") @Deprecated(since = "2.8.0")
@@ -57,8 +57,7 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME;
public @interface Column { public @interface Column {
/** /**
* (Optional) The name of the column. Defaults to * (Optional) The name of the column. Defaults to the property or field name.
* the property or field name.
* *
* @return String * @return String
*/ */
@@ -72,12 +71,10 @@ public @interface Column {
String comment() default ""; String comment() default "";
/** /**
* (Optional) Whether the column is a unique key. This is a * (Optional) Whether the column is a unique key. This is a shortcut for the <code>UniqueConstraint</code>
* shortcut for the <code>UniqueConstraint</code> annotation at the table * annotation at the table level and is useful for when the unique key constraint corresponds to only a single
* level and is useful for when the unique key constraint * column. This constraint applies in addition to any constraint entailed by primary key mapping and to constraints
* corresponds to only a single column. This constraint applies * specified at the table level.
* in addition to any constraint entailed by primary key mapping and
* to constraints specified at the table level.
* *
* @return boolean * @return boolean
*/ */
@@ -98,24 +95,22 @@ public @interface Column {
String example() default ""; String example() default "";
/** /**
* (Optional) Whether the column is included in SQL INSERT * (Optional) Whether the column is included in SQL INSERT statements generated by the persistence provider.
* statements generated by the persistence provider.
* *
* @return boolean * @return boolean
*/ */
boolean insertable() default true; boolean insertable() default true;
/** /**
* (Optional) Whether the column is included in SQL UPDATE * (Optional) Whether the column is included in SQL UPDATE statements generated by the persistence provider.
* statements generated by the persistence provider.
* *
* @return boolean * @return boolean
*/ */
boolean updatable() default true; boolean updatable() default true;
/** /**
* (Optional) The name of the table that contains the column. * (Optional) The name of the table that contains the column. If absent the column is assumed to be in the primary
* If absent the column is assumed to be in the primary table. * table.
* *
* @return String * @return String
*/ */
@@ -123,32 +118,28 @@ public @interface Column {
String table() default ""; String table() default "";
/** /**
* (Optional) The column length. (Applies only if a * (Optional) The column length. (Applies only if a string-valued column is used.) if type==String and length ==
* string-valued column is used.) * 65535 then sqltype is TEXT <br>
* if type==String and length == 65535 then sqltype is TEXT <br> * if type==String and length &#60;= 16777215 then sqltype is MEDIUMTEXT <br>
* if type==String and length &#60;= 16777215 then sqltype is MEDIUMTEXT <br> * if type==String and length &#62; 16777215 then sqltype is LONGTEXT <br>
* if type==String and length &#62; 16777215 then sqltype is LONGTEXT <br> * if type==byte[] and length &#60;= 65535 then sqltype is BLOB <br>
* if type==byte[] and length &#60;= 65535 then sqltype is BLOB <br> * if type==byte[] and length &#60;= 16777215 then sqltype is MEDIUMBLOB <br>
* if type==byte[] and length &#60;= 16777215 then sqltype is MEDIUMBLOB <br> * if type==byte[] and length &#62; 16777215 then sqltype is LONGBLOB <br>
* if type==byte[] and length &#62; 16777215 then sqltype is LONGBLOB <br>
* *
* @return int * @return int
*/ */
int length() default 255; int length() default 255;
/** /**
* (Optional) The precision for a decimal (exact numeric) * (Optional) The precision for a decimal (exact numeric) column. (Applies only if a decimal column is used.) Value
* column. (Applies only if a decimal column is used.) * must be set by developer if used when generating the DDL for the column.
* Value must be set by developer if used when generating
* the DDL for the column.
* *
* @return int * @return int
*/ */
int precision() default 0; int precision() default 0;
/** /**
* (Optional) The scale for a decimal (exact numeric) column. * (Optional) The scale for a decimal (exact numeric) column. (Applies only if a decimal column is used.)
* (Applies only if a decimal column is used.)
* *
* @return int * @return int
*/ */

View File

@@ -1,32 +1,28 @@
/******************************************************************************* /**
* Copyright (c) 2008 - 2013 Oracle Corporation. All rights reserved. * ***************************************************************************** Copyright (c) 2008 - 2013 Oracle
* Corporation. All rights reserved.
* *
* This program and the accompanying materials are made available under the * <p>This program and the accompanying materials are made available under the terms of the Eclipse Public License v1.0
* terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0 * and Eclipse Distribution License v. 1.0 which accompanies this distribution. The Eclipse Public License is available
* which accompanies this distribution. * at http://www.eclipse.org/legal/epl-v10.html and the Eclipse Distribution License is available at
* 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. * http://www.eclipse.org/org/documents/edl-v10.php.
* *
* Contributors: * <p>Contributors: Linda DeMichiel - Java Persistence 2.1 Linda DeMichiel - Java Persistence 2.0
* Linda DeMichiel - Java Persistence 2.1
* Linda DeMichiel - Java Persistence 2.0
* *
******************************************************************************/ * <p>****************************************************************************
*/
package javax.persistence; package javax.persistence;
import java.lang.annotation.*;
import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.RetentionPolicy.RUNTIME; import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.*;
/** /**
* Specifies that the class is an entity. This annotation is applied to the * Specifies that the class is an entity. This annotation is applied to the entity class.
* entity class.
* *
* @since Java Persistence 1.0 * @since Java Persistence 1.0
*
* @deprecated replace by {@link org.redkale.persistence.Entity} * @deprecated replace by {@link org.redkale.persistence.Entity}
*
* @see org.redkale.persistence.Entity * @see org.redkale.persistence.Entity
*/ */
@Deprecated(since = "2.8.0") @Deprecated(since = "2.8.0")
@@ -36,14 +32,13 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME;
@Retention(RUNTIME) @Retention(RUNTIME)
public @interface Entity { public @interface Entity {
/** /**
* (Optional) The entity name. Defaults to the unqualified * (Optional) The entity name. Defaults to the unqualified name of the entity class. This name is used to refer to
* name of the entity class. This name is used to refer to the * the entity in queries. The name must not be a reserved literal in the Java Persistence query language.
* entity in queries. The name must not be a reserved literal *
* in the Java Persistence query language.
* @return String * @return String
*/ */
String name() default ""; String name() default "";
/** /**
* (Optional) The comment of the entity. * (Optional) The comment of the entity.

View File

@@ -1,39 +1,32 @@
/******************************************************************************* /**
* Copyright (c) 2008 - 2013 Oracle Corporation. All rights reserved. * ***************************************************************************** Copyright (c) 2008 - 2013 Oracle
* Corporation. All rights reserved.
* *
* This program and the accompanying materials are made available under the * <p>This program and the accompanying materials are made available under the terms of the Eclipse Public License v1.0
* terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0 * and Eclipse Distribution License v. 1.0 which accompanies this distribution. The Eclipse Public License is available
* which accompanies this distribution. * at http://www.eclipse.org/legal/epl-v10.html and the Eclipse Distribution License is available at
* 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. * http://www.eclipse.org/org/documents/edl-v10.php.
* *
* Contributors: * <p>Contributors: Linda DeMichiel - Java Persistence 2.1 Linda DeMichiel - Java Persistence 2.0
* Linda DeMichiel - Java Persistence 2.1
* Linda DeMichiel - Java Persistence 2.0
* *
******************************************************************************/ * <p>****************************************************************************
*/
package javax.persistence; package javax.persistence;
import java.lang.annotation.*;
import static java.lang.annotation.ElementType.*; import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.RUNTIME; import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.*;
/** /**
* Specifies the primary key of an entity. * Specifies the primary key of an entity. The field or property to which the <code>Id</code> annotation is applied
* The field or property to which the <code>Id</code> annotation is applied * should be one of the following types: any Java primitive type; any primitive wrapper type; <code>String</code>;
* should be one of the following types: any Java primitive type; * <code>java.util.Date</code>; <code>java.sql.Date</code>; <code>java.math.BigDecimal</code>; <code>
* any primitive wrapper type; * java.math.BigInteger</code>.
* <code>String</code>;
* <code>java.util.Date</code>;
* <code>java.sql.Date</code>;
* <code>java.math.BigDecimal</code>;
* <code>java.math.BigInteger</code>.
* *
* <p>The mapped column for the primary key of the entity is assumed * <p>The mapped column for the primary key of the entity is assumed to be the primary key of the primary table. If no
* to be the primary key of the primary table. If no <code>Column</code> annotation * <code>Column</code> annotation is specified, the primary key column name is assumed to be the name of the primary key
* is specified, the primary key column name is assumed to be the name * property or field.
* of the primary key property or field.
* *
* <pre> * <pre>
* Example: * Example:
@@ -42,17 +35,12 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME;
* public Long getId() { return id; } * public Long getId() { return id; }
* </pre> * </pre>
* *
* @see Column * @see Column see GeneratedValue
* see GeneratedValue
*
* @since Java Persistence 1.0 * @since Java Persistence 1.0
*
* @deprecated replace by {@link org.redkale.persistence.Id} * @deprecated replace by {@link org.redkale.persistence.Id}
*
* @see org.redkale.persistence.Id * @see org.redkale.persistence.Id
*/ */
@Deprecated(since = "2.8.0") @Deprecated(since = "2.8.0")
@Target({METHOD, FIELD}) @Target({METHOD, FIELD})
@Retention(RUNTIME) @Retention(RUNTIME)
public @interface Id {} public @interface Id {}

View File

@@ -1,47 +1,40 @@
/** ***************************************************************************** /**
* Copyright (c) 2011 - 2013 Oracle Corporation. All rights reserved. * ***************************************************************************** Copyright (c) 2011 - 2013 Oracle
* Corporation. All rights reserved.
* *
* This program and the accompanying materials are made available under the * <p>This program and the accompanying materials are made available under the terms of the Eclipse Public License v1.0
* terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0 * and Eclipse Distribution License v. 1.0 which accompanies this distribution. The Eclipse Public License is available
* which accompanies this distribution. * at http://www.eclipse.org/legal/epl-v10.html and the Eclipse Distribution License is available at
* 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. * http://www.eclipse.org/org/documents/edl-v10.php.
* *
* Contributors: * <p>Contributors: Linda DeMichiel - Java Persistence 2.1
* Linda DeMichiel - Java Persistence 2.1
* *
***************************************************************************** */ * <p>****************************************************************************
*/
package javax.persistence; package javax.persistence;
import java.lang.annotation.*;
import static java.lang.annotation.RetentionPolicy.RUNTIME; import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.*;
/** /**
* Used in schema generation to specify creation of an index. * Used in schema generation to specify creation of an index.
* <p>
* Note that it is not necessary to specify an index for a primary key,
* as the primary key index will be created automatically.
* *
* <p> * <p>Note that it is not necessary to specify an index for a primary key, as the primary key index will be created
* The syntax of the <code>columnList</code> element is a * automatically.
* <code>column_list</code>, as follows: *
* <p>The syntax of the <code>columnList</code> element is a <code>column_list</code>, as follows:
* *
* <pre> * <pre>
* column::= index_column [,index_column]* * column::= index_column [,index_column]*
* index_column::= column_name [ASC | DESC] * index_column::= column_name [ASC | DESC]
* </pre> * </pre>
* *
* <p> * <p>If <code>ASC</code> or <code>DESC</code> is not specified, <code>ASC</code> (ascending order) is assumed.
* If <code>ASC</code> or <code>DESC</code> is not specified,
* <code>ASC</code> (ascending order) is assumed.
* *
* @since Java Persistence 2.1 * @since Java Persistence 2.1
*
* @deprecated replace by {@link org.redkale.persistence.Index} * @deprecated replace by {@link org.redkale.persistence.Index}
*
* @see org.redkale.persistence.Index * @see org.redkale.persistence.Index
*
*/ */
@Deprecated(since = "2.8.0") @Deprecated(since = "2.8.0")
@Target({}) @Target({})
@@ -56,8 +49,7 @@ public @interface Index {
String name() default ""; String name() default "";
/** /**
* (Required) The names of the columns to be included in the index, * (Required) The names of the columns to be included in the index, in order.
* in order.
* *
* @return String * @return String
*/ */
@@ -69,5 +61,4 @@ public @interface Index {
* @return boolean * @return boolean
*/ */
boolean unique() default false; boolean unique() default false;
} }

View File

@@ -1,31 +1,28 @@
/** ***************************************************************************** /**
* Copyright (c) 2008 - 2013 Oracle Corporation. All rights reserved. * ***************************************************************************** Copyright (c) 2008 - 2013 Oracle
* Corporation. All rights reserved.
* *
* This program and the accompanying materials are made available under the * <p>This program and the accompanying materials are made available under the terms of the Eclipse Public License v1.0
* terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0 * and Eclipse Distribution License v. 1.0 which accompanies this distribution. The Eclipse Public License is available
* which accompanies this distribution. * at http://www.eclipse.org/legal/epl-v10.html and the Eclipse Distribution License is available at
* 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. * http://www.eclipse.org/org/documents/edl-v10.php.
* *
* Contributors: * <p>Contributors: Linda DeMichiel - Java Persistence 2.1 Linda DeMichiel - Java Persistence 2.0
* Linda DeMichiel - Java Persistence 2.1
* Linda DeMichiel - Java Persistence 2.0
* *
***************************************************************************** */ * <p>****************************************************************************
*/
package javax.persistence; package javax.persistence;
import java.lang.annotation.*;
import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.RetentionPolicy.RUNTIME; import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.*;
/** /**
* Specifies the primary table for the annotated entity. Additional * Specifies the primary table for the annotated entity. Additional tables may be specified using SecondaryTable or
* tables may be specified using SecondaryTable or SecondaryTables annotation. * SecondaryTables annotation.
* *
* <p> * <p>If no <code>Table</code> annotation is specified for an entity class, the default values apply.
* If no <code>Table</code> annotation is specified for an entity
* class, the default values apply.
* *
* <pre> * <pre>
* Example: * Example:
@@ -36,9 +33,7 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME;
* </pre> * </pre>
* *
* @since Java Persistence 1.0 * @since Java Persistence 1.0
*
* @deprecated replace by {@link org.redkale.persistence.Table} * @deprecated replace by {@link org.redkale.persistence.Table}
*
* @see org.redkale.persistence.Table * @see org.redkale.persistence.Table
*/ */
@Deprecated(since = "2.8.0") @Deprecated(since = "2.8.0")
@@ -48,38 +43,36 @@ public @interface Table {
/** /**
* (Optional) The name of the table. * (Optional) The name of the table.
* <p> *
* Defaults to the entity name. * <p>Defaults to the entity name.
* *
* @return String * @return String
*/ */
String name() default ""; String name() default "";
/** (Optional) The catalog of the table. /**
* <p> * (Optional) The catalog of the table.
* Defaults to the default catalog. *
* <p>Defaults to the default catalog.
* *
* @return String * @return String
*/ */
String catalog() default ""; String catalog() default "";
/** /**
* (Optional) Unique constraints that are to be placed on * (Optional) Unique constraints that are to be placed on the table. These are only used if table generation is in
* the table. These are only used if table generation is in * effect. These constraints apply in addition to any constraints specified by the <code>Column</code> and <code>
* effect. These constraints apply in addition to any constraints * JoinColumn</code> annotations and constraints entailed by primary key mappings.
* specified by the <code>Column</code> and <code>JoinColumn</code> *
* annotations and constraints entailed by primary key mappings. * <p>Defaults to no additional constraints.
* <p> *
* Defaults to no additional constraints.
* @return UniqueConstraint[] * @return UniqueConstraint[]
*/ */
UniqueConstraint[] uniqueConstraints() default {}; UniqueConstraint[] uniqueConstraints() default {};
/** /**
* (Optional) Indexes for the table. These are only used if * (Optional) Indexes for the table. These are only used if table generation is in effect. Note that it is not
* table generation is in effect. Note that it is not necessary * necessary to specify an index for a primary key, as the primary key index will be created automatically.
* to specify an index for a primary key, as the primary key
* index will be created automatically.
* *
* @return indexes * @return indexes
* @since Java Persistence 2.1 * @since Java Persistence 2.1
@@ -92,5 +85,4 @@ public @interface Table {
* @return String * @return String
*/ */
String comment() default ""; String comment() default "";
} }

View File

@@ -1,28 +1,26 @@
/******************************************************************************* /**
* Copyright (c) 2008 - 2013 Oracle Corporation. All rights reserved. * ***************************************************************************** Copyright (c) 2008 - 2013 Oracle
* Corporation. All rights reserved.
* *
* This program and the accompanying materials are made available under the * <p>This program and the accompanying materials are made available under the terms of the Eclipse Public License v1.0
* terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0 * and Eclipse Distribution License v. 1.0 which accompanies this distribution. The Eclipse Public License is available
* which accompanies this distribution. * at http://www.eclipse.org/legal/epl-v10.html and the Eclipse Distribution License is available at
* 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. * http://www.eclipse.org/org/documents/edl-v10.php.
* *
* Contributors: * <p>Contributors: Linda DeMichiel - Java Persistence 2.1 Linda DeMichiel - Java Persistence 2.0
* Linda DeMichiel - Java Persistence 2.1
* Linda DeMichiel - Java Persistence 2.0
* *
******************************************************************************/ * <p>****************************************************************************
*/
package javax.persistence; package javax.persistence;
import java.lang.annotation.*;
import static java.lang.annotation.ElementType.*; import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.RUNTIME; import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.*;
/** /**
* Specifies that the property or field is not persistent. It is used * Specifies that the property or field is not persistent. It is used to annotate a property or field of an entity
* to annotate a property or field of an entity class, mapped * class, mapped superclass, or embeddable class.
* superclass, or embeddable class.
* *
* <pre> * <pre>
* Example: * Example:
@@ -36,13 +34,10 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME;
* </pre> * </pre>
* *
* @since Java Persistence 1.0 * @since Java Persistence 1.0
*
* @deprecated replace by {@link org.redkale.persistence.Transient} * @deprecated replace by {@link org.redkale.persistence.Transient}
*
* @see org.redkale.persistence.Transient * @see org.redkale.persistence.Transient
*/ */
@Deprecated(since = "2.8.0") @Deprecated(since = "2.8.0")
@Target({METHOD, FIELD}) @Target({METHOD, FIELD})
@Retention(RUNTIME) @Retention(RUNTIME)
public @interface Transient {} public @interface Transient {}

View File

@@ -1,26 +1,24 @@
/** ***************************************************************************** /**
* Copyright (c) 2008 - 2013 Oracle Corporation. All rights reserved. * ***************************************************************************** Copyright (c) 2008 - 2013 Oracle
* Corporation. All rights reserved.
* *
* This program and the accompanying materials are made available under the * <p>This program and the accompanying materials are made available under the terms of the Eclipse Public License v1.0
* terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0 * and Eclipse Distribution License v. 1.0 which accompanies this distribution. The Eclipse Public License is available
* which accompanies this distribution. * at http://www.eclipse.org/legal/epl-v10.html and the Eclipse Distribution License is available at
* 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. * http://www.eclipse.org/org/documents/edl-v10.php.
* *
* Contributors: * <p>Contributors: Linda DeMichiel - Java Persistence 2.1 Linda DeMichiel - Java Persistence 2.0
* Linda DeMichiel - Java Persistence 2.1
* Linda DeMichiel - Java Persistence 2.0
* *
***************************************************************************** */ * <p>****************************************************************************
*/
package javax.persistence; package javax.persistence;
import java.lang.annotation.*;
import static java.lang.annotation.RetentionPolicy.RUNTIME; import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.*;
/** /**
* Specifies that a unique constraint is to be included in * Specifies that a unique constraint is to be included in the generated DDL for a primary or secondary table.
* the generated DDL for a primary or secondary table.
* *
* <pre> * <pre>
* Example: * Example:
@@ -34,26 +32,24 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME;
* </pre> * </pre>
* *
* @since Java Persistence 1.0 * @since Java Persistence 1.0
*
* @deprecated replace by {@link org.redkale.persistence.UniqueConstraint} * @deprecated replace by {@link org.redkale.persistence.UniqueConstraint}
*
* @see org.redkale.persistence.UniqueConstraint * @see org.redkale.persistence.UniqueConstraint
*
*/ */
@Deprecated(since = "2.8.0") @Deprecated(since = "2.8.0")
@Target({}) @Target({})
@Retention(RUNTIME) @Retention(RUNTIME)
public @interface UniqueConstraint { public @interface UniqueConstraint {
/** (Optional) Constraint name. A provider-chosen name will be chosen /**
* if a name is not specified. * (Optional) Constraint name. A provider-chosen name will be chosen if a name is not specified.
* *
* @return String * @return String
* @since Java Persistence 2.0 * @since Java Persistence 2.0
*/ */
String name() default ""; String name() default "";
/** (Required) An array of the column names that make up the constraint. /**
* (Required) An array of the column names that make up the constraint.
* *
* @return String[] * @return String[]
*/ */

View File

@@ -1,17 +1,14 @@
/** /**
* <p>
* see: https://redkale.org * see: https://redkale.org
* *
* @author zhangjx * @author zhangjx
*
*/ */
module org.redkale { module org.redkale {
requires java.base; requires java.base;
requires java.logging; requires java.logging;
requires java.net.http; requires java.net.http;
requires java.sql; requires java.sql;
requires jdk.unsupported; //sun.misc.Unsafe requires jdk.unsupported; // sun.misc.Unsafe
exports org.redkale.annotation; exports org.redkale.annotation;
exports org.redkale.boot; exports org.redkale.boot;
@@ -54,5 +51,4 @@ module org.redkale {
uses org.redkale.source.spi.CacheSourceProvider; uses org.redkale.source.spi.CacheSourceProvider;
uses org.redkale.source.spi.DataSourceProvider; uses org.redkale.source.spi.DataSourceProvider;
uses org.redkale.source.spi.DataNativeSqlParserProvider; uses org.redkale.source.spi.DataNativeSqlParserProvider;
} }

View File

@@ -7,14 +7,14 @@ package org.redkale.annotation;
import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.RetentionPolicy.RUNTIME; import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.*; import java.lang.annotation.*;
/** /**
* 自动加载。 使用场景: * 自动加载。 使用场景: 1、被标记为&#64;AutoLoad(false)的Service类不会被自动加载, 当被依赖时才会被加载 2、被标记为&#64;AutoLoad(false)的Servlet类不会被自动加载
* 1、被标记为&#64;AutoLoad(false)的Service类不会被自动加载, 当被依赖时才会被加载 *
* 2、被标记为&#64;AutoLoad(false)的Servlet类不会被自动加载 * <p>详情见: https://redkale.org
* *
* <p> 详情见: https://redkale.org
* @author zhangjx * @author zhangjx
*/ */
@Documented @Documented

View File

@@ -5,10 +5,11 @@
*/ */
package org.redkale.annotation; package org.redkale.annotation;
import java.lang.annotation.*;
import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.RetentionPolicy.RUNTIME; import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.*;
/** /**
* 标记参数bean * 标记参数bean
* *
@@ -18,6 +19,4 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME;
@Documented @Documented
@Target(TYPE) @Target(TYPE)
@Retention(RUNTIME) @Retention(RUNTIME)
public @interface Bean { public @interface Bean {}
}

View File

@@ -3,16 +3,15 @@
*/ */
package org.redkale.annotation; package org.redkale.annotation;
import java.lang.annotation.*;
import static java.lang.annotation.ElementType.*; import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.*; import static java.lang.annotation.RetentionPolicy.*;
import java.lang.annotation.*;
/** /**
* 被标记的元素表示会被动态字节码调用 * 被标记的元素表示会被动态字节码调用
* *
* <p> * <p>详情见: https://redkale.org
* 详情见: https://redkale.org
*
* *
* @author zhangjx * @author zhangjx
* @since 2.8.0 * @since 2.8.0

View File

@@ -5,18 +5,17 @@
*/ */
package org.redkale.annotation; package org.redkale.annotation;
import java.lang.annotation.*;
import static java.lang.annotation.ElementType.*; import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.RUNTIME; import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.*;
/** /**
* 接收命令的标记, 只能标记在本地模式下Service里参数为(String)或(String, String[])的public方法上 * 接收命令的标记, 只能标记在本地模式下Service里参数为(String)或(String, String[])的public方法上
* *
* <p> * <p>详情见: https://redkale.org
* 详情见: https://redkale.org
* *
* @author zhangjx * @author zhangjx
*
* @since 2.1.0 * @since 2.1.0
*/ */
@Documented @Documented
@@ -35,7 +34,6 @@ public @interface Command {
* 参数帮助说明在value不为空命令redkale --help时显示 * 参数帮助说明在value不为空命令redkale --help时显示
* *
* @return String * @return String
*
* @since 2.7.0 * @since 2.7.0
*/ */
String description() default ""; String description() default "";

View File

@@ -5,15 +5,15 @@
*/ */
package org.redkale.annotation; package org.redkale.annotation;
import java.lang.annotation.*;
import static java.lang.annotation.ElementType.*; import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.RUNTIME; import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.*;
/** /**
* 标记注释,备注 * 标记注释,备注
* *
* <p> * <p>详情见: https://redkale.org
* 详情见: https://redkale.org
* *
* @author zhangjx * @author zhangjx
*/ */

View File

@@ -2,6 +2,7 @@ package org.redkale.annotation;
import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.RetentionPolicy.RUNTIME; import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.*; import java.lang.annotation.*;
/** /**
@@ -9,8 +10,7 @@ import java.lang.annotation.*;
* 1、直接构造, 不使用Sncp动态构建对象 <br> * 1、直接构造, 不使用Sncp动态构建对象 <br>
* 2、不会生成对应协议的Servlet <br> * 2、不会生成对应协议的Servlet <br>
* *
* <p> * <p>详情见: https://redkale.org
* 详情见: https://redkale.org
* *
* @author zhangjx * @author zhangjx
* @since 2.8.0 * @since 2.8.0
@@ -19,6 +19,4 @@ import java.lang.annotation.*;
@Documented @Documented
@Target({TYPE}) @Target({TYPE})
@Retention(RUNTIME) @Retention(RUNTIME)
public @interface Component { public @interface Component {}
}

View File

@@ -5,15 +5,15 @@
*/ */
package org.redkale.annotation; package org.redkale.annotation;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.*;
import static java.lang.annotation.ElementType.*; import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.*;
/** /**
* 类似java.beans.ConstructorProperties, 必须配合Creator使用 * 类似java.beans.ConstructorProperties, 必须配合Creator使用
* *
* <p> * <p>详情见: https://redkale.org
* 详情见: https://redkale.org
* *
* @author zhangjx * @author zhangjx
*/ */

View File

@@ -5,14 +5,17 @@
*/ */
package org.redkale.annotation; package org.redkale.annotation;
import java.lang.annotation.*;
import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.RetentionPolicy.RUNTIME; import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.*;
/** /**
* 等于level日志级别且包含keys字符串的日志才会被排除 <br> * 等于level日志级别且包含keys字符串的日志才会被排除 <br>
* *
* <blockquote><pre> * <blockquote>
*
* <pre>
* &#64;LogExcludeLevel(levels = {"FINEST"}, keys = {"SET username ="}) * &#64;LogExcludeLevel(levels = {"FINEST"}, keys = {"SET username ="})
* public class UserRecord { * public class UserRecord {
* public int userid; * public int userid;
@@ -20,9 +23,11 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME;
* } * }
* *
* 这样当调用DataSource对UserRecord对象进行操作时拼接的SQL语句含"SET username ="字样的都会在FINEST日志级别过滤掉 * 这样当调用DataSource对UserRecord对象进行操作时拼接的SQL语句含"SET username ="字样的都会在FINEST日志级别过滤掉
* </pre></blockquote> * </pre>
* <p> *
* 详情见: https://redkale.org * </blockquote>
*
* <p>详情见: https://redkale.org
* *
* @author zhangjx * @author zhangjx
*/ */

View File

@@ -5,15 +5,15 @@
*/ */
package org.redkale.annotation; package org.redkale.annotation;
import java.lang.annotation.*;
import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.RetentionPolicy.RUNTIME; import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.*;
/** /**
* 被标记的日志级别以上的才会被记录 * 被标记的日志级别以上的才会被记录
* *
* <p> * <p>详情见: https://redkale.org
* 详情见: https://redkale.org
* *
* @author zhangjx * @author zhangjx
*/ */

View File

@@ -6,22 +6,20 @@ package org.redkale.annotation;
import java.lang.annotation.*; import java.lang.annotation.*;
/** /**
* 非阻塞模式标记, 标记在Service类和方法、Filter类、HttpServlet类上 <br> * 非阻塞模式标记, 标记在Service类和方法、Filter类、HttpServlet类上 <br>
* 一般情况下,没有显注此注解的方法视为阻塞时, 以下两种情况除外: <br> * 一般情况下,没有显注此注解的方法视为阻塞时, 以下两种情况除外: <br>
* 1、返回类型是CompletionStage <br> * 1、返回类型是CompletionStage <br>
* 2、返回类型是void且参数存在CompletionHandler类型 <br> * 2、返回类型是void且参数存在CompletionHandler类型 <br>
* 阻塞模式的方法会在work线程池中运行 非阻塞在IO线程中运行。 * 阻塞模式的方法会在work线程池中运行 非阻塞在IO线程中运行。
* *
* <p> * <p>详情见: https://redkale.org
* 详情见: https://redkale.org
* *
* @author zhangjx * @author zhangjx
*
* @since 2.8.0 * @since 2.8.0
*/ */
@Target({ElementType.TYPE, ElementType.METHOD}) @Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME) @Retention(RetentionPolicy.RUNTIME)
public @interface NonBlocking { //不可使用@Inherited防止被继承, 见HttpServlet.preExecute/authenticate/execute public @interface NonBlocking { // 不可使用@Inherited防止被继承, 见HttpServlet.preExecute/authenticate/execute
boolean value() default true; boolean value() default true;
} }

View File

@@ -8,14 +8,11 @@ import java.lang.annotation.*;
/** /**
* 标记值可以为null * 标记值可以为null
* *
* 详情见: https://redkale.org * <p>详情见: https://redkale.org
* *
* @author zhangjx * @author zhangjx
*
* @since 2.8.0 * @since 2.8.0
*/ */
@Documented @Documented
@Retention(RetentionPolicy.RUNTIME) @Retention(RetentionPolicy.RUNTIME)
public @interface Nonnull { public @interface Nonnull {}
}

View File

@@ -8,14 +8,11 @@ import java.lang.annotation.*;
/** /**
* 标记值可以为null * 标记值可以为null
* *
* 详情见: https://redkale.org * <p>详情见: https://redkale.org
* *
* @author zhangjx * @author zhangjx
*
* @since 2.8.0 * @since 2.8.0
*/ */
@Documented @Documented
@Retention(RetentionPolicy.RUNTIME) @Retention(RetentionPolicy.RUNTIME)
public @interface Nullable { public @interface Nullable {}
}

View File

@@ -3,20 +3,19 @@
*/ */
package org.redkale.annotation; package org.redkale.annotation;
import java.lang.annotation.Documented;
import static java.lang.annotation.ElementType.PARAMETER; import static java.lang.annotation.ElementType.PARAMETER;
import java.lang.annotation.Retention;
import static java.lang.annotation.RetentionPolicy.RUNTIME; import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target; import java.lang.annotation.Target;
/** /**
* 参数名注解,编译时加上 <b>-parameters</b> 参数可以不用此注解 * 参数名注解,编译时加上 <b>-parameters</b> 参数可以不用此注解
* *
* <p> * <p>详情见: https://redkale.org
* 详情见: https://redkale.org
* *
* @author zhangjx * @author zhangjx
*
* @since 2.8.0 * @since 2.8.0
*/ */
@Documented @Documented

View File

@@ -3,20 +3,18 @@
*/ */
package org.redkale.annotation; package org.redkale.annotation;
import java.lang.annotation.Documented;
import static java.lang.annotation.ElementType.*; import static java.lang.annotation.ElementType.*;
import java.lang.annotation.Retention;
import static java.lang.annotation.RetentionPolicy.*; import static java.lang.annotation.RetentionPolicy.*;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target; import java.lang.annotation.Target;
/** /**
*
* @since Common Annotations 1.0 * @since Common Annotations 1.0
*
* @since 2.8.0 * @since 2.8.0
*/ */
@Documented @Documented
@Retention(RUNTIME) @Retention(RUNTIME)
@Target(METHOD) @Target(METHOD)
public @interface PostConstruct { public @interface PostConstruct {}
}

View File

@@ -3,19 +3,16 @@
*/ */
package org.redkale.annotation; package org.redkale.annotation;
import java.lang.annotation.*;
import static java.lang.annotation.ElementType.*; import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.*; import static java.lang.annotation.RetentionPolicy.*;
import java.lang.annotation.*;
/** /**
*
*
* @since Common Annotations 1.0 * @since Common Annotations 1.0
*
* @since 2.8.0 * @since 2.8.0
*/ */
@Documented @Documented
@Retention(RUNTIME) @Retention(RUNTIME)
@Target(METHOD) @Target(METHOD)
public @interface PreDestroy { public @interface PreDestroy {}
}

View File

@@ -30,14 +30,10 @@ import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME) @Retention(RetentionPolicy.RUNTIME)
public @interface Priority { public @interface Priority {
/** /** 最高优先级, 其他值必须比此值小 */
* 最高优先级, 其他值必须比此值小
*/
public static final int HIGHTEST = Integer.MAX_VALUE; public static final int HIGHTEST = Integer.MAX_VALUE;
/** /** 最低优先级, 其他值必须比此值大 */
* 最低优先级, 其他值必须比此值大
*/
public static final int LOWEST = Integer.MIN_VALUE; public static final int LOWEST = Integer.MIN_VALUE;
/** /**

View File

@@ -8,12 +8,11 @@ package org.redkale.annotation;
import java.lang.annotation.*; import java.lang.annotation.*;
/** /**
* &#64;Resource(name = "@") 表示资源name采用所属对象的name <br> * &#64;Resource(name = "@") 表示资源name采用所属对象的name <br>
* &#64;Resource(name = "#name") 表示资源对象自身的name <br> * &#64;Resource(name = "#name") 表示资源对象自身的name <br>
* &#64;Resource(name = "#type") 表示资源对象自身的类型 <br> * &#64;Resource(name = "#type") 表示资源对象自身的类型 <br>
* *
* @since Common Annotations 1.0 * @since Common Annotations 1.0
*
* @since 2.8.0 * @since 2.8.0
*/ */
@Target({ElementType.TYPE, ElementType.METHOD, ElementType.FIELD}) @Target({ElementType.TYPE, ElementType.METHOD, ElementType.FIELD})
@@ -30,19 +29,23 @@ public @interface Resource {
* 是否必须存在 * 是否必须存在
* *
* @return boolean * @return boolean
*
* @since 2.8.0 * @since 2.8.0
*/ */
public boolean required() default true; public boolean required() default true;
/** /**
* 资源名称 <br> * 资源名称 <br>
* <blockquote><pre> *
* <blockquote>
*
* <pre>
* name规则: * name规则:
* 1: "@"有特殊含义, 表示资源本身,"@"不能单独使用 * 1: "@"有特殊含义, 表示资源本身,"@"不能单独使用
* 2: "#name"、"#type"有特殊含义 * 2: "#name"、"#type"有特殊含义
* 3: 只能是字母、数字、(短横)-、(下划线)_、点(.)的组合 * 3: 只能是字母、数字、(短横)-、(下划线)_、点(.)的组合
* </pre></blockquote> * </pre>
*
* </blockquote>
* *
* @return String * @return String
*/ */
@@ -54,5 +57,4 @@ public @interface Resource {
* @return Class * @return Class
*/ */
public Class<?> type() default Object.class; public Class<?> type() default Object.class;
} }

View File

@@ -5,16 +5,19 @@
*/ */
package org.redkale.annotation; package org.redkale.annotation;
import java.lang.annotation.*;
import static java.lang.annotation.ElementType.METHOD; import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.RetentionPolicy.RUNTIME; import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.*;
/** /**
* &#64;Resource资源被更新时的监听事件, 本注解只能标记在方法参数为ResourceEvent[]上 <br> * &#64;Resource资源被更新时的监听事件, 本注解只能标记在方法参数为ResourceEvent[]上 <br>
* 注意: 一个类只能存在一个&#64;ResourceChanged的方法 多余的会被忽略 <br> * 注意: 一个类只能存在一个&#64;ResourceChanged的方法 多余的会被忽略 <br>
* 方法在资源被更新以后调用。 * 方法在资源被更新以后调用。
* *
* <blockquote><pre> * <blockquote>
*
* <pre>
* public class RecordService implements Service { * public class RecordService implements Service {
* *
* &#64;Resource(name = "record.id") * &#64;Resource(name = "record.id")
@@ -39,10 +42,11 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME;
* factory.register("record.name", "my new name"); * factory.register("record.name", "my new name");
* } * }
* } * }
* </pre></blockquote> * </pre>
* *
* <p> * </blockquote>
* 详情见: https://redkale.org *
* <p>详情见: https://redkale.org
* *
* @author zhangjx * @author zhangjx
*/ */
@@ -53,8 +57,7 @@ public @interface ResourceChanged {
/** /**
* 新旧值是否不同时才回调方法 <br> * 新旧值是否不同时才回调方法 <br>
* true: 新值与旧值不同时才回调ResourceChanged方法 * true: 新值与旧值不同时才回调ResourceChanged方法 false: 只要执行了ResourceFactory.register 就回调ResourceChanged方法
* false: 只要执行了ResourceFactory.register 就回调ResourceChanged方法
* *
* @since 2.7.0 * @since 2.7.0
* @return boolean * @return boolean

View File

@@ -5,16 +5,19 @@
*/ */
package org.redkale.annotation; package org.redkale.annotation;
import java.lang.annotation.*;
import static java.lang.annotation.ElementType.METHOD; import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.RetentionPolicy.RUNTIME; import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.*;
/** /**
* &#64;Resource资源被依赖注入时的监听事件。<br> * &#64;Resource资源被依赖注入时的监听事件。<br>
* 本注解只能标记在空参数或者(String、Object、java.lang.reflect.Field)三个参数类型的任意组合方法上 <br> * 本注解只能标记在空参数或者(String、Object、java.lang.reflect.Field)三个参数类型的任意组合方法上 <br>
* 方法在资源被依赖注入后调用。 * 方法在资源被依赖注入后调用。
* *
* <blockquote><pre> * <blockquote>
*
* <pre>
* public class ResourceService implements Service { * public class ResourceService implements Service {
* *
* &#64;Resource(name = "res.id") * &#64;Resource(name = "res.id")
@@ -48,16 +51,15 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME;
* factory.inject(record); * factory.inject(record);
* } * }
* } * }
* </pre></blockquote> * </pre>
* *
* <p> * </blockquote>
* 详情见: https://redkale.org *
* <p>详情见: https://redkale.org
* *
* @author zhangjx * @author zhangjx
*/ */
@Documented @Documented
@Target({METHOD}) @Target({METHOD})
@Retention(RUNTIME) @Retention(RUNTIME)
public @interface ResourceInjected { public @interface ResourceInjected {}
}

View File

@@ -7,15 +7,14 @@ package org.redkale.annotation;
import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.RetentionPolicy.RUNTIME; import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.*; import java.lang.annotation.*;
/** /**
* 显式的指明资源类型。 * 显式的指明资源类型。 调用ResourceFactory.register(Object rs)时通常执行的是ResourceFactory.register(rs.getClass(), Object rs);
* 调用ResourceFactory.register(Object rs)时通常执行的是ResourceFactory.register(rs.getClass(), Object rs);
* 若rs.getClass()的类标记了&#64;ResourceType, 则使用&#64;ResourceType.value()的class值进行注入。 * 若rs.getClass()的类标记了&#64;ResourceType, 则使用&#64;ResourceType.value()的class值进行注入。
* *
* <p> * <p>详情见: https://redkale.org
* 详情见: https://redkale.org
* *
* @author zhangjx * @author zhangjx
*/ */

View File

@@ -1,4 +1,2 @@
/** /** 提供基础注解包 */
* 提供基础注解包
*/
package org.redkale.annotation; package org.redkale.annotation;

View File

@@ -59,9 +59,9 @@
package org.redkale.asm; package org.redkale.asm;
/** /**
* A visitor to visit a Java annotation. The methods of this class must be * A visitor to visit a Java annotation. The methods of this class must be called in the following order: (
* called in the following order: ( &#60;tt&#62;visit&#60;/tt&#62; | &#60;tt&#62;visitEnum&#60;/tt&#62; | * &#60;tt&#62;visit&#60;/tt&#62; | &#60;tt&#62;visitEnum&#60;/tt&#62; | &#60;tt&#62;visitAnnotation&#60;/tt&#62; |
* &#60;tt&#62;visitAnnotation&#60;/tt&#62; | &#60;tt&#62;visitArray&#60;/tt&#62; )* &#60;tt&#62;visitEnd&#60;/tt&#62;. * &#60;tt&#62;visitArray&#60;/tt&#62; )* &#60;tt&#62;visitEnd&#60;/tt&#62;.
* *
* @author Eric Bruneton * @author Eric Bruneton
* @author Eugene Kuleshov * @author Eugene Kuleshov
@@ -69,23 +69,19 @@ package org.redkale.asm;
public abstract class AnnotationVisitor { public abstract class AnnotationVisitor {
/** /**
* The ASM API version implemented by this visitor. The value of this field * The ASM API version implemented by this visitor. The value of this field must be one of {@link Opcodes#ASM4},
* must be one of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}. * {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
*/ */
protected final int api; protected final int api;
/** /** The annotation visitor to which this visitor must delegate method calls. May be null. */
* The annotation visitor to which this visitor must delegate method calls.
* May be null.
*/
protected AnnotationVisitor av; protected AnnotationVisitor av;
/** /**
* Constructs a new {@link AnnotationVisitor}. * Constructs a new {@link AnnotationVisitor}.
* *
* @param api * @param api the ASM API version implemented by this visitor. Must be one of {@link Opcodes#ASM4},
* the ASM API version implemented by this visitor. Must be one * {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
* of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
*/ */
public AnnotationVisitor(final int api) { public AnnotationVisitor(final int api) {
this(api, null); this(api, null);
@@ -94,12 +90,9 @@ public abstract class AnnotationVisitor {
/** /**
* Constructs a new {@link AnnotationVisitor}. * Constructs a new {@link AnnotationVisitor}.
* *
* @param api * @param api the ASM API version implemented by this visitor. Must be one of {@link Opcodes#ASM4},
* the ASM API version implemented by this visitor. Must be one * {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
* of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}. * @param av the annotation visitor to which this visitor must delegate method calls. May be null.
* @param av
* the annotation visitor to which this visitor must delegate
* method calls. May be null.
*/ */
public AnnotationVisitor(final int api, final AnnotationVisitor av) { public AnnotationVisitor(final int api, final AnnotationVisitor av) {
this.api = api; this.api = api;
@@ -109,17 +102,12 @@ public abstract class AnnotationVisitor {
/** /**
* Visits a primitive value of the annotation. * Visits a primitive value of the annotation.
* *
* @param name * @param name the value name.
* the value name. * @param value the actual value, whose type must be {@link Byte}, {@link Boolean}, {@link Character},
* @param value * {@link Short}, {@link Integer} , {@link Long}, {@link Float}, {@link Double}, {@link String} or {@link Type}
* the actual value, whose type must be {@link Byte}, * of OBJECT or ARRAY sort. This value can also be an array of byte, boolean, short, char, int, long, float or
* {@link Boolean}, {@link Character}, {@link Short}, * double values (this is equivalent to using {@link #visitArray visitArray} and visiting each array element in
* {@link Integer} , {@link Long}, {@link Float}, {@link Double}, * turn, but is more convenient).
* {@link String} or {@link Type} of OBJECT or ARRAY sort. This
* value can also be an array of byte, boolean, short, char, int,
* long, float or double values (this is equivalent to using
* {@link #visitArray visitArray} and visiting each array element
* in turn, but is more convenient).
*/ */
public void visit(String name, Object value) { public void visit(String name, Object value) {
if (av != null) { if (av != null) {
@@ -130,12 +118,9 @@ public abstract class AnnotationVisitor {
/** /**
* Visits an enumeration value of the annotation. * Visits an enumeration value of the annotation.
* *
* @param name * @param name the value name.
* the value name. * @param desc the class descriptor of the enumeration class.
* @param desc * @param value the actual enumeration value.
* the class descriptor of the enumeration class.
* @param value
* the actual enumeration value.
*/ */
public void visitEnum(String name, String desc, String value) { public void visitEnum(String name, String desc, String value) {
if (av != null) { if (av != null) {
@@ -146,15 +131,11 @@ public abstract class AnnotationVisitor {
/** /**
* Visits a nested annotation value of the annotation. * Visits a nested annotation value of the annotation.
* *
* @param name * @param name the value name.
* the value name. * @param desc the class descriptor of the nested annotation class.
* @param desc * @return a visitor to visit the actual nested annotation value, or &#60;tt&#62;null&#60;/tt&#62; if this visitor
* the class descriptor of the nested annotation class. * is not interested in visiting this nested annotation. <i>The nested annotation value must be fully visited
* @return a visitor to visit the actual nested annotation value, or * before calling other methods on this annotation visitor</i>.
* &#60;tt&#62;null&#60;/tt&#62; if this visitor is not interested in visiting this
* nested annotation. <i>The nested annotation value must be fully
* visited before calling other methods on this annotation
* visitor</i>.
*/ */
public AnnotationVisitor visitAnnotation(String name, String desc) { public AnnotationVisitor visitAnnotation(String name, String desc) {
if (av != null) { if (av != null) {
@@ -164,18 +145,14 @@ public abstract class AnnotationVisitor {
} }
/** /**
* Visits an array value of the annotation. Note that arrays of primitive * Visits an array value of the annotation. Note that arrays of primitive types (such as byte, boolean, short, char,
* types (such as byte, boolean, short, char, int, long, float or double) * int, long, float or double) can be passed as value to {@link #visit visit}. This is what {@link ClassReader}
* can be passed as value to {@link #visit visit}. This is what * does.
* {@link ClassReader} does.
* *
* @param name * @param name the value name.
* the value name. * @return a visitor to visit the actual array value elements, or &#60;tt&#62;null&#60;/tt&#62; if this visitor is
* @return a visitor to visit the actual array value elements, or * not interested in visiting these values. The 'name' parameters passed to the methods of this visitor are
* &#60;tt&#62;null&#60;/tt&#62; if this visitor is not interested in visiting these * ignored. <i>All the array values must be visited before calling other methods on this annotation visitor</i>.
* values. The 'name' parameters passed to the methods of this
* visitor are ignored. <i>All the array values must be visited
* before calling other methods on this annotation visitor</i>.
*/ */
public AnnotationVisitor visitArray(String name) { public AnnotationVisitor visitArray(String name) {
if (av != null) { if (av != null) {
@@ -184,9 +161,7 @@ public abstract class AnnotationVisitor {
return null; return null;
} }
/** /** Visits the end of the annotation. */
* Visits the end of the annotation.
*/
public void visitEnd() { public void visitEnd() {
if (av != null) { if (av != null) {
av.visitEnd(); av.visitEnd();

View File

@@ -66,50 +66,34 @@ package org.redkale.asm;
*/ */
final class AnnotationWriter extends AnnotationVisitor { final class AnnotationWriter extends AnnotationVisitor {
/** /** The class writer to which this annotation must be added. */
* The class writer to which this annotation must be added.
*/
private final ClassWriter cw; private final ClassWriter cw;
/** /** The number of values in this annotation. */
* The number of values in this annotation.
*/
private int size; private int size;
/** /**
* &#60;tt&#62;true&#60;tt&#62; if values are named, &#60;tt&#62;false&#60;/tt&#62; otherwise. Annotation * &#60;tt&#62;true&#60;tt&#62; if values are named, &#60;tt&#62;false&#60;/tt&#62; otherwise. Annotation writers
* writers used for annotation default and annotation arrays use unnamed * used for annotation default and annotation arrays use unnamed values.
* values.
*/ */
private final boolean named; private final boolean named;
/** /**
* The annotation values in bytecode form. This byte vector only contains * The annotation values in bytecode form. This byte vector only contains the values themselves, i.e. the number of
* the values themselves, i.e. the number of values must be stored as a * values must be stored as a unsigned short just before these bytes.
* unsigned short just before these bytes.
*/ */
private final ByteVector bv; private final ByteVector bv;
/** /** The byte vector to be used to store the number of values of this annotation. See {@link #bv}. */
* The byte vector to be used to store the number of values of this
* annotation. See {@link #bv}.
*/
private final ByteVector parent; private final ByteVector parent;
/** /** Where the number of values of this annotation must be stored in {@link #parent}. */
* Where the number of values of this annotation must be stored in
* {@link #parent}.
*/
private final int offset; private final int offset;
/** /** Next annotation writer. This field is used to store annotation lists. */
* Next annotation writer. This field is used to store annotation lists.
*/
AnnotationWriter next; AnnotationWriter next;
/** /** Previous annotation writer. This field is used to store annotation lists. */
* Previous annotation writer. This field is used to store annotation lists.
*/
AnnotationWriter prev; AnnotationWriter prev;
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
@@ -119,20 +103,14 @@ final class AnnotationWriter extends AnnotationVisitor {
/** /**
* Constructs a new {@link AnnotationWriter}. * Constructs a new {@link AnnotationWriter}.
* *
* @param cw * @param cw the class writer to which this annotation must be added.
* the class writer to which this annotation must be added. * @param named &#60;tt&#62;true&#60;tt&#62; if values are named, &#60;tt&#62;false&#60;/tt&#62; otherwise.
* @param named * @param bv where the annotation values must be stored.
* &#60;tt&#62;true&#60;tt&#62; if values are named, &#60;tt&#62;false&#60;/tt&#62; otherwise. * @param parent where the number of annotation values must be stored.
* @param bv * @param offset where in &#60;tt&#62;parent&#60;/tt&#62; the number of annotation values must be stored.
* where the annotation values must be stored.
* @param parent
* where the number of annotation values must be stored.
* @param offset
* where in &#60;tt&#62;parent&#60;/tt&#62; the number of annotation values must
* be stored.
*/ */
AnnotationWriter(final ClassWriter cw, final boolean named, AnnotationWriter(
final ByteVector bv, final ByteVector parent, final int offset) { final ClassWriter cw, final boolean named, final ByteVector bv, final ByteVector parent, final int offset) {
super(Opcodes.ASM6); super(Opcodes.ASM6);
this.cw = cw; this.cw = cw;
this.named = named; this.named = named;
@@ -219,8 +197,7 @@ final class AnnotationWriter extends AnnotationVisitor {
} }
@Override @Override
public void visitEnum(final String name, final String desc, public void visitEnum(final String name, final String desc, final String value) {
final String value) {
++size; ++size;
if (named) { if (named) {
bv.putShort(cw.newUTF8(name)); bv.putShort(cw.newUTF8(name));
@@ -229,8 +206,7 @@ final class AnnotationWriter extends AnnotationVisitor {
} }
@Override @Override
public AnnotationVisitor visitAnnotation(final String name, public AnnotationVisitor visitAnnotation(final String name, final String desc) {
final String desc) {
++size; ++size;
if (named) { if (named) {
bv.putShort(cw.newUTF8(name)); bv.putShort(cw.newUTF8(name));
@@ -280,11 +256,9 @@ final class AnnotationWriter extends AnnotationVisitor {
} }
/** /**
* Puts the annotations of this annotation writer list into the given byte * Puts the annotations of this annotation writer list into the given byte vector.
* vector.
* *
* @param out * @param out where the annotations must be put.
* where the annotations must be put.
*/ */
void put(final ByteVector out) { void put(final ByteVector out) {
int n = 0; int n = 0;
@@ -311,15 +285,11 @@ final class AnnotationWriter extends AnnotationVisitor {
/** /**
* Puts the given annotation lists into the given byte vector. * Puts the given annotation lists into the given byte vector.
* *
* @param panns * @param panns an array of annotation writer lists.
* an array of annotation writer lists. * @param off index of the first annotation to be written.
* @param off * @param out where the annotations must be put.
* index of the first annotation to be written.
* @param out
* where the annotations must be put.
*/ */
static void put(final AnnotationWriter[] panns, final int off, static void put(final AnnotationWriter[] panns, final int off, final ByteVector out) {
final ByteVector out) {
int size = 1 + 2 * (panns.length - off); int size = 1 + 2 * (panns.length - off);
for (int i = off; i < panns.length; ++i) { for (int i = off; i < panns.length; ++i) {
size += panns[i] == null ? 0 : panns[i].getSize(); size += panns[i] == null ? 0 : panns[i].getSize();
@@ -346,49 +316,45 @@ final class AnnotationWriter extends AnnotationVisitor {
} }
/** /**
* Puts the given type reference and type path into the given bytevector. * Puts the given type reference and type path into the given bytevector. LOCAL_VARIABLE and RESOURCE_VARIABLE
* LOCAL_VARIABLE and RESOURCE_VARIABLE target types are not supported. * target types are not supported.
* *
* @param typeRef * @param typeRef a reference to the annotated type. See {@link TypeReference}.
* a reference to the annotated type. See {@link TypeReference}. * @param typePath the path to the annotated type argument, wildcard bound, array element type, or static inner type
* @param typePath * within 'typeRef'. May be &#60;tt&#62;null&#60;/tt&#62; if the annotation targets 'typeRef' as a whole.
* the path to the annotated type argument, wildcard bound, array * @param out where the type reference and type path must be put.
* element type, or static inner type within 'typeRef'. May be
* &#60;tt&#62;null&#60;/tt&#62; if the annotation targets 'typeRef' as a whole.
* @param out
* where the type reference and type path must be put.
*/ */
static void putTarget(int typeRef, TypePath typePath, ByteVector out) { static void putTarget(int typeRef, TypePath typePath, ByteVector out) {
switch (typeRef >>> 24) { switch (typeRef >>> 24) {
case 0x00: // CLASS_TYPE_PARAMETER case 0x00: // CLASS_TYPE_PARAMETER
case 0x01: // METHOD_TYPE_PARAMETER case 0x01: // METHOD_TYPE_PARAMETER
case 0x16: // METHOD_FORMAL_PARAMETER case 0x16: // METHOD_FORMAL_PARAMETER
out.putShort(typeRef >>> 16); out.putShort(typeRef >>> 16);
break; break;
case 0x13: // FIELD case 0x13: // FIELD
case 0x14: // METHOD_RETURN case 0x14: // METHOD_RETURN
case 0x15: // METHOD_RECEIVER case 0x15: // METHOD_RECEIVER
out.putByte(typeRef >>> 24); out.putByte(typeRef >>> 24);
break; break;
case 0x47: // CAST case 0x47: // CAST
case 0x48: // CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT case 0x48: // CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT
case 0x49: // METHOD_INVOCATION_TYPE_ARGUMENT case 0x49: // METHOD_INVOCATION_TYPE_ARGUMENT
case 0x4A: // CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT case 0x4A: // CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT
case 0x4B: // METHOD_REFERENCE_TYPE_ARGUMENT case 0x4B: // METHOD_REFERENCE_TYPE_ARGUMENT
out.putInt(typeRef); out.putInt(typeRef);
break; break;
// case 0x10: // CLASS_EXTENDS // case 0x10: // CLASS_EXTENDS
// case 0x11: // CLASS_TYPE_PARAMETER_BOUND // case 0x11: // CLASS_TYPE_PARAMETER_BOUND
// case 0x12: // METHOD_TYPE_PARAMETER_BOUND // case 0x12: // METHOD_TYPE_PARAMETER_BOUND
// case 0x17: // THROWS // case 0x17: // THROWS
// case 0x42: // EXCEPTION_PARAMETER // case 0x42: // EXCEPTION_PARAMETER
// case 0x43: // INSTANCEOF // case 0x43: // INSTANCEOF
// case 0x44: // NEW // case 0x44: // NEW
// case 0x45: // CONSTRUCTOR_REFERENCE // case 0x45: // CONSTRUCTOR_REFERENCE
// case 0x46: // METHOD_REFERENCE // case 0x46: // METHOD_REFERENCE
default: default:
out.put12(typeRef >>> 24, (typeRef & 0xFFFF00) >> 8); out.put12(typeRef >>> 24, (typeRef & 0xFFFF00) >> 8);
break; break;
} }
if (typePath == null) { if (typePath == null) {
out.putByte(0); out.putByte(0);

View File

@@ -13,7 +13,6 @@ import org.redkale.convert.json.JsonConvert;
* 存放方法的字节信息 * 存放方法的字节信息
* *
* @see org.redkale.asm.AsmMethodBoost * @see org.redkale.asm.AsmMethodBoost
*
* @since 2.8.0 * @since 2.8.0
*/ */
public class AsmMethodBean { public class AsmMethodBean {
@@ -30,8 +29,7 @@ public class AsmMethodBean {
private String[] exceptions; private String[] exceptions;
public AsmMethodBean() { public AsmMethodBean() {}
}
public AsmMethodBean(int access, String name, String desc, String signature, String[] exceptions) { public AsmMethodBean(int access, String name, String desc, String signature, String[] exceptions) {
this.access = access; this.access = access;

View File

@@ -3,17 +3,6 @@
*/ */
package org.redkale.asm; package org.redkale.asm;
import java.io.InputStream;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
import org.redkale.annotation.Nullable;
import static org.redkale.asm.Opcodes.ACC_PRIVATE; import static org.redkale.asm.Opcodes.ACC_PRIVATE;
import static org.redkale.asm.Opcodes.ACC_PROTECTED; import static org.redkale.asm.Opcodes.ACC_PROTECTED;
import static org.redkale.asm.Opcodes.ACC_PUBLIC; import static org.redkale.asm.Opcodes.ACC_PUBLIC;
@@ -28,6 +17,18 @@ import static org.redkale.asm.Opcodes.IRETURN;
import static org.redkale.asm.Opcodes.LLOAD; import static org.redkale.asm.Opcodes.LLOAD;
import static org.redkale.asm.Opcodes.LRETURN; import static org.redkale.asm.Opcodes.LRETURN;
import static org.redkale.asm.Opcodes.RETURN; import static org.redkale.asm.Opcodes.RETURN;
import java.io.InputStream;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
import org.redkale.annotation.Nullable;
import org.redkale.inject.ResourceFactory; import org.redkale.inject.ResourceFactory;
import org.redkale.util.Utility; import org.redkale.util.Utility;
@@ -35,7 +36,6 @@ import org.redkale.util.Utility;
* 生产动态字节码的方法扩展器, 可以进行方法加强动作 * 生产动态字节码的方法扩展器, 可以进行方法加强动作
* *
* @param <T> 泛型 * @param <T> 泛型
*
* @since 2.8.0 * @since 2.8.0
*/ */
public abstract class AsmMethodBoost<T> { public abstract class AsmMethodBoost<T> {
@@ -60,16 +60,14 @@ public abstract class AsmMethodBoost<T> {
} }
/** /**
*
* 返回一个类所有方法的字节信息, key为: method.getName+':'+Type.getMethodDescriptor(method) * 返回一个类所有方法的字节信息, key为: method.getName+':'+Type.getMethodDescriptor(method)
* *
* @param clazz Class * @param clazz Class
*
* @return Map * @return Map
*/ */
public static Map<String, AsmMethodBean> getMethodBeans(Class clazz) { public static Map<String, AsmMethodBean> getMethodBeans(Class clazz) {
Map<String, AsmMethodBean> rs = MethodParamClassVisitor.getMethodParamNames(new HashMap<>(), clazz); Map<String, AsmMethodBean> rs = MethodParamClassVisitor.getMethodParamNames(new HashMap<>(), clazz);
//返回的List中参数列表可能会比方法参数量多因为方法内的临时变量也会存入list中 所以需要list的元素集合比方法的参数多 // 返回的List中参数列表可能会比方法参数量多因为方法内的临时变量也会存入list中 所以需要list的元素集合比方法的参数多
rs.values().forEach(AsmMethodBean::removeEmptyNames); rs.values().forEach(AsmMethodBean::removeEmptyNames);
return rs; return rs;
} }
@@ -82,7 +80,6 @@ public abstract class AsmMethodBoost<T> {
* 获取需屏蔽的方法上的注解 * 获取需屏蔽的方法上的注解
* *
* @param method 方法 * @param method 方法
*
* @return 需要屏蔽的注解 * @return 需要屏蔽的注解
*/ */
public abstract List<Class<? extends Annotation>> filterMethodAnnotations(Method method); public abstract List<Class<? extends Annotation>> filterMethodAnnotations(Method method);
@@ -90,34 +87,39 @@ public abstract class AsmMethodBoost<T> {
/** /**
* 对方法进行动态加强处理 * 对方法进行动态加强处理
* *
* @param classLoader ClassLoader * @param classLoader ClassLoader
* @param cw 动态字节码Writer * @param cw 动态字节码Writer
* @param newDynName 动态新类名 * @param newDynName 动态新类名
* @param fieldPrefix 动态字段的前缀 * @param fieldPrefix 动态字段的前缀
* @param filterAnns 需要过滤的注解 * @param filterAnns 需要过滤的注解
* @param method 操作的方法 * @param method 操作的方法
* @param newMethodName 新的方法名, 可能为null * @param newMethodName 新的方法名, 可能为null
*
* @return 下一个新的方法名不做任何处理应返回参数newMethodName * @return 下一个新的方法名不做任何处理应返回参数newMethodName
*/ */
public abstract String doMethod(ClassLoader classLoader, ClassWriter cw, String newDynName, public abstract String doMethod(
String fieldPrefix, List<Class<? extends Annotation>> filterAnns, Method method, @Nullable String newMethodName); ClassLoader classLoader,
ClassWriter cw,
String newDynName,
String fieldPrefix,
List<Class<? extends Annotation>> filterAnns,
Method method,
@Nullable String newMethodName);
/** 处理所有动态方法后调用 /**
* 处理所有动态方法后调用
* *
* @param classLoader ClassLoader * @param classLoader ClassLoader
* @param cw 动态字节码Writer * @param cw 动态字节码Writer
* @param newDynName 动态新类名 * @param newDynName 动态新类名
* @param fieldPrefix 动态字段的前缀 * @param fieldPrefix 动态字段的前缀
*/ */
public void doAfterMethods(ClassLoader classLoader, ClassWriter cw, String newDynName, String fieldPrefix) { public void doAfterMethods(ClassLoader classLoader, ClassWriter cw, String newDynName, String fieldPrefix) {}
}
/** /**
* 实例对象进行操作,通常用于给动态的字段赋值 * 实例对象进行操作,通常用于给动态的字段赋值
* *
* @param resourceFactory ResourceFactory * @param resourceFactory ResourceFactory
* @param service 实例对象 * @param service 实例对象
*/ */
public abstract void doInstance(ResourceFactory resourceFactory, T service); public abstract void doInstance(ResourceFactory resourceFactory, T service);
@@ -126,10 +128,14 @@ public abstract class AsmMethodBoost<T> {
return AsmMethodBean.get(methodBeans, method); return AsmMethodBean.get(methodBeans, method);
} }
protected MethodVisitor createMethodVisitor(ClassWriter cw, Method method, String newMethodName, AsmMethodBean methodBean) { protected MethodVisitor createMethodVisitor(
return new MethodDebugVisitor(cw.visitMethod(getAcc(method, newMethodName), ClassWriter cw, Method method, String newMethodName, AsmMethodBean methodBean) {
getNowMethodName(method, newMethodName), Type.getMethodDescriptor(method), return new MethodDebugVisitor(cw.visitMethod(
getMethodSignature(method, methodBean), getMethodExceptions(method, methodBean))); getAcc(method, newMethodName),
getNowMethodName(method, newMethodName),
Type.getMethodDescriptor(method),
getMethodSignature(method, methodBean),
getMethodExceptions(method, methodBean)));
} }
protected int getAcc(Method method, String newMethodName) { protected int getAcc(Method method, String newMethodName) {
@@ -163,28 +169,30 @@ public abstract class AsmMethodBoost<T> {
} }
} }
protected void visitRawAnnotation(Method method, String newMethodName, MethodVisitor mv, Class selfAnnType, List filterAnns) { protected void visitRawAnnotation(
Method method, String newMethodName, MethodVisitor mv, Class selfAnnType, List filterAnns) {
if (newMethodName == null) { if (newMethodName == null) {
//给方法加上原有的Annotation // 给方法加上原有的Annotation
final Annotation[] anns = method.getAnnotations(); final Annotation[] anns = method.getAnnotations();
for (Annotation ann : anns) { for (Annotation ann : anns) {
if (ann.annotationType() != selfAnnType if (ann.annotationType() != selfAnnType
&& (filterAnns == null || !filterAnns.contains(ann.annotationType()))) { && (filterAnns == null || !filterAnns.contains(ann.annotationType()))) {
Asms.visitAnnotation(mv.visitAnnotation(Type.getDescriptor(ann.annotationType()), true), ann); Asms.visitAnnotation(mv.visitAnnotation(Type.getDescriptor(ann.annotationType()), true), ann);
} }
} }
//给参数加上原有的Annotation // 给参数加上原有的Annotation
final Annotation[][] annss = method.getParameterAnnotations(); final Annotation[][] annss = method.getParameterAnnotations();
for (int k = 0; k < annss.length; k++) { for (int k = 0; k < annss.length; k++) {
for (Annotation ann : annss[k]) { for (Annotation ann : annss[k]) {
Asms.visitAnnotation(mv.visitParameterAnnotation(k, Type.getDescriptor(ann.annotationType()), true), ann); Asms.visitAnnotation(
mv.visitParameterAnnotation(k, Type.getDescriptor(ann.annotationType()), true), ann);
} }
} }
} }
} }
protected List<Integer> visitVarInsnParamTypes(MethodVisitor mv, Method method, int insn) { protected List<Integer> visitVarInsnParamTypes(MethodVisitor mv, Method method, int insn) {
//传参数 // 传参数
Class[] paramTypes = method.getParameterTypes(); Class[] paramTypes = method.getParameterTypes();
List<Integer> insns = new ArrayList<>(); List<Integer> insns = new ArrayList<>();
for (Class pt : paramTypes) { for (Class pt : paramTypes) {
@@ -207,19 +215,27 @@ public abstract class AsmMethodBoost<T> {
return insns; return insns;
} }
protected void visitParamTypesLocalVariable(MethodVisitor mv, Method method, Label l0, Label l2, List<Integer> insns, AsmMethodBean methodBean) { protected void visitParamTypesLocalVariable(
MethodVisitor mv, Method method, Label l0, Label l2, List<Integer> insns, AsmMethodBean methodBean) {
Class[] paramTypes = method.getParameterTypes(); Class[] paramTypes = method.getParameterTypes();
if (methodBean != null && paramTypes.length > 0) { if (methodBean != null && paramTypes.length > 0) {
mv.visitLabel(l2); mv.visitLabel(l2);
List<AsmMethodParam> params = methodBean.getParams(); List<AsmMethodParam> params = methodBean.getParams();
for (int i = 0; i < paramTypes.length; i++) { for (int i = 0; i < paramTypes.length; i++) {
AsmMethodParam param = params.get(i); AsmMethodParam param = params.get(i);
mv.visitLocalVariable(param.getName(), param.description(paramTypes[i]), param.signature(paramTypes[i]), l0, l2, insns.get(i)); mv.visitLocalVariable(
param.getName(),
param.description(paramTypes[i]),
param.signature(paramTypes[i]),
l0,
l2,
insns.get(i));
} }
} }
} }
protected void visitInsnReturn(MethodVisitor mv, Method method, Label l0, List<Integer> insns, AsmMethodBean methodBean) { protected void visitInsnReturn(
MethodVisitor mv, Method method, Label l0, List<Integer> insns, AsmMethodBean methodBean) {
if (method.getGenericReturnType() == void.class) { if (method.getGenericReturnType() == void.class) {
mv.visitInsn(RETURN); mv.visitInsn(RETURN);
} else { } else {
@@ -245,7 +261,6 @@ public abstract class AsmMethodBoost<T> {
* 生产动态字节码的方法扩展器, 可以进行方法加强动作 * 生产动态字节码的方法扩展器, 可以进行方法加强动作
* *
* @param <T> 泛型 * @param <T> 泛型
*
* @since 2.8.0 * @since 2.8.0
*/ */
static class AsmMethodBoosts<T> extends AsmMethodBoost<T> { static class AsmMethodBoosts<T> extends AsmMethodBoost<T> {
@@ -280,8 +295,14 @@ public abstract class AsmMethodBoost<T> {
} }
@Override @Override
public String doMethod(ClassLoader classLoader, ClassWriter cw, String newDynName, String fieldPrefix, public String doMethod(
List<Class<? extends Annotation>> filterAnns, Method method, String newMethodName) { ClassLoader classLoader,
ClassWriter cw,
String newDynName,
String fieldPrefix,
List<Class<? extends Annotation>> filterAnns,
Method method,
String newMethodName) {
String newName = newMethodName; String newName = newMethodName;
for (AsmMethodBoost item : items) { for (AsmMethodBoost item : items) {
if (item != null) { if (item != null) {
@@ -308,7 +329,6 @@ public abstract class AsmMethodBoost<T> {
} }
} }
} }
} }
static class MethodParamClassVisitor extends ClassVisitor { static class MethodParamClassVisitor extends ClassVisitor {
@@ -324,7 +344,12 @@ public abstract class AsmMethodBoost<T> {
} }
@Override @Override
public MethodVisitor visitMethod(int methodAccess, String methodName, String methodDesc, String methodSignature, String[] methodExceptions) { public MethodVisitor visitMethod(
int methodAccess,
String methodName,
String methodDesc,
String methodSignature,
String[] methodExceptions) {
super.visitMethod(api, methodName, methodDesc, methodSignature, methodExceptions); super.visitMethod(api, methodName, methodDesc, methodSignature, methodExceptions);
if (java.lang.reflect.Modifier.isStatic(methodAccess)) { if (java.lang.reflect.Modifier.isStatic(methodAccess)) {
return null; return null;
@@ -333,7 +358,8 @@ public abstract class AsmMethodBoost<T> {
if (methodBeanMap.containsKey(key)) { if (methodBeanMap.containsKey(key)) {
return null; return null;
} }
AsmMethodBean bean = new AsmMethodBean(methodAccess, methodName, methodDesc, methodSignature, methodExceptions); AsmMethodBean bean =
new AsmMethodBean(methodAccess, methodName, methodDesc, methodSignature, methodExceptions);
List<AsmMethodParam> paramList = bean.getParams(); List<AsmMethodParam> paramList = bean.getParams();
methodBeanMap.put(key, bean); methodBeanMap.put(key, bean);
return new MethodVisitor(Opcodes.ASM6) { return new MethodVisitor(Opcodes.ASM6) {
@@ -343,12 +369,13 @@ public abstract class AsmMethodBoost<T> {
} }
@Override @Override
public void visitLocalVariable(String varName, String varDesc, String varSignature, Label start, Label end, int varIndex) { public void visitLocalVariable(
String varName, String varDesc, String varSignature, Label start, Label end, int varIndex) {
if (varIndex < 1) { if (varIndex < 1) {
return; return;
} }
int size = paramList.size(); int size = paramList.size();
//index并不会按顺序执行 // index并不会按顺序执行
if (varIndex > size) { if (varIndex > size) {
for (int i = size; i < varIndex; i++) { for (int i = size; i < varIndex; i++) {
paramList.add(new AsmMethodParam(" ", varDesc, varSignature)); paramList.add(new AsmMethodParam(" ", varDesc, varSignature));
@@ -360,7 +387,7 @@ public abstract class AsmMethodBoost<T> {
}; };
} }
//返回的List中参数列表可能会比方法参数量多因为方法内的临时变量也会存入list中 所以需要list的元素集合比方法的参数多 // 返回的List中参数列表可能会比方法参数量多因为方法内的临时变量也会存入list中 所以需要list的元素集合比方法的参数多
static Map<String, AsmMethodBean> getMethodParamNames(Map<String, AsmMethodBean> map, Class clazz) { static Map<String, AsmMethodBean> getMethodParamNames(Map<String, AsmMethodBean> map, Class clazz) {
String n = clazz.getName(); String n = clazz.getName();
InputStream in = clazz.getResourceAsStream(n.substring(n.lastIndexOf('.') + 1) + ".class"); InputStream in = clazz.getResourceAsStream(n.substring(n.lastIndexOf('.') + 1) + ".class");
@@ -368,11 +395,12 @@ public abstract class AsmMethodBoost<T> {
return map; return map;
} }
try { try {
new ClassReader(Utility.readBytesThenClose(in)).accept(new MethodParamClassVisitor(Opcodes.ASM6, clazz, map), 0); new ClassReader(Utility.readBytesThenClose(in))
} catch (Exception e) { //无需理会 .accept(new MethodParamClassVisitor(Opcodes.ASM6, clazz, map), 0);
} catch (Exception e) { // 无需理会
} }
Class superClass = clazz.getSuperclass(); Class superClass = clazz.getSuperclass();
if (superClass == null || superClass == Object.class) { //接口的getSuperclass为null if (superClass == null || superClass == Object.class) { // 接口的getSuperclass为null
return map; return map;
} }
return getMethodParamNames(map, superClass); return getMethodParamNames(map, superClass);

View File

@@ -11,7 +11,6 @@ import org.redkale.util.TypeToken;
* *
* @see org.redkale.asm.AsmMethodBean * @see org.redkale.asm.AsmMethodBean
* @see org.redkale.asm.AsmMethodBoost * @see org.redkale.asm.AsmMethodBoost
*
* @since 2.8.0 * @since 2.8.0
*/ */
public class AsmMethodParam { public class AsmMethodParam {
@@ -22,8 +21,7 @@ public class AsmMethodParam {
private String signature; private String signature;
public AsmMethodParam() { public AsmMethodParam() {}
}
public AsmMethodParam(String name) { public AsmMethodParam(String name) {
this.name = name; this.name = name;

View File

@@ -3,8 +3,6 @@
*/ */
package org.redkale.asm; package org.redkale.asm;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import static org.redkale.asm.Opcodes.BIPUSH; import static org.redkale.asm.Opcodes.BIPUSH;
import static org.redkale.asm.Opcodes.CHECKCAST; import static org.redkale.asm.Opcodes.CHECKCAST;
import static org.redkale.asm.Opcodes.GETSTATIC; import static org.redkale.asm.Opcodes.GETSTATIC;
@@ -12,32 +10,40 @@ import static org.redkale.asm.Opcodes.ICONST_0;
import static org.redkale.asm.Opcodes.INVOKESTATIC; import static org.redkale.asm.Opcodes.INVOKESTATIC;
import static org.redkale.asm.Opcodes.INVOKEVIRTUAL; import static org.redkale.asm.Opcodes.INVOKEVIRTUAL;
import static org.redkale.asm.Opcodes.SIPUSH; import static org.redkale.asm.Opcodes.SIPUSH;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import org.redkale.util.RedkaleException; import org.redkale.util.RedkaleException;
/** /**
* ASM简单的工具方法 <br> * ASM简单的工具方法 <br>
* *
* <p> * <p>详情见: https://redkale.org
* 详情见: https://redkale.org
* *
* @author zhangjx * @author zhangjx
*
* @since 2.8.0 * @since 2.8.0
*/ */
public final class Asms { public final class Asms {
private Asms() { private Asms() {}
}
public static Handle createLambdaMetaHandle() { public static Handle createLambdaMetaHandle() {
return new Handle(Opcodes.H_INVOKESTATIC, "java/lang/invoke/LambdaMetafactory", "metafactory", "(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;", false); return new Handle(
Opcodes.H_INVOKESTATIC,
"java/lang/invoke/LambdaMetafactory",
"metafactory",
"(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;",
false);
} }
public static void visitAnnotation(final AnnotationVisitor av, final Annotation ann) { public static void visitAnnotation(final AnnotationVisitor av, final Annotation ann) {
try { try {
for (Method anm : ann.annotationType().getMethods()) { for (Method anm : ann.annotationType().getMethods()) {
final String mname = anm.getName(); final String mname = anm.getName();
if ("equals".equals(mname) || "hashCode".equals(mname) || "toString".equals(mname) || "annotationType".equals(mname)) { if ("equals".equals(mname)
|| "hashCode".equals(mname)
|| "toString".equals(mname)
|| "annotationType".equals(mname)) {
continue; continue;
} }
final Object r = anm.invoke(ann); final Object r = anm.invoke(ann);
@@ -62,7 +68,9 @@ public final class Asms {
} else if (r instanceof Annotation[]) { } else if (r instanceof Annotation[]) {
AnnotationVisitor av1 = av.visitArray(mname); AnnotationVisitor av1 = av.visitArray(mname);
for (Annotation item : (Annotation[]) r) { for (Annotation item : (Annotation[]) r) {
visitAnnotation(av1.visitAnnotation(null, Type.getDescriptor(((Annotation) item).annotationType())), item); visitAnnotation(
av1.visitAnnotation(null, Type.getDescriptor(((Annotation) item).annotationType())),
item);
} }
av1.visitEnd(); av1.visitEnd();
} else if (r instanceof Class) { } else if (r instanceof Class) {
@@ -70,7 +78,9 @@ public final class Asms {
} else if (r instanceof Enum) { } else if (r instanceof Enum) {
av.visitEnum(mname, Type.getDescriptor(r.getClass()), ((Enum) r).name()); av.visitEnum(mname, Type.getDescriptor(r.getClass()), ((Enum) r).name());
} else if (r instanceof Annotation) { } else if (r instanceof Annotation) {
visitAnnotation(av.visitAnnotation(null, Type.getDescriptor(((Annotation) r).annotationType())), (Annotation) r); visitAnnotation(
av.visitAnnotation(null, Type.getDescriptor(((Annotation) r).annotationType())),
(Annotation) r);
} else { } else {
av.visit(mname, r); av.visit(mname, r);
} }

View File

@@ -68,34 +68,27 @@ import java.util.Arrays;
*/ */
public class Attribute { public class Attribute {
/** /** The type of this attribute. */
* The type of this attribute.
*/
public final String type; public final String type;
/** /** The raw value of this attribute, used only for unknown attributes. */
* The raw value of this attribute, used only for unknown attributes.
*/
byte[] value; byte[] value;
/** /** The next attribute in this attribute list. May be &#60;tt&#62;null&#60;/tt&#62;. */
* The next attribute in this attribute list. May be &#60;tt&#62;null&#60;/tt&#62;.
*/
Attribute next; Attribute next;
/** /**
* Constructs a new empty attribute. * Constructs a new empty attribute.
* *
* @param type * @param type the type of the attribute.
* the type of the attribute.
*/ */
protected Attribute(final String type) { protected Attribute(final String type) {
this.type = type; this.type = type;
} }
/** /**
* Returns &#60;tt&#62;true&#60;/tt&#62; if this type of attribute is unknown. The default * Returns &#60;tt&#62;true&#60;/tt&#62; if this type of attribute is unknown. The default implementation of this
* implementation of this method always returns &#60;tt&#62;true&#60;/tt&#62;. * method always returns &#60;tt&#62;true&#60;/tt&#62;.
* *
* @return &#60;tt&#62;true&#60;/tt&#62; if this type of attribute is unknown. * @return &#60;tt&#62;true&#60;/tt&#62; if this type of attribute is unknown.
*/ */
@@ -115,46 +108,37 @@ public class Attribute {
/** /**
* Returns the labels corresponding to this attribute. * Returns the labels corresponding to this attribute.
* *
* @return the labels corresponding to this attribute, or &#60;tt&#62;null&#60;/tt&#62; if * @return the labels corresponding to this attribute, or &#60;tt&#62;null&#60;/tt&#62; if this attribute is not a
* this attribute is not a code attribute that contains labels. * code attribute that contains labels.
*/ */
protected Label[] getLabels() { protected Label[] getLabels() {
return null; return null;
} }
/** /**
* Reads a {@link #type type} attribute. This method must return a * Reads a {@link #type type} attribute. This method must return a <i>new</i> {@link Attribute} object, of type
* <i>new</i> {@link Attribute} object, of type {@link #type type}, * {@link #type type}, corresponding to the &#60;tt&#62;len&#60;/tt&#62; bytes starting at the given offset, in the
* corresponding to the &#60;tt&#62;len&#60;/tt&#62; bytes starting at the given offset, in * given class reader.
* the given class reader.
* *
* @param cr * @param cr the class that contains the attribute to be read.
* the class that contains the attribute to be read. * @param off index of the first byte of the attribute's content in {@link ClassReader#b cr.b}. The 6 attribute
* @param off * header bytes, containing the type and the length of the attribute, are not taken into account here.
* index of the first byte of the attribute's content in * @param len the length of the attribute's content.
* {@link ClassReader#b cr.b}. The 6 attribute header bytes, * @param buf buffer to be used to call {@link ClassReader#readUTF8 readUTF8},
* containing the type and the length of the attribute, are not * {@link ClassReader#readClass(int,char[]) readClass} or {@link ClassReader#readConst readConst}.
* taken into account here. * @param codeOff index of the first byte of code's attribute content in {@link ClassReader#b cr.b}, or -1 if the
* @param len * attribute to be read is not a code attribute. The 6 attribute header bytes, containing the type and the
* the length of the attribute's content. * length of the attribute, are not taken into account here.
* @param buf * @param labels the labels of the method's code, or &#60;tt&#62;null&#60;/tt&#62; if the attribute to be read is
* buffer to be used to call {@link ClassReader#readUTF8 * not a code attribute.
* readUTF8}, {@link ClassReader#readClass(int,char[]) readClass} * @return a <i>new</i> {@link Attribute} object corresponding to the given bytes.
* or {@link ClassReader#readConst readConst}.
* @param codeOff
* index of the first byte of code's attribute content in
* {@link ClassReader#b cr.b}, or -1 if the attribute to be read
* is not a code attribute. The 6 attribute header bytes,
* containing the type and the length of the attribute, are not
* taken into account here.
* @param labels
* the labels of the method's code, or &#60;tt&#62;null&#60;/tt&#62; if the
* attribute to be read is not a code attribute.
* @return a <i>new</i> {@link Attribute} object corresponding to the given
* bytes.
*/ */
protected Attribute read(final ClassReader cr, final int off, protected Attribute read(
final int len, final char[] buf, final int codeOff, final ClassReader cr,
final int off,
final int len,
final char[] buf,
final int codeOff,
final Label[] labels) { final Label[] labels) {
Attribute attr = new Attribute(type); Attribute attr = new Attribute(type);
attr.value = new byte[len]; attr.value = new byte[len];
@@ -165,30 +149,20 @@ public class Attribute {
/** /**
* Returns the byte array form of this attribute. * Returns the byte array form of this attribute.
* *
* @param cw * @param cw the class to which this attribute must be added. This parameter can be used to add to the constant pool
* the class to which this attribute must be added. This * of this class the items that corresponds to this attribute.
* parameter can be used to add to the constant pool of this * @param code the bytecode of the method corresponding to this code attribute, or &#60;tt&#62;null&#60;/tt&#62; if
* class the items that corresponds to this attribute. * this attribute is not a code attributes.
* @param code * @param len the length of the bytecode of the method corresponding to this code attribute, or
* the bytecode of the method corresponding to this code * &#60;tt&#62;null&#60;/tt&#62; if this attribute is not a code attribute.
* attribute, or &#60;tt&#62;null&#60;/tt&#62; if this attribute is not a code * @param maxStack the maximum stack size of the method corresponding to this code attribute, or -1 if this
* attributes. * attribute is not a code attribute.
* @param len * @param maxLocals the maximum number of local variables of the method corresponding to this code attribute, or -1
* the length of the bytecode of the method corresponding to this * if this attribute is not a code attribute.
* code attribute, or &#60;tt&#62;null&#60;/tt&#62; if this attribute is not a
* code attribute.
* @param maxStack
* the maximum stack size of the method corresponding to this
* code attribute, or -1 if this attribute is not a code
* attribute.
* @param maxLocals
* the maximum number of local variables of the method
* corresponding to this code attribute, or -1 if this attribute
* is not a code attribute.
* @return the byte array form of this attribute. * @return the byte array form of this attribute.
*/ */
protected ByteVector write(final ClassWriter cw, final byte[] code, protected ByteVector write(
final int len, final int maxStack, final int maxLocals) { final ClassWriter cw, final byte[] code, final int len, final int maxStack, final int maxLocals) {
ByteVector v = new ByteVector(); ByteVector v = new ByteVector();
v.data = value; v.data = value;
v.length = value.length; v.length = value.length;
@@ -213,30 +187,20 @@ public class Attribute {
/** /**
* Returns the size of all the attributes in this attribute list. * Returns the size of all the attributes in this attribute list.
* *
* @param cw * @param cw the class writer to be used to convert the attributes into byte arrays, with the {@link #write write}
* the class writer to be used to convert the attributes into * method.
* byte arrays, with the {@link #write write} method. * @param code the bytecode of the method corresponding to these code attributes, or &#60;tt&#62;null&#60;/tt&#62;
* @param code * if these attributes are not code attributes.
* the bytecode of the method corresponding to these code * @param len the length of the bytecode of the method corresponding to these code attributes, or
* attributes, or &#60;tt&#62;null&#60;/tt&#62; if these attributes are not code * &#60;tt&#62;null&#60;/tt&#62; if these attributes are not code attributes.
* attributes. * @param maxStack the maximum stack size of the method corresponding to these code attributes, or -1 if these
* @param len * attributes are not code attributes.
* the length of the bytecode of the method corresponding to * @param maxLocals the maximum number of local variables of the method corresponding to these code attributes, or
* these code attributes, or &#60;tt&#62;null&#60;/tt&#62; if these attributes * -1 if these attributes are not code attributes.
* are not code attributes. * @return the size of all the attributes in this attribute list. This size includes the size of the attribute
* @param maxStack * headers.
* the maximum stack size of the method corresponding to these
* code attributes, or -1 if these attributes are not code
* attributes.
* @param maxLocals
* the maximum number of local variables of the method
* corresponding to these code attributes, or -1 if these
* attributes are not code attributes.
* @return the size of all the attributes in this attribute list. This size
* includes the size of the attribute headers.
*/ */
final int getSize(final ClassWriter cw, final byte[] code, final int len, final int getSize(final ClassWriter cw, final byte[] code, final int len, final int maxStack, final int maxLocals) {
final int maxStack, final int maxLocals) {
Attribute attr = this; Attribute attr = this;
int size = 0; int size = 0;
while (attr != null) { while (attr != null) {
@@ -248,33 +212,27 @@ public class Attribute {
} }
/** /**
* Writes all the attributes of this attribute list in the given byte * Writes all the attributes of this attribute list in the given byte vector.
* vector.
* *
* @param cw * @param cw the class writer to be used to convert the attributes into byte arrays, with the {@link #write write}
* the class writer to be used to convert the attributes into * method.
* byte arrays, with the {@link #write write} method. * @param code the bytecode of the method corresponding to these code attributes, or &#60;tt&#62;null&#60;/tt&#62;
* @param code * if these attributes are not code attributes.
* the bytecode of the method corresponding to these code * @param len the length of the bytecode of the method corresponding to these code attributes, or
* attributes, or &#60;tt&#62;null&#60;/tt&#62; if these attributes are not code * &#60;tt&#62;null&#60;/tt&#62; if these attributes are not code attributes.
* attributes. * @param maxStack the maximum stack size of the method corresponding to these code attributes, or -1 if these
* @param len * attributes are not code attributes.
* the length of the bytecode of the method corresponding to * @param maxLocals the maximum number of local variables of the method corresponding to these code attributes, or
* these code attributes, or &#60;tt&#62;null&#60;/tt&#62; if these attributes * -1 if these attributes are not code attributes.
* are not code attributes. * @param out where the attributes must be written.
* @param maxStack
* the maximum stack size of the method corresponding to these
* code attributes, or -1 if these attributes are not code
* attributes.
* @param maxLocals
* the maximum number of local variables of the method
* corresponding to these code attributes, or -1 if these
* attributes are not code attributes.
* @param out
* where the attributes must be written.
*/ */
final void put(final ClassWriter cw, final byte[] code, final int len, final void put(
final int maxStack, final int maxLocals, final ByteVector out) { final ClassWriter cw,
final byte[] code,
final int len,
final int maxStack,
final int maxLocals,
final ByteVector out) {
Attribute attr = this; Attribute attr = this;
while (attr != null) { while (attr != null) {
ByteVector b = attr.write(cw, code, len, maxStack, maxLocals); ByteVector b = attr.write(cw, code, len, maxStack, maxLocals);
@@ -284,15 +242,12 @@ public class Attribute {
} }
} }
//The stuff below is temporary - once proper support for nestmate attribute has been added, it can be safely removed. // The stuff below is temporary - once proper support for nestmate attribute has been added, it can be safely
//see also changes in ClassReader.accept. // removed.
/** // see also changes in ClassReader.accept.
* /** */
*/
public static class NestMembers extends Attribute { public static class NestMembers extends Attribute {
/** /** */
*
*/
public NestMembers() { public NestMembers() {
super("NestMembers"); super("NestMembers");
} }
@@ -307,7 +262,7 @@ public class Attribute {
int size = cr.readShort(off); int size = cr.readShort(off);
a.classes = new String[size]; a.classes = new String[size];
off += 2; off += 2;
for (int i = 0; i < size ; i++) { for (int i = 0; i < size; i++) {
a.classes[i] = cr.readClass(off, buf); a.classes[i] = cr.readClass(off, buf);
off += 2; off += 2;
} }
@@ -326,16 +281,12 @@ public class Attribute {
} }
} }
/** /** */
*
*/
public static class NestHost extends Attribute { public static class NestHost extends Attribute {
byte[] bytes; byte[] bytes;
String clazz; String clazz;
/** /** */
*
*/
public NestHost() { public NestHost() {
super("NestHost"); super("NestHost");
} }
@@ -357,8 +308,5 @@ public class Attribute {
} }
} }
static final Attribute[] DEFAULT_ATTRIBUTE_PROTOS = new Attribute[] { static final Attribute[] DEFAULT_ATTRIBUTE_PROTOS = new Attribute[] {new NestMembers(), new NestHost()};
new NestMembers(),
new NestHost()
};
} }

View File

@@ -59,48 +59,37 @@
package org.redkale.asm; package org.redkale.asm;
/** /**
* A dynamically extensible vector of bytes. This class is roughly equivalent to * A dynamically extensible vector of bytes. This class is roughly equivalent to a DataOutputStream on top of a
* a DataOutputStream on top of a ByteArrayOutputStream, but is more efficient. * ByteArrayOutputStream, but is more efficient.
* *
* @author Eric Bruneton * @author Eric Bruneton
*/ */
public class ByteVector { public class ByteVector {
/** /** The content of this vector. */
* The content of this vector.
*/
byte[] data; byte[] data;
/** /** Actual number of bytes in this vector. */
* Actual number of bytes in this vector.
*/
int length; int length;
/** /** Constructs a new {@link ByteVector ByteVector} with a default initial size. */
* Constructs a new {@link ByteVector ByteVector} with a default initial
* size.
*/
public ByteVector() { public ByteVector() {
data = new byte[64]; data = new byte[64];
} }
/** /**
* Constructs a new {@link ByteVector ByteVector} with the given initial * Constructs a new {@link ByteVector ByteVector} with the given initial size.
* size.
* *
* @param initialSize * @param initialSize the initial size of the byte vector to be constructed.
* the initial size of the byte vector to be constructed.
*/ */
public ByteVector(final int initialSize) { public ByteVector(final int initialSize) {
data = new byte[initialSize]; data = new byte[initialSize];
} }
/** /**
* Puts a byte into this byte vector. The byte vector is automatically * Puts a byte into this byte vector. The byte vector is automatically enlarged if necessary.
* enlarged if necessary.
* *
* @param b * @param b a byte.
* a byte.
* @return this byte vector. * @return this byte vector.
*/ */
public ByteVector putByte(final int b) { public ByteVector putByte(final int b) {
@@ -114,13 +103,10 @@ public class ByteVector {
} }
/** /**
* Puts two bytes into this byte vector. The byte vector is automatically * Puts two bytes into this byte vector. The byte vector is automatically enlarged if necessary.
* enlarged if necessary.
* *
* @param b1 * @param b1 a byte.
* a byte. * @param b2 another byte.
* @param b2
* another byte.
* @return this byte vector. * @return this byte vector.
*/ */
ByteVector put11(final int b1, final int b2) { ByteVector put11(final int b1, final int b2) {
@@ -136,11 +122,9 @@ public class ByteVector {
} }
/** /**
* Puts a short into this byte vector. The byte vector is automatically * Puts a short into this byte vector. The byte vector is automatically enlarged if necessary.
* enlarged if necessary.
* *
* @param s * @param s a short.
* a short.
* @return this byte vector. * @return this byte vector.
*/ */
public ByteVector putShort(final int s) { public ByteVector putShort(final int s) {
@@ -156,13 +140,10 @@ public class ByteVector {
} }
/** /**
* Puts a byte and a short into this byte vector. The byte vector is * Puts a byte and a short into this byte vector. The byte vector is automatically enlarged if necessary.
* automatically enlarged if necessary.
* *
* @param b * @param b a byte.
* a byte. * @param s a short.
* @param s
* a short.
* @return this byte vector. * @return this byte vector.
*/ */
ByteVector put12(final int b, final int s) { ByteVector put12(final int b, final int s) {
@@ -179,11 +160,9 @@ public class ByteVector {
} }
/** /**
* Puts an int into this byte vector. The byte vector is automatically * Puts an int into this byte vector. The byte vector is automatically enlarged if necessary.
* enlarged if necessary.
* *
* @param i * @param i an int.
* an int.
* @return this byte vector. * @return this byte vector.
*/ */
public ByteVector putInt(final int i) { public ByteVector putInt(final int i) {
@@ -201,11 +180,9 @@ public class ByteVector {
} }
/** /**
* Puts a long into this byte vector. The byte vector is automatically * Puts a long into this byte vector. The byte vector is automatically enlarged if necessary.
* enlarged if necessary.
* *
* @param l * @param l a long.
* a long.
* @return this byte vector. * @return this byte vector.
*/ */
public ByteVector putLong(final long l) { public ByteVector putLong(final long l) {
@@ -229,11 +206,9 @@ public class ByteVector {
} }
/** /**
* Puts an UTF8 string into this byte vector. The byte vector is * Puts an UTF8 string into this byte vector. The byte vector is automatically enlarged if necessary.
* automatically enlarged if necessary.
* *
* @param s * @param s a String whose UTF8 encoded length must be less than 65536.
* a String whose UTF8 encoded length must be less than 65536.
* @return this byte vector. * @return this byte vector.
*/ */
public ByteVector putUTF8(final String s) { public ByteVector putUTF8(final String s) {
@@ -268,20 +243,14 @@ public class ByteVector {
} }
/** /**
* Puts an UTF8 string into this byte vector. The byte vector is * Puts an UTF8 string into this byte vector. The byte vector is automatically enlarged if necessary. The string
* automatically enlarged if necessary. The string length is encoded in two * length is encoded in two bytes before the encoded characters, if there is space for that (i.e. if this.length - i
* bytes before the encoded characters, if there is space for that (i.e. if * - 2 >= 0).
* this.length - i - 2 >= 0).
* *
* @param s * @param s the String to encode.
* the String to encode. * @param i the index of the first character to encode. The previous characters are supposed to have already been
* @param i * encoded, using only one byte per character.
* the index of the first character to encode. The previous * @param maxByteLength the maximum byte length of the encoded string, including the already encoded characters.
* characters are supposed to have already been encoded, using
* only one byte per character.
* @param maxByteLength
* the maximum byte length of the encoded string, including the
* already encoded characters.
* @return this byte vector. * @return this byte vector.
*/ */
ByteVector encodeUTF8(final String s, int i, int maxByteLength) { ByteVector encodeUTF8(final String s, int i, int maxByteLength) {
@@ -303,8 +272,8 @@ public class ByteVector {
} }
int start = length - i - 2; int start = length - i - 2;
if (start >= 0) { if (start >= 0) {
data[start] = (byte) (byteLength >>> 8); data[start] = (byte) (byteLength >>> 8);
data[start + 1] = (byte) byteLength; data[start + 1] = (byte) byteLength;
} }
if (length + byteLength - i > data.length) { if (length + byteLength - i > data.length) {
enlarge(byteLength - i); enlarge(byteLength - i);
@@ -328,16 +297,12 @@ public class ByteVector {
} }
/** /**
* Puts an array of bytes into this byte vector. The byte vector is * Puts an array of bytes into this byte vector. The byte vector is automatically enlarged if necessary.
* automatically enlarged if necessary.
* *
* @param b * @param b an array of bytes. May be &#60;tt&#62;null&#60;/tt&#62; to put &#60;tt&#62;len&#60;/tt&#62; null bytes
* an array of bytes. May be &#60;tt&#62;null&#60;/tt&#62; to put &#60;tt&#62;len&#60;/tt&#62; * into this byte vector.
* null bytes into this byte vector. * @param off index of the fist byte of b that must be copied.
* @param off * @param len number of bytes of b that must be copied.
* index of the fist byte of b that must be copied.
* @param len
* number of bytes of b that must be copied.
* @return this byte vector. * @return this byte vector.
*/ */
public ByteVector putByteArray(final byte[] b, final int off, final int len) { public ByteVector putByteArray(final byte[] b, final int off, final int len) {
@@ -354,9 +319,7 @@ public class ByteVector {
/** /**
* Enlarge this byte vector so that it can receive n more bytes. * Enlarge this byte vector so that it can receive n more bytes.
* *
* @param size * @param size number of additional bytes that this byte vector should be able to receive.
* number of additional bytes that this byte vector should be
* able to receive.
*/ */
private void enlarge(final int size) { private void enlarge(final int size) {
int length1 = 2 * data.length; int length1 = 2 * data.length;

File diff suppressed because it is too large Load Diff

View File

@@ -59,35 +59,31 @@
package org.redkale.asm; package org.redkale.asm;
/** /**
* A visitor to visit a Java class. The methods of this class must be called in * A visitor to visit a Java class. The methods of this class must be called in the following order:
* the following order: &#60;tt&#62;visit&#60;/tt&#62; [ &#60;tt&#62;visitSource&#60;/tt&#62; ] [ * &#60;tt&#62;visit&#60;/tt&#62; [ &#60;tt&#62;visitSource&#60;/tt&#62; ] [ &#60;tt&#62;visitModule&#60;/tt&#62; ][
* &#60;tt&#62;visitModule&#60;/tt&#62; ][ &#60;tt&#62;visitOuterClass&#60;/tt&#62; ] ( &#60;tt&#62;visitAnnotation&#60;/tt&#62; | * &#60;tt&#62;visitOuterClass&#60;/tt&#62; ] ( &#60;tt&#62;visitAnnotation&#60;/tt&#62; |
* &#60;tt&#62;visitTypeAnnotation&#60;/tt&#62; | &#60;tt&#62;visitAttribute&#60;/tt&#62; )* ( * &#60;tt&#62;visitTypeAnnotation&#60;/tt&#62; | &#60;tt&#62;visitAttribute&#60;/tt&#62; )* (
* &#60;tt&#62;visitInnerClass&#60;/tt&#62; | &#60;tt&#62;visitField&#60;/tt&#62; | &#60;tt&#62;visitMethod&#60;/tt&#62; )* * &#60;tt&#62;visitInnerClass&#60;/tt&#62; | &#60;tt&#62;visitField&#60;/tt&#62; | &#60;tt&#62;visitMethod&#60;/tt&#62;
* &#60;tt&#62;visitEnd&#60;/tt&#62;. * )* &#60;tt&#62;visitEnd&#60;/tt&#62;.
* *
* @author Eric Bruneton * @author Eric Bruneton
*/ */
public abstract class ClassVisitor { public abstract class ClassVisitor {
/** /**
* The ASM API version implemented by this visitor. The value of this field * The ASM API version implemented by this visitor. The value of this field must be one of {@link Opcodes#ASM4},
* must be one of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}. * {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
*/ */
protected final int api; protected final int api;
/** /** The class visitor to which this visitor must delegate method calls. May be null. */
* The class visitor to which this visitor must delegate method calls. May
* be null.
*/
protected ClassVisitor cv; protected ClassVisitor cv;
/** /**
* Constructs a new {@link ClassVisitor}. * Constructs a new {@link ClassVisitor}.
* *
* @param api * @param api the ASM API version implemented by this visitor. Must be one of {@link Opcodes#ASM4},
* the ASM API version implemented by this visitor. Must be one * {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
* of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
*/ */
public ClassVisitor(final int api) { public ClassVisitor(final int api) {
this(api, null); this(api, null);
@@ -96,12 +92,9 @@ public abstract class ClassVisitor {
/** /**
* Constructs a new {@link ClassVisitor}. * Constructs a new {@link ClassVisitor}.
* *
* @param api * @param api the ASM API version implemented by this visitor. Must be one of {@link Opcodes#ASM4},
* the ASM API version implemented by this visitor. Must be one * {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
* of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}. * @param cv the class visitor to which this visitor must delegate method calls. May be null.
* @param cv
* the class visitor to which this visitor must delegate method
* calls. May be null.
*/ */
public ClassVisitor(final int api, final ClassVisitor cv) { public ClassVisitor(final int api, final ClassVisitor cv) {
this.api = api; this.api = api;
@@ -111,30 +104,19 @@ public abstract class ClassVisitor {
/** /**
* Visits the header of the class. * Visits the header of the class.
* *
* @param version * @param version the class version.
* the class version. * @param access the class's access flags (see {@link Opcodes}). This parameter also indicates if the class is
* @param access * deprecated.
* the class's access flags (see {@link Opcodes}). This parameter * @param name the internal name of the class (see {@link Type#getInternalName() getInternalName}).
* also indicates if the class is deprecated. * @param signature the signature of this class. May be &#60;tt&#62;null&#60;/tt&#62; if the class is not a generic
* @param name * one, and does not extend or implement generic classes or interfaces.
* the internal name of the class (see * @param superName the internal of name of the super class (see {@link Type#getInternalName() getInternalName}).
* {@link Type#getInternalName() getInternalName}). * For interfaces, the super class is {@link Object}. May be &#60;tt&#62;null&#60;/tt&#62;, but only for the
* @param signature * {@link Object} class.
* the signature of this class. May be &#60;tt&#62;null&#60;/tt&#62; if the class * @param interfaces the internal names of the class's interfaces (see {@link Type#getInternalName()
* is not a generic one, and does not extend or implement generic * getInternalName}). May be &#60;tt&#62;null&#60;/tt&#62;.
* classes or interfaces.
* @param superName
* the internal of name of the super class (see
* {@link Type#getInternalName() getInternalName}). For
* interfaces, the super class is {@link Object}. May be
* &#60;tt&#62;null&#60;/tt&#62;, but only for the {@link Object} class.
* @param interfaces
* the internal names of the class's interfaces (see
* {@link Type#getInternalName() getInternalName}). May be
* &#60;tt&#62;null&#60;/tt&#62;.
*/ */
public void visit(int version, int access, String name, String signature, public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) {
String superName, String[] interfaces) {
if (cv != null) { if (cv != null) {
cv.visit(version, access, name, signature, superName, interfaces); cv.visit(version, access, name, signature, superName, interfaces);
} }
@@ -143,13 +125,10 @@ public abstract class ClassVisitor {
/** /**
* Visits the source of the class. * Visits the source of the class.
* *
* @param source * @param source the name of the source file from which the class was compiled. May be
* the name of the source file from which the class was compiled. * &#60;tt&#62;null&#60;/tt&#62;.
* May be &#60;tt&#62;null&#60;/tt&#62;. * @param debug additional debug information to compute the correspondance between source and compiled elements of
* @param debug * the class. May be &#60;tt&#62;null&#60;/tt&#62;.
* additional debug information to compute the correspondance
* between source and compiled elements of the class. May be
* &#60;tt&#62;null&#60;/tt&#62;.
*/ */
public void visitSource(String source, String debug) { public void visitSource(String source, String debug) {
if (cv != null) { if (cv != null) {
@@ -159,15 +138,12 @@ public abstract class ClassVisitor {
/** /**
* Visit the module corresponding to the class. * Visit the module corresponding to the class.
* @param name *
* module name * @param name module name
* @param access * @param access module flags, among {@code ACC_OPEN}, {@code ACC_SYNTHETIC} and {@code ACC_MANDATED}.
* module flags, among {@code ACC_OPEN}, {@code ACC_SYNTHETIC} * @param version module version or null.
* and {@code ACC_MANDATED}. * @return a visitor to visit the module values, or &#60;tt&#62;null&#60;/tt&#62; if this visitor is not interested
* @param version * in visiting this module.
* module version or null.
* @return a visitor to visit the module values, or &#60;tt&#62;null&#60;/tt&#62; if
* this visitor is not interested in visiting this module.
*/ */
public ModuleVisitor visitModule(String name, int access, String version) { public ModuleVisitor visitModule(String name, int access, String version) {
if (api < Opcodes.ASM6) { if (api < Opcodes.ASM6) {
@@ -180,19 +156,13 @@ public abstract class ClassVisitor {
} }
/** /**
* Visits the enclosing class of the class. This method must be called only * Visits the enclosing class of the class. This method must be called only if the class has an enclosing class.
* if the class has an enclosing class.
* *
* @param owner * @param owner internal name of the enclosing class of the class.
* internal name of the enclosing class of the class. * @param name the name of the method that contains the class, or &#60;tt&#62;null&#60;/tt&#62; if the class is not
* @param name * enclosed in a method of its enclosing class.
* the name of the method that contains the class, or * @param desc the descriptor of the method that contains the class, or &#60;tt&#62;null&#60;/tt&#62; if the class
* &#60;tt&#62;null&#60;/tt&#62; if the class is not enclosed in a method of its * is not enclosed in a method of its enclosing class.
* enclosing class.
* @param desc
* the descriptor of the method that contains the class, or
* &#60;tt&#62;null&#60;/tt&#62; if the class is not enclosed in a method of its
* enclosing class.
*/ */
public void visitOuterClass(String owner, String name, String desc) { public void visitOuterClass(String owner, String name, String desc) {
if (cv != null) { if (cv != null) {
@@ -203,12 +173,10 @@ public abstract class ClassVisitor {
/** /**
* Visits an annotation of the class. * Visits an annotation of the class.
* *
* @param desc * @param desc the class descriptor of the annotation class.
* the class descriptor of the annotation class. * @param visible &#60;tt&#62;true&#60;/tt&#62; if the annotation is visible at runtime.
* @param visible * @return a visitor to visit the annotation values, or &#60;tt&#62;null&#60;/tt&#62; if this visitor is not
* &#60;tt&#62;true&#60;/tt&#62; if the annotation is visible at runtime. * interested in visiting this annotation.
* @return a visitor to visit the annotation values, or &#60;tt&#62;null&#60;/tt&#62; if
* this visitor is not interested in visiting this annotation.
*/ */
public AnnotationVisitor visitAnnotation(String desc, boolean visible) { public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
if (cv != null) { if (cv != null) {
@@ -220,27 +188,18 @@ public abstract class ClassVisitor {
/** /**
* Visits an annotation on a type in the class signature. * Visits an annotation on a type in the class signature.
* *
* @param typeRef * @param typeRef a reference to the annotated type. The sort of this type reference must be
* a reference to the annotated type. The sort of this type * {@link TypeReference#CLASS_TYPE_PARAMETER CLASS_TYPE_PARAMETER},
* reference must be {@link TypeReference#CLASS_TYPE_PARAMETER * {@link TypeReference#CLASS_TYPE_PARAMETER_BOUND CLASS_TYPE_PARAMETER_BOUND} or
* CLASS_TYPE_PARAMETER}, * {@link TypeReference#CLASS_EXTENDS CLASS_EXTENDS}. See {@link TypeReference}.
* {@link TypeReference#CLASS_TYPE_PARAMETER_BOUND * @param typePath the path to the annotated type argument, wildcard bound, array element type, or static inner type
* CLASS_TYPE_PARAMETER_BOUND} or * within 'typeRef'. May be &#60;tt&#62;null&#60;/tt&#62; if the annotation targets 'typeRef' as a whole.
* {@link TypeReference#CLASS_EXTENDS CLASS_EXTENDS}. See * @param desc the class descriptor of the annotation class.
* {@link TypeReference}. * @param visible &#60;tt&#62;true&#60;/tt&#62; if the annotation is visible at runtime.
* @param typePath * @return a visitor to visit the annotation values, or &#60;tt&#62;null&#60;/tt&#62; if this visitor is not
* the path to the annotated type argument, wildcard bound, array * interested in visiting this annotation.
* element type, or static inner type within 'typeRef'. May be
* &#60;tt&#62;null&#60;/tt&#62; if the annotation targets 'typeRef' as a whole.
* @param desc
* the class descriptor of the annotation class.
* @param visible
* &#60;tt&#62;true&#60;/tt&#62; if the annotation is visible at runtime.
* @return a visitor to visit the annotation values, or &#60;tt&#62;null&#60;/tt&#62; if
* this visitor is not interested in visiting this annotation.
*/ */
public AnnotationVisitor visitTypeAnnotation(int typeRef, public AnnotationVisitor visitTypeAnnotation(int typeRef, TypePath typePath, String desc, boolean visible) {
TypePath typePath, String desc, boolean visible) {
if (cv != null) { if (cv != null) {
return cv.visitTypeAnnotation(typeRef, typePath, desc, visible); return cv.visitTypeAnnotation(typeRef, typePath, desc, visible);
} }
@@ -250,8 +209,7 @@ public abstract class ClassVisitor {
/** /**
* Visits a non standard attribute of the class. * Visits a non standard attribute of the class.
* *
* @param attr * @param attr an attribute.
* an attribute.
*/ */
public void visitAttribute(Attribute attr) { public void visitAttribute(Attribute attr) {
if (cv != null) { if (cv != null) {
@@ -260,25 +218,16 @@ public abstract class ClassVisitor {
} }
/** /**
* Visits information about an inner class. This inner class is not * Visits information about an inner class. This inner class is not necessarily a member of the class being visited.
* necessarily a member of the class being visited.
* *
* @param name * @param name the internal name of an inner class (see {@link Type#getInternalName() getInternalName}).
* the internal name of an inner class (see * @param outerName the internal name of the class to which the inner class belongs (see
* {@link Type#getInternalName() getInternalName}). * {@link Type#getInternalName() getInternalName}). May be &#60;tt&#62;null&#60;/tt&#62; for not member classes.
* @param outerName * @param innerName the (simple) name of the inner class inside its enclosing class. May be
* the internal name of the class to which the inner class * &#60;tt&#62;null&#60;/tt&#62; for anonymous inner classes.
* belongs (see {@link Type#getInternalName() getInternalName}). * @param access the access flags of the inner class as originally declared in the enclosing class.
* May be &#60;tt&#62;null&#60;/tt&#62; for not member classes.
* @param innerName
* the (simple) name of the inner class inside its enclosing
* class. May be &#60;tt&#62;null&#60;/tt&#62; for anonymous inner classes.
* @param access
* the access flags of the inner class as originally declared in
* the enclosing class.
*/ */
public void visitInnerClass(String name, String outerName, public void visitInnerClass(String name, String outerName, String innerName, int access) {
String innerName, int access) {
if (cv != null) { if (cv != null) {
cv.visitInnerClass(name, outerName, innerName, access); cv.visitInnerClass(name, outerName, innerName, access);
} }
@@ -287,32 +236,22 @@ public abstract class ClassVisitor {
/** /**
* Visits a field of the class. * Visits a field of the class.
* *
* @param access * @param access the field's access flags (see {@link Opcodes}). This parameter also indicates if the field is
* the field's access flags (see {@link Opcodes}). This parameter * synthetic and/or deprecated.
* also indicates if the field is synthetic and/or deprecated. * @param name the field's name.
* @param name * @param desc the field's descriptor (see {@link Type Type}).
* the field's name. * @param signature the field's signature. May be &#60;tt&#62;null&#60;/tt&#62; if the field's type does not use
* @param desc * generic types.
* the field's descriptor (see {@link Type Type}). * @param value the field's initial value. This parameter, which may be &#60;tt&#62;null&#60;/tt&#62; if the field
* @param signature * does not have an initial value, must be an {@link Integer}, a {@link Float}, a {@link Long}, a {@link Double}
* the field's signature. May be &#60;tt&#62;null&#60;/tt&#62; if the field's * or a {@link String} (for &#60;tt&#62;int&#60;/tt&#62;, &#60;tt&#62;float&#60;/tt&#62;,
* type does not use generic types. * &#60;tt&#62;long&#60;/tt&#62; or &#60;tt&#62;String&#60;/tt&#62; fields respectively). <i>This parameter is
* @param value * only used for static fields</i>. Its value is ignored for non static fields, which must be initialized
* the field's initial value. This parameter, which may be * through bytecode instructions in constructors or methods.
* &#60;tt&#62;null&#60;/tt&#62; if the field does not have an initial value, * @return a visitor to visit field annotations and attributes, or &#60;tt&#62;null&#60;/tt&#62; if this class
* must be an {@link Integer}, a {@link Float}, a {@link Long}, a * visitor is not interested in visiting these annotations and attributes.
* {@link Double} or a {@link String} (for &#60;tt&#62;int&#60;/tt&#62;,
* &#60;tt&#62;float&#60;/tt&#62;, &#60;tt&#62;long&#60;/tt&#62; or &#60;tt&#62;String&#60;/tt&#62; fields
* respectively). <i>This parameter is only used for static
* fields</i>. Its value is ignored for non static fields, which
* must be initialized through bytecode instructions in
* constructors or methods.
* @return a visitor to visit field annotations and attributes, or
* &#60;tt&#62;null&#60;/tt&#62; if this class visitor is not interested in visiting
* these annotations and attributes.
*/ */
public FieldVisitor visitField(int access, String name, String desc, public FieldVisitor visitField(int access, String name, String desc, String signature, Object value) {
String signature, Object value) {
if (cv != null) { if (cv != null) {
return cv.visitField(access, name, desc, signature, value); return cv.visitField(access, name, desc, signature, value);
} }
@@ -320,32 +259,21 @@ public abstract class ClassVisitor {
} }
/** /**
* Visits a method of the class. This method <i>must</i> return a new * Visits a method of the class. This method <i>must</i> return a new {@link MethodVisitor} instance (or
* {@link MethodVisitor} instance (or &#60;tt&#62;null&#60;/tt&#62;) each time it is called, * &#60;tt&#62;null&#60;/tt&#62;) each time it is called, i.e., it should not return a previously returned visitor.
* i.e., it should not return a previously returned visitor.
* *
* @param access * @param access the method's access flags (see {@link Opcodes}). This parameter also indicates if the method is
* the method's access flags (see {@link Opcodes}). This * synthetic and/or deprecated.
* parameter also indicates if the method is synthetic and/or * @param name the method's name.
* deprecated. * @param desc the method's descriptor (see {@link Type Type}).
* @param name * @param signature the method's signature. May be &#60;tt&#62;null&#60;/tt&#62; if the method parameters, return
* the method's name. * type and exceptions do not use generic types.
* @param desc * @param exceptions the internal names of the method's exception classes (see {@link Type#getInternalName()
* the method's descriptor (see {@link Type Type}). * getInternalName}). May be &#60;tt&#62;null&#60;/tt&#62;.
* @param signature * @return an object to visit the byte code of the method, or &#60;tt&#62;null&#60;/tt&#62; if this class visitor is
* the method's signature. May be &#60;tt&#62;null&#60;/tt&#62; if the method * not interested in visiting the code of this method.
* parameters, return type and exceptions do not use generic
* types.
* @param exceptions
* the internal names of the method's exception classes (see
* {@link Type#getInternalName() getInternalName}). May be
* &#60;tt&#62;null&#60;/tt&#62;.
* @return an object to visit the byte code of the method, or &#60;tt&#62;null&#60;/tt&#62;
* if this class visitor is not interested in visiting the code of
* this method.
*/ */
public MethodVisitor visitMethod(int access, String name, String desc, public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
String signature, String[] exceptions) {
if (cv != null) { if (cv != null) {
return cv.visitMethod(access, name, desc, signature, exceptions); return cv.visitMethod(access, name, desc, signature, exceptions);
} }
@@ -353,9 +281,8 @@ public abstract class ClassVisitor {
} }
/** /**
* Visits the end of the class. This method, which is the last one to be * Visits the end of the class. This method, which is the last one to be called, is used to inform the visitor that
* called, is used to inform the visitor that all the fields and methods of * all the fields and methods of the class have been visited.
* the class have been visited.
*/ */
public void visitEnd() { public void visitEnd() {
if (cv != null) { if (cv != null) {

File diff suppressed because it is too large Load Diff

View File

@@ -66,109 +66,78 @@ package org.redkale.asm;
*/ */
class Context { class Context {
/** /** Prototypes of the attributes that must be parsed for this class. */
* Prototypes of the attributes that must be parsed for this class.
*/
Attribute[] attrs; Attribute[] attrs;
/** /** The {@link ClassReader} option flags for the parsing of this class. */
* The {@link ClassReader} option flags for the parsing of this class.
*/
int flags; int flags;
/** /** The buffer used to read strings. */
* The buffer used to read strings.
*/
char[] buffer; char[] buffer;
/** /** The start index of each bootstrap method. */
* The start index of each bootstrap method.
*/
int[] bootstrapMethods; int[] bootstrapMethods;
/** /** The access flags of the method currently being parsed. */
* The access flags of the method currently being parsed.
*/
int access; int access;
/** /** The name of the method currently being parsed. */
* The name of the method currently being parsed.
*/
String name; String name;
/** /** The descriptor of the method currently being parsed. */
* The descriptor of the method currently being parsed.
*/
String desc; String desc;
/** /**
* The label objects, indexed by bytecode offset, of the method currently * The label objects, indexed by bytecode offset, of the method currently being parsed (only bytecode offsets for
* being parsed (only bytecode offsets for which a label is needed have a * which a label is needed have a non null associated Label object).
* non null associated Label object).
*/ */
Label[] labels; Label[] labels;
/** /** The target of the type annotation currently being parsed. */
* The target of the type annotation currently being parsed.
*/
int typeRef; int typeRef;
/** /** The path of the type annotation currently being parsed. */
* The path of the type annotation currently being parsed.
*/
TypePath typePath; TypePath typePath;
/** /** The offset of the latest stack map frame that has been parsed. */
* The offset of the latest stack map frame that has been parsed.
*/
int offset; int offset;
/** /**
* The labels corresponding to the start of the local variable ranges in the * The labels corresponding to the start of the local variable ranges in the local variable type annotation
* local variable type annotation currently being parsed. * currently being parsed.
*/ */
Label[] start; Label[] start;
/** /**
* The labels corresponding to the end of the local variable ranges in the * The labels corresponding to the end of the local variable ranges in the local variable type annotation currently
* local variable type annotation currently being parsed. * being parsed.
*/ */
Label[] end; Label[] end;
/** /**
* The local variable indices for each local variable range in the local * The local variable indices for each local variable range in the local variable type annotation currently being
* variable type annotation currently being parsed. * parsed.
*/ */
int[] index; int[] index;
/** /** The encoding of the latest stack map frame that has been parsed. */
* The encoding of the latest stack map frame that has been parsed.
*/
int mode; int mode;
/** /** The number of locals in the latest stack map frame that has been parsed. */
* The number of locals in the latest stack map frame that has been parsed.
*/
int localCount; int localCount;
/** /**
* The number locals in the latest stack map frame that has been parsed, * The number locals in the latest stack map frame that has been parsed, minus the number of locals in the previous
* minus the number of locals in the previous frame. * frame.
*/ */
int localDiff; int localDiff;
/** /** The local values of the latest stack map frame that has been parsed. */
* The local values of the latest stack map frame that has been parsed.
*/
Object[] local; Object[] local;
/** /** The stack size of the latest stack map frame that has been parsed. */
* The stack size of the latest stack map frame that has been parsed.
*/
int stackCount; int stackCount;
/** /** The stack values of the latest stack map frame that has been parsed. */
* The stack values of the latest stack map frame that has been parsed.
*/
Object[] stack; Object[] stack;
} }

View File

@@ -60,18 +60,16 @@
package org.redkale.asm; package org.redkale.asm;
/** /**
* Information about the input stack map frame at the "current" instruction of a * Information about the input stack map frame at the "current" instruction of a method. This is implemented as a Frame
* method. This is implemented as a Frame subclass for a "basic block" * subclass for a "basic block" containing only one instruction.
* containing only one instruction.
* *
* @author Eric Bruneton * @author Eric Bruneton
*/ */
class CurrentFrame extends Frame { class CurrentFrame extends Frame {
/** /**
* Sets this CurrentFrame to the input stack map frame of the next "current" * Sets this CurrentFrame to the input stack map frame of the next "current" instruction, i.e. the instruction just
* instruction, i.e. the instruction just after the given one. It is assumed * after the given one. It is assumed that the value of this object when this method is called is the stack map
* that the value of this object when this method is called is the stack map
* frame status just before the given instruction is executed. * frame status just before the given instruction is executed.
*/ */
@Override @Override

View File

@@ -65,40 +65,30 @@ package org.redkale.asm;
*/ */
class Edge { class Edge {
/** /** Denotes a normal control flow graph edge. */
* Denotes a normal control flow graph edge.
*/
static final int NORMAL = 0; static final int NORMAL = 0;
/** /**
* Denotes a control flow graph edge corresponding to an exception handler. * Denotes a control flow graph edge corresponding to an exception handler. More precisely any {@link Edge} whose
* More precisely any {@link Edge} whose {@link #info} is strictly positive * {@link #info} is strictly positive corresponds to an exception handler. The actual value of {@link #info} is the
* corresponds to an exception handler. The actual value of {@link #info} is * index, in the {@link ClassWriter} type table, of the exception that is catched.
* the index, in the {@link ClassWriter} type table, of the exception that
* is catched.
*/ */
static final int EXCEPTION = 0x7FFFFFFF; static final int EXCEPTION = 0x7FFFFFFF;
/** /**
* Information about this control flow graph edge. If * Information about this control flow graph edge. If {@link ClassWriter#COMPUTE_MAXS} is used this field is the
* {@link ClassWriter#COMPUTE_MAXS} is used this field is the (relative) * (relative) stack size in the basic block from which this edge originates. This size is equal to the stack size at
* stack size in the basic block from which this edge originates. This size * the "jump" instruction to which this edge corresponds, relatively to the stack size at the beginning of the
* is equal to the stack size at the "jump" instruction to which this edge * originating basic block. If {@link ClassWriter#COMPUTE_FRAMES} is used, this field is the kind of this control
* corresponds, relatively to the stack size at the beginning of the * flow graph edge (i.e. NORMAL or EXCEPTION).
* originating basic block. If {@link ClassWriter#COMPUTE_FRAMES} is used,
* this field is the kind of this control flow graph edge (i.e. NORMAL or
* EXCEPTION).
*/ */
int info; int info;
/** /** The successor block of the basic block from which this edge originates. */
* The successor block of the basic block from which this edge originates.
*/
Label successor; Label successor;
/** /**
* The next edge in the list of successors of the originating basic block. * The next edge in the list of successors of the originating basic block. See {@link Label#successors successors}.
* See {@link Label#successors successors}.
*/ */
Edge next; Edge next;
} }

View File

@@ -59,32 +59,28 @@
package org.redkale.asm; package org.redkale.asm;
/** /**
* A visitor to visit a Java field. The methods of this class must be called in * A visitor to visit a Java field. The methods of this class must be called in the following order: (
* the following order: ( &#60;tt&#62;visitAnnotation&#60;/tt&#62; | * &#60;tt&#62;visitAnnotation&#60;/tt&#62; | &#60;tt&#62;visitTypeAnnotation&#60;/tt&#62; |
* &#60;tt&#62;visitTypeAnnotation&#60;/tt&#62; | &#60;tt&#62;visitAttribute&#60;/tt&#62; )* &#60;tt&#62;visitEnd&#60;/tt&#62;. * &#60;tt&#62;visitAttribute&#60;/tt&#62; )* &#60;tt&#62;visitEnd&#60;/tt&#62;.
* *
* @author Eric Bruneton * @author Eric Bruneton
*/ */
public abstract class FieldVisitor { public abstract class FieldVisitor {
/** /**
* The ASM API version implemented by this visitor. The value of this field * The ASM API version implemented by this visitor. The value of this field must be one of {@link Opcodes#ASM4},
* must be one of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}. * {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
*/ */
protected final int api; protected final int api;
/** /** The field visitor to which this visitor must delegate method calls. May be null. */
* The field visitor to which this visitor must delegate method calls. May
* be null.
*/
protected FieldVisitor fv; protected FieldVisitor fv;
/** /**
* Constructs a new {@link FieldVisitor}. * Constructs a new {@link FieldVisitor}.
* *
* @param api * @param api the ASM API version implemented by this visitor. Must be one of {@link Opcodes#ASM4},
* the ASM API version implemented by this visitor. Must be one * {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
* of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
*/ */
public FieldVisitor(final int api) { public FieldVisitor(final int api) {
this(api, null); this(api, null);
@@ -93,12 +89,9 @@ public abstract class FieldVisitor {
/** /**
* Constructs a new {@link FieldVisitor}. * Constructs a new {@link FieldVisitor}.
* *
* @param api * @param api the ASM API version implemented by this visitor. Must be one of {@link Opcodes#ASM4},
* the ASM API version implemented by this visitor. Must be one * {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
* of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}. * @param fv the field visitor to which this visitor must delegate method calls. May be null.
* @param fv
* the field visitor to which this visitor must delegate method
* calls. May be null.
*/ */
public FieldVisitor(final int api, final FieldVisitor fv) { public FieldVisitor(final int api, final FieldVisitor fv) {
this.api = api; this.api = api;
@@ -108,12 +101,10 @@ public abstract class FieldVisitor {
/** /**
* Visits an annotation of the field. * Visits an annotation of the field.
* *
* @param desc * @param desc the class descriptor of the annotation class.
* the class descriptor of the annotation class. * @param visible &#60;tt&#62;true&#60;/tt&#62; if the annotation is visible at runtime.
* @param visible * @return a visitor to visit the annotation values, or &#60;tt&#62;null&#60;/tt&#62; if this visitor is not
* &#60;tt&#62;true&#60;/tt&#62; if the annotation is visible at runtime. * interested in visiting this annotation.
* @return a visitor to visit the annotation values, or &#60;tt&#62;null&#60;/tt&#62; if
* this visitor is not interested in visiting this annotation.
*/ */
public AnnotationVisitor visitAnnotation(String desc, boolean visible) { public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
if (fv != null) { if (fv != null) {
@@ -125,23 +116,16 @@ public abstract class FieldVisitor {
/** /**
* Visits an annotation on the type of the field. * Visits an annotation on the type of the field.
* *
* @param typeRef * @param typeRef a reference to the annotated type. The sort of this type reference must be
* a reference to the annotated type. The sort of this type * {@link TypeReference#FIELD FIELD}. See {@link TypeReference}.
* reference must be {@link TypeReference#FIELD FIELD}. See * @param typePath the path to the annotated type argument, wildcard bound, array element type, or static inner type
* {@link TypeReference}. * within 'typeRef'. May be &#60;tt&#62;null&#60;/tt&#62; if the annotation targets 'typeRef' as a whole.
* @param typePath * @param desc the class descriptor of the annotation class.
* the path to the annotated type argument, wildcard bound, array * @param visible &#60;tt&#62;true&#60;/tt&#62; if the annotation is visible at runtime.
* element type, or static inner type within 'typeRef'. May be * @return a visitor to visit the annotation values, or &#60;tt&#62;null&#60;/tt&#62; if this visitor is not
* &#60;tt&#62;null&#60;/tt&#62; if the annotation targets 'typeRef' as a whole. * interested in visiting this annotation.
* @param desc
* the class descriptor of the annotation class.
* @param visible
* &#60;tt&#62;true&#60;/tt&#62; if the annotation is visible at runtime.
* @return a visitor to visit the annotation values, or &#60;tt&#62;null&#60;/tt&#62; if
* this visitor is not interested in visiting this annotation.
*/ */
public AnnotationVisitor visitTypeAnnotation(int typeRef, public AnnotationVisitor visitTypeAnnotation(int typeRef, TypePath typePath, String desc, boolean visible) {
TypePath typePath, String desc, boolean visible) {
if (fv != null) { if (fv != null) {
return fv.visitTypeAnnotation(typeRef, typePath, desc, visible); return fv.visitTypeAnnotation(typeRef, typePath, desc, visible);
} }
@@ -151,8 +135,7 @@ public abstract class FieldVisitor {
/** /**
* Visits a non standard attribute of the field. * Visits a non standard attribute of the field.
* *
* @param attr * @param attr an attribute.
* an attribute.
*/ */
public void visitAttribute(Attribute attr) { public void visitAttribute(Attribute attr) {
if (fv != null) { if (fv != null) {
@@ -161,9 +144,8 @@ public abstract class FieldVisitor {
} }
/** /**
* Visits the end of the field. This method, which is the last one to be * Visits the end of the field. This method, which is the last one to be called, is used to inform the visitor that
* called, is used to inform the visitor that all the annotations and * all the annotations and attributes of the field have been visited.
* attributes of the field have been visited.
*/ */
public void visitEnd() { public void visitEnd() {
if (fv != null) { if (fv != null) {

View File

@@ -65,64 +65,37 @@ package org.redkale.asm;
*/ */
final class FieldWriter extends FieldVisitor { final class FieldWriter extends FieldVisitor {
/** /** The class writer to which this field must be added. */
* The class writer to which this field must be added.
*/
private final ClassWriter cw; private final ClassWriter cw;
/** /** Access flags of this field. */
* Access flags of this field.
*/
private final int access; private final int access;
/** /** The index of the constant pool item that contains the name of this method. */
* The index of the constant pool item that contains the name of this
* method.
*/
private final int name; private final int name;
/** /** The index of the constant pool item that contains the descriptor of this field. */
* The index of the constant pool item that contains the descriptor of this
* field.
*/
private final int desc; private final int desc;
/** /** The index of the constant pool item that contains the signature of this field. */
* The index of the constant pool item that contains the signature of this
* field.
*/
private int signature; private int signature;
/** /** The index of the constant pool item that contains the constant value of this field. */
* The index of the constant pool item that contains the constant value of
* this field.
*/
private int value; private int value;
/** /** The runtime visible annotations of this field. May be &#60;tt&#62;null&#60;/tt&#62;. */
* The runtime visible annotations of this field. May be &#60;tt&#62;null&#60;/tt&#62;.
*/
private AnnotationWriter anns; private AnnotationWriter anns;
/** /** The runtime invisible annotations of this field. May be &#60;tt&#62;null&#60;/tt&#62;. */
* The runtime invisible annotations of this field. May be &#60;tt&#62;null&#60;/tt&#62;.
*/
private AnnotationWriter ianns; private AnnotationWriter ianns;
/** /** The runtime visible type annotations of this field. May be &#60;tt&#62;null&#60;/tt&#62;. */
* The runtime visible type annotations of this field. May be &#60;tt&#62;null&#60;/tt&#62;.
*/
private AnnotationWriter tanns; private AnnotationWriter tanns;
/** /** The runtime invisible type annotations of this field. May be &#60;tt&#62;null&#60;/tt&#62;. */
* The runtime invisible type annotations of this field. May be
* &#60;tt&#62;null&#60;/tt&#62;.
*/
private AnnotationWriter itanns; private AnnotationWriter itanns;
/** /** The non standard attributes of this field. May be &#60;tt&#62;null&#60;/tt&#62;. */
* The non standard attributes of this field. May be &#60;tt&#62;null&#60;/tt&#62;.
*/
private Attribute attrs; private Attribute attrs;
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
@@ -132,21 +105,20 @@ final class FieldWriter extends FieldVisitor {
/** /**
* Constructs a new {@link FieldWriter}. * Constructs a new {@link FieldWriter}.
* *
* @param cw * @param cw the class writer to which this field must be added.
* the class writer to which this field must be added. * @param access the field's access flags (see {@link Opcodes}).
* @param access * @param name the field's name.
* the field's access flags (see {@link Opcodes}). * @param desc the field's descriptor (see {@link Type}).
* @param name * @param signature the field's signature. May be &#60;tt&#62;null&#60;/tt&#62;.
* the field's name. * @param value the field's constant value. May be &#60;tt&#62;null&#60;/tt&#62;.
* @param desc
* the field's descriptor (see {@link Type}).
* @param signature
* the field's signature. May be &#60;tt&#62;null&#60;/tt&#62;.
* @param value
* the field's constant value. May be &#60;tt&#62;null&#60;/tt&#62;.
*/ */
FieldWriter(final ClassWriter cw, final int access, final String name, FieldWriter(
final String desc, final String signature, final Object value) { final ClassWriter cw,
final int access,
final String name,
final String desc,
final String signature,
final Object value) {
super(Opcodes.ASM6); super(Opcodes.ASM6);
if (cw.firstField == null) { if (cw.firstField == null) {
cw.firstField = this; cw.firstField = this;
@@ -171,8 +143,7 @@ final class FieldWriter extends FieldVisitor {
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
@Override @Override
public AnnotationVisitor visitAnnotation(final String desc, public AnnotationVisitor visitAnnotation(final String desc, final boolean visible) {
final boolean visible) {
ByteVector bv = new ByteVector(); ByteVector bv = new ByteVector();
// write type, and reserve space for values count // write type, and reserve space for values count
bv.putShort(cw.newUTF8(desc)).putShort(0); bv.putShort(cw.newUTF8(desc)).putShort(0);
@@ -188,15 +159,14 @@ final class FieldWriter extends FieldVisitor {
} }
@Override @Override
public AnnotationVisitor visitTypeAnnotation(final int typeRef, public AnnotationVisitor visitTypeAnnotation(
final TypePath typePath, final String desc, final boolean visible) { final int typeRef, final TypePath typePath, final String desc, final boolean visible) {
ByteVector bv = new ByteVector(); ByteVector bv = new ByteVector();
// write target_type and target_info // write target_type and target_info
AnnotationWriter.putTarget(typeRef, typePath, bv); AnnotationWriter.putTarget(typeRef, typePath, bv);
// write type, and reserve space for values count // write type, and reserve space for values count
bv.putShort(cw.newUTF8(desc)).putShort(0); bv.putShort(cw.newUTF8(desc)).putShort(0);
AnnotationWriter aw = new AnnotationWriter(cw, true, bv, bv, AnnotationWriter aw = new AnnotationWriter(cw, true, bv, bv, bv.length - 2);
bv.length - 2);
if (visible) { if (visible) {
aw.next = tanns; aw.next = tanns;
tanns = aw; tanns = aw;
@@ -215,7 +185,7 @@ final class FieldWriter extends FieldVisitor {
@Override @Override
public void visitEnd() { public void visitEnd() {
//do nothing // do nothing
} }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
@@ -234,8 +204,7 @@ final class FieldWriter extends FieldVisitor {
size += 8; size += 8;
} }
if ((access & Opcodes.ACC_SYNTHETIC) != 0) { if ((access & Opcodes.ACC_SYNTHETIC) != 0) {
if ((cw.version & 0xFFFF) < Opcodes.V1_5 if ((cw.version & 0xFFFF) < Opcodes.V1_5 || (access & ClassWriter.ACC_SYNTHETIC_ATTRIBUTE) != 0) {
|| (access & ClassWriter.ACC_SYNTHETIC_ATTRIBUTE) != 0) {
cw.newUTF8("Synthetic"); cw.newUTF8("Synthetic");
size += 6; size += 6;
} }
@@ -273,12 +242,12 @@ final class FieldWriter extends FieldVisitor {
/** /**
* Puts the content of this field into the given byte vector. * Puts the content of this field into the given byte vector.
* *
* @param out * @param out where the content of this field must be put.
* where the content of this field must be put.
*/ */
void put(final ByteVector out) { void put(final ByteVector out) {
final int FACTOR = ClassWriter.TO_ACC_SYNTHETIC; final int FACTOR = ClassWriter.TO_ACC_SYNTHETIC;
int mask = Opcodes.ACC_DEPRECATED | ClassWriter.ACC_SYNTHETIC_ATTRIBUTE int mask = Opcodes.ACC_DEPRECATED
| ClassWriter.ACC_SYNTHETIC_ATTRIBUTE
| ((access & ClassWriter.ACC_SYNTHETIC_ATTRIBUTE) / FACTOR); | ((access & ClassWriter.ACC_SYNTHETIC_ATTRIBUTE) / FACTOR);
out.putShort(access & ~mask).putShort(name).putShort(desc); out.putShort(access & ~mask).putShort(name).putShort(desc);
int attributeCount = 0; int attributeCount = 0;
@@ -286,8 +255,7 @@ final class FieldWriter extends FieldVisitor {
++attributeCount; ++attributeCount;
} }
if ((access & Opcodes.ACC_SYNTHETIC) != 0) { if ((access & Opcodes.ACC_SYNTHETIC) != 0) {
if ((cw.version & 0xFFFF) < Opcodes.V1_5 if ((cw.version & 0xFFFF) < Opcodes.V1_5 || (access & ClassWriter.ACC_SYNTHETIC_ATTRIBUTE) != 0) {
|| (access & ClassWriter.ACC_SYNTHETIC_ATTRIBUTE) != 0) {
++attributeCount; ++attributeCount;
} }
} }
@@ -318,8 +286,7 @@ final class FieldWriter extends FieldVisitor {
out.putInt(2).putShort(value); out.putInt(2).putShort(value);
} }
if ((access & Opcodes.ACC_SYNTHETIC) != 0) { if ((access & Opcodes.ACC_SYNTHETIC) != 0) {
if ((cw.version & 0xFFFF) < Opcodes.V1_5 if ((cw.version & 0xFFFF) < Opcodes.V1_5 || (access & ClassWriter.ACC_SYNTHETIC_ATTRIBUTE) != 0) {
|| (access & ClassWriter.ACC_SYNTHETIC_ATTRIBUTE) != 0) {
out.putShort(cw.newUTF8("Synthetic")).putInt(0); out.putShort(cw.newUTF8("Synthetic")).putInt(0);
} }
} }

File diff suppressed because it is too large Load Diff

View File

@@ -68,59 +68,36 @@ package org.redkale.asm;
public final class Handle { public final class Handle {
/** /**
* The kind of field or method designated by this Handle. Should be * The kind of field or method designated by this Handle. Should be {@link Opcodes#H_GETFIELD},
* {@link Opcodes#H_GETFIELD}, {@link Opcodes#H_GETSTATIC}, * {@link Opcodes#H_GETSTATIC}, {@link Opcodes#H_PUTFIELD}, {@link Opcodes#H_PUTSTATIC},
* {@link Opcodes#H_PUTFIELD}, {@link Opcodes#H_PUTSTATIC}, * {@link Opcodes#H_INVOKEVIRTUAL}, {@link Opcodes#H_INVOKESTATIC}, {@link Opcodes#H_INVOKESPECIAL},
* {@link Opcodes#H_INVOKEVIRTUAL}, {@link Opcodes#H_INVOKESTATIC}, * {@link Opcodes#H_NEWINVOKESPECIAL} or {@link Opcodes#H_INVOKEINTERFACE}.
* {@link Opcodes#H_INVOKESPECIAL}, {@link Opcodes#H_NEWINVOKESPECIAL} or
* {@link Opcodes#H_INVOKEINTERFACE}.
*/ */
final int tag; final int tag;
/** /** The internal name of the class that owns the field or method designated by this handle. */
* The internal name of the class that owns the field or method designated
* by this handle.
*/
final String owner; final String owner;
/** /** The name of the field or method designated by this handle. */
* The name of the field or method designated by this handle.
*/
final String name; final String name;
/** /** The descriptor of the field or method designated by this handle. */
* The descriptor of the field or method designated by this handle.
*/
final String desc; final String desc;
/** Indicate if the owner is an interface or not. */
/**
* Indicate if the owner is an interface or not.
*/
final boolean itf; final boolean itf;
/** /**
* Constructs a new field or method handle. * Constructs a new field or method handle.
* *
* @param tag * @param tag the kind of field or method designated by this Handle. Must be {@link Opcodes#H_GETFIELD},
* the kind of field or method designated by this Handle. Must be * {@link Opcodes#H_GETSTATIC}, {@link Opcodes#H_PUTFIELD}, {@link Opcodes#H_PUTSTATIC},
* {@link Opcodes#H_GETFIELD}, {@link Opcodes#H_GETSTATIC}, * {@link Opcodes#H_INVOKEVIRTUAL}, {@link Opcodes#H_INVOKESTATIC}, {@link Opcodes#H_INVOKESPECIAL},
* {@link Opcodes#H_PUTFIELD}, {@link Opcodes#H_PUTSTATIC}, * {@link Opcodes#H_NEWINVOKESPECIAL} or {@link Opcodes#H_INVOKEINTERFACE}.
* {@link Opcodes#H_INVOKEVIRTUAL}, * @param owner the internal name of the class that owns the field or method designated by this handle.
* {@link Opcodes#H_INVOKESTATIC}, * @param name the name of the field or method designated by this handle.
* {@link Opcodes#H_INVOKESPECIAL}, * @param desc the descriptor of the field or method designated by this handle.
* {@link Opcodes#H_NEWINVOKESPECIAL} or * @param itf true if the owner is an interface.
* {@link Opcodes#H_INVOKEINTERFACE}.
* @param owner
* the internal name of the class that owns the field or method
* designated by this handle.
* @param name
* the name of the field or method designated by this handle.
* @param desc
* the descriptor of the field or method designated by this
* handle.
* @param itf
* true if the owner is an interface.
*/ */
public Handle(int tag, String owner, String name, String desc, boolean itf) { public Handle(int tag, String owner, String name, String desc, boolean itf) {
this.tag = tag; this.tag = tag;
@@ -133,23 +110,18 @@ public final class Handle {
/** /**
* Returns the kind of field or method designated by this handle. * Returns the kind of field or method designated by this handle.
* *
* @return {@link Opcodes#H_GETFIELD}, {@link Opcodes#H_GETSTATIC}, * @return {@link Opcodes#H_GETFIELD}, {@link Opcodes#H_GETSTATIC}, {@link Opcodes#H_PUTFIELD},
* {@link Opcodes#H_PUTFIELD}, {@link Opcodes#H_PUTSTATIC}, * {@link Opcodes#H_PUTSTATIC}, {@link Opcodes#H_INVOKEVIRTUAL}, {@link Opcodes#H_INVOKESTATIC},
* {@link Opcodes#H_INVOKEVIRTUAL}, {@link Opcodes#H_INVOKESTATIC}, * {@link Opcodes#H_INVOKESPECIAL}, {@link Opcodes#H_NEWINVOKESPECIAL} or {@link Opcodes#H_INVOKEINTERFACE}.
* {@link Opcodes#H_INVOKESPECIAL},
* {@link Opcodes#H_NEWINVOKESPECIAL} or
* {@link Opcodes#H_INVOKEINTERFACE}.
*/ */
public int getTag() { public int getTag() {
return tag; return tag;
} }
/** /**
* Returns the internal name of the class that owns the field or method * Returns the internal name of the class that owns the field or method designated by this handle.
* designated by this handle.
* *
* @return the internal name of the class that owns the field or method * @return the internal name of the class that owns the field or method designated by this handle.
* designated by this handle.
*/ */
public String getOwner() { public String getOwner() {
return owner; return owner;
@@ -174,11 +146,9 @@ public final class Handle {
} }
/** /**
* Returns true if the owner of the field or method designated * Returns true if the owner of the field or method designated by this handle is an interface.
* by this handle is an interface.
* *
* @return true if the owner of the field or method designated * @return true if the owner of the field or method designated by this handle is an interface.
* by this handle is an interface.
*/ */
public boolean isInterface() { public boolean isInterface() {
return itf; return itf;
@@ -193,18 +163,16 @@ public final class Handle {
return false; return false;
} }
Handle h = (Handle) obj; Handle h = (Handle) obj;
return tag == h.tag && itf == h.itf && owner.equals(h.owner) return tag == h.tag && itf == h.itf && owner.equals(h.owner) && name.equals(h.name) && desc.equals(h.desc);
&& name.equals(h.name) && desc.equals(h.desc);
} }
@Override @Override
public int hashCode() { public int hashCode() {
return tag + (itf? 64: 0) + owner.hashCode() * name.hashCode() * desc.hashCode(); return tag + (itf ? 64 : 0) + owner.hashCode() * name.hashCode() * desc.hashCode();
} }
/** /**
* Returns the textual representation of this handle. The textual * Returns the textual representation of this handle. The textual representation is:
* representation is:
* *
* <pre> * <pre>
* for a reference to a class: * for a reference to a class:
@@ -217,6 +185,6 @@ public final class Handle {
*/ */
@Override @Override
public String toString() { public String toString() {
return owner + '.' + name + desc + " (" + tag + (itf? " itf": "") + ')'; return owner + '.' + name + desc + " (" + tag + (itf ? " itf" : "") + ')';
} }
} }

View File

@@ -65,48 +65,36 @@ package org.redkale.asm;
*/ */
class Handler { class Handler {
/** /** Beginning of the exception handler's scope (inclusive). */
* Beginning of the exception handler's scope (inclusive).
*/
Label start; Label start;
/** /** End of the exception handler's scope (exclusive). */
* End of the exception handler's scope (exclusive).
*/
Label end; Label end;
/** /** Beginning of the exception handler's code. */
* Beginning of the exception handler's code.
*/
Label handler; Label handler;
/** /**
* Internal name of the type of exceptions handled by this handler, or * Internal name of the type of exceptions handled by this handler, or &#60;tt&#62;null&#60;/tt&#62; to catch any
* &#60;tt&#62;null&#60;/tt&#62; to catch any exceptions. * exceptions.
*/ */
String desc; String desc;
/** /**
* Constant pool index of the internal name of the type of exceptions * Constant pool index of the internal name of the type of exceptions handled by this handler, or 0 to catch any
* handled by this handler, or 0 to catch any exceptions. * exceptions.
*/ */
int type; int type;
/** /** Next exception handler block info. */
* Next exception handler block info.
*/
Handler next; Handler next;
/** /**
* Removes the range between start and end from the given exception * Removes the range between start and end from the given exception handlers.
* handlers.
* *
* @param h * @param h an exception handler list.
* an exception handler list. * @param start the start of the range to be removed.
* @param start * @param end the end of the range to be removed. Maybe null.
* the start of the range to be removed.
* @param end
* the end of the range to be removed. Maybe null.
* @return the exception handler list with the start-end range removed. * @return the exception handler list with the start-end range removed.
*/ */
static Handler remove(Handler h, Label start, Label end) { static Handler remove(Handler h, Label start, Label end) {

View File

@@ -59,94 +59,61 @@
package org.redkale.asm; package org.redkale.asm;
/** /**
* A constant pool item. Constant pool items can be created with the 'newXXX' * A constant pool item. Constant pool items can be created with the 'newXXX' methods in the {@link ClassWriter} class.
* methods in the {@link ClassWriter} class.
* *
* @author Eric Bruneton * @author Eric Bruneton
*/ */
final class Item { final class Item {
/** /** Index of this item in the constant pool. */
* Index of this item in the constant pool.
*/
int index; int index;
/** /**
* Type of this constant pool item. A single class is used to represent all * Type of this constant pool item. A single class is used to represent all constant pool item types, in order to
* constant pool item types, in order to minimize the bytecode size of this * minimize the bytecode size of this package. The value of this field is one of {@link ClassWriter#INT},
* package. The value of this field is one of {@link ClassWriter#INT}, * {@link ClassWriter#LONG}, {@link ClassWriter#FLOAT}, {@link ClassWriter#DOUBLE}, {@link ClassWriter#UTF8},
* {@link ClassWriter#LONG}, {@link ClassWriter#FLOAT}, * {@link ClassWriter#STR}, {@link ClassWriter#CLASS}, {@link ClassWriter#NAME_TYPE}, {@link ClassWriter#FIELD},
* {@link ClassWriter#DOUBLE}, {@link ClassWriter#UTF8}, * {@link ClassWriter#METH}, {@link ClassWriter#IMETH}, {@link ClassWriter#MODULE}, {@link ClassWriter#PACKAGE},
* {@link ClassWriter#STR}, {@link ClassWriter#CLASS},
* {@link ClassWriter#NAME_TYPE}, {@link ClassWriter#FIELD},
* {@link ClassWriter#METH}, {@link ClassWriter#IMETH},
* {@link ClassWriter#MODULE}, {@link ClassWriter#PACKAGE},
* {@link ClassWriter#MTYPE}, {@link ClassWriter#INDY}. * {@link ClassWriter#MTYPE}, {@link ClassWriter#INDY}.
* *
* MethodHandle constant 9 variations are stored using a range of 9 values * <p>MethodHandle constant 9 variations are stored using a range of 9 values from {@link ClassWriter#HANDLE_BASE} +
* from {@link ClassWriter#HANDLE_BASE} + 1 to * 1 to {@link ClassWriter#HANDLE_BASE} + 9.
* {@link ClassWriter#HANDLE_BASE} + 9.
* *
* Special Item types are used for Items that are stored in the ClassWriter * <p>Special Item types are used for Items that are stored in the ClassWriter {@link ClassWriter#typeTable},
* {@link ClassWriter#typeTable}, instead of the constant pool, in order to * instead of the constant pool, in order to avoid clashes with normal constant pool items in the ClassWriter
* avoid clashes with normal constant pool items in the ClassWriter constant * constant pool's hash table. These special item types are {@link ClassWriter#TYPE_NORMAL},
* pool's hash table. These special item types are * {@link ClassWriter#TYPE_UNINIT} and {@link ClassWriter#TYPE_MERGED}.
* {@link ClassWriter#TYPE_NORMAL}, {@link ClassWriter#TYPE_UNINIT} and
* {@link ClassWriter#TYPE_MERGED}.
*/ */
int type; int type;
/** /** Value of this item, for an integer item. */
* Value of this item, for an integer item.
*/
int intVal; int intVal;
/** /** Value of this item, for a long item. */
* Value of this item, for a long item.
*/
long longVal; long longVal;
/** /** First part of the value of this item, for items that do not hold a primitive value. */
* First part of the value of this item, for items that do not hold a
* primitive value.
*/
String strVal1; String strVal1;
/** /** Second part of the value of this item, for items that do not hold a primitive value. */
* Second part of the value of this item, for items that do not hold a
* primitive value.
*/
String strVal2; String strVal2;
/** /** Third part of the value of this item, for items that do not hold a primitive value. */
* Third part of the value of this item, for items that do not hold a
* primitive value.
*/
String strVal3; String strVal3;
/** /** The hash code value of this constant pool item. */
* The hash code value of this constant pool item.
*/
int hashCode; int hashCode;
/** /** Link to another constant pool item, used for collision lists in the constant pool's hash table. */
* Link to another constant pool item, used for collision lists in the
* constant pool's hash table.
*/
Item next; Item next;
/** /** Constructs an uninitialized {@link Item}. */
* Constructs an uninitialized {@link Item}. Item() {}
*/
Item() {
}
/** /**
* Constructs an uninitialized {@link Item} for constant pool element at * Constructs an uninitialized {@link Item} for constant pool element at given position.
* given position.
* *
* @param index * @param index index of the item to be constructed.
* index of the item to be constructed.
*/ */
Item(final int index) { Item(final int index) {
this.index = index; this.index = index;
@@ -155,10 +122,8 @@ final class Item {
/** /**
* Constructs a copy of the given item. * Constructs a copy of the given item.
* *
* @param index * @param index index of the item to be constructed.
* index of the item to be constructed. * @param i the item that must be copied into the item to be constructed.
* @param i
* the item that must be copied into the item to be constructed.
*/ */
Item(final int index, final Item i) { Item(final int index, final Item i) {
this.index = index; this.index = index;
@@ -174,8 +139,7 @@ final class Item {
/** /**
* Sets this item to an integer item. * Sets this item to an integer item.
* *
* @param intVal * @param intVal the value of this item.
* the value of this item.
*/ */
void set(final int intVal) { void set(final int intVal) {
this.type = ClassWriter.INT; this.type = ClassWriter.INT;
@@ -186,8 +150,7 @@ final class Item {
/** /**
* Sets this item to a long item. * Sets this item to a long item.
* *
* @param longVal * @param longVal the value of this item.
* the value of this item.
*/ */
void set(final long longVal) { void set(final long longVal) {
this.type = ClassWriter.LONG; this.type = ClassWriter.LONG;
@@ -198,8 +161,7 @@ final class Item {
/** /**
* Sets this item to a float item. * Sets this item to a float item.
* *
* @param floatVal * @param floatVal the value of this item.
* the value of this item.
*/ */
void set(final float floatVal) { void set(final float floatVal) {
this.type = ClassWriter.FLOAT; this.type = ClassWriter.FLOAT;
@@ -210,8 +172,7 @@ final class Item {
/** /**
* Sets this item to a double item. * Sets this item to a double item.
* *
* @param doubleVal * @param doubleVal the value of this item.
* the value of this item.
*/ */
void set(final double doubleVal) { void set(final double doubleVal) {
this.type = ClassWriter.DOUBLE; this.type = ClassWriter.DOUBLE;
@@ -222,76 +183,62 @@ final class Item {
/** /**
* Sets this item to an item that do not hold a primitive value. * Sets this item to an item that do not hold a primitive value.
* *
* @param type * @param type the type of this item.
* the type of this item. * @param strVal1 first part of the value of this item.
* @param strVal1 * @param strVal2 second part of the value of this item.
* first part of the value of this item. * @param strVal3 third part of the value of this item.
* @param strVal2
* second part of the value of this item.
* @param strVal3
* third part of the value of this item.
*/ */
@SuppressWarnings("fallthrough") @SuppressWarnings("fallthrough")
void set(final int type, final String strVal1, final String strVal2, void set(final int type, final String strVal1, final String strVal2, final String strVal3) {
final String strVal3) {
this.type = type; this.type = type;
this.strVal1 = strVal1; this.strVal1 = strVal1;
this.strVal2 = strVal2; this.strVal2 = strVal2;
this.strVal3 = strVal3; this.strVal3 = strVal3;
switch (type) { switch (type) {
case ClassWriter.CLASS: case ClassWriter.CLASS:
this.intVal = 0; // intVal of a class must be zero, see visitInnerClass this.intVal = 0; // intVal of a class must be zero, see visitInnerClass
case ClassWriter.UTF8: case ClassWriter.UTF8:
case ClassWriter.STR: case ClassWriter.STR:
case ClassWriter.MTYPE: case ClassWriter.MTYPE:
case ClassWriter.MODULE: case ClassWriter.MODULE:
case ClassWriter.PACKAGE: case ClassWriter.PACKAGE:
case ClassWriter.TYPE_NORMAL: case ClassWriter.TYPE_NORMAL:
hashCode = 0x7FFFFFFF & (type + strVal1.hashCode()); hashCode = 0x7FFFFFFF & (type + strVal1.hashCode());
return; return;
case ClassWriter.NAME_TYPE: { case ClassWriter.NAME_TYPE: {
hashCode = 0x7FFFFFFF & (type + strVal1.hashCode() hashCode = 0x7FFFFFFF & (type + strVal1.hashCode() * strVal2.hashCode());
* strVal2.hashCode()); return;
return; }
} // ClassWriter.FIELD:
// ClassWriter.FIELD: // ClassWriter.METH:
// ClassWriter.METH: // ClassWriter.IMETH:
// ClassWriter.IMETH: // ClassWriter.HANDLE_BASE + 1..9
// ClassWriter.HANDLE_BASE + 1..9 default:
default: hashCode = 0x7FFFFFFF & (type + strVal1.hashCode() * strVal2.hashCode() * strVal3.hashCode());
hashCode = 0x7FFFFFFF & (type + strVal1.hashCode()
* strVal2.hashCode() * strVal3.hashCode());
} }
} }
/** /**
* Sets the item to an InvokeDynamic item. * Sets the item to an InvokeDynamic item.
* *
* @param name * @param name invokedynamic's name.
* invokedynamic's name. * @param desc invokedynamic's desc.
* @param desc * @param bsmIndex zero based index into the class attribute BootrapMethods.
* invokedynamic's desc.
* @param bsmIndex
* zero based index into the class attribute BootrapMethods.
*/ */
void set(String name, String desc, int bsmIndex) { void set(String name, String desc, int bsmIndex) {
this.type = ClassWriter.INDY; this.type = ClassWriter.INDY;
this.longVal = bsmIndex; this.longVal = bsmIndex;
this.strVal1 = name; this.strVal1 = name;
this.strVal2 = desc; this.strVal2 = desc;
this.hashCode = 0x7FFFFFFF & (ClassWriter.INDY + bsmIndex this.hashCode = 0x7FFFFFFF & (ClassWriter.INDY + bsmIndex * strVal1.hashCode() * strVal2.hashCode());
* strVal1.hashCode() * strVal2.hashCode());
} }
/** /**
* Sets the item to a BootstrapMethod item. * Sets the item to a BootstrapMethod item.
* *
* @param position * @param position position in byte in the class attribute BootrapMethods.
* position in byte in the class attribute BootrapMethods. * @param hashCode hashcode of the item. This hashcode is processed from the hashcode of the bootstrap method and
* @param hashCode * the hashcode of all bootstrap arguments.
* hashcode of the item. This hashcode is processed from the
* hashcode of the bootstrap method and the hashcode of all
* bootstrap arguments.
*/ */
void set(int position, int hashCode) { void set(int position, int hashCode) {
this.type = ClassWriter.BSM; this.type = ClassWriter.BSM;
@@ -300,48 +247,43 @@ final class Item {
} }
/** /**
* Indicates if the given item is equal to this one. <i>This method assumes * Indicates if the given item is equal to this one. <i>This method assumes that the two items have the same
* that the two items have the same {@link #type}</i>. * {@link #type}</i>.
* *
* @param i * @param i the item to be compared to this one. Both items must have the same {@link #type}.
* the item to be compared to this one. Both items must have the * @return &#60;tt&#62;true&#60;/tt&#62; if the given item if equal to this one, &#60;tt&#62;false&#60;/tt&#62;
* same {@link #type}. * otherwise.
* @return &#60;tt&#62;true&#60;/tt&#62; if the given item if equal to this one,
* &#60;tt&#62;false&#60;/tt&#62; otherwise.
*/ */
boolean isEqualTo(final Item i) { boolean isEqualTo(final Item i) {
switch (type) { switch (type) {
case ClassWriter.UTF8: case ClassWriter.UTF8:
case ClassWriter.STR: case ClassWriter.STR:
case ClassWriter.CLASS: case ClassWriter.CLASS:
case ClassWriter.MODULE: case ClassWriter.MODULE:
case ClassWriter.PACKAGE: case ClassWriter.PACKAGE:
case ClassWriter.MTYPE: case ClassWriter.MTYPE:
case ClassWriter.TYPE_NORMAL: case ClassWriter.TYPE_NORMAL:
return i.strVal1.equals(strVal1); return i.strVal1.equals(strVal1);
case ClassWriter.TYPE_MERGED: case ClassWriter.TYPE_MERGED:
case ClassWriter.LONG: case ClassWriter.LONG:
case ClassWriter.DOUBLE: case ClassWriter.DOUBLE:
return i.longVal == longVal; return i.longVal == longVal;
case ClassWriter.INT: case ClassWriter.INT:
case ClassWriter.FLOAT: case ClassWriter.FLOAT:
return i.intVal == intVal; return i.intVal == intVal;
case ClassWriter.TYPE_UNINIT: case ClassWriter.TYPE_UNINIT:
return i.intVal == intVal && i.strVal1.equals(strVal1); return i.intVal == intVal && i.strVal1.equals(strVal1);
case ClassWriter.NAME_TYPE: case ClassWriter.NAME_TYPE:
return i.strVal1.equals(strVal1) && i.strVal2.equals(strVal2); return i.strVal1.equals(strVal1) && i.strVal2.equals(strVal2);
case ClassWriter.INDY: { case ClassWriter.INDY: {
return i.longVal == longVal && i.strVal1.equals(strVal1) return i.longVal == longVal && i.strVal1.equals(strVal1) && i.strVal2.equals(strVal2);
&& i.strVal2.equals(strVal2); }
} // case ClassWriter.FIELD:
// case ClassWriter.FIELD: // case ClassWriter.METH:
// case ClassWriter.METH: // case ClassWriter.IMETH:
// case ClassWriter.IMETH: // case ClassWriter.HANDLE_BASE + 1..9
// case ClassWriter.HANDLE_BASE + 1..9 default:
default: return i.strVal1.equals(strVal1) && i.strVal2.equals(strVal2) && i.strVal3.equals(strVal3);
return i.strVal1.equals(strVal1) && i.strVal2.equals(strVal2)
&& i.strVal3.equals(strVal3);
} }
} }
} }

View File

@@ -59,88 +59,61 @@
package org.redkale.asm; package org.redkale.asm;
/** /**
* A label represents a position in the bytecode of a method. Labels are used * A label represents a position in the bytecode of a method. Labels are used for jump, goto, and switch instructions,
* for jump, goto, and switch instructions, and for try catch blocks. A label * and for try catch blocks. A label designates the <i>instruction</i> that is just after. Note however that there can
* designates the <i>instruction</i> that is just after. Note however that there * be other elements between a label and the instruction it designates (such as other labels, stack map frames, line
* can be other elements between a label and the instruction it designates (such * numbers, etc.).
* as other labels, stack map frames, line numbers, etc.).
* *
* @author Eric Bruneton * @author Eric Bruneton
*/ */
public class Label { public class Label {
/** /**
* Indicates if this label is only used for debug attributes. Such a label * Indicates if this label is only used for debug attributes. Such a label is not the start of a basic block, the
* is not the start of a basic block, the target of a jump instruction, or * target of a jump instruction, or an exception handler. It can be safely ignored in control flow graph analysis
* an exception handler. It can be safely ignored in control flow graph * algorithms (for optimization purposes).
* analysis algorithms (for optimization purposes).
*/ */
static final int DEBUG = 1; static final int DEBUG = 1;
/** /** Indicates if the position of this label is known. */
* Indicates if the position of this label is known.
*/
static final int RESOLVED = 2; static final int RESOLVED = 2;
/** /** Indicates if this label has been updated, after instruction resizing. */
* Indicates if this label has been updated, after instruction resizing.
*/
static final int RESIZED = 4; static final int RESIZED = 4;
/** /**
* Indicates if this basic block has been pushed in the basic block stack. * Indicates if this basic block has been pushed in the basic block stack. See {@link MethodWriter#visitMaxs
* See {@link MethodWriter#visitMaxs visitMaxs}. * visitMaxs}.
*/ */
static final int PUSHED = 8; static final int PUSHED = 8;
/** /** Indicates if this label is the target of a jump instruction, or the start of an exception handler. */
* Indicates if this label is the target of a jump instruction, or the start
* of an exception handler.
*/
static final int TARGET = 16; static final int TARGET = 16;
/** /** Indicates if a stack map frame must be stored for this label. */
* Indicates if a stack map frame must be stored for this label.
*/
static final int STORE = 32; static final int STORE = 32;
/** /** Indicates if this label corresponds to a reachable basic block. */
* Indicates if this label corresponds to a reachable basic block.
*/
static final int REACHABLE = 64; static final int REACHABLE = 64;
/** /** Indicates if this basic block ends with a JSR instruction. */
* Indicates if this basic block ends with a JSR instruction.
*/
static final int JSR = 128; static final int JSR = 128;
/** /** Indicates if this basic block ends with a RET instruction. */
* Indicates if this basic block ends with a RET instruction.
*/
static final int RET = 256; static final int RET = 256;
/** /** Indicates if this basic block is the start of a subroutine. */
* Indicates if this basic block is the start of a subroutine.
*/
static final int SUBROUTINE = 512; static final int SUBROUTINE = 512;
/** /** Indicates if this subroutine basic block has been visited by a visitSubroutine(null, ...) call. */
* Indicates if this subroutine basic block has been visited by a
* visitSubroutine(null, ...) call.
*/
static final int VISITED = 1024; static final int VISITED = 1024;
/** /** Indicates if this subroutine basic block has been visited by a visitSubroutine(!null, ...) call. */
* Indicates if this subroutine basic block has been visited by a
* visitSubroutine(!null, ...) call.
*/
static final int VISITED2 = 2048; static final int VISITED2 = 2048;
/** /**
* Field used to associate user information to a label. Warning: this field * Field used to associate user information to a label. Warning: this field is used by the ASM tree package. In
* is used by the ASM tree package. In order to use it with the ASM tree * order to use it with the ASM tree package you must override the
* package you must override the
*
*/ */
public Object info; public Object info;
@@ -160,36 +133,26 @@ public class Label {
int status; int status;
/** /**
* The line number corresponding to this label, if known. If there are * The line number corresponding to this label, if known. If there are several lines, each line is stored in a
* several lines, each line is stored in a separate label, all linked via * separate label, all linked via their next field (these links are created in ClassReader and removed just before
* their next field (these links are created in ClassReader and removed just * visitLabel is called, so that this does not impact the rest of the code).
* before visitLabel is called, so that this does not impact the rest of the
* code).
*/ */
int line; int line;
/** /** The position of this label in the code, if known. */
* The position of this label in the code, if known.
*/
int position; int position;
/** /** Number of forward references to this label, times two. */
* Number of forward references to this label, times two.
*/
private int referenceCount; private int referenceCount;
/** /**
* Informations about forward references. Each forward reference is * Informations about forward references. Each forward reference is described by two consecutive integers in this
* described by two consecutive integers in this array: the first one is the * array: the first one is the position of the first byte of the bytecode instruction that contains the forward
* position of the first byte of the bytecode instruction that contains the * reference, while the second is the position of the first byte of the forward reference itself. In fact the sign
* forward reference, while the second is the position of the first byte of * of the first integer indicates if this reference uses 2 or 4 bytes, and its absolute value gives the position of
* the forward reference itself. In fact the sign of the first integer * the bytecode instruction. This array is also used as a bitset to store the subroutines to which a basic block
* indicates if this reference uses 2 or 4 bytes, and its absolute value * belongs. This information is needed in {@linked MethodWriter#visitMaxs}, after all forward references have been
* gives the position of the bytecode instruction. This array is also used * resolved. Hence the same array can be used for both purposes without problems.
* as a bitset to store the subroutines to which a basic block belongs. This
* information is needed in {@linked MethodWriter#visitMaxs}, after all
* forward references have been resolved. Hence the same array can be used
* for both purposes without problems.
*/ */
private int[] srcAndRefPositions; private int[] srcAndRefPositions;
@@ -223,57 +186,48 @@ public class Label {
*/ */
/** /**
* Start of the output stack relatively to the input stack. The exact * Start of the output stack relatively to the input stack. The exact semantics of this field depends on the
* semantics of this field depends on the algorithm that is used. * algorithm that is used.
* *
* When only the maximum stack size is computed, this field is the number of * <p>When only the maximum stack size is computed, this field is the number of elements in the input stack.
* elements in the input stack.
* *
* When the stack map frames are completely computed, this field is the * <p>When the stack map frames are completely computed, this field is the offset of the first output stack element
* offset of the first output stack element relatively to the top of the * relatively to the top of the input stack. This offset is always negative or null. A null offset means that the
* input stack. This offset is always negative or null. A null offset means * output stack must be appended to the input stack. A -n offset means that the first n output stack elements must
* that the output stack must be appended to the input stack. A -n offset * replace the top n input stack elements, and that the other elements must be appended to the input stack.
* means that the first n output stack elements must replace the top n input
* stack elements, and that the other elements must be appended to the input
* stack.
*/ */
int inputStackTop; int inputStackTop;
/** /**
* Maximum height reached by the output stack, relatively to the top of the * Maximum height reached by the output stack, relatively to the top of the input stack. This maximum is always
* input stack. This maximum is always positive or null. * positive or null.
*/ */
int outputStackMax; int outputStackMax;
/** /**
* Information about the input and output stack map frames of this basic * Information about the input and output stack map frames of this basic block. This field is only used when
* block. This field is only used when {@link ClassWriter#COMPUTE_FRAMES} * {@link ClassWriter#COMPUTE_FRAMES} option is used.
* option is used.
*/ */
Frame frame; Frame frame;
/** /**
* The successor of this label, in the order they are visited. This linked * The successor of this label, in the order they are visited. This linked list does not include labels used for
* list does not include labels used for debug info only. If * debug info only. If {@link ClassWriter#COMPUTE_FRAMES} option is used then, in addition, it does not contain
* {@link ClassWriter#COMPUTE_FRAMES} option is used then, in addition, it * successive labels that denote the same bytecode position (in this case only the first label appears in this
* does not contain successive labels that denote the same bytecode position * list).
* (in this case only the first label appears in this list).
*/ */
Label successor; Label successor;
/** /**
* The successors of this node in the control flow graph. These successors * The successors of this node in the control flow graph. These successors are stored in a linked list of
* are stored in a linked list of {@link Edge Edge} objects, linked to each * {@link Edge Edge} objects, linked to each other by their {@link Edge#next} field.
* other by their {@link Edge#next} field.
*/ */
Edge successors; Edge successors;
/** /**
* The next basic block in the basic block stack. This stack is used in the * The next basic block in the basic block stack. This stack is used in the main loop of the fix point algorithm
* main loop of the fix point algorithm used in the second step of the * used in the second step of the control flow analysis algorithms. It is also used in {@link #visitSubroutine} to
* control flow analysis algorithms. It is also used in * avoid using a recursive method, and in ClassReader to temporarily store multiple source lines for a label.
* {@link #visitSubroutine} to avoid using a recursive method, and in
* ClassReader to temporarily store multiple source lines for a label.
* *
* @see MethodWriter#visitMaxs * @see MethodWriter#visitMaxs
*/ */
@@ -283,11 +237,9 @@ public class Label {
// Constructor // Constructor
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
/** /** Constructs a new label. */
* Constructs a new label.
*/
public Label() { public Label() {
//do nothing // do nothing
} }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
@@ -295,44 +247,33 @@ public class Label {
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
/** /**
* Returns the offset corresponding to this label. This offset is computed * Returns the offset corresponding to this label. This offset is computed from the start of the method's bytecode.
* from the start of the method's bytecode. <i>This method is intended for * <i>This method is intended for {@link Attribute} sub classes, and is normally not needed by class generators or
* {@link Attribute} sub classes, and is normally not needed by class * adapters.</i>
* generators or adapters.</i>
* *
* @return the offset corresponding to this label. * @return the offset corresponding to this label.
* @throws IllegalStateException * @throws IllegalStateException if this label is not resolved yet.
* if this label is not resolved yet.
*/ */
public int getOffset() { public int getOffset() {
if ((status & RESOLVED) == 0) { if ((status & RESOLVED) == 0) {
throw new IllegalStateException( throw new IllegalStateException("Label offset position has not been resolved yet");
"Label offset position has not been resolved yet");
} }
return position; return position;
} }
/** /**
* Puts a reference to this label in the bytecode of a method. If the * Puts a reference to this label in the bytecode of a method. If the position of the label is known, the offset is
* position of the label is known, the offset is computed and written * computed and written directly. Otherwise, a null offset is written and a new forward reference is declared for
* directly. Otherwise, a null offset is written and a new forward reference * this label.
* is declared for this label.
* *
* @param owner * @param owner the code writer that calls this method.
* the code writer that calls this method. * @param out the bytecode of the method.
* @param out * @param source the position of first byte of the bytecode instruction that contains this label.
* the bytecode of the method. * @param wideOffset &#60;tt&#62;true&#60;/tt&#62; if the reference must be stored in 4 bytes, or
* @param source * &#60;tt&#62;false&#60;/tt&#62; if it must be stored with 2 bytes.
* the position of first byte of the bytecode instruction that * @throws IllegalArgumentException if this label has not been created by the given code writer.
* contains this label.
* @param wideOffset
* &#60;tt&#62;true&#60;/tt&#62; if the reference must be stored in 4 bytes, or
* &#60;tt&#62;false&#60;/tt&#62; if it must be stored with 2 bytes.
* @throws IllegalArgumentException
* if this label has not been created by the given code writer.
*/ */
void put(final MethodWriter owner, final ByteVector out, final int source, void put(final MethodWriter owner, final ByteVector out, final int source, final boolean wideOffset) {
final boolean wideOffset) {
if ((status & RESOLVED) == 0) { if ((status & RESOLVED) == 0) {
if (wideOffset) { if (wideOffset) {
addReference(-1 - source, out.length); addReference(-1 - source, out.length);
@@ -351,27 +292,21 @@ public class Label {
} }
/** /**
* Adds a forward reference to this label. This method must be called only * Adds a forward reference to this label. This method must be called only for a true forward reference, i.e. only
* for a true forward reference, i.e. only if this label is not resolved * if this label is not resolved yet. For backward references, the offset of the reference can be, and must be,
* yet. For backward references, the offset of the reference can be, and * computed and stored directly.
* must be, computed and stored directly.
* *
* @param sourcePosition * @param sourcePosition the position of the referencing instruction. This position will be used to compute the
* the position of the referencing instruction. This position * offset of this forward reference.
* will be used to compute the offset of this forward reference. * @param referencePosition the position where the offset for this forward reference must be stored.
* @param referencePosition
* the position where the offset for this forward reference must
* be stored.
*/ */
private void addReference(final int sourcePosition, private void addReference(final int sourcePosition, final int referencePosition) {
final int referencePosition) {
if (srcAndRefPositions == null) { if (srcAndRefPositions == null) {
srcAndRefPositions = new int[6]; srcAndRefPositions = new int[6];
} }
if (referenceCount >= srcAndRefPositions.length) { if (referenceCount >= srcAndRefPositions.length) {
int[] a = new int[srcAndRefPositions.length + 6]; int[] a = new int[srcAndRefPositions.length + 6];
System.arraycopy(srcAndRefPositions, 0, a, 0, System.arraycopy(srcAndRefPositions, 0, a, 0, srcAndRefPositions.length);
srcAndRefPositions.length);
srcAndRefPositions = a; srcAndRefPositions = a;
} }
srcAndRefPositions[referenceCount++] = sourcePosition; srcAndRefPositions[referenceCount++] = sourcePosition;
@@ -379,29 +314,21 @@ public class Label {
} }
/** /**
* Resolves all forward references to this label. This method must be called * Resolves all forward references to this label. This method must be called when this label is added to the
* when this label is added to the bytecode of the method, i.e. when its * bytecode of the method, i.e. when its position becomes known. This method fills in the blanks that where left in
* position becomes known. This method fills in the blanks that where left * the bytecode by each forward reference previously added to this label.
* in the bytecode by each forward reference previously added to this label.
* *
* @param owner * @param owner the code writer that calls this method.
* the code writer that calls this method. * @param position the position of this label in the bytecode.
* @param position * @param data the bytecode of the method.
* the position of this label in the bytecode. * @return &#60;tt&#62;true&#60;/tt&#62; if a blank that was left for this label was too small to store the offset.
* @param data * In such a case the corresponding jump instruction is replaced with a pseudo instruction (using unused
* the bytecode of the method. * opcodes) using an unsigned two bytes offset. These pseudo instructions will be replaced with standard
* @return &#60;tt&#62;true&#60;/tt&#62; if a blank that was left for this label was too * bytecode instructions with wider offsets (4 bytes instead of 2), in ClassReader.
* small to store the offset. In such a case the corresponding jump * @throws IllegalArgumentException if this label has already been resolved, or if it has not been created by the
* instruction is replaced with a pseudo instruction (using unused * given code writer.
* opcodes) using an unsigned two bytes offset. These pseudo
* instructions will be replaced with standard bytecode instructions
* with wider offsets (4 bytes instead of 2), in ClassReader.
* @throws IllegalArgumentException
* if this label has already been resolved, or if it has not
* been created by the given code writer.
*/ */
boolean resolve(final MethodWriter owner, final int position, boolean resolve(final MethodWriter owner, final int position, final byte[] data) {
final byte[] data) {
boolean needUpdate = false; boolean needUpdate = false;
this.status |= RESOLVED; this.status |= RESOLVED;
this.position = position; this.position = position;
@@ -446,10 +373,9 @@ public class Label {
} }
/** /**
* Returns the first label of the series to which this label belongs. For an * Returns the first label of the series to which this label belongs. For an isolated label or for the first label
* isolated label or for the first label in a series of successive labels, * in a series of successive labels, this method returns the label itself. For other labels it returns the first
* this method returns the label itself. For other labels it returns the * label of the series.
* first label of the series.
* *
* @return the first label of the series to which this label belongs. * @return the first label of the series to which this label belongs.
*/ */
@@ -464,8 +390,7 @@ public class Label {
/** /**
* Returns true is this basic block belongs to the given subroutine. * Returns true is this basic block belongs to the given subroutine.
* *
* @param id * @param id a subroutine id.
* a subroutine id.
* @return true is this basic block belongs to the given subroutine. * @return true is this basic block belongs to the given subroutine.
*/ */
boolean inSubroutine(final long id) { boolean inSubroutine(final long id) {
@@ -476,13 +401,10 @@ public class Label {
} }
/** /**
* Returns true if this basic block and the given one belong to a common * Returns true if this basic block and the given one belong to a common subroutine.
* subroutine.
* *
* @param block * @param block another basic block.
* another basic block. * @return true if this basic block and the given one belong to a common subroutine.
* @return true if this basic block and the given one belong to a common
* subroutine.
*/ */
boolean inSameSubroutine(final Label block) { boolean inSameSubroutine(final Label block) {
if ((status & VISITED) == 0 || (block.status & VISITED) == 0) { if ((status & VISITED) == 0 || (block.status & VISITED) == 0) {
@@ -499,10 +421,8 @@ public class Label {
/** /**
* Marks this basic block as belonging to the given subroutine. * Marks this basic block as belonging to the given subroutine.
* *
* @param id * @param id a subroutine id.
* a subroutine id. * @param nbSubroutines the total number of subroutines in the method.
* @param nbSubroutines
* the total number of subroutines in the method.
*/ */
void addToSubroutine(final long id, final int nbSubroutines) { void addToSubroutine(final long id, final int nbSubroutines) {
if ((status & VISITED) == 0) { if ((status & VISITED) == 0) {
@@ -513,19 +433,14 @@ public class Label {
} }
/** /**
* Finds the basic blocks that belong to a given subroutine, and marks these * Finds the basic blocks that belong to a given subroutine, and marks these blocks as belonging to this subroutine.
* blocks as belonging to this subroutine. This method follows the control * This method follows the control flow graph to find all the blocks that are reachable from the current block
* flow graph to find all the blocks that are reachable from the current * WITHOUT following any JSR target.
* block WITHOUT following any JSR target.
* *
* @param JSR * @param JSR a JSR block that jumps to this subroutine. If this JSR is not null it is added to the successor of the
* a JSR block that jumps to this subroutine. If this JSR is not * RET blocks found in the subroutine.
* null it is added to the successor of the RET blocks found in * @param id the id of this subroutine.
* the subroutine. * @param nbSubroutines the total number of subroutines in the method.
* @param id
* the id of this subroutine.
* @param nbSubroutines
* the total number of subroutines in the method.
*/ */
void visitSubroutine(final Label JSR, final long id, final int nbSubroutines) { void visitSubroutine(final Label JSR, final long id, final int nbSubroutines) {
// user managed stack of labels, to avoid using a recursive method // user managed stack of labels, to avoid using a recursive method

View File

@@ -9,8 +9,8 @@ import java.util.*;
/** /**
* MethodVisitor 的调试类 * MethodVisitor 的调试类
* <p> *
* 详情见: https://redkale.org * <p>详情见: https://redkale.org
* *
* @author zhangjx * @author zhangjx
*/ */
@@ -36,7 +36,7 @@ public class MethodDebugVisitor extends MethodVisitor {
private final Map<Label, Integer> labels = new LinkedHashMap<>(); private final Map<Label, Integer> labels = new LinkedHashMap<>();
private static final String[] opcodes = new String[200]; //0 -18 private static final String[] opcodes = new String[200]; // 0 -18
static { static {
try { try {
@@ -66,14 +66,11 @@ public class MethodDebugVisitor extends MethodVisitor {
opcodes[(int) (Integer) field.get(null)] = name; opcodes[(int) (Integer) field.get(null)] = name;
} }
} catch (Exception ex) { } catch (Exception ex) {
throw new RuntimeException(ex); //不可能会发生 throw new RuntimeException(ex); // 不可能会发生
} }
} }
/** /** @param visitor MethodVisitor */
*
* @param visitor MethodVisitor
*/
public MethodDebugVisitor(MethodVisitor visitor) { public MethodDebugVisitor(MethodVisitor visitor) {
super(Opcodes.ASM6, visitor); super(Opcodes.ASM6, visitor);
this.visitor = visitor; this.visitor = visitor;
@@ -105,7 +102,8 @@ public class MethodDebugVisitor extends MethodVisitor {
public AnnotationVisitor visitTypeAnnotation(int typeRef, TypePath typePath, String desc, boolean visible) { public AnnotationVisitor visitTypeAnnotation(int typeRef, TypePath typePath, String desc, boolean visible) {
AnnotationVisitor av = visitor.visitTypeAnnotation(typeRef, typePath, desc, visible); AnnotationVisitor av = visitor.visitTypeAnnotation(typeRef, typePath, desc, visible);
if (debug) { if (debug) {
System.out.println("mv.visitTypeAnnotation(" + typeRef + ", " + typePath + ", \"" + desc + "\", " + visible + ");"); System.out.println(
"mv.visitTypeAnnotation(" + typeRef + ", " + typePath + ", \"" + desc + "\", " + visible + ");");
} }
return av; return av;
} }
@@ -139,11 +137,12 @@ public class MethodDebugVisitor extends MethodVisitor {
} else if (type == 4) { } else if (type == 4) {
typestr = "Opcodes.F_SAME1"; typestr = "Opcodes.F_SAME1";
} }
System.out.println("mv.visitFrame(" + typestr + ", " + nLocal + ", " + Arrays.toString(local) + ", " + nStack + ", " + Arrays.toString(stack) + ");"); System.out.println("mv.visitFrame(" + typestr + ", " + nLocal + ", " + Arrays.toString(local) + ", "
+ nStack + ", " + Arrays.toString(stack) + ");");
} }
} }
public void visitJumpInsn(int opcode, Label var) { //调用此方法的 ClassWriter 必须由 COMPUTE_FRAMES 构建 public void visitJumpInsn(int opcode, Label var) { // 调用此方法的 ClassWriter 必须由 COMPUTE_FRAMES 构建
visitor.visitJumpInsn(opcode, var); visitor.visitJumpInsn(opcode, var);
if (debug) { if (debug) {
Integer index = labels.get(var); Integer index = labels.get(var);
@@ -179,7 +178,8 @@ public class MethodDebugVisitor extends MethodVisitor {
public void visitMethodInsn(int opcode, String owner, String name, String desc, boolean itf) { public void visitMethodInsn(int opcode, String owner, String name, String desc, boolean itf) {
visitor.visitMethodInsn(opcode, owner, name, desc, itf); visitor.visitMethodInsn(opcode, owner, name, desc, itf);
if (debug) { if (debug) {
System.out.println("mv.visitMethodInsn(" + opcodes[opcode] + ", \"" + owner + "\", \"" + name + "\", \"" + desc + "\", " + itf + ");"); System.out.println("mv.visitMethodInsn(" + opcodes[opcode] + ", \"" + owner + "\", \"" + name + "\", \""
+ desc + "\", " + itf + ");");
} }
} }
@@ -193,14 +193,16 @@ public class MethodDebugVisitor extends MethodVisitor {
public void visitLocalVariable(String name, String desc, String signature, Label start, Label end, int index) { public void visitLocalVariable(String name, String desc, String signature, Label start, Label end, int index) {
visitor.visitLocalVariable(name, desc, signature, start, end, index); visitor.visitLocalVariable(name, desc, signature, start, end, index);
if (debug) { if (debug) {
System.out.println("mv.visitLocalVariable(\"" + name + "\", \"" + desc + "\", \"" + signature + "\", null, null, " + index + ");"); System.out.println("mv.visitLocalVariable(\"" + name + "\", \"" + desc + "\", \"" + signature
+ "\", null, null, " + index + ");");
} }
} }
public void visitFieldInsn(int opcode, String owner, String name, String desc) { public void visitFieldInsn(int opcode, String owner, String name, String desc) {
visitor.visitFieldInsn(opcode, owner, name, desc); visitor.visitFieldInsn(opcode, owner, name, desc);
if (debug) { if (debug) {
System.out.println("mv.visitFieldInsn(" + opcodes[opcode] + ", \"" + owner + "\", \"" + name + "\", \"" + desc + "\");"); System.out.println("mv.visitFieldInsn(" + opcodes[opcode] + ", \"" + owner + "\", \"" + name + "\", \""
+ desc + "\");");
} }
} }
@@ -258,5 +260,4 @@ public class MethodDebugVisitor extends MethodVisitor {
System.out.println("mv.visitEnd();\r\n\r\n\r\n"); System.out.println("mv.visitEnd();\r\n\r\n\r\n");
} }
} }
} }

View File

@@ -59,49 +59,42 @@
package org.redkale.asm; package org.redkale.asm;
/** /**
* A visitor to visit a Java method. The methods of this class must be called in * A visitor to visit a Java method. The methods of this class must be called in the following order: (
* the following order: ( &#60;tt&#62;visitParameter&#60;/tt&#62; )* [ * &#60;tt&#62;visitParameter&#60;/tt&#62; )* [ &#60;tt&#62;visitAnnotationDefault&#60;/tt&#62; ] (
* &#60;tt&#62;visitAnnotationDefault&#60;/tt&#62; ] ( &#60;tt&#62;visitAnnotation&#60;/tt&#62; | * &#60;tt&#62;visitAnnotation&#60;/tt&#62; | &#60;tt&#62;visitParameterAnnotation&#60;/tt&#62;
* &#60;tt&#62;visitParameterAnnotation&#60;/tt&#62; &#60;tt&#62;visitTypeAnnotation&#60;/tt&#62; | * &#60;tt&#62;visitTypeAnnotation&#60;/tt&#62; | &#60;tt&#62;visitAttribute&#60;/tt&#62; )* [
* &#60;tt&#62;visitAttribute&#60;/tt&#62; )* [ &#60;tt&#62;visitCode&#60;/tt&#62; ( &#60;tt&#62;visitFrame&#60;/tt&#62; | * &#60;tt&#62;visitCode&#60;/tt&#62; ( &#60;tt&#62;visitFrame&#60;/tt&#62; | &#60;tt&#62;visit<i>X</i>Insn&#60;/tt&#62;
* &#60;tt&#62;visit<i>X</i>Insn&#60;/tt&#62; | &#60;tt&#62;visitLabel&#60;/tt&#62; | * | &#60;tt&#62;visitLabel&#60;/tt&#62; | &#60;tt&#62;visitInsnAnnotation&#60;/tt&#62; |
* &#60;tt&#62;visitInsnAnnotation&#60;/tt&#62; | &#60;tt&#62;visitTryCatchBlock&#60;/tt&#62; | * &#60;tt&#62;visitTryCatchBlock&#60;/tt&#62; | &#60;tt&#62;visitTryCatchAnnotation&#60;/tt&#62; |
* &#60;tt&#62;visitTryCatchAnnotation&#60;/tt&#62; | &#60;tt&#62;visitLocalVariable&#60;/tt&#62; | * &#60;tt&#62;visitLocalVariable&#60;/tt&#62; | &#60;tt&#62;visitLocalVariableAnnotation&#60;/tt&#62; |
* &#60;tt&#62;visitLocalVariableAnnotation&#60;/tt&#62; | &#60;tt&#62;visitLineNumber&#60;/tt&#62; )* * &#60;tt&#62;visitLineNumber&#60;/tt&#62; )* &#60;tt&#62;visitMaxs&#60;/tt&#62; ] &#60;tt&#62;visitEnd&#60;/tt&#62;.
* &#60;tt&#62;visitMaxs&#60;/tt&#62; ] &#60;tt&#62;visitEnd&#60;/tt&#62;. In addition, the * In addition, the &#60;tt&#62;visit<i>X</i>Insn&#60;/tt&#62; and &#60;tt&#62;visitLabel&#60;/tt&#62; methods must be
* &#60;tt&#62;visit<i>X</i>Insn&#60;/tt&#62; and &#60;tt&#62;visitLabel&#60;/tt&#62; methods must be called in * called in the sequential order of the bytecode instructions of the visited code,
* the sequential order of the bytecode instructions of the visited code, * &#60;tt&#62;visitInsnAnnotation&#60;/tt&#62; must be called <i>after</i> the annotated instruction,
* &#60;tt&#62;visitInsnAnnotation&#60;/tt&#62; must be called <i>after</i> the annotated * &#60;tt&#62;visitTryCatchBlock&#60;/tt&#62; must be called <i>before</i> the labels passed as arguments have been
* instruction, &#60;tt&#62;visitTryCatchBlock&#60;/tt&#62; must be called <i>before</i> the * visited, &#60;tt&#62;visitTryCatchBlockAnnotation&#60;/tt&#62; must be called <i>after</i> the corresponding try
* labels passed as arguments have been visited, * catch block has been visited, and the &#60;tt&#62;visitLocalVariable&#60;/tt&#62;,
* &#60;tt&#62;visitTryCatchBlockAnnotation&#60;/tt&#62; must be called <i>after</i> the * &#60;tt&#62;visitLocalVariableAnnotation&#60;/tt&#62; and &#60;tt&#62;visitLineNumber&#60;/tt&#62; methods must be
* corresponding try catch block has been visited, and the * called <i>after</i> the labels passed as arguments have been visited.
* &#60;tt&#62;visitLocalVariable&#60;/tt&#62;, &#60;tt&#62;visitLocalVariableAnnotation&#60;/tt&#62; and
* &#60;tt&#62;visitLineNumber&#60;/tt&#62; methods must be called <i>after</i> the labels
* passed as arguments have been visited.
* *
* @author Eric Bruneton * @author Eric Bruneton
*/ */
public abstract class MethodVisitor { public abstract class MethodVisitor {
/** /**
* The ASM API version implemented by this visitor. The value of this field * The ASM API version implemented by this visitor. The value of this field must be one of {@link Opcodes#ASM4},
* must be one of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}. * {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
*/ */
protected final int api; protected final int api;
/** /** The method visitor to which this visitor must delegate method calls. May be null. */
* The method visitor to which this visitor must delegate method calls. May
* be null.
*/
protected MethodVisitor mv; protected MethodVisitor mv;
/** /**
* Constructs a new {@link MethodVisitor}. * Constructs a new {@link MethodVisitor}.
* *
* @param api * @param api the ASM API version implemented by this visitor. Must be one of {@link Opcodes#ASM4},
* the ASM API version implemented by this visitor. Must be one * {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
* of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
*/ */
public MethodVisitor(final int api) { public MethodVisitor(final int api) {
this(api, null); this(api, null);
@@ -110,12 +103,9 @@ public abstract class MethodVisitor {
/** /**
* Constructs a new {@link MethodVisitor}. * Constructs a new {@link MethodVisitor}.
* *
* @param api * @param api the ASM API version implemented by this visitor. Must be one of {@link Opcodes#ASM4},
* the ASM API version implemented by this visitor. Must be one * {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
* of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}. * @param mv the method visitor to which this visitor must delegate method calls. May be null.
* @param mv
* the method visitor to which this visitor must delegate method
* calls. May be null.
*/ */
public MethodVisitor(final int api, final MethodVisitor mv) { public MethodVisitor(final int api, final MethodVisitor mv) {
this.api = api; this.api = api;
@@ -129,12 +119,10 @@ public abstract class MethodVisitor {
/** /**
* Visits a parameter of this method. * Visits a parameter of this method.
* *
* @param name * @param name parameter name or null if none is provided.
* parameter name or null if none is provided. * @param access the parameter's access flags, only &#60;tt&#62;ACC_FINAL&#60;/tt&#62;,
* @param access * &#60;tt&#62;ACC_SYNTHETIC&#60;/tt&#62; or/and &#60;tt&#62;ACC_MANDATED&#60;/tt&#62; are allowed (see
* the parameter's access flags, only &#60;tt&#62;ACC_FINAL&#60;/tt&#62;, * {@link Opcodes}).
* &#60;tt&#62;ACC_SYNTHETIC&#60;/tt&#62; or/and &#60;tt&#62;ACC_MANDATED&#60;/tt&#62; are
* allowed (see {@link Opcodes}).
*/ */
public void visitParameter(String name, int access) { public void visitParameter(String name, int access) {
if (mv != null) { if (mv != null) {
@@ -145,12 +133,10 @@ public abstract class MethodVisitor {
/** /**
* Visits the default value of this annotation interface method. * Visits the default value of this annotation interface method.
* *
* @return a visitor to the visit the actual default value of this * @return a visitor to the visit the actual default value of this annotation interface method, or
* annotation interface method, or &#60;tt&#62;null&#60;/tt&#62; if this visitor is * &#60;tt&#62;null&#60;/tt&#62; if this visitor is not interested in visiting this default value. The 'name'
* not interested in visiting this default value. The 'name' * parameters passed to the methods of this annotation visitor are ignored. Moreover, exacly one visit method
* parameters passed to the methods of this annotation visitor are * must be called on this annotation visitor, followed by visitEnd.
* ignored. Moreover, exacly one visit method must be called on this
* annotation visitor, followed by visitEnd.
*/ */
public AnnotationVisitor visitAnnotationDefault() { public AnnotationVisitor visitAnnotationDefault() {
if (mv != null) { if (mv != null) {
@@ -162,12 +148,10 @@ public abstract class MethodVisitor {
/** /**
* Visits an annotation of this method. * Visits an annotation of this method.
* *
* @param desc * @param desc the class descriptor of the annotation class.
* the class descriptor of the annotation class. * @param visible &#60;tt&#62;true&#60;/tt&#62; if the annotation is visible at runtime.
* @param visible * @return a visitor to visit the annotation values, or &#60;tt&#62;null&#60;/tt&#62; if this visitor is not
* &#60;tt&#62;true&#60;/tt&#62; if the annotation is visible at runtime. * interested in visiting this annotation.
* @return a visitor to visit the annotation values, or &#60;tt&#62;null&#60;/tt&#62; if
* this visitor is not interested in visiting this annotation.
*/ */
public AnnotationVisitor visitAnnotation(String desc, boolean visible) { public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
if (mv != null) { if (mv != null) {
@@ -179,30 +163,20 @@ public abstract class MethodVisitor {
/** /**
* Visits an annotation on a type in the method signature. * Visits an annotation on a type in the method signature.
* *
* @param typeRef * @param typeRef a reference to the annotated type. The sort of this type reference must be
* a reference to the annotated type. The sort of this type * {@link TypeReference#METHOD_TYPE_PARAMETER METHOD_TYPE_PARAMETER},
* reference must be {@link TypeReference#METHOD_TYPE_PARAMETER * {@link TypeReference#METHOD_TYPE_PARAMETER_BOUND METHOD_TYPE_PARAMETER_BOUND},
* METHOD_TYPE_PARAMETER}, * {@link TypeReference#METHOD_RETURN METHOD_RETURN}, {@link TypeReference#METHOD_RECEIVER METHOD_RECEIVER},
* {@link TypeReference#METHOD_TYPE_PARAMETER_BOUND * {@link TypeReference#METHOD_FORMAL_PARAMETER METHOD_FORMAL_PARAMETER} or {@link TypeReference#THROWS THROWS}.
* METHOD_TYPE_PARAMETER_BOUND}, * See {@link TypeReference}.
* {@link TypeReference#METHOD_RETURN METHOD_RETURN}, * @param typePath the path to the annotated type argument, wildcard bound, array element type, or static inner type
* {@link TypeReference#METHOD_RECEIVER METHOD_RECEIVER}, * within 'typeRef'. May be &#60;tt&#62;null&#60;/tt&#62; if the annotation targets 'typeRef' as a whole.
* {@link TypeReference#METHOD_FORMAL_PARAMETER * @param desc the class descriptor of the annotation class.
* METHOD_FORMAL_PARAMETER} or {@link TypeReference#THROWS * @param visible &#60;tt&#62;true&#60;/tt&#62; if the annotation is visible at runtime.
* THROWS}. See {@link TypeReference}. * @return a visitor to visit the annotation values, or &#60;tt&#62;null&#60;/tt&#62; if this visitor is not
* @param typePath * interested in visiting this annotation.
* the path to the annotated type argument, wildcard bound, array
* element type, or static inner type within 'typeRef'. May be
* &#60;tt&#62;null&#60;/tt&#62; if the annotation targets 'typeRef' as a whole.
* @param desc
* the class descriptor of the annotation class.
* @param visible
* &#60;tt&#62;true&#60;/tt&#62; if the annotation is visible at runtime.
* @return a visitor to visit the annotation values, or &#60;tt&#62;null&#60;/tt&#62; if
* this visitor is not interested in visiting this annotation.
*/ */
public AnnotationVisitor visitTypeAnnotation(int typeRef, public AnnotationVisitor visitTypeAnnotation(int typeRef, TypePath typePath, String desc, boolean visible) {
TypePath typePath, String desc, boolean visible) {
if (mv != null) { if (mv != null) {
return mv.visitTypeAnnotation(typeRef, typePath, desc, visible); return mv.visitTypeAnnotation(typeRef, typePath, desc, visible);
} }
@@ -212,17 +186,13 @@ public abstract class MethodVisitor {
/** /**
* Visits an annotation of a parameter this method. * Visits an annotation of a parameter this method.
* *
* @param parameter * @param parameter the parameter index.
* the parameter index. * @param desc the class descriptor of the annotation class.
* @param desc * @param visible &#60;tt&#62;true&#60;/tt&#62; if the annotation is visible at runtime.
* the class descriptor of the annotation class. * @return a visitor to visit the annotation values, or &#60;tt&#62;null&#60;/tt&#62; if this visitor is not
* @param visible * interested in visiting this annotation.
* &#60;tt&#62;true&#60;/tt&#62; if the annotation is visible at runtime.
* @return a visitor to visit the annotation values, or &#60;tt&#62;null&#60;/tt&#62; if
* this visitor is not interested in visiting this annotation.
*/ */
public AnnotationVisitor visitParameterAnnotation(int parameter, public AnnotationVisitor visitParameterAnnotation(int parameter, String desc, boolean visible) {
String desc, boolean visible) {
if (mv != null) { if (mv != null) {
return mv.visitParameterAnnotation(parameter, desc, visible); return mv.visitParameterAnnotation(parameter, desc, visible);
} }
@@ -232,8 +202,7 @@ public abstract class MethodVisitor {
/** /**
* Visits a non standard attribute of this method. * Visits a non standard attribute of this method.
* *
* @param attr * @param attr an attribute.
* an attribute.
*/ */
public void visitAttribute(Attribute attr) { public void visitAttribute(Attribute attr) {
if (mv != null) { if (mv != null) {
@@ -241,9 +210,7 @@ public abstract class MethodVisitor {
} }
} }
/** /** Starts the visit of the method's code, if any (i.e. non abstract method). */
* Starts the visit of the method's code, if any (i.e. non abstract method).
*/
public void visitCode() { public void visitCode() {
if (mv != null) { if (mv != null) {
mv.visitCode(); mv.visitCode();
@@ -251,82 +218,57 @@ public abstract class MethodVisitor {
} }
/** /**
* Visits the current state of the local variables and operand stack * Visits the current state of the local variables and operand stack elements. This method must(*) be called <i>just
* elements. This method must(*) be called <i>just before</i> any * before</i> any instruction <b>i</b> that follows an unconditional branch instruction such as GOTO or THROW, that
* instruction <b>i</b> that follows an unconditional branch instruction * is the target of a jump instruction, or that starts an exception handler block. The visited types must describe
* such as GOTO or THROW, that is the target of a jump instruction, or that * the values of the local variables and of the operand stack elements <i>just before</i> <b>i</b> is executed.<br>
* starts an exception handler block. The visited types must describe the
* values of the local variables and of the operand stack elements <i>just
* before</i> <b>i</b> is executed.<br>
* <br> * <br>
* (*) this is mandatory only for classes whose version is greater than or * (*) this is mandatory only for classes whose version is greater than or equal to {@link Opcodes#V1_6 V1_6}. <br>
* equal to {@link Opcodes#V1_6 V1_6}. <br>
* <br> * <br>
* The frames of a method must be given either in expanded form, or in * The frames of a method must be given either in expanded form, or in compressed form (all frames must use the same
* compressed form (all frames must use the same format, i.e. you must not * format, i.e. you must not mix expanded and compressed frames within a single method):
* mix expanded and compressed frames within a single method):
* <ul>
* <li>In expanded form, all frames must have the F_NEW type.</li>
* <li>In compressed form, frames are basically "deltas" from the state of
* the previous frame:
* <ul>
* <li>{@link Opcodes#F_SAME} representing frame with exactly the same
* locals as the previous frame and with the empty stack.</li>
* <li>{@link Opcodes#F_SAME1} representing frame with exactly the same
* locals as the previous frame and with single value on the stack (
* <code>nStack</code> is 1 and <code>stack[0]</code> contains value for the
* type of the stack item).</li>
* <li>{@link Opcodes#F_APPEND} representing frame with current locals are
* the same as the locals in the previous frame, except that additional
* locals are defined (<code>nLocal</code> is 1, 2 or 3 and
* <code>local</code> elements contains values representing added types).</li>
* <li>{@link Opcodes#F_CHOP} representing frame with current locals are the
* same as the locals in the previous frame, except that the last 1-3 locals
* are absent and with the empty stack (<code>nLocals</code> is 1, 2 or 3).</li>
* <li>{@link Opcodes#F_FULL} representing complete frame data.</li>
* </ul>
* </li>
* </ul>
* <br>
* In both cases the first frame, corresponding to the method's parameters
* and access flags, is implicit and must not be visited. Also, it is
* illegal to visit two or more frames for the same code location (i.e., at
* least one instruction must be visited between two calls to visitFrame).
* *
* @param type * <ul>
* the type of this stack map frame. Must be * <li>In expanded form, all frames must have the F_NEW type.
* {@link Opcodes#F_NEW} for expanded frames, or * <li>In compressed form, frames are basically "deltas" from the state of the previous frame:
* {@link Opcodes#F_FULL}, {@link Opcodes#F_APPEND}, * <ul>
* {@link Opcodes#F_CHOP}, {@link Opcodes#F_SAME} or * <li>{@link Opcodes#F_SAME} representing frame with exactly the same locals as the previous frame and with
* {@link Opcodes#F_APPEND}, {@link Opcodes#F_SAME1} for * the empty stack.
* compressed frames. * <li>{@link Opcodes#F_SAME1} representing frame with exactly the same locals as the previous frame and
* @param nLocal * with single value on the stack ( <code>nStack</code> is 1 and <code>stack[0]</code> contains value
* the number of local variables in the visited frame. * for the type of the stack item).
* @param local * <li>{@link Opcodes#F_APPEND} representing frame with current locals are the same as the locals in the
* the local variable types in this frame. This array must not be * previous frame, except that additional locals are defined (<code>nLocal</code> is 1, 2 or 3 and
* modified. Primitive types are represented by * <code>local</code> elements contains values representing added types).
* {@link Opcodes#TOP}, {@link Opcodes#INTEGER}, * <li>{@link Opcodes#F_CHOP} representing frame with current locals are the same as the locals in the
* {@link Opcodes#FLOAT}, {@link Opcodes#LONG}, * previous frame, except that the last 1-3 locals are absent and with the empty stack (<code>nLocals
* {@link Opcodes#DOUBLE},{@link Opcodes#NULL} or * </code> is 1, 2 or 3).
* {@link Opcodes#UNINITIALIZED_THIS} (long and double are * <li>{@link Opcodes#F_FULL} representing complete frame data.
* represented by a single element). Reference types are * </ul>
* represented by String objects (representing internal names), * </ul>
* and uninitialized types by Label objects (this label *
* designates the NEW instruction that created this uninitialized * <br>
* value). * In both cases the first frame, corresponding to the method's parameters and access flags, is implicit and must
* @param nStack * not be visited. Also, it is illegal to visit two or more frames for the same code location (i.e., at least one
* the number of operand stack elements in the visited frame. * instruction must be visited between two calls to visitFrame).
* @param stack *
* the operand stack types in this frame. This array must not be * @param type the type of this stack map frame. Must be {@link Opcodes#F_NEW} for expanded frames, or
* modified. Its content has the same format as the "local" * {@link Opcodes#F_FULL}, {@link Opcodes#F_APPEND}, {@link Opcodes#F_CHOP}, {@link Opcodes#F_SAME} or
* array. * {@link Opcodes#F_APPEND}, {@link Opcodes#F_SAME1} for compressed frames.
* @throws IllegalStateException * @param nLocal the number of local variables in the visited frame.
* if a frame is visited just after another one, without any * @param local the local variable types in this frame. This array must not be modified. Primitive types are
* instruction between the two (unless this frame is a * represented by {@link Opcodes#TOP}, {@link Opcodes#INTEGER}, {@link Opcodes#FLOAT}, {@link Opcodes#LONG},
* Opcodes#F_SAME frame, in which case it is silently ignored). * {@link Opcodes#DOUBLE},{@link Opcodes#NULL} or {@link Opcodes#UNINITIALIZED_THIS} (long and double are
* represented by a single element). Reference types are represented by String objects (representing internal
* names), and uninitialized types by Label objects (this label designates the NEW instruction that created this
* uninitialized value).
* @param nStack the number of operand stack elements in the visited frame.
* @param stack the operand stack types in this frame. This array must not be modified. Its content has the same
* format as the "local" array.
* @throws IllegalStateException if a frame is visited just after another one, without any instruction between the
* two (unless this frame is a Opcodes#F_SAME frame, in which case it is silently ignored).
*/ */
public void visitFrame(int type, int nLocal, Object[] local, int nStack, public void visitFrame(int type, int nLocal, Object[] local, int nStack, Object[] stack) {
Object[] stack) {
if (mv != null) { if (mv != null) {
mv.visitFrame(type, nLocal, local, nStack, stack); mv.visitFrame(type, nLocal, local, nStack, stack);
} }
@@ -339,22 +281,15 @@ public abstract class MethodVisitor {
/** /**
* Visits a zero operand instruction. * Visits a zero operand instruction.
* *
* @param opcode * @param opcode the opcode of the instruction to be visited. This opcode is either NOP, ACONST_NULL, ICONST_M1,
* the opcode of the instruction to be visited. This opcode is * ICONST_0, ICONST_1, ICONST_2, ICONST_3, ICONST_4, ICONST_5, LCONST_0, LCONST_1, FCONST_0, FCONST_1, FCONST_2,
* either NOP, ACONST_NULL, ICONST_M1, ICONST_0, ICONST_1, * DCONST_0, DCONST_1, IALOAD, LALOAD, FALOAD, DALOAD, AALOAD, BALOAD, CALOAD, SALOAD, IASTORE, LASTORE,
* ICONST_2, ICONST_3, ICONST_4, ICONST_5, LCONST_0, LCONST_1, * FASTORE, DASTORE, AASTORE, BASTORE, CASTORE, SASTORE, POP, POP2, DUP, DUP_X1, DUP_X2, DUP2, DUP2_X1, DUP2_X2,
* FCONST_0, FCONST_1, FCONST_2, DCONST_0, DCONST_1, IALOAD, * SWAP, IADD, LADD, FADD, DADD, ISUB, LSUB, FSUB, DSUB, IMUL, LMUL, FMUL, DMUL, IDIV, LDIV, FDIV, DDIV, IREM,
* LALOAD, FALOAD, DALOAD, AALOAD, BALOAD, CALOAD, SALOAD, * LREM, FREM, DREM, INEG, LNEG, FNEG, DNEG, ISHL, LSHL, ISHR, LSHR, IUSHR, LUSHR, IAND, LAND, IOR, LOR, IXOR,
* IASTORE, LASTORE, FASTORE, DASTORE, AASTORE, BASTORE, CASTORE, * LXOR, I2L, I2F, I2D, L2I, L2F, L2D, F2I, F2L, F2D, D2I, D2L, D2F, I2B, I2C, I2S, LCMP, FCMPL, FCMPG, DCMPL,
* SASTORE, POP, POP2, DUP, DUP_X1, DUP_X2, DUP2, DUP2_X1, * DCMPG, IRETURN, LRETURN, FRETURN, DRETURN, ARETURN, RETURN, ARRAYLENGTH, ATHROW, MONITORENTER, or
* DUP2_X2, SWAP, IADD, LADD, FADD, DADD, ISUB, LSUB, FSUB, DSUB, * MONITOREXIT.
* IMUL, LMUL, FMUL, DMUL, IDIV, LDIV, FDIV, DDIV, IREM, LREM,
* FREM, DREM, INEG, LNEG, FNEG, DNEG, ISHL, LSHL, ISHR, LSHR,
* IUSHR, LUSHR, IAND, LAND, IOR, LOR, IXOR, LXOR, I2L, I2F, I2D,
* L2I, L2F, L2D, F2I, F2L, F2D, D2I, D2L, D2F, I2B, I2C, I2S,
* LCMP, FCMPL, FCMPG, DCMPL, DCMPG, IRETURN, LRETURN, FRETURN,
* DRETURN, ARETURN, RETURN, ARRAYLENGTH, ATHROW, MONITORENTER,
* or MONITOREXIT.
*/ */
public void visitInsn(int opcode) { public void visitInsn(int opcode) {
if (mv != null) { if (mv != null) {
@@ -365,20 +300,13 @@ public abstract class MethodVisitor {
/** /**
* Visits an instruction with a single int operand. * Visits an instruction with a single int operand.
* *
* @param opcode * @param opcode the opcode of the instruction to be visited. This opcode is either BIPUSH, SIPUSH or NEWARRAY.
* the opcode of the instruction to be visited. This opcode is * @param operand the operand of the instruction to be visited.<br>
* either BIPUSH, SIPUSH or NEWARRAY. * When opcode is BIPUSH, operand value should be between Byte.MIN_VALUE and Byte.MAX_VALUE.<br>
* @param operand * When opcode is SIPUSH, operand value should be between Short.MIN_VALUE and Short.MAX_VALUE.<br>
* the operand of the instruction to be visited.<br> * When opcode is NEWARRAY, operand value should be one of {@link Opcodes#T_BOOLEAN}, {@link Opcodes#T_CHAR},
* When opcode is BIPUSH, operand value should be between * {@link Opcodes#T_FLOAT}, {@link Opcodes#T_DOUBLE}, {@link Opcodes#T_BYTE}, {@link Opcodes#T_SHORT},
* Byte.MIN_VALUE and Byte.MAX_VALUE.<br> * {@link Opcodes#T_INT} or {@link Opcodes#T_LONG}.
* When opcode is SIPUSH, operand value should be between
* Short.MIN_VALUE and Short.MAX_VALUE.<br>
* When opcode is NEWARRAY, operand value should be one of
* {@link Opcodes#T_BOOLEAN}, {@link Opcodes#T_CHAR},
* {@link Opcodes#T_FLOAT}, {@link Opcodes#T_DOUBLE},
* {@link Opcodes#T_BYTE}, {@link Opcodes#T_SHORT},
* {@link Opcodes#T_INT} or {@link Opcodes#T_LONG}.
*/ */
public void visitIntInsn(int opcode, int operand) { public void visitIntInsn(int opcode, int operand) {
if (mv != null) { if (mv != null) {
@@ -387,16 +315,12 @@ public abstract class MethodVisitor {
} }
/** /**
* Visits a local variable instruction. A local variable instruction is an * Visits a local variable instruction. A local variable instruction is an instruction that loads or stores the
* instruction that loads or stores the value of a local variable. * value of a local variable.
* *
* @param opcode * @param opcode the opcode of the local variable instruction to be visited. This opcode is either ILOAD, LLOAD,
* the opcode of the local variable instruction to be visited. * FLOAD, DLOAD, ALOAD, ISTORE, LSTORE, FSTORE, DSTORE, ASTORE or RET.
* This opcode is either ILOAD, LLOAD, FLOAD, DLOAD, ALOAD, * @param var the operand of the instruction to be visited. This operand is the index of a local variable.
* ISTORE, LSTORE, FSTORE, DSTORE, ASTORE or RET.
* @param var
* the operand of the instruction to be visited. This operand is
* the index of a local variable.
*/ */
public void visitVarInsn(int opcode, int var) { public void visitVarInsn(int opcode, int var) {
if (mv != null) { if (mv != null) {
@@ -405,16 +329,13 @@ public abstract class MethodVisitor {
} }
/** /**
* Visits a type instruction. A type instruction is an instruction that * Visits a type instruction. A type instruction is an instruction that takes the internal name of a class as
* takes the internal name of a class as parameter. * parameter.
* *
* @param opcode * @param opcode the opcode of the type instruction to be visited. This opcode is either NEW, ANEWARRAY, CHECKCAST
* the opcode of the type instruction to be visited. This opcode * or INSTANCEOF.
* is either NEW, ANEWARRAY, CHECKCAST or INSTANCEOF. * @param type the operand of the instruction to be visited. This operand must be the internal name of an object or
* @param type * array class (see {@link Type#getInternalName() getInternalName}).
* the operand of the instruction to be visited. This operand
* must be the internal name of an object or array class (see
* {@link Type#getInternalName() getInternalName}).
*/ */
public void visitTypeInsn(int opcode, String type) { public void visitTypeInsn(int opcode, String type) {
if (mv != null) { if (mv != null) {
@@ -423,47 +344,32 @@ public abstract class MethodVisitor {
} }
/** /**
* Visits a field instruction. A field instruction is an instruction that * Visits a field instruction. A field instruction is an instruction that loads or stores the value of a field of an
* loads or stores the value of a field of an object. * object.
* *
* @param opcode * @param opcode the opcode of the type instruction to be visited. This opcode is either GETSTATIC, PUTSTATIC,
* the opcode of the type instruction to be visited. This opcode * GETFIELD or PUTFIELD.
* is either GETSTATIC, PUTSTATIC, GETFIELD or PUTFIELD. * @param owner the internal name of the field's owner class (see {@link Type#getInternalName() getInternalName}).
* @param owner * @param name the field's name.
* the internal name of the field's owner class (see * @param desc the field's descriptor (see {@link Type Type}).
* {@link Type#getInternalName() getInternalName}).
* @param name
* the field's name.
* @param desc
* the field's descriptor (see {@link Type Type}).
*/ */
public void visitFieldInsn(int opcode, String owner, String name, public void visitFieldInsn(int opcode, String owner, String name, String desc) {
String desc) {
if (mv != null) { if (mv != null) {
mv.visitFieldInsn(opcode, owner, name, desc); mv.visitFieldInsn(opcode, owner, name, desc);
} }
} }
/** /**
* Visits a method instruction. A method instruction is an instruction that * Visits a method instruction. A method instruction is an instruction that invokes a method.
* invokes a method.
* *
* @param opcode * @param opcode the opcode of the type instruction to be visited. This opcode is either INVOKEVIRTUAL,
* the opcode of the type instruction to be visited. This opcode * INVOKESPECIAL, INVOKESTATIC or INVOKEINTERFACE.
* is either INVOKEVIRTUAL, INVOKESPECIAL, INVOKESTATIC or * @param owner the internal name of the method's owner class (see {@link Type#getInternalName() getInternalName}).
* INVOKEINTERFACE. * @param name the method's name.
* @param owner * @param desc the method's descriptor (see {@link Type Type}).
* the internal name of the method's owner class (see * @param itf if the method's owner class is an interface.
* {@link Type#getInternalName() getInternalName}).
* @param name
* the method's name.
* @param desc
* the method's descriptor (see {@link Type Type}).
* @param itf
* if the method's owner class is an interface.
*/ */
public void visitMethodInsn(int opcode, String owner, String name, public void visitMethodInsn(int opcode, String owner, String name, String desc, boolean itf) {
String desc, boolean itf) {
if (mv != null) { if (mv != null) {
mv.visitMethodInsn(opcode, owner, name, desc, itf); mv.visitMethodInsn(opcode, owner, name, desc, itf);
} }
@@ -472,39 +378,27 @@ public abstract class MethodVisitor {
/** /**
* Visits an invokedynamic instruction. * Visits an invokedynamic instruction.
* *
* @param name * @param name the method's name.
* the method's name. * @param desc the method's descriptor (see {@link Type Type}).
* @param desc * @param bsm the bootstrap method.
* the method's descriptor (see {@link Type Type}). * @param bsmArgs the bootstrap method constant arguments. Each argument must be an {@link Integer}, {@link Float},
* @param bsm * {@link Long}, {@link Double}, {@link String}, {@link Type} or {@link Handle} value. This method is allowed to
* the bootstrap method. * modify the content of the array so a caller should expect that this array may change.
* @param bsmArgs
* the bootstrap method constant arguments. Each argument must be
* an {@link Integer}, {@link Float}, {@link Long},
* {@link Double}, {@link String}, {@link Type} or {@link Handle}
* value. This method is allowed to modify the content of the
* array so a caller should expect that this array may change.
*/ */
public void visitInvokeDynamicInsn(String name, String desc, Handle bsm, public void visitInvokeDynamicInsn(String name, String desc, Handle bsm, Object... bsmArgs) {
Object... bsmArgs) {
if (mv != null) { if (mv != null) {
mv.visitInvokeDynamicInsn(name, desc, bsm, bsmArgs); mv.visitInvokeDynamicInsn(name, desc, bsm, bsmArgs);
} }
} }
/** /**
* Visits a jump instruction. A jump instruction is an instruction that may * Visits a jump instruction. A jump instruction is an instruction that may jump to another instruction.
* jump to another instruction.
* *
* @param opcode * @param opcode the opcode of the type instruction to be visited. This opcode is either IFEQ, IFNE, IFLT, IFGE,
* the opcode of the type instruction to be visited. This opcode * IFGT, IFLE, IF_ICMPEQ, IF_ICMPNE, IF_ICMPLT, IF_ICMPGE, IF_ICMPGT, IF_ICMPLE, IF_ACMPEQ, IF_ACMPNE, GOTO,
* is either IFEQ, IFNE, IFLT, IFGE, IFGT, IFLE, IF_ICMPEQ, * JSR, IFNULL or IFNONNULL.
* IF_ICMPNE, IF_ICMPLT, IF_ICMPGE, IF_ICMPGT, IF_ICMPLE, * @param label the operand of the instruction to be visited. This operand is a label that designates the
* IF_ACMPEQ, IF_ACMPNE, GOTO, JSR, IFNULL or IFNONNULL. * instruction to which the jump instruction may jump.
* @param label
* the operand of the instruction to be visited. This operand is
* a label that designates the instruction to which the jump
* instruction may jump.
*/ */
public void visitJumpInsn(int opcode, Label label) { public void visitJumpInsn(int opcode, Label label) {
if (mv != null) { if (mv != null) {
@@ -513,11 +407,9 @@ public abstract class MethodVisitor {
} }
/** /**
* Visits a label. A label designates the instruction that will be visited * Visits a label. A label designates the instruction that will be visited just after it.
* just after it.
* *
* @param label * @param label a {@link Label Label} object.
* a {@link Label Label} object.
*/ */
public void visitLabel(Label label) { public void visitLabel(Label label) {
if (mv != null) { if (mv != null) {
@@ -530,10 +422,9 @@ public abstract class MethodVisitor {
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
/** /**
* Visits a LDC instruction. Note that new constant types may be added in * Visits a LDC instruction. Note that new constant types may be added in future versions of the Java Virtual
* future versions of the Java Virtual Machine. To easily detect new * Machine. To easily detect new constant types, implementations of this method should check for unexpected constant
* constant types, implementations of this method should check for * types, like this:
* unexpected constant types, like this:
* *
* <pre> * <pre>
* if (cst instanceof Integer) { * if (cst instanceof Integer) {
@@ -564,14 +455,10 @@ public abstract class MethodVisitor {
* } * }
* </pre> * </pre>
* *
* @param cst * @param cst the constant to be loaded on the stack. This parameter must be a non null {@link Integer}, a
* the constant to be loaded on the stack. This parameter must be * {@link Float}, a {@link Long}, a {@link Double}, a {@link String}, a {@link Type} of OBJECT or ARRAY sort for
* a non null {@link Integer}, a {@link Float}, a {@link Long}, a * &#60;tt&#62;.class&#60;/tt&#62; constants, for classes whose version is 49.0, a {@link Type} of METHOD sort
* {@link Double}, a {@link String}, a {@link Type} of OBJECT or * or a {@link Handle} for MethodType and MethodHandle constants, for classes whose version is 51.0.
* ARRAY sort for &#60;tt&#62;.class&#60;/tt&#62; constants, for classes whose
* version is 49.0, a {@link Type} of METHOD sort or a
* {@link Handle} for MethodType and MethodHandle constants, for
* classes whose version is 51.0.
*/ */
public void visitLdcInsn(Object cst) { public void visitLdcInsn(Object cst) {
if (mv != null) { if (mv != null) {
@@ -582,10 +469,8 @@ public abstract class MethodVisitor {
/** /**
* Visits an IINC instruction. * Visits an IINC instruction.
* *
* @param var * @param var index of the local variable to be incremented.
* index of the local variable to be incremented. * @param increment amount to increment the local variable by.
* @param increment
* amount to increment the local variable by.
*/ */
public void visitIincInsn(int var, int increment) { public void visitIincInsn(int var, int increment) {
if (mv != null) { if (mv != null) {
@@ -596,18 +481,13 @@ public abstract class MethodVisitor {
/** /**
* Visits a TABLESWITCH instruction. * Visits a TABLESWITCH instruction.
* *
* @param min * @param min the minimum key value.
* the minimum key value. * @param max the maximum key value.
* @param max * @param dflt beginning of the default handler block.
* the maximum key value. * @param labels beginnings of the handler blocks. &#60;tt&#62;labels[i]&#60;/tt&#62; is the beginning of the
* @param dflt * handler block for the &#60;tt&#62;min + i&#60;/tt&#62; key.
* beginning of the default handler block.
* @param labels
* beginnings of the handler blocks. &#60;tt&#62;labels[i]&#60;/tt&#62; is the
* beginning of the handler block for the &#60;tt&#62;min + i&#60;/tt&#62; key.
*/ */
public void visitTableSwitchInsn(int min, int max, Label dflt, public void visitTableSwitchInsn(int min, int max, Label dflt, Label... labels) {
Label... labels) {
if (mv != null) { if (mv != null) {
mv.visitTableSwitchInsn(min, max, dflt, labels); mv.visitTableSwitchInsn(min, max, dflt, labels);
} }
@@ -616,13 +496,10 @@ public abstract class MethodVisitor {
/** /**
* Visits a LOOKUPSWITCH instruction. * Visits a LOOKUPSWITCH instruction.
* *
* @param dflt * @param dflt beginning of the default handler block.
* beginning of the default handler block. * @param keys the values of the keys.
* @param keys * @param labels beginnings of the handler blocks. &#60;tt&#62;labels[i]&#60;/tt&#62; is the beginning of the
* the values of the keys. * handler block for the &#60;tt&#62;keys[i]&#60;/tt&#62; key.
* @param labels
* beginnings of the handler blocks. &#60;tt&#62;labels[i]&#60;/tt&#62; is the
* beginning of the handler block for the &#60;tt&#62;keys[i]&#60;/tt&#62; key.
*/ */
public void visitLookupSwitchInsn(Label dflt, int[] keys, Label[] labels) { public void visitLookupSwitchInsn(Label dflt, int[] keys, Label[] labels) {
if (mv != null) { if (mv != null) {
@@ -633,10 +510,8 @@ public abstract class MethodVisitor {
/** /**
* Visits a MULTIANEWARRAY instruction. * Visits a MULTIANEWARRAY instruction.
* *
* @param desc * @param desc an array type descriptor (see {@link Type Type}).
* an array type descriptor (see {@link Type Type}). * @param dims number of dimensions of the array to allocate.
* @param dims
* number of dimensions of the array to allocate.
*/ */
public void visitMultiANewArrayInsn(String desc, int dims) { public void visitMultiANewArrayInsn(String desc, int dims) {
if (mv != null) { if (mv != null) {
@@ -645,38 +520,25 @@ public abstract class MethodVisitor {
} }
/** /**
* Visits an annotation on an instruction. This method must be called just * Visits an annotation on an instruction. This method must be called just <i>after</i> the annotated instruction.
* <i>after</i> the annotated instruction. It can be called several times * It can be called several times for the same instruction.
* for the same instruction.
* *
* @param typeRef * @param typeRef a reference to the annotated type. The sort of this type reference must be
* a reference to the annotated type. The sort of this type * {@link TypeReference#INSTANCEOF INSTANCEOF}, {@link TypeReference#NEW NEW},
* reference must be {@link TypeReference#INSTANCEOF INSTANCEOF}, * {@link TypeReference#CONSTRUCTOR_REFERENCE CONSTRUCTOR_REFERENCE}, {@link TypeReference#METHOD_REFERENCE
* {@link TypeReference#NEW NEW}, * METHOD_REFERENCE}, {@link TypeReference#CAST CAST}, {@link TypeReference#CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT
* {@link TypeReference#CONSTRUCTOR_REFERENCE * CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT}, {@link TypeReference#METHOD_INVOCATION_TYPE_ARGUMENT
* CONSTRUCTOR_REFERENCE}, {@link TypeReference#METHOD_REFERENCE * METHOD_INVOCATION_TYPE_ARGUMENT}, {@link TypeReference#CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT
* METHOD_REFERENCE}, {@link TypeReference#CAST CAST}, * CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT}, or {@link TypeReference#METHOD_REFERENCE_TYPE_ARGUMENT
* {@link TypeReference#CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT * METHOD_REFERENCE_TYPE_ARGUMENT}. See {@link TypeReference}.
* CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT}, * @param typePath the path to the annotated type argument, wildcard bound, array element type, or static inner type
* {@link TypeReference#METHOD_INVOCATION_TYPE_ARGUMENT * within 'typeRef'. May be &#60;tt&#62;null&#60;/tt&#62; if the annotation targets 'typeRef' as a whole.
* METHOD_INVOCATION_TYPE_ARGUMENT}, * @param desc the class descriptor of the annotation class.
* {@link TypeReference#CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT * @param visible &#60;tt&#62;true&#60;/tt&#62; if the annotation is visible at runtime.
* CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT}, or * @return a visitor to visit the annotation values, or &#60;tt&#62;null&#60;/tt&#62; if this visitor is not
* {@link TypeReference#METHOD_REFERENCE_TYPE_ARGUMENT * interested in visiting this annotation.
* METHOD_REFERENCE_TYPE_ARGUMENT}. See {@link TypeReference}.
* @param typePath
* the path to the annotated type argument, wildcard bound, array
* element type, or static inner type within 'typeRef'. May be
* &#60;tt&#62;null&#60;/tt&#62; if the annotation targets 'typeRef' as a whole.
* @param desc
* the class descriptor of the annotation class.
* @param visible
* &#60;tt&#62;true&#60;/tt&#62; if the annotation is visible at runtime.
* @return a visitor to visit the annotation values, or &#60;tt&#62;null&#60;/tt&#62; if
* this visitor is not interested in visiting this annotation.
*/ */
public AnnotationVisitor visitInsnAnnotation(int typeRef, public AnnotationVisitor visitInsnAnnotation(int typeRef, TypePath typePath, String desc, boolean visible) {
TypePath typePath, String desc, boolean visible) {
if (mv != null) { if (mv != null) {
return mv.visitInsnAnnotation(typeRef, typePath, desc, visible); return mv.visitInsnAnnotation(typeRef, typePath, desc, visible);
} }
@@ -690,50 +552,35 @@ public abstract class MethodVisitor {
/** /**
* Visits a try catch block. * Visits a try catch block.
* *
* @param start * @param start beginning of the exception handler's scope (inclusive).
* beginning of the exception handler's scope (inclusive). * @param end end of the exception handler's scope (exclusive).
* @param end * @param handler beginning of the exception handler's code.
* end of the exception handler's scope (exclusive). * @param type internal name of the type of exceptions handled by the handler, or &#60;tt&#62;null&#60;/tt&#62; to
* @param handler * catch any exceptions (for "finally" blocks).
* beginning of the exception handler's code. * @throws IllegalArgumentException if one of the labels has already been visited by this visitor (by the
* @param type * {@link #visitLabel visitLabel} method).
* internal name of the type of exceptions handled by the
* handler, or &#60;tt&#62;null&#60;/tt&#62; to catch any exceptions (for
* "finally" blocks).
* @throws IllegalArgumentException
* if one of the labels has already been visited by this visitor
* (by the {@link #visitLabel visitLabel} method).
*/ */
public void visitTryCatchBlock(Label start, Label end, Label handler, public void visitTryCatchBlock(Label start, Label end, Label handler, String type) {
String type) {
if (mv != null) { if (mv != null) {
mv.visitTryCatchBlock(start, end, handler, type); mv.visitTryCatchBlock(start, end, handler, type);
} }
} }
/** /**
* Visits an annotation on an exception handler type. This method must be * Visits an annotation on an exception handler type. This method must be called <i>after</i> the
* called <i>after</i> the {@link #visitTryCatchBlock} for the annotated * {@link #visitTryCatchBlock} for the annotated exception handler. It can be called several times for the same
* exception handler. It can be called several times for the same exception * exception handler.
* handler.
* *
* @param typeRef * @param typeRef a reference to the annotated type. The sort of this type reference must be
* a reference to the annotated type. The sort of this type * {@link TypeReference#EXCEPTION_PARAMETER EXCEPTION_PARAMETER}. See {@link TypeReference}.
* reference must be {@link TypeReference#EXCEPTION_PARAMETER * @param typePath the path to the annotated type argument, wildcard bound, array element type, or static inner type
* EXCEPTION_PARAMETER}. See {@link TypeReference}. * within 'typeRef'. May be &#60;tt&#62;null&#60;/tt&#62; if the annotation targets 'typeRef' as a whole.
* @param typePath * @param desc the class descriptor of the annotation class.
* the path to the annotated type argument, wildcard bound, array * @param visible &#60;tt&#62;true&#60;/tt&#62; if the annotation is visible at runtime.
* element type, or static inner type within 'typeRef'. May be * @return a visitor to visit the annotation values, or &#60;tt&#62;null&#60;/tt&#62; if this visitor is not
* &#60;tt&#62;null&#60;/tt&#62; if the annotation targets 'typeRef' as a whole. * interested in visiting this annotation.
* @param desc
* the class descriptor of the annotation class.
* @param visible
* &#60;tt&#62;true&#60;/tt&#62; if the annotation is visible at runtime.
* @return a visitor to visit the annotation values, or &#60;tt&#62;null&#60;/tt&#62; if
* this visitor is not interested in visiting this annotation.
*/ */
public AnnotationVisitor visitTryCatchAnnotation(int typeRef, public AnnotationVisitor visitTryCatchAnnotation(int typeRef, TypePath typePath, String desc, boolean visible) {
TypePath typePath, String desc, boolean visible) {
if (mv != null) { if (mv != null) {
return mv.visitTryCatchAnnotation(typeRef, typePath, desc, visible); return mv.visitTryCatchAnnotation(typeRef, typePath, desc, visible);
} }
@@ -743,28 +590,17 @@ public abstract class MethodVisitor {
/** /**
* Visits a local variable declaration. * Visits a local variable declaration.
* *
* @param name * @param name the name of a local variable.
* the name of a local variable. * @param desc the type descriptor of this local variable.
* @param desc * @param signature the type signature of this local variable. May be &#60;tt&#62;null&#60;/tt&#62; if the local
* the type descriptor of this local variable. * variable type does not use generic types.
* @param signature * @param start the first instruction corresponding to the scope of this local variable (inclusive).
* the type signature of this local variable. May be * @param end the last instruction corresponding to the scope of this local variable (exclusive).
* &#60;tt&#62;null&#60;/tt&#62; if the local variable type does not use generic * @param index the local variable's index.
* types. * @throws IllegalArgumentException if one of the labels has not already been visited by this visitor (by the
* @param start * {@link #visitLabel visitLabel} method).
* the first instruction corresponding to the scope of this local
* variable (inclusive).
* @param end
* the last instruction corresponding to the scope of this local
* variable (exclusive).
* @param index
* the local variable's index.
* @throws IllegalArgumentException
* if one of the labels has not already been visited by this
* visitor (by the {@link #visitLabel visitLabel} method).
*/ */
public void visitLocalVariable(String name, String desc, String signature, public void visitLocalVariable(String name, String desc, String signature, Label start, Label end, int index) {
Label start, Label end, int index) {
if (mv != null) { if (mv != null) {
mv.visitLocalVariable(name, desc, signature, start, end, index); mv.visitLocalVariable(name, desc, signature, start, end, index);
} }
@@ -773,38 +609,25 @@ public abstract class MethodVisitor {
/** /**
* Visits an annotation on a local variable type. * Visits an annotation on a local variable type.
* *
* @param typeRef * @param typeRef a reference to the annotated type. The sort of this type reference must be
* a reference to the annotated type. The sort of this type * {@link TypeReference#LOCAL_VARIABLE LOCAL_VARIABLE} or {@link TypeReference#RESOURCE_VARIABLE
* reference must be {@link TypeReference#LOCAL_VARIABLE * RESOURCE_VARIABLE}. See {@link TypeReference}.
* LOCAL_VARIABLE} or {@link TypeReference#RESOURCE_VARIABLE * @param typePath the path to the annotated type argument, wildcard bound, array element type, or static inner type
* RESOURCE_VARIABLE}. See {@link TypeReference}. * within 'typeRef'. May be &#60;tt&#62;null&#60;/tt&#62; if the annotation targets 'typeRef' as a whole.
* @param typePath * @param start the fist instructions corresponding to the continuous ranges that make the scope of this local
* the path to the annotated type argument, wildcard bound, array * variable (inclusive).
* element type, or static inner type within 'typeRef'. May be * @param end the last instructions corresponding to the continuous ranges that make the scope of this local
* &#60;tt&#62;null&#60;/tt&#62; if the annotation targets 'typeRef' as a whole. * variable (exclusive). This array must have the same size as the 'start' array.
* @param start * @param index the local variable's index in each range. This array must have the same size as the 'start' array.
* the fist instructions corresponding to the continuous ranges * @param desc the class descriptor of the annotation class.
* that make the scope of this local variable (inclusive). * @param visible &#60;tt&#62;true&#60;/tt&#62; if the annotation is visible at runtime.
* @param end * @return a visitor to visit the annotation values, or &#60;tt&#62;null&#60;/tt&#62; if this visitor is not
* the last instructions corresponding to the continuous ranges * interested in visiting this annotation.
* that make the scope of this local variable (exclusive). This
* array must have the same size as the 'start' array.
* @param index
* the local variable's index in each range. This array must have
* the same size as the 'start' array.
* @param desc
* the class descriptor of the annotation class.
* @param visible
* &#60;tt&#62;true&#60;/tt&#62; if the annotation is visible at runtime.
* @return a visitor to visit the annotation values, or &#60;tt&#62;null&#60;/tt&#62; if
* this visitor is not interested in visiting this annotation.
*/ */
public AnnotationVisitor visitLocalVariableAnnotation(int typeRef, public AnnotationVisitor visitLocalVariableAnnotation(
TypePath typePath, Label[] start, Label[] end, int[] index, int typeRef, TypePath typePath, Label[] start, Label[] end, int[] index, String desc, boolean visible) {
String desc, boolean visible) {
if (mv != null) { if (mv != null) {
return mv.visitLocalVariableAnnotation(typeRef, typePath, start, return mv.visitLocalVariableAnnotation(typeRef, typePath, start, end, index, desc, visible);
end, index, desc, visible);
} }
return null; return null;
} }
@@ -812,14 +635,10 @@ public abstract class MethodVisitor {
/** /**
* Visits a line number declaration. * Visits a line number declaration.
* *
* @param line * @param line a line number. This number refers to the source file from which the class was compiled.
* a line number. This number refers to the source file from * @param start the first instruction corresponding to this line number.
* which the class was compiled. * @throws IllegalArgumentException if &#60;tt&#62;start&#60;/tt&#62; has not already been visited by this visitor
* @param start * (by the {@link #visitLabel visitLabel} method).
* the first instruction corresponding to this line number.
* @throws IllegalArgumentException
* if &#60;tt&#62;start&#60;/tt&#62; has not already been visited by this
* visitor (by the {@link #visitLabel visitLabel} method).
*/ */
public void visitLineNumber(int line, Label start) { public void visitLineNumber(int line, Label start) {
if (mv != null) { if (mv != null) {
@@ -828,13 +647,10 @@ public abstract class MethodVisitor {
} }
/** /**
* Visits the maximum stack size and the maximum number of local variables * Visits the maximum stack size and the maximum number of local variables of the method.
* of the method.
* *
* @param maxStack * @param maxStack maximum stack size of the method.
* maximum stack size of the method. * @param maxLocals maximum number of local variables for the method.
* @param maxLocals
* maximum number of local variables for the method.
*/ */
public void visitMaxs(int maxStack, int maxLocals) { public void visitMaxs(int maxStack, int maxLocals) {
if (mv != null) { if (mv != null) {
@@ -843,9 +659,8 @@ public abstract class MethodVisitor {
} }
/** /**
* Visits the end of the method. This method, which is the last one to be * Visits the end of the method. This method, which is the last one to be called, is used to inform the visitor that
* called, is used to inform the visitor that all the annotations and * all the annotations and attributes of the method have been visited.
* attributes of the method have been visited.
*/ */
public void visitEnd() { public void visitEnd() {
if (mv != null) { if (mv != null) {

File diff suppressed because it is too large Load Diff

View File

@@ -59,36 +59,29 @@
package org.redkale.asm; package org.redkale.asm;
/** /**
* A visitor to visit a Java module. The methods of this class must be called in * A visitor to visit a Java module. The methods of this class must be called in the following order:
* the following order: &#60;tt&#62;visitMainClass&#60;/tt&#62; | ( &#60;tt&#62;visitPackage&#60;/tt&#62; | * &#60;tt&#62;visitMainClass&#60;/tt&#62; | ( &#60;tt&#62;visitPackage&#60;/tt&#62; |
* &#60;tt&#62;visitRequire&#60;/tt&#62; | &#60;tt&#62;visitExport&#60;/tt&#62; | &#60;tt&#62;visitOpen&#60;/tt&#62; | * &#60;tt&#62;visitRequire&#60;/tt&#62; | &#60;tt&#62;visitExport&#60;/tt&#62; | &#60;tt&#62;visitOpen&#60;/tt&#62; |
* &#60;tt&#62;visitUse&#60;/tt&#62; | &#60;tt&#62;visitProvide&#60;/tt&#62; )* &#60;tt&#62;visitEnd&#60;/tt&#62;. * &#60;tt&#62;visitUse&#60;/tt&#62; | &#60;tt&#62;visitProvide&#60;/tt&#62; )* &#60;tt&#62;visitEnd&#60;/tt&#62;.
* *
* The methods {@link #visitRequire(String, int, String)}, {@link #visitExport(String, int, String...)}, * <p>The methods {@link #visitRequire(String, int, String)}, {@link #visitExport(String, int, String...)},
* {@link #visitOpen(String, int, String...)} and {@link #visitPackage(String)} * {@link #visitOpen(String, int, String...)} and {@link #visitPackage(String)} take as parameter a package name or a
* take as parameter a package name or a module name. Unlike the other names which are internal names * module name. Unlike the other names which are internal names (names separated by slash), module and package names are
* (names separated by slash), module and package names are qualified names (names separated by dot). * qualified names (names separated by dot).
* *
* @author Remi Forax * @author Remi Forax
*/ */
public abstract class ModuleVisitor { public abstract class ModuleVisitor {
/** /** The ASM API version implemented by this visitor. The value of this field must be {@link Opcodes#ASM6}. */
* The ASM API version implemented by this visitor. The value of this field
* must be {@link Opcodes#ASM6}.
*/
protected final int api; protected final int api;
/** /** The module visitor to which this visitor must delegate method calls. May be null. */
* The module visitor to which this visitor must delegate method calls. May
* be null.
*/
protected ModuleVisitor mv; protected ModuleVisitor mv;
/** /**
* Constructs a new {@link ModuleVisitor}. * Constructs a new {@link ModuleVisitor}.
* *
* @param api * @param api the ASM API version implemented by this visitor. Must be {@link Opcodes#ASM6}.
* the ASM API version implemented by this visitor. Must be {@link Opcodes#ASM6}.
*/ */
public ModuleVisitor(final int api) { public ModuleVisitor(final int api) {
this(api, null); this(api, null);
@@ -97,11 +90,8 @@ public abstract class ModuleVisitor {
/** /**
* Constructs a new {@link ModuleVisitor}. * Constructs a new {@link ModuleVisitor}.
* *
* @param api * @param api the ASM API version implemented by this visitor. Must be {@link Opcodes#ASM6}.
* the ASM API version implemented by this visitor. Must be {@link Opcodes#ASM6}. * @param mv the module visitor to which this visitor must delegate method calls. May be null.
* @param mv
* the module visitor to which this visitor must delegate method
* calls. May be null.
*/ */
public ModuleVisitor(final int api, final ModuleVisitor mv) { public ModuleVisitor(final int api, final ModuleVisitor mv) {
if (api != Opcodes.ASM6) { if (api != Opcodes.ASM6) {
@@ -137,9 +127,8 @@ public abstract class ModuleVisitor {
* Visits a dependence of the current module. * Visits a dependence of the current module.
* *
* @param module the qualified name of the dependence. * @param module the qualified name of the dependence.
* @param access the access flag of the dependence among * @param access the access flag of the dependence among ACC_TRANSITIVE, ACC_STATIC_PHASE, ACC_SYNTHETIC and
* ACC_TRANSITIVE, ACC_STATIC_PHASE, ACC_SYNTHETIC * ACC_MANDATED.
* and ACC_MANDATED.
* @param version the module version at compile time or null. * @param version the module version at compile time or null.
*/ */
public void visitRequire(String module, int access, String version) { public void visitRequire(String module, int access, String version) {
@@ -152,12 +141,10 @@ public abstract class ModuleVisitor {
* Visit an exported package of the current module. * Visit an exported package of the current module.
* *
* @param packaze the qualified name of the exported package. * @param packaze the qualified name of the exported package.
* @param access the access flag of the exported package, * @param access the access flag of the exported package, valid values are among {@code ACC_SYNTHETIC} and
* valid values are among {@code ACC_SYNTHETIC} and * {@code ACC_MANDATED}.
* {@code ACC_MANDATED}. * @param modules the qualified names of the modules that can access to the public classes of the exported package
* @param modules the qualified names of the modules that can access to * or &#60;tt&#62;null&#60;/tt&#62;.
* the public classes of the exported package or
* &#60;tt&#62;null&#60;/tt&#62;.
*/ */
public void visitExport(String packaze, int access, String... modules) { public void visitExport(String packaze, int access, String... modules) {
if (mv != null) { if (mv != null) {
@@ -169,12 +156,10 @@ public abstract class ModuleVisitor {
* Visit an open package of the current module. * Visit an open package of the current module.
* *
* @param packaze the qualified name of the opened package. * @param packaze the qualified name of the opened package.
* @param access the access flag of the opened package, * @param access the access flag of the opened package, valid values are among {@code ACC_SYNTHETIC} and
* valid values are among {@code ACC_SYNTHETIC} and * {@code ACC_MANDATED}.
* {@code ACC_MANDATED}. * @param modules the qualified names of the modules that can use deep reflection to the classes of the open package
* @param modules the qualified names of the modules that can use deep * or &#60;tt&#62;null&#60;/tt&#62;.
* reflection to the classes of the open package or
* &#60;tt&#62;null&#60;/tt&#62;.
*/ */
public void visitOpen(String packaze, int access, String... modules) { public void visitOpen(String packaze, int access, String... modules) {
if (mv != null) { if (mv != null) {
@@ -183,8 +168,7 @@ public abstract class ModuleVisitor {
} }
/** /**
* Visit a service used by the current module. * Visit a service used by the current module. The name must be the internal name of an interface or a class.
* The name must be the internal name of an interface or a class.
* *
* @param service the internal name of the service. * @param service the internal name of the service.
*/ */
@@ -198,8 +182,7 @@ public abstract class ModuleVisitor {
* Visit an implementation of a service. * Visit an implementation of a service.
* *
* @param service the internal name of the service * @param service the internal name of the service
* @param providers the internal names of the implementations * @param providers the internal names of the implementations of the service (there is at least one provider).
* of the service (there is at least one provider).
*/ */
public void visitProvide(String service, String... providers) { public void visitProvide(String service, String... providers) {
if (mv != null) { if (mv != null) {
@@ -208,8 +191,8 @@ public abstract class ModuleVisitor {
} }
/** /**
* Visits the end of the module. This method, which is the last one to be * Visits the end of the module. This method, which is the last one to be called, is used to inform the visitor that
* called, is used to inform the visitor that everything have been visited. * everything have been visited.
*/ */
public void visitEnd() { public void visitEnd() {
if (mv != null) { if (mv != null) {

View File

@@ -59,122 +59,90 @@
package org.redkale.asm; package org.redkale.asm;
/** /** @author Remi Forax */
* @author Remi Forax
*/
final class ModuleWriter extends ModuleVisitor { final class ModuleWriter extends ModuleVisitor {
/** /** The class writer to which this Module attribute must be added. */
* The class writer to which this Module attribute must be added.
*/
private final ClassWriter cw; private final ClassWriter cw;
/** /** size in byte of the Module attribute. */
* size in byte of the Module attribute.
*/
int size; int size;
/** /** Number of attributes associated with the current module (Version, ConcealPackages, etc) */
* Number of attributes associated with the current module
* (Version, ConcealPackages, etc)
*/
int attributeCount; int attributeCount;
/** /** Size in bytes of the attributes associated with the current module */
* Size in bytes of the attributes associated with the current module
*/
int attributesSize; int attributesSize;
/** /** module name index in the constant pool */
* module name index in the constant pool
*/
private final int name; private final int name;
/** /** module access flags */
* module access flags
*/
private final int access; private final int access;
/** /** module version index in the constant pool or 0 */
* module version index in the constant pool or 0
*/
private final int version; private final int version;
/** /** module main class index in the constant pool or 0 */
* module main class index in the constant pool or 0
*/
private int mainClass; private int mainClass;
/** /** number of packages */
* number of packages
*/
private int packageCount; private int packageCount;
/** /**
* The packages in bytecode form. This byte vector only contains * The packages in bytecode form. This byte vector only contains the items themselves, the number of items is store
* the items themselves, the number of items is store in packageCount * in packageCount
*/ */
private ByteVector packages; private ByteVector packages;
/** /** number of requires items */
* number of requires items
*/
private int requireCount; private int requireCount;
/** /**
* The requires items in bytecode form. This byte vector only contains * The requires items in bytecode form. This byte vector only contains the items themselves, the number of items is
* the items themselves, the number of items is store in requireCount * store in requireCount
*/ */
private ByteVector requires; private ByteVector requires;
/** /** number of exports items */
* number of exports items
*/
private int exportCount; private int exportCount;
/** /**
* The exports items in bytecode form. This byte vector only contains * The exports items in bytecode form. This byte vector only contains the items themselves, the number of items is
* the items themselves, the number of items is store in exportCount * store in exportCount
*/ */
private ByteVector exports; private ByteVector exports;
/** /** number of opens items */
* number of opens items
*/
private int openCount; private int openCount;
/** /**
* The opens items in bytecode form. This byte vector only contains * The opens items in bytecode form. This byte vector only contains the items themselves, the number of items is
* the items themselves, the number of items is store in openCount * store in openCount
*/ */
private ByteVector opens; private ByteVector opens;
/** /** number of uses items */
* number of uses items
*/
private int useCount; private int useCount;
/** /**
* The uses items in bytecode form. This byte vector only contains * The uses items in bytecode form. This byte vector only contains the items themselves, the number of items is
* the items themselves, the number of items is store in useCount * store in useCount
*/ */
private ByteVector uses; private ByteVector uses;
/** /** number of provides items */
* number of provides items
*/
private int provideCount; private int provideCount;
/** /**
* The uses provides in bytecode form. This byte vector only contains * The uses provides in bytecode form. This byte vector only contains the items themselves, the number of items is
* the items themselves, the number of items is store in provideCount * store in provideCount
*/ */
private ByteVector provides; private ByteVector provides;
ModuleWriter(final ClassWriter cw, final int name, ModuleWriter(final ClassWriter cw, final int name, final int access, final int version) {
final int access, final int version) {
super(Opcodes.ASM6); super(Opcodes.ASM6);
this.cw = cw; this.cw = cw;
this.size = 16; // name + access + version + 5 counts this.size = 16; // name + access + version + 5 counts
this.name = name; this.name = name;
this.access = access; this.access = access;
this.version = version; this.version = version;
@@ -209,9 +177,7 @@ final class ModuleWriter extends ModuleVisitor {
if (requires == null) { if (requires == null) {
requires = new ByteVector(); requires = new ByteVector();
} }
requires.putShort(cw.newModule(module)) requires.putShort(cw.newModule(module)).putShort(access).putShort(version == null ? 0 : cw.newUTF8(version));
.putShort(access)
.putShort(version == null? 0: cw.newUTF8(version));
requireCount++; requireCount++;
size += 6; size += 6;
} }
@@ -227,7 +193,7 @@ final class ModuleWriter extends ModuleVisitor {
size += 6; size += 6;
} else { } else {
exports.putShort(modules.length); exports.putShort(modules.length);
for(String module: modules) { for (String module : modules) {
exports.putShort(cw.newModule(module)); exports.putShort(cw.newModule(module));
} }
size += 6 + 2 * modules.length; size += 6 + 2 * modules.length;
@@ -246,7 +212,7 @@ final class ModuleWriter extends ModuleVisitor {
size += 6; size += 6;
} else { } else {
opens.putShort(modules.length); opens.putShort(modules.length);
for(String module: modules) { for (String module : modules) {
opens.putShort(cw.newModule(module)); opens.putShort(cw.newModule(module));
} }
size += 6 + 2 * modules.length; size += 6 + 2 * modules.length;
@@ -271,7 +237,7 @@ final class ModuleWriter extends ModuleVisitor {
} }
provides.putShort(cw.newClass(service)); provides.putShort(cw.newClass(service));
provides.putShort(providers.length); provides.putShort(providers.length);
for(String provider: providers) { for (String provider : providers) {
provides.putShort(cw.newClass(provider)); provides.putShort(cw.newClass(provider));
} }
provideCount++; provideCount++;
@@ -289,9 +255,9 @@ final class ModuleWriter extends ModuleVisitor {
} }
if (packages != null) { if (packages != null) {
out.putShort(cw.newUTF8("ModulePackages")) out.putShort(cw.newUTF8("ModulePackages"))
.putInt(2 + 2 * packageCount) .putInt(2 + 2 * packageCount)
.putShort(packageCount) .putShort(packageCount)
.putByteArray(packages.data, 0, packages.length); .putByteArray(packages.data, 0, packages.length);
} }
} }

View File

@@ -59,13 +59,10 @@
package org.redkale.asm; package org.redkale.asm;
/** /**
* Defines the JVM opcodes, access flags and array type codes. This interface * Defines the JVM opcodes, access flags and array type codes. This interface does not define all the JVM opcodes
* does not define all the JVM opcodes because some opcodes are automatically * because some opcodes are automatically handled. For example, the xLOAD and xSTORE opcodes are automatically replaced
* handled. For example, the xLOAD and xSTORE opcodes are automatically replaced * by xLOAD_n and xSTORE_n opcodes when possible. The xLOAD_n and xSTORE_n opcodes are therefore not defined in this
* by xLOAD_n and xSTORE_n opcodes when possible. The xLOAD_n and xSTORE_n * interface. Likewise for LDC, automatically replaced by LDC_W or LDC2_W when necessary, WIDE, GOTO_W and JSR_W.
* opcodes are therefore not defined in this interface. Likewise for LDC,
* automatically replaced by LDC_W or LDC2_W when necessary, WIDE, GOTO_W and
* JSR_W.
* *
* @author Eric Bruneton * @author Eric Bruneton
* @author Eugene Kuleshov * @author Eugene Kuleshov
@@ -117,7 +114,6 @@ public interface Opcodes {
int ACC_MANDATED = 0x8000; // parameter, module, module * int ACC_MANDATED = 0x8000; // parameter, module, module *
int ACC_MODULE = 0x8000; // class int ACC_MODULE = 0x8000; // class
// ASM specific pseudo access flags // ASM specific pseudo access flags
int ACC_DEPRECATED = 0x20000; // class, field, method int ACC_DEPRECATED = 0x20000; // class, field, method
@@ -147,39 +143,30 @@ public interface Opcodes {
// stack map frame types // stack map frame types
/** /** Represents an expanded frame. See {@link ClassReader#EXPAND_FRAMES}. */
* Represents an expanded frame. See {@link ClassReader#EXPAND_FRAMES}.
*/
int F_NEW = -1; int F_NEW = -1;
/** /** Represents a compressed frame with complete frame data. */
* Represents a compressed frame with complete frame data.
*/
int F_FULL = 0; int F_FULL = 0;
/** /**
* Represents a compressed frame where locals are the same as the locals in * Represents a compressed frame where locals are the same as the locals in the previous frame, except that
* the previous frame, except that additional 1-3 locals are defined, and * additional 1-3 locals are defined, and with an empty stack.
* with an empty stack.
*/ */
int F_APPEND = 1; int F_APPEND = 1;
/** /**
* Represents a compressed frame where locals are the same as the locals in * Represents a compressed frame where locals are the same as the locals in the previous frame, except that the last
* the previous frame, except that the last 1-3 locals are absent and with * 1-3 locals are absent and with an empty stack.
* an empty stack.
*/ */
int F_CHOP = 2; int F_CHOP = 2;
/** /** Represents a compressed frame with exactly the same locals as the previous frame and with an empty stack. */
* Represents a compressed frame with exactly the same locals as the
* previous frame and with an empty stack.
*/
int F_SAME = 3; int F_SAME = 3;
/** /**
* Represents a compressed frame with exactly the same locals as the * Represents a compressed frame with exactly the same locals as the previous frame and with a single value on the
* previous frame and with a single value on the stack. * stack.
*/ */
int F_SAME1 = 4; int F_SAME1 = 4;
@@ -187,13 +174,26 @@ public interface Opcodes {
// these values are compared by reference and not by value // these values are compared by reference and not by value
// The constructor of Integer was deprecated in 9 // The constructor of Integer was deprecated in 9
// but we are stuck with it by backward compatibility // but we are stuck with it by backward compatibility
@SuppressWarnings("deprecation") Integer TOP = new Integer(0); @SuppressWarnings("deprecation")
@SuppressWarnings("deprecation") Integer INTEGER = new Integer(1); Integer TOP = new Integer(0);
@SuppressWarnings("deprecation") Integer FLOAT = new Integer(2);
@SuppressWarnings("deprecation") Integer DOUBLE = new Integer(3); @SuppressWarnings("deprecation")
@SuppressWarnings("deprecation") Integer LONG = new Integer(4); Integer INTEGER = new Integer(1);
@SuppressWarnings("deprecation") Integer NULL = new Integer(5);
@SuppressWarnings("deprecation") Integer UNINITIALIZED_THIS = new Integer(6); @SuppressWarnings("deprecation")
Integer FLOAT = new Integer(2);
@SuppressWarnings("deprecation")
Integer DOUBLE = new Integer(3);
@SuppressWarnings("deprecation")
Integer LONG = new Integer(4);
@SuppressWarnings("deprecation")
Integer NULL = new Integer(5);
@SuppressWarnings("deprecation")
Integer UNINITIALIZED_THIS = new Integer(6);
// opcodes // visit method (- = idem) // opcodes // visit method (- = idem)

View File

@@ -62,154 +62,94 @@ import java.lang.reflect.Constructor;
import java.lang.reflect.Method; import java.lang.reflect.Method;
/** /**
* A Java field or method type. This class can be used to make it easier to * A Java field or method type. This class can be used to make it easier to manipulate type and method descriptors.
* manipulate type and method descriptors.
* *
* @author Eric Bruneton * @author Eric Bruneton
* @author Chris Nokleberg * @author Chris Nokleberg
*/ */
public class Type { public class Type {
/** /** The sort of the &#60;tt&#62;void&#60;/tt&#62; type. See {@link #getSort getSort}. */
* The sort of the &#60;tt&#62;void&#60;/tt&#62; type. See {@link #getSort getSort}.
*/
public static final int VOID = 0; public static final int VOID = 0;
/** /** The sort of the &#60;tt&#62;boolean&#60;/tt&#62; type. See {@link #getSort getSort}. */
* The sort of the &#60;tt&#62;boolean&#60;/tt&#62; type. See {@link #getSort getSort}.
*/
public static final int BOOLEAN = 1; public static final int BOOLEAN = 1;
/** /** The sort of the &#60;tt&#62;char&#60;/tt&#62; type. See {@link #getSort getSort}. */
* The sort of the &#60;tt&#62;char&#60;/tt&#62; type. See {@link #getSort getSort}.
*/
public static final int CHAR = 2; public static final int CHAR = 2;
/** /** The sort of the &#60;tt&#62;byte&#60;/tt&#62; type. See {@link #getSort getSort}. */
* The sort of the &#60;tt&#62;byte&#60;/tt&#62; type. See {@link #getSort getSort}.
*/
public static final int BYTE = 3; public static final int BYTE = 3;
/** /** The sort of the &#60;tt&#62;short&#60;/tt&#62; type. See {@link #getSort getSort}. */
* The sort of the &#60;tt&#62;short&#60;/tt&#62; type. See {@link #getSort getSort}.
*/
public static final int SHORT = 4; public static final int SHORT = 4;
/** /** The sort of the &#60;tt&#62;int&#60;/tt&#62; type. See {@link #getSort getSort}. */
* The sort of the &#60;tt&#62;int&#60;/tt&#62; type. See {@link #getSort getSort}.
*/
public static final int INT = 5; public static final int INT = 5;
/** /** The sort of the &#60;tt&#62;float&#60;/tt&#62; type. See {@link #getSort getSort}. */
* The sort of the &#60;tt&#62;float&#60;/tt&#62; type. See {@link #getSort getSort}.
*/
public static final int FLOAT = 6; public static final int FLOAT = 6;
/** /** The sort of the &#60;tt&#62;long&#60;/tt&#62; type. See {@link #getSort getSort}. */
* The sort of the &#60;tt&#62;long&#60;/tt&#62; type. See {@link #getSort getSort}.
*/
public static final int LONG = 7; public static final int LONG = 7;
/** /** The sort of the &#60;tt&#62;double&#60;/tt&#62; type. See {@link #getSort getSort}. */
* The sort of the &#60;tt&#62;double&#60;/tt&#62; type. See {@link #getSort getSort}.
*/
public static final int DOUBLE = 8; public static final int DOUBLE = 8;
/** /** The sort of array reference types. See {@link #getSort getSort}. */
* The sort of array reference types. See {@link #getSort getSort}.
*/
public static final int ARRAY = 9; public static final int ARRAY = 9;
/** /** The sort of object reference types. See {@link #getSort getSort}. */
* The sort of object reference types. See {@link #getSort getSort}.
*/
public static final int OBJECT = 10; public static final int OBJECT = 10;
/** /** The sort of method types. See {@link #getSort getSort}. */
* The sort of method types. See {@link #getSort getSort}.
*/
public static final int METHOD = 11; public static final int METHOD = 11;
/** /** The &#60;tt&#62;void&#60;/tt&#62; type. */
* The &#60;tt&#62;void&#60;/tt&#62; type. public static final Type VOID_TYPE = new Type(VOID, null, ('V' << 24) | (5 << 16) | (0 << 8) | 0, 1);
*/
public static final Type VOID_TYPE = new Type(VOID, null, ('V' << 24)
| (5 << 16) | (0 << 8) | 0, 1);
/** /** The &#60;tt&#62;boolean&#60;/tt&#62; type. */
* The &#60;tt&#62;boolean&#60;/tt&#62; type. public static final Type BOOLEAN_TYPE = new Type(BOOLEAN, null, ('Z' << 24) | (0 << 16) | (5 << 8) | 1, 1);
*/
public static final Type BOOLEAN_TYPE = new Type(BOOLEAN, null, ('Z' << 24)
| (0 << 16) | (5 << 8) | 1, 1);
/** /** The &#60;tt&#62;char&#60;/tt&#62; type. */
* The &#60;tt&#62;char&#60;/tt&#62; type. public static final Type CHAR_TYPE = new Type(CHAR, null, ('C' << 24) | (0 << 16) | (6 << 8) | 1, 1);
*/
public static final Type CHAR_TYPE = new Type(CHAR, null, ('C' << 24)
| (0 << 16) | (6 << 8) | 1, 1);
/** /** The &#60;tt&#62;byte&#60;/tt&#62; type. */
* The &#60;tt&#62;byte&#60;/tt&#62; type. public static final Type BYTE_TYPE = new Type(BYTE, null, ('B' << 24) | (0 << 16) | (5 << 8) | 1, 1);
*/
public static final Type BYTE_TYPE = new Type(BYTE, null, ('B' << 24)
| (0 << 16) | (5 << 8) | 1, 1);
/** /** The &#60;tt&#62;short&#60;/tt&#62; type. */
* The &#60;tt&#62;short&#60;/tt&#62; type. public static final Type SHORT_TYPE = new Type(SHORT, null, ('S' << 24) | (0 << 16) | (7 << 8) | 1, 1);
*/
public static final Type SHORT_TYPE = new Type(SHORT, null, ('S' << 24)
| (0 << 16) | (7 << 8) | 1, 1);
/** /** The &#60;tt&#62;int&#60;/tt&#62; type. */
* The &#60;tt&#62;int&#60;/tt&#62; type. public static final Type INT_TYPE = new Type(INT, null, ('I' << 24) | (0 << 16) | (0 << 8) | 1, 1);
*/
public static final Type INT_TYPE = new Type(INT, null, ('I' << 24)
| (0 << 16) | (0 << 8) | 1, 1);
/** /** The &#60;tt&#62;float&#60;/tt&#62; type. */
* The &#60;tt&#62;float&#60;/tt&#62; type. public static final Type FLOAT_TYPE = new Type(FLOAT, null, ('F' << 24) | (2 << 16) | (2 << 8) | 1, 1);
*/
public static final Type FLOAT_TYPE = new Type(FLOAT, null, ('F' << 24)
| (2 << 16) | (2 << 8) | 1, 1);
/** /** The &#60;tt&#62;long&#60;/tt&#62; type. */
* The &#60;tt&#62;long&#60;/tt&#62; type. public static final Type LONG_TYPE = new Type(LONG, null, ('J' << 24) | (1 << 16) | (1 << 8) | 2, 1);
*/
public static final Type LONG_TYPE = new Type(LONG, null, ('J' << 24)
| (1 << 16) | (1 << 8) | 2, 1);
/** /** The &#60;tt&#62;double&#60;/tt&#62; type. */
* The &#60;tt&#62;double&#60;/tt&#62; type. public static final Type DOUBLE_TYPE = new Type(DOUBLE, null, ('D' << 24) | (3 << 16) | (3 << 8) | 2, 1);
*/
public static final Type DOUBLE_TYPE = new Type(DOUBLE, null, ('D' << 24)
| (3 << 16) | (3 << 8) | 2, 1);
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
// Fields // Fields
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
/** /** The sort of this Java type. */
* The sort of this Java type.
*/
private final int sort; private final int sort;
/** /** A buffer containing the internal name of this Java type. This field is only used for reference types. */
* A buffer containing the internal name of this Java type. This field is
* only used for reference types.
*/
private final char[] buf; private final char[] buf;
/** /**
* The offset of the internal name of this Java type in {@link #buf buf} or, * The offset of the internal name of this Java type in {@link #buf buf} or, for primitive types, the size,
* for primitive types, the size, descriptor and getOpcode offsets for this * descriptor and getOpcode offsets for this type (byte 0 contains the size, byte 1 the descriptor, byte 2 the
* type (byte 0 contains the size, byte 1 the descriptor, byte 2 the offset * offset for IALOAD or IASTORE, byte 3 the offset for all other instructions).
* for IALOAD or IASTORE, byte 3 the offset for all other instructions).
*/ */
private final int off; private final int off;
/** /** The length of the internal name of this Java type. */
* The length of the internal name of this Java type.
*/
private final int len; private final int len;
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
@@ -219,14 +159,10 @@ public class Type {
/** /**
* Constructs a reference type. * Constructs a reference type.
* *
* @param sort * @param sort the sort of the reference type to be constructed.
* the sort of the reference type to be constructed. * @param buf a buffer containing the descriptor of the previous type.
* @param buf * @param off the offset of this descriptor in the previous buffer.
* a buffer containing the descriptor of the previous type. * @param len the length of this descriptor.
* @param off
* the offset of this descriptor in the previous buffer.
* @param len
* the length of this descriptor.
*/ */
private Type(final int sort, final char[] buf, final int off, final int len) { private Type(final int sort, final char[] buf, final int off, final int len) {
this.sort = sort; this.sort = sort;
@@ -238,8 +174,7 @@ public class Type {
/** /**
* Returns the Java type corresponding to the given type descriptor. * Returns the Java type corresponding to the given type descriptor.
* *
* @param typeDescriptor * @param typeDescriptor a field or method type descriptor.
* a field or method type descriptor.
* @return the Java type corresponding to the given type descriptor. * @return the Java type corresponding to the given type descriptor.
*/ */
public static Type getType(final String typeDescriptor) { public static Type getType(final String typeDescriptor) {
@@ -249,8 +184,7 @@ public class Type {
/** /**
* Returns the Java type corresponding to the given internal name. * Returns the Java type corresponding to the given internal name.
* *
* @param internalName * @param internalName an internal name.
* an internal name.
* @return the Java type corresponding to the given internal name. * @return the Java type corresponding to the given internal name.
*/ */
public static Type getObjectType(final String internalName) { public static Type getObjectType(final String internalName) {
@@ -259,11 +193,10 @@ public class Type {
} }
/** /**
* Returns the Java type corresponding to the given method descriptor. * Returns the Java type corresponding to the given method descriptor. Equivalent to <code>
* Equivalent to <code>Type.getType(methodDescriptor)</code>. * Type.getType(methodDescriptor)</code>.
* *
* @param methodDescriptor * @param methodDescriptor a method descriptor.
* a method descriptor.
* @return the Java type corresponding to the given method descriptor. * @return the Java type corresponding to the given method descriptor.
*/ */
public static Type getMethodType(final String methodDescriptor) { public static Type getMethodType(final String methodDescriptor) {
@@ -271,26 +204,20 @@ public class Type {
} }
/** /**
* Returns the Java method type corresponding to the given argument and * Returns the Java method type corresponding to the given argument and return types.
* return types.
* *
* @param returnType * @param returnType the return type of the method.
* the return type of the method. * @param argumentTypes the argument types of the method.
* @param argumentTypes * @return the Java type corresponding to the given argument and return types.
* the argument types of the method.
* @return the Java type corresponding to the given argument and return
* types.
*/ */
public static Type getMethodType(final Type returnType, public static Type getMethodType(final Type returnType, final Type... argumentTypes) {
final Type... argumentTypes) {
return getType(getMethodDescriptor(returnType, argumentTypes)); return getType(getMethodDescriptor(returnType, argumentTypes));
} }
/** /**
* Returns the Java type corresponding to the given class. * Returns the Java type corresponding to the given class.
* *
* @param c * @param c a class.
* a class.
* @return the Java type corresponding to the given class. * @return the Java type corresponding to the given class.
*/ */
public static Type getType(final Class<?> c) { public static Type getType(final Class<?> c) {
@@ -311,7 +238,7 @@ public class Type {
return DOUBLE_TYPE; return DOUBLE_TYPE;
} else if (c == Float.TYPE) { } else if (c == Float.TYPE) {
return FLOAT_TYPE; return FLOAT_TYPE;
} else /* if (c == Long.TYPE) */{ } else /* if (c == Long.TYPE) */ {
return LONG_TYPE; return LONG_TYPE;
} }
} else { } else {
@@ -322,8 +249,7 @@ public class Type {
/** /**
* Returns the Java method type corresponding to the given constructor. * Returns the Java method type corresponding to the given constructor.
* *
* @param c * @param c a {@link Constructor Constructor} object.
* a {@link Constructor Constructor} object.
* @return the Java method type corresponding to the given constructor. * @return the Java method type corresponding to the given constructor.
*/ */
public static Type getType(final Constructor<?> c) { public static Type getType(final Constructor<?> c) {
@@ -333,8 +259,7 @@ public class Type {
/** /**
* Returns the Java method type corresponding to the given method. * Returns the Java method type corresponding to the given method.
* *
* @param m * @param m a {@link Method Method} object.
* a {@link Method Method} object.
* @return the Java method type corresponding to the given method. * @return the Java method type corresponding to the given method.
*/ */
public static Type getType(final Method m) { public static Type getType(final Method m) {
@@ -342,13 +267,10 @@ public class Type {
} }
/** /**
* Returns the Java types corresponding to the argument types of the given * Returns the Java types corresponding to the argument types of the given method descriptor.
* method descriptor.
* *
* @param methodDescriptor * @param methodDescriptor a method descriptor.
* a method descriptor. * @return the Java types corresponding to the argument types of the given method descriptor.
* @return the Java types corresponding to the argument types of the given
* method descriptor.
*/ */
public static Type[] getArgumentTypes(final String methodDescriptor) { public static Type[] getArgumentTypes(final String methodDescriptor) {
char[] buf = methodDescriptor.toCharArray(); char[] buf = methodDescriptor.toCharArray();
@@ -360,7 +282,7 @@ public class Type {
break; break;
} else if (car == 'L') { } else if (car == 'L') {
while (buf[off++] != ';') { while (buf[off++] != ';') {
//do nothing // do nothing
} }
++size; ++size;
} else if (car != '[') { } else if (car != '[') {
@@ -379,13 +301,10 @@ public class Type {
} }
/** /**
* Returns the Java types corresponding to the argument types of the given * Returns the Java types corresponding to the argument types of the given method.
* method.
* *
* @param method * @param method a method.
* a method. * @return the Java types corresponding to the argument types of the given method.
* @return the Java types corresponding to the argument types of the given
* method.
*/ */
public static Type[] getArgumentTypes(final Method method) { public static Type[] getArgumentTypes(final Method method) {
Class<?>[] classes = method.getParameterTypes(); Class<?>[] classes = method.getParameterTypes();
@@ -397,13 +316,10 @@ public class Type {
} }
/** /**
* Returns the Java type corresponding to the return type of the given * Returns the Java type corresponding to the return type of the given method descriptor.
* method descriptor.
* *
* @param methodDescriptor * @param methodDescriptor a method descriptor.
* a method descriptor. * @return the Java type corresponding to the return type of the given method descriptor.
* @return the Java type corresponding to the return type of the given
* method descriptor.
*/ */
public static Type getReturnType(final String methodDescriptor) { public static Type getReturnType(final String methodDescriptor) {
char[] buf = methodDescriptor.toCharArray(); char[] buf = methodDescriptor.toCharArray();
@@ -414,20 +330,17 @@ public class Type {
return getType(buf, off); return getType(buf, off);
} else if (car == 'L') { } else if (car == 'L') {
while (buf[off++] != ';') { while (buf[off++] != ';') {
//do nothing // do nothing
} }
} }
} }
} }
/** /**
* Returns the Java type corresponding to the return type of the given * Returns the Java type corresponding to the return type of the given method.
* method.
* *
* @param method * @param method a method.
* a method. * @return the Java type corresponding to the return type of the given method.
* @return the Java type corresponding to the return type of the given
* method.
*/ */
public static Type getReturnType(final Method method) { public static Type getReturnType(final Method method) {
return getType(method.getReturnType()); return getType(method.getReturnType());
@@ -436,13 +349,11 @@ public class Type {
/** /**
* Computes the size of the arguments and of the return value of a method. * Computes the size of the arguments and of the return value of a method.
* *
* @param desc * @param desc the descriptor of a method.
* the descriptor of a method. * @return the size of the arguments of the method (plus one for the implicit this argument), argSize, and the size
* @return the size of the arguments of the method (plus one for the * of its return value, retSize, packed into a single int i = &#60;tt&#62;(argSize &lt;&lt; 2) |
* implicit this argument), argSize, and the size of its return * retSize&#60;/tt&#62; (argSize is therefore equal to &#60;tt&#62;i &gt;&gt; 2&#60;/tt&#62;, and retSize to
* value, retSize, packed into a single int i = * &#60;tt&#62;i &amp; 0x03&#60;/tt&#62;).
* &#60;tt&#62;(argSize &lt;&lt; 2) | retSize&#60;/tt&#62; (argSize is therefore equal to
* &#60;tt&#62;i &gt;&gt; 2&#60;/tt&#62;, and retSize to &#60;tt&#62;i &amp; 0x03&#60;/tt&#62;).
*/ */
public static int getArgumentsAndReturnSizes(final String desc) { public static int getArgumentsAndReturnSizes(final String desc) {
int n = 1; int n = 1;
@@ -451,11 +362,10 @@ public class Type {
char car = desc.charAt(c++); char car = desc.charAt(c++);
if (car == ')') { if (car == ')') {
car = desc.charAt(c); car = desc.charAt(c);
return n << 2 return n << 2 | (car == 'V' ? 0 : (car == 'D' || car == 'J' ? 2 : 1));
| (car == 'V' ? 0 : (car == 'D' || car == 'J' ? 2 : 1));
} else if (car == 'L') { } else if (car == 'L') {
while (desc.charAt(c++) != ';') { while (desc.charAt(c++) != ';') {
//do nothing // do nothing
} }
n += 1; n += 1;
} else if (car == '[') { } else if (car == '[') {
@@ -474,58 +384,55 @@ public class Type {
} }
/** /**
* Returns the Java type corresponding to the given type descriptor. For * Returns the Java type corresponding to the given type descriptor. For method descriptors, buf is supposed to
* method descriptors, buf is supposed to contain nothing more than the * contain nothing more than the descriptor itself.
* descriptor itself.
* *
* @param buf * @param buf a buffer containing a type descriptor.
* a buffer containing a type descriptor. * @param off the offset of this descriptor in the previous buffer.
* @param off
* the offset of this descriptor in the previous buffer.
* @return the Java type corresponding to the given type descriptor. * @return the Java type corresponding to the given type descriptor.
*/ */
private static Type getType(final char[] buf, final int off) { private static Type getType(final char[] buf, final int off) {
int len; int len;
switch (buf[off]) { switch (buf[off]) {
case 'V': case 'V':
return VOID_TYPE; return VOID_TYPE;
case 'Z': case 'Z':
return BOOLEAN_TYPE; return BOOLEAN_TYPE;
case 'C': case 'C':
return CHAR_TYPE; return CHAR_TYPE;
case 'B': case 'B':
return BYTE_TYPE; return BYTE_TYPE;
case 'S': case 'S':
return SHORT_TYPE; return SHORT_TYPE;
case 'I': case 'I':
return INT_TYPE; return INT_TYPE;
case 'F': case 'F':
return FLOAT_TYPE; return FLOAT_TYPE;
case 'J': case 'J':
return LONG_TYPE; return LONG_TYPE;
case 'D': case 'D':
return DOUBLE_TYPE; return DOUBLE_TYPE;
case '[': case '[':
len = 1; len = 1;
while (buf[off + len] == '[') { while (buf[off + len] == '[') {
++len; ++len;
} }
if (buf[off + len] == 'L') { if (buf[off + len] == 'L') {
++len; ++len;
while (buf[off + len] != ';') {
++len;
}
}
return new Type(ARRAY, buf, off, len + 1);
case 'L':
len = 1;
while (buf[off + len] != ';') { while (buf[off + len] != ';') {
++len; ++len;
} }
} return new Type(OBJECT, buf, off + 1, len - 1);
return new Type(ARRAY, buf, off, len + 1); // case '(':
case 'L': default:
len = 1; return new Type(METHOD, buf, off, buf.length - off);
while (buf[off + len] != ';') {
++len;
}
return new Type(OBJECT, buf, off + 1, len - 1);
// case '(':
default:
return new Type(METHOD, buf, off, buf.length - off);
} }
} }
@@ -536,19 +443,16 @@ public class Type {
/** /**
* Returns the sort of this Java type. * Returns the sort of this Java type.
* *
* @return {@link #VOID VOID}, {@link #BOOLEAN BOOLEAN}, {@link #CHAR CHAR}, * @return {@link #VOID VOID}, {@link #BOOLEAN BOOLEAN}, {@link #CHAR CHAR}, {@link #BYTE BYTE}, {@link #SHORT
* {@link #BYTE BYTE}, {@link #SHORT SHORT}, {@link #INT INT}, * SHORT}, {@link #INT INT}, {@link #FLOAT FLOAT}, {@link #LONG LONG}, {@link #DOUBLE DOUBLE}, {@link #ARRAY
* {@link #FLOAT FLOAT}, {@link #LONG LONG}, {@link #DOUBLE DOUBLE}, * ARRAY}, {@link #OBJECT OBJECT} or {@link #METHOD METHOD}.
* {@link #ARRAY ARRAY}, {@link #OBJECT OBJECT} or {@link #METHOD
* METHOD}.
*/ */
public int getSort() { public int getSort() {
return sort; return sort;
} }
/** /**
* Returns the number of dimensions of this array type. This method should * Returns the number of dimensions of this array type. This method should only be used for an array type.
* only be used for an array type.
* *
* @return the number of dimensions of this array type. * @return the number of dimensions of this array type.
*/ */
@@ -561,8 +465,7 @@ public class Type {
} }
/** /**
* Returns the type of the elements of this array type. This method should * Returns the type of the elements of this array type. This method should only be used for an array type.
* only be used for an array type.
* *
* @return Returns the type of the elements of this array type. * @return Returns the type of the elements of this array type.
*/ */
@@ -571,49 +474,47 @@ public class Type {
} }
/** /**
* Returns the binary name of the class corresponding to this type. This * Returns the binary name of the class corresponding to this type. This method must not be used on method types.
* method must not be used on method types.
* *
* @return the binary name of the class corresponding to this type. * @return the binary name of the class corresponding to this type.
*/ */
public String getClassName() { public String getClassName() {
switch (sort) { switch (sort) {
case VOID: case VOID:
return "void"; return "void";
case BOOLEAN: case BOOLEAN:
return "boolean"; return "boolean";
case CHAR: case CHAR:
return "char"; return "char";
case BYTE: case BYTE:
return "byte"; return "byte";
case SHORT: case SHORT:
return "short"; return "short";
case INT: case INT:
return "int"; return "int";
case FLOAT: case FLOAT:
return "float"; return "float";
case LONG: case LONG:
return "long"; return "long";
case DOUBLE: case DOUBLE:
return "double"; return "double";
case ARRAY: case ARRAY:
StringBuilder sb = new StringBuilder(getElementType().getClassName()); StringBuilder sb = new StringBuilder(getElementType().getClassName());
for (int i = getDimensions(); i > 0; --i) { for (int i = getDimensions(); i > 0; --i) {
sb.append("[]"); sb.append("[]");
} }
return sb.toString(); return sb.toString();
case OBJECT: case OBJECT:
return new String(buf, off, len).replace('/', '.'); return new String(buf, off, len).replace('/', '.');
default: default:
return null; return null;
} }
} }
/** /**
* Returns the internal name of the class corresponding to this object or * Returns the internal name of the class corresponding to this object or array type. The internal name of a class
* array type. The internal name of a class is its fully qualified name (as * is its fully qualified name (as returned by Class.getName(), where '.' are replaced by '/'. This method should
* returned by Class.getName(), where '.' are replaced by '/'. This method * only be used for an object or array type.
* should only be used for an object or array type.
* *
* @return the internal name of the class corresponding to this object type. * @return the internal name of the class corresponding to this object type.
*/ */
@@ -622,8 +523,7 @@ public class Type {
} }
/** /**
* Returns the argument types of methods of this type. This method should * Returns the argument types of methods of this type. This method should only be used for method types.
* only be used for method types.
* *
* @return the argument types of methods of this type. * @return the argument types of methods of this type.
*/ */
@@ -632,8 +532,7 @@ public class Type {
} }
/** /**
* Returns the return type of methods of this type. This method should only * Returns the return type of methods of this type. This method should only be used for method types.
* be used for method types.
* *
* @return the return type of methods of this type. * @return the return type of methods of this type.
*/ */
@@ -642,15 +541,13 @@ public class Type {
} }
/** /**
* Returns the size of the arguments and of the return value of methods of * Returns the size of the arguments and of the return value of methods of this type. This method should only be
* this type. This method should only be used for method types. * used for method types.
* *
* @return the size of the arguments (plus one for the implicit this * @return the size of the arguments (plus one for the implicit this argument), argSize, and the size of the return
* argument), argSize, and the size of the return value, retSize, * value, retSize, packed into a single int i = &#60;tt&#62;(argSize &lt;&lt; 2) | retSize&#60;/tt&#62; (argSize
* packed into a single * is therefore equal to &#60;tt&#62;i &gt;&gt; 2&#60;/tt&#62;, and retSize to &#60;tt&#62;i &amp;
* int i = &#60;tt&#62;(argSize &lt;&lt; 2) | retSize&#60;/tt&#62; * 0x03&#60;/tt&#62;).
* (argSize is therefore equal to &#60;tt&#62;i &gt;&gt; 2&#60;/tt&#62;,
* and retSize to &#60;tt&#62;i &amp; 0x03&#60;/tt&#62;).
*/ */
public int getArgumentsAndReturnSizes() { public int getArgumentsAndReturnSizes() {
return getArgumentsAndReturnSizes(getDescriptor()); return getArgumentsAndReturnSizes(getDescriptor());
@@ -672,18 +569,13 @@ public class Type {
} }
/** /**
* Returns the descriptor corresponding to the given argument and return * Returns the descriptor corresponding to the given argument and return types.
* types.
* *
* @param returnType * @param returnType the return type of the method.
* the return type of the method. * @param argumentTypes the argument types of the method.
* @param argumentTypes * @return the descriptor corresponding to the given argument and return types.
* the argument types of the method.
* @return the descriptor corresponding to the given argument and return
* types.
*/ */
public static String getMethodDescriptor(final Type returnType, public static String getMethodDescriptor(final Type returnType, final Type... argumentTypes) {
final Type... argumentTypes) {
StringBuilder buf = new StringBuilder(); StringBuilder buf = new StringBuilder();
buf.append('('); buf.append('(');
for (int i = 0; i < argumentTypes.length; ++i) { for (int i = 0; i < argumentTypes.length; ++i) {
@@ -695,11 +587,9 @@ public class Type {
} }
/** /**
* Appends the descriptor corresponding to this Java type to the given * Appends the descriptor corresponding to this Java type to the given string buffer.
* string buffer.
* *
* @param buf * @param buf the string buffer to which the descriptor must be appended.
* the string buffer to which the descriptor must be appended.
*/ */
private void getDescriptor(final StringBuilder buf) { private void getDescriptor(final StringBuilder buf) {
if (this.buf == null) { if (this.buf == null) {
@@ -721,12 +611,10 @@ public class Type {
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
/** /**
* Returns the internal name of the given class. The internal name of a * Returns the internal name of the given class. The internal name of a class is its fully qualified name, as
* class is its fully qualified name, as returned by Class.getName(), where * returned by Class.getName(), where '.' are replaced by '/'.
* '.' are replaced by '/'.
* *
* @param c * @param c an object or array class.
* an object or array class.
* @return the internal name of the given class. * @return the internal name of the given class.
*/ */
public static String getInternalName(final Class<?> c) { public static String getInternalName(final Class<?> c) {
@@ -736,8 +624,7 @@ public class Type {
/** /**
* Returns the descriptor corresponding to the given Java type. * Returns the descriptor corresponding to the given Java type.
* *
* @param c * @param c an object class, a primitive class or an array class.
* an object class, a primitive class or an array class.
* @return the descriptor corresponding to the given class. * @return the descriptor corresponding to the given class.
*/ */
public static String getDescriptor(final Class<?> c) { public static String getDescriptor(final Class<?> c) {
@@ -749,8 +636,7 @@ public class Type {
/** /**
* Returns the descriptor corresponding to the given constructor. * Returns the descriptor corresponding to the given constructor.
* *
* @param c * @param c a {@link Constructor Constructor} object.
* a {@link Constructor Constructor} object.
* @return the descriptor of the given constructor. * @return the descriptor of the given constructor.
*/ */
public static String getConstructorDescriptor(final Constructor<?> c) { public static String getConstructorDescriptor(final Constructor<?> c) {
@@ -766,8 +652,7 @@ public class Type {
/** /**
* Returns the descriptor corresponding to the given method. * Returns the descriptor corresponding to the given method.
* *
* @param m * @param m a {@link Method Method} object.
* a {@link Method Method} object.
* @return the descriptor of the given method. * @return the descriptor of the given method.
*/ */
public static String getMethodDescriptor(final Method m) { public static String getMethodDescriptor(final Method m) {
@@ -785,10 +670,8 @@ public class Type {
/** /**
* Appends the descriptor of the given class to the given string buffer. * Appends the descriptor of the given class to the given string buffer.
* *
* @param buf * @param buf the string buffer to which the descriptor must be appended.
* the string buffer to which the descriptor must be appended. * @param c the class whose descriptor must be computed.
* @param c
* the class whose descriptor must be computed.
*/ */
private static void getDescriptor(final StringBuilder buf, final Class<?> c) { private static void getDescriptor(final StringBuilder buf, final Class<?> c) {
Class<?> d = c; Class<?> d = c;
@@ -811,7 +694,7 @@ public class Type {
car = 'D'; car = 'D';
} else if (d == Float.TYPE) { } else if (d == Float.TYPE) {
car = 'F'; car = 'F';
} else /* if (d == Long.TYPE) */{ } else /* if (d == Long.TYPE) */ {
car = 'J'; car = 'J';
} }
buf.append(car); buf.append(car);
@@ -838,11 +721,10 @@ public class Type {
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
/** /**
* Returns the size of values of this type. This method must not be used for * Returns the size of values of this type. This method must not be used for method types.
* method types.
* *
* @return the size of values of this type, i.e., 2 for &#60;tt&#62;long&#60;/tt&#62; and * @return the size of values of this type, i.e., 2 for &#60;tt&#62;long&#60;/tt&#62; and
* &#60;tt&#62;double&#60;/tt&#62;, 0 for &#60;tt&#62;void&#60;/tt&#62; and 1 otherwise. * &#60;tt&#62;double&#60;/tt&#62;, 0 for &#60;tt&#62;void&#60;/tt&#62; and 1 otherwise.
*/ */
public int getSize() { public int getSize() {
// the size is in byte 0 of 'off' for primitive types (buf == null) // the size is in byte 0 of 'off' for primitive types (buf == null)
@@ -850,16 +732,13 @@ public class Type {
} }
/** /**
* Returns a JVM instruction opcode adapted to this Java type. This method * Returns a JVM instruction opcode adapted to this Java type. This method must not be used for method types.
* must not be used for method types.
* *
* @param opcode * @param opcode a JVM instruction opcode. This opcode must be one of ILOAD, ISTORE, IALOAD, IASTORE, IADD, ISUB,
* a JVM instruction opcode. This opcode must be one of ILOAD, * IMUL, IDIV, IREM, INEG, ISHL, ISHR, IUSHR, IAND, IOR, IXOR and IRETURN.
* ISTORE, IALOAD, IASTORE, IADD, ISUB, IMUL, IDIV, IREM, INEG, * @return an opcode that is similar to the given opcode, but adapted to this Java type. For example, if this type
* ISHL, ISHR, IUSHR, IAND, IOR, IXOR and IRETURN. * is &#60;tt&#62;float&#60;/tt&#62; and &#60;tt&#62;opcode&#60;/tt&#62; is IRETURN, this method returns
* @return an opcode that is similar to the given opcode, but adapted to * FRETURN.
* this Java type. For example, if this type is &#60;tt&#62;float&#60;/tt&#62; and
* &#60;tt&#62;opcode&#60;/tt&#62; is IRETURN, this method returns FRETURN.
*/ */
public int getOpcode(final int opcode) { public int getOpcode(final int opcode) {
if (opcode == Opcodes.IALOAD || opcode == Opcodes.IASTORE) { if (opcode == Opcodes.IALOAD || opcode == Opcodes.IASTORE) {
@@ -880,8 +759,7 @@ public class Type {
/** /**
* Tests if the given object is equal to this type. * Tests if the given object is equal to this type.
* *
* @param o * @param o the object to be compared to this type.
* the object to be compared to this type.
* @return &#60;tt&#62;true&#60;/tt&#62; if the given object is equal to this type. * @return &#60;tt&#62;true&#60;/tt&#62; if the given object is equal to this type.
*/ */
@Override @Override

View File

@@ -60,55 +60,35 @@
package org.redkale.asm; package org.redkale.asm;
/** /**
* The path to a type argument, wildcard bound, array element type, or static * The path to a type argument, wildcard bound, array element type, or static inner type within an enclosing type.
* inner type within an enclosing type.
* *
* @author Eric Bruneton * @author Eric Bruneton
*/ */
public class TypePath { public class TypePath {
/** /** A type path step that steps into the element type of an array type. See {@link #getStep getStep}. */
* A type path step that steps into the element type of an array type. See public static final int ARRAY_ELEMENT = 0;
* {@link #getStep getStep}.
*/
public final static int ARRAY_ELEMENT = 0;
/** /** A type path step that steps into the nested type of a class type. See {@link #getStep getStep}. */
* A type path step that steps into the nested type of a class type. See public static final int INNER_TYPE = 1;
* {@link #getStep getStep}.
*/
public final static int INNER_TYPE = 1;
/** /** A type path step that steps into the bound of a wildcard type. See {@link #getStep getStep}. */
* A type path step that steps into the bound of a wildcard type. See public static final int WILDCARD_BOUND = 2;
* {@link #getStep getStep}.
*/
public final static int WILDCARD_BOUND = 2;
/** /** A type path step that steps into a type argument of a generic type. See {@link #getStep getStep}. */
* A type path step that steps into a type argument of a generic type. See public static final int TYPE_ARGUMENT = 3;
* {@link #getStep getStep}.
*/
public final static int TYPE_ARGUMENT = 3;
/** /** The byte array where the path is stored, in Java class file format. */
* The byte array where the path is stored, in Java class file format.
*/
byte[] b; byte[] b;
/** /** The offset of the first byte of the type path in 'b'. */
* The offset of the first byte of the type path in 'b'.
*/
int offset; int offset;
/** /**
* Creates a new type path. * Creates a new type path.
* *
* @param b * @param b the byte array containing the type path in Java class file format.
* the byte array containing the type path in Java class file * @param offset the offset of the first byte of the type path in 'b'.
* format.
* @param offset
* the offset of the first byte of the type path in 'b'.
*/ */
TypePath(byte[] b, int offset) { TypePath(byte[] b, int offset) {
this.b = b; this.b = b;
@@ -127,37 +107,29 @@ public class TypePath {
/** /**
* Returns the value of the given step of this path. * Returns the value of the given step of this path.
* *
* @param index * @param index an index between 0 and {@link #getLength()}, exclusive.
* an index between 0 and {@link #getLength()}, exclusive. * @return {@link #ARRAY_ELEMENT ARRAY_ELEMENT}, {@link #INNER_TYPE INNER_TYPE}, {@link #WILDCARD_BOUND
* @return {@link #ARRAY_ELEMENT ARRAY_ELEMENT}, {@link #INNER_TYPE * WILDCARD_BOUND}, or {@link #TYPE_ARGUMENT TYPE_ARGUMENT}.
* INNER_TYPE}, {@link #WILDCARD_BOUND WILDCARD_BOUND}, or
* {@link #TYPE_ARGUMENT TYPE_ARGUMENT}.
*/ */
public int getStep(int index) { public int getStep(int index) {
return b[offset + 2 * index + 1]; return b[offset + 2 * index + 1];
} }
/** /**
* Returns the index of the type argument that the given step is stepping * Returns the index of the type argument that the given step is stepping into. This method should only be used for
* into. This method should only be used for steps whose value is * steps whose value is {@link #TYPE_ARGUMENT TYPE_ARGUMENT}.
* {@link #TYPE_ARGUMENT TYPE_ARGUMENT}.
* *
* @param index * @param index an index between 0 and {@link #getLength()}, exclusive.
* an index between 0 and {@link #getLength()}, exclusive. * @return the index of the type argument that the given step is stepping into.
* @return the index of the type argument that the given step is stepping
* into.
*/ */
public int getStepArgument(int index) { public int getStepArgument(int index) {
return b[offset + 2 * index + 2]; return b[offset + 2 * index + 2];
} }
/** /**
* Converts a type path in string form, in the format used by * Converts a type path in string form, in the format used by {@link #toString()}, into a TypePath object.
* {@link #toString()}, into a TypePath object.
* *
* @param typePath * @param typePath a type path in string form, in the format used by {@link #toString()}. May be null or empty.
* a type path in string form, in the format used by
* {@link #toString()}. May be null or empty.
* @return the corresponding TypePath object, or null if the path is empty. * @return the corresponding TypePath object, or null if the path is empty.
*/ */
public static TypePath fromString(final String typePath) { public static TypePath fromString(final String typePath) {
@@ -167,7 +139,7 @@ public class TypePath {
int n = typePath.length(); int n = typePath.length();
ByteVector out = new ByteVector(n); ByteVector out = new ByteVector(n);
out.putByte(0); out.putByte(0);
for (int i = 0; i < n;) { for (int i = 0; i < n; ) {
char c = typePath.charAt(i++); char c = typePath.charAt(i++);
if (c == '[') { if (c == '[') {
out.put11(ARRAY_ELEMENT, 0); out.put11(ARRAY_ELEMENT, 0);
@@ -192,11 +164,9 @@ public class TypePath {
} }
/** /**
* Returns a string representation of this type path. {@link #ARRAY_ELEMENT * Returns a string representation of this type path. {@link #ARRAY_ELEMENT ARRAY_ELEMENT} steps are represented
* ARRAY_ELEMENT} steps are represented with '[', {@link #INNER_TYPE * with '[', {@link #INNER_TYPE INNER_TYPE} steps with '.', {@link #WILDCARD_BOUND WILDCARD_BOUND} steps with '*'
* INNER_TYPE} steps with '.', {@link #WILDCARD_BOUND WILDCARD_BOUND} steps * and {@link #TYPE_ARGUMENT TYPE_ARGUMENT} steps with their type argument index in decimal form followed by ';'.
* with '*' and {@link #TYPE_ARGUMENT TYPE_ARGUMENT} steps with their type
* argument index in decimal form followed by ';'.
*/ */
@Override @Override
public String toString() { public String toString() {
@@ -204,20 +174,20 @@ public class TypePath {
StringBuilder result = new StringBuilder(length * 2); StringBuilder result = new StringBuilder(length * 2);
for (int i = 0; i < length; ++i) { for (int i = 0; i < length; ++i) {
switch (getStep(i)) { switch (getStep(i)) {
case ARRAY_ELEMENT: case ARRAY_ELEMENT:
result.append('['); result.append('[');
break; break;
case INNER_TYPE: case INNER_TYPE:
result.append('.'); result.append('.');
break; break;
case WILDCARD_BOUND: case WILDCARD_BOUND:
result.append('*'); result.append('*');
break; break;
case TYPE_ARGUMENT: case TYPE_ARGUMENT:
result.append(getStepArgument(i)).append(';'); result.append(getStepArgument(i)).append(';');
break; break;
default: default:
result.append('_'); result.append('_');
} }
} }
return result.toString(); return result.toString();

View File

@@ -60,160 +60,136 @@
package org.redkale.asm; package org.redkale.asm;
/** /**
* A reference to a type appearing in a class, field or method declaration, or * A reference to a type appearing in a class, field or method declaration, or on an instruction. Such a reference
* on an instruction. Such a reference designates the part of the class where * designates the part of the class where the referenced type is appearing (e.g. an 'extends', 'implements' or 'throws'
* the referenced type is appearing (e.g. an 'extends', 'implements' or 'throws' * clause, a 'new' instruction, a 'catch' clause, a type cast, a local variable declaration, etc).
* clause, a 'new' instruction, a 'catch' clause, a type cast, a local variable
* declaration, etc).
* *
* @author Eric Bruneton * @author Eric Bruneton
*/ */
public class TypeReference { public class TypeReference {
/** /** The sort of type references that target a type parameter of a generic class. See {@link #getSort getSort}. */
* The sort of type references that target a type parameter of a generic public static final int CLASS_TYPE_PARAMETER = 0x00;
* class. See {@link #getSort getSort}.
*/ /** The sort of type references that target a type parameter of a generic method. See {@link #getSort getSort}. */
public final static int CLASS_TYPE_PARAMETER = 0x00; public static final int METHOD_TYPE_PARAMETER = 0x01;
/** /**
* The sort of type references that target a type parameter of a generic * The sort of type references that target the super class of a class or one of the interfaces it implements. See
* method. See {@link #getSort getSort}.
*/
public final static int METHOD_TYPE_PARAMETER = 0x01;
/**
* The sort of type references that target the super class of a class or one
* of the interfaces it implements. See {@link #getSort getSort}.
*/
public final static int CLASS_EXTENDS = 0x10;
/**
* The sort of type references that target a bound of a type parameter of a
* generic class. See {@link #getSort getSort}.
*/
public final static int CLASS_TYPE_PARAMETER_BOUND = 0x11;
/**
* The sort of type references that target a bound of a type parameter of a
* generic method. See {@link #getSort getSort}.
*/
public final static int METHOD_TYPE_PARAMETER_BOUND = 0x12;
/**
* The sort of type references that target the type of a field. See
* {@link #getSort getSort}. * {@link #getSort getSort}.
*/ */
public final static int FIELD = 0x13; public static final int CLASS_EXTENDS = 0x10;
/** /**
* The sort of type references that target the return type of a method. See * The sort of type references that target a bound of a type parameter of a generic class. See {@link #getSort
* getSort}.
*/
public static final int CLASS_TYPE_PARAMETER_BOUND = 0x11;
/**
* The sort of type references that target a bound of a type parameter of a generic method. See {@link #getSort
* getSort}.
*/
public static final int METHOD_TYPE_PARAMETER_BOUND = 0x12;
/** The sort of type references that target the type of a field. See {@link #getSort getSort}. */
public static final int FIELD = 0x13;
/** The sort of type references that target the return type of a method. See {@link #getSort getSort}. */
public static final int METHOD_RETURN = 0x14;
/** The sort of type references that target the receiver type of a method. See {@link #getSort getSort}. */
public static final int METHOD_RECEIVER = 0x15;
/**
* The sort of type references that target the type of a formal parameter of a method. See {@link #getSort getSort}.
*/
public static final int METHOD_FORMAL_PARAMETER = 0x16;
/**
* The sort of type references that target the type of an exception declared in the throws clause of a method. See
* {@link #getSort getSort}. * {@link #getSort getSort}.
*/ */
public final static int METHOD_RETURN = 0x14; public static final int THROWS = 0x17;
/** /**
* The sort of type references that target the receiver type of a method. * The sort of type references that target the type of a local variable in a method. See {@link #getSort getSort}.
* See {@link #getSort getSort}.
*/ */
public final static int METHOD_RECEIVER = 0x15; public static final int LOCAL_VARIABLE = 0x40;
/** /**
* The sort of type references that target the type of a formal parameter of * The sort of type references that target the type of a resource variable in a method. See {@link #getSort
* a method. See {@link #getSort getSort}. * getSort}.
*/ */
public final static int METHOD_FORMAL_PARAMETER = 0x16; public static final int RESOURCE_VARIABLE = 0x41;
/** /**
* The sort of type references that target the type of an exception declared * The sort of type references that target the type of the exception of a 'catch' clause in a method. See
* in the throws clause of a method. See {@link #getSort getSort}. * {@link #getSort getSort}.
*/ */
public final static int THROWS = 0x17; public static final int EXCEPTION_PARAMETER = 0x42;
/** /**
* The sort of type references that target the type of a local variable in a * The sort of type references that target the type declared in an 'instanceof' instruction. See {@link #getSort
* method. See {@link #getSort getSort}. * getSort}.
*/ */
public final static int LOCAL_VARIABLE = 0x40; public static final int INSTANCEOF = 0x43;
/** /**
* The sort of type references that target the type of a resource variable * The sort of type references that target the type of the object created by a 'new' instruction. See
* in a method. See {@link #getSort getSort}. * {@link #getSort getSort}.
*/ */
public final static int RESOURCE_VARIABLE = 0x41; public static final int NEW = 0x44;
/** /**
* The sort of type references that target the type of the exception of a * The sort of type references that target the receiver type of a constructor reference. See {@link #getSort
* 'catch' clause in a method. See {@link #getSort getSort}. * getSort}.
*/ */
public final static int EXCEPTION_PARAMETER = 0x42; public static final int CONSTRUCTOR_REFERENCE = 0x45;
/** /**
* The sort of type references that target the type declared in an * The sort of type references that target the receiver type of a method reference. See {@link #getSort getSort}.
* 'instanceof' instruction. See {@link #getSort getSort}.
*/ */
public final static int INSTANCEOF = 0x43; public static final int METHOD_REFERENCE = 0x46;
/** /**
* The sort of type references that target the type of the object created by * The sort of type references that target the type declared in an explicit or implicit cast instruction. See
* a 'new' instruction. See {@link #getSort getSort}. * {@link #getSort getSort}.
*/ */
public final static int NEW = 0x44; public static final int CAST = 0x47;
/** /**
* The sort of type references that target the receiver type of a * The sort of type references that target a type parameter of a generic constructor in a constructor call. See
* constructor reference. See {@link #getSort getSort}. * {@link #getSort getSort}.
*/ */
public final static int CONSTRUCTOR_REFERENCE = 0x45; public static final int CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT = 0x48;
/** /**
* The sort of type references that target the receiver type of a method * The sort of type references that target a type parameter of a generic method in a method call. See
* reference. See {@link #getSort getSort}. * {@link #getSort getSort}.
*/ */
public final static int METHOD_REFERENCE = 0x46; public static final int METHOD_INVOCATION_TYPE_ARGUMENT = 0x49;
/** /**
* The sort of type references that target the type declared in an explicit * The sort of type references that target a type parameter of a generic constructor in a constructor reference. See
* or implicit cast instruction. See {@link #getSort getSort}. * {@link #getSort getSort}.
*/ */
public final static int CAST = 0x47; public static final int CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT = 0x4A;
/** /**
* The sort of type references that target a type parameter of a generic * The sort of type references that target a type parameter of a generic method in a method reference. See
* constructor in a constructor call. See {@link #getSort getSort}. * {@link #getSort getSort}.
*/ */
public final static int CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT = 0x48; public static final int METHOD_REFERENCE_TYPE_ARGUMENT = 0x4B;
/** /** The type reference value in Java class file format. */
* The sort of type references that target a type parameter of a generic
* method in a method call. See {@link #getSort getSort}.
*/
public final static int METHOD_INVOCATION_TYPE_ARGUMENT = 0x49;
/**
* The sort of type references that target a type parameter of a generic
* constructor in a constructor reference. See {@link #getSort getSort}.
*/
public final static int CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT = 0x4A;
/**
* The sort of type references that target a type parameter of a generic
* method in a method reference. See {@link #getSort getSort}.
*/
public final static int METHOD_REFERENCE_TYPE_ARGUMENT = 0x4B;
/**
* The type reference value in Java class file format.
*/
private int value; private int value;
/** /**
* Creates a new TypeReference. * Creates a new TypeReference.
* *
* @param typeRef * @param typeRef the int encoded value of the type reference, as received in a visit method related to type
* the int encoded value of the type reference, as received in a * annotations, like visitTypeAnnotation.
* visit method related to type annotations, like
* visitTypeAnnotation.
*/ */
public TypeReference(int typeRef) { public TypeReference(int typeRef) {
this.value = typeRef; this.value = typeRef;
@@ -222,14 +198,10 @@ public class TypeReference {
/** /**
* Returns a type reference of the given sort. * Returns a type reference of the given sort.
* *
* @param sort * @param sort {@link #FIELD FIELD}, {@link #METHOD_RETURN METHOD_RETURN}, {@link #METHOD_RECEIVER METHOD_RECEIVER},
* {@link #FIELD FIELD}, {@link #METHOD_RETURN METHOD_RETURN}, * {@link #LOCAL_VARIABLE LOCAL_VARIABLE}, {@link #RESOURCE_VARIABLE RESOURCE_VARIABLE}, {@link #INSTANCEOF
* {@link #METHOD_RECEIVER METHOD_RECEIVER}, * INSTANCEOF}, {@link #NEW NEW}, {@link #CONSTRUCTOR_REFERENCE CONSTRUCTOR_REFERENCE}, or
* {@link #LOCAL_VARIABLE LOCAL_VARIABLE}, * {@link #METHOD_REFERENCE METHOD_REFERENCE}.
* {@link #RESOURCE_VARIABLE RESOURCE_VARIABLE},
* {@link #INSTANCEOF INSTANCEOF}, {@link #NEW NEW},
* {@link #CONSTRUCTOR_REFERENCE CONSTRUCTOR_REFERENCE}, or
* {@link #METHOD_REFERENCE METHOD_REFERENCE}.
* @return a type reference of the given sort. * @return a type reference of the given sort.
*/ */
public static TypeReference newTypeReference(int sort) { public static TypeReference newTypeReference(int sort) {
@@ -239,45 +211,33 @@ public class TypeReference {
/** /**
* Returns a reference to a type parameter of a generic class or method. * Returns a reference to a type parameter of a generic class or method.
* *
* @param sort * @param sort {@link #CLASS_TYPE_PARAMETER CLASS_TYPE_PARAMETER} or {@link #METHOD_TYPE_PARAMETER
* {@link #CLASS_TYPE_PARAMETER CLASS_TYPE_PARAMETER} or * METHOD_TYPE_PARAMETER}.
* {@link #METHOD_TYPE_PARAMETER METHOD_TYPE_PARAMETER}. * @param paramIndex the type parameter index.
* @param paramIndex
* the type parameter index.
* @return a reference to the given generic class or method type parameter. * @return a reference to the given generic class or method type parameter.
*/ */
public static TypeReference newTypeParameterReference(int sort, public static TypeReference newTypeParameterReference(int sort, int paramIndex) {
int paramIndex) {
return new TypeReference((sort << 24) | (paramIndex << 16)); return new TypeReference((sort << 24) | (paramIndex << 16));
} }
/** /**
* Returns a reference to a type parameter bound of a generic class or * Returns a reference to a type parameter bound of a generic class or method.
* method.
* *
* @param sort * @param sort {@link #CLASS_TYPE_PARAMETER CLASS_TYPE_PARAMETER} or {@link #METHOD_TYPE_PARAMETER
* {@link #CLASS_TYPE_PARAMETER CLASS_TYPE_PARAMETER} or * METHOD_TYPE_PARAMETER}.
* {@link #METHOD_TYPE_PARAMETER METHOD_TYPE_PARAMETER}. * @param paramIndex the type parameter index.
* @param paramIndex * @param boundIndex the type bound index within the above type parameters.
* the type parameter index. * @return a reference to the given generic class or method type parameter bound.
* @param boundIndex
* the type bound index within the above type parameters.
* @return a reference to the given generic class or method type parameter
* bound.
*/ */
public static TypeReference newTypeParameterBoundReference(int sort, public static TypeReference newTypeParameterBoundReference(int sort, int paramIndex, int boundIndex) {
int paramIndex, int boundIndex) { return new TypeReference((sort << 24) | (paramIndex << 16) | (boundIndex << 8));
return new TypeReference((sort << 24) | (paramIndex << 16)
| (boundIndex << 8));
} }
/** /**
* Returns a reference to the super class or to an interface of the * Returns a reference to the super class or to an interface of the 'implements' clause of a class.
* 'implements' clause of a class.
* *
* @param itfIndex * @param itfIndex the index of an interface in the 'implements' clause of a class, or -1 to reference the super
* the index of an interface in the 'implements' clause of a * class of the class.
* class, or -1 to reference the super class of the class.
* @return a reference to the given super type of a class. * @return a reference to the given super type of a class.
*/ */
public static TypeReference newSuperTypeReference(int itfIndex) { public static TypeReference newSuperTypeReference(int itfIndex) {
@@ -288,23 +248,17 @@ public class TypeReference {
/** /**
* Returns a reference to the type of a formal parameter of a method. * Returns a reference to the type of a formal parameter of a method.
* *
* @param paramIndex * @param paramIndex the formal parameter index.
* the formal parameter index.
*
* @return a reference to the type of the given method formal parameter. * @return a reference to the type of the given method formal parameter.
*/ */
public static TypeReference newFormalParameterReference(int paramIndex) { public static TypeReference newFormalParameterReference(int paramIndex) {
return new TypeReference((METHOD_FORMAL_PARAMETER << 24) return new TypeReference((METHOD_FORMAL_PARAMETER << 24) | (paramIndex << 16));
| (paramIndex << 16));
} }
/** /**
* Returns a reference to the type of an exception, in a 'throws' clause of * Returns a reference to the type of an exception, in a 'throws' clause of a method.
* a method.
*
* @param exceptionIndex
* the index of an exception in a 'throws' clause of a method.
* *
* @param exceptionIndex the index of an exception in a 'throws' clause of a method.
* @return a reference to the type of the given exception. * @return a reference to the type of the given exception.
*/ */
public static TypeReference newExceptionReference(int exceptionIndex) { public static TypeReference newExceptionReference(int exceptionIndex) {
@@ -312,37 +266,25 @@ public class TypeReference {
} }
/** /**
* Returns a reference to the type of the exception declared in a 'catch' * Returns a reference to the type of the exception declared in a 'catch' clause of a method.
* clause of a method.
*
* @param tryCatchBlockIndex
* the index of a try catch block (using the order in which they
* are visited with visitTryCatchBlock).
* *
* @param tryCatchBlockIndex the index of a try catch block (using the order in which they are visited with
* visitTryCatchBlock).
* @return a reference to the type of the given exception. * @return a reference to the type of the given exception.
*/ */
public static TypeReference newTryCatchReference(int tryCatchBlockIndex) { public static TypeReference newTryCatchReference(int tryCatchBlockIndex) {
return new TypeReference((EXCEPTION_PARAMETER << 24) return new TypeReference((EXCEPTION_PARAMETER << 24) | (tryCatchBlockIndex << 8));
| (tryCatchBlockIndex << 8));
} }
/** /**
* Returns a reference to the type of a type argument in a constructor or * Returns a reference to the type of a type argument in a constructor or method call or reference.
* method call or reference.
*
* @param sort
* {@link #CAST CAST},
* {@link #CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT
* CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT},
* {@link #METHOD_INVOCATION_TYPE_ARGUMENT
* METHOD_INVOCATION_TYPE_ARGUMENT},
* {@link #CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT
* CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT}, or
* {@link #METHOD_REFERENCE_TYPE_ARGUMENT
* METHOD_REFERENCE_TYPE_ARGUMENT}.
* @param argIndex
* the type argument index.
* *
* @param sort {@link #CAST CAST}, {@link #CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT
* CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT}, {@link #METHOD_INVOCATION_TYPE_ARGUMENT
* METHOD_INVOCATION_TYPE_ARGUMENT}, {@link #CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT
* CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT}, or {@link #METHOD_REFERENCE_TYPE_ARGUMENT
* METHOD_REFERENCE_TYPE_ARGUMENT}.
* @param argIndex the type argument index.
* @return a reference to the type of the given type argument. * @return a reference to the type of the given type argument.
*/ */
public static TypeReference newTypeArgumentReference(int sort, int argIndex) { public static TypeReference newTypeArgumentReference(int sort, int argIndex) {
@@ -352,39 +294,27 @@ public class TypeReference {
/** /**
* Returns the sort of this type reference. * Returns the sort of this type reference.
* *
* @return {@link #CLASS_TYPE_PARAMETER CLASS_TYPE_PARAMETER}, * @return {@link #CLASS_TYPE_PARAMETER CLASS_TYPE_PARAMETER}, {@link #METHOD_TYPE_PARAMETER METHOD_TYPE_PARAMETER},
* {@link #METHOD_TYPE_PARAMETER METHOD_TYPE_PARAMETER}, * {@link #CLASS_EXTENDS CLASS_EXTENDS}, {@link #CLASS_TYPE_PARAMETER_BOUND CLASS_TYPE_PARAMETER_BOUND},
* {@link #CLASS_EXTENDS CLASS_EXTENDS}, * {@link #METHOD_TYPE_PARAMETER_BOUND METHOD_TYPE_PARAMETER_BOUND}, {@link #FIELD FIELD}, {@link #METHOD_RETURN
* {@link #CLASS_TYPE_PARAMETER_BOUND CLASS_TYPE_PARAMETER_BOUND}, * METHOD_RETURN}, {@link #METHOD_RECEIVER METHOD_RECEIVER}, {@link #METHOD_FORMAL_PARAMETER
* {@link #METHOD_TYPE_PARAMETER_BOUND METHOD_TYPE_PARAMETER_BOUND}, * METHOD_FORMAL_PARAMETER}, {@link #THROWS THROWS}, {@link #LOCAL_VARIABLE LOCAL_VARIABLE},
* {@link #FIELD FIELD}, {@link #METHOD_RETURN METHOD_RETURN}, * {@link #RESOURCE_VARIABLE RESOURCE_VARIABLE}, {@link #EXCEPTION_PARAMETER EXCEPTION_PARAMETER},
* {@link #METHOD_RECEIVER METHOD_RECEIVER}, * {@link #INSTANCEOF INSTANCEOF}, {@link #NEW NEW}, {@link #CONSTRUCTOR_REFERENCE CONSTRUCTOR_REFERENCE},
* {@link #METHOD_FORMAL_PARAMETER METHOD_FORMAL_PARAMETER}, * {@link #METHOD_REFERENCE METHOD_REFERENCE}, {@link #CAST CAST}, {@link #CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT
* {@link #THROWS THROWS}, {@link #LOCAL_VARIABLE LOCAL_VARIABLE}, * CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT}, {@link #METHOD_INVOCATION_TYPE_ARGUMENT
* {@link #RESOURCE_VARIABLE RESOURCE_VARIABLE}, * METHOD_INVOCATION_TYPE_ARGUMENT}, {@link #CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT
* {@link #EXCEPTION_PARAMETER EXCEPTION_PARAMETER}, * CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT}, or {@link #METHOD_REFERENCE_TYPE_ARGUMENT
* {@link #INSTANCEOF INSTANCEOF}, {@link #NEW NEW}, * METHOD_REFERENCE_TYPE_ARGUMENT}.
* {@link #CONSTRUCTOR_REFERENCE CONSTRUCTOR_REFERENCE},
* {@link #METHOD_REFERENCE METHOD_REFERENCE}, {@link #CAST CAST},
* {@link #CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT
* CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT},
* {@link #METHOD_INVOCATION_TYPE_ARGUMENT
* METHOD_INVOCATION_TYPE_ARGUMENT},
* {@link #CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT
* CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT}, or
* {@link #METHOD_REFERENCE_TYPE_ARGUMENT
* METHOD_REFERENCE_TYPE_ARGUMENT}.
*/ */
public int getSort() { public int getSort() {
return value >>> 24; return value >>> 24;
} }
/** /**
* Returns the index of the type parameter referenced by this type * Returns the index of the type parameter referenced by this type reference. This method must only be used for type
* reference. This method must only be used for type references whose sort * references whose sort is {@link #CLASS_TYPE_PARAMETER CLASS_TYPE_PARAMETER}, {@link #METHOD_TYPE_PARAMETER
* is {@link #CLASS_TYPE_PARAMETER CLASS_TYPE_PARAMETER}, * METHOD_TYPE_PARAMETER}, {@link #CLASS_TYPE_PARAMETER_BOUND CLASS_TYPE_PARAMETER_BOUND} or
* {@link #METHOD_TYPE_PARAMETER METHOD_TYPE_PARAMETER},
* {@link #CLASS_TYPE_PARAMETER_BOUND CLASS_TYPE_PARAMETER_BOUND} or
* {@link #METHOD_TYPE_PARAMETER_BOUND METHOD_TYPE_PARAMETER_BOUND}. * {@link #METHOD_TYPE_PARAMETER_BOUND METHOD_TYPE_PARAMETER_BOUND}.
* *
* @return a type parameter index. * @return a type parameter index.
@@ -394,11 +324,10 @@ public class TypeReference {
} }
/** /**
* Returns the index of the type parameter bound, within the type parameter * Returns the index of the type parameter bound, within the type parameter {@link #getTypeParameterIndex},
* {@link #getTypeParameterIndex}, referenced by this type reference. This * referenced by this type reference. This method must only be used for type references whose sort is
* method must only be used for type references whose sort is * {@link #CLASS_TYPE_PARAMETER_BOUND CLASS_TYPE_PARAMETER_BOUND} or {@link #METHOD_TYPE_PARAMETER_BOUND
* {@link #CLASS_TYPE_PARAMETER_BOUND CLASS_TYPE_PARAMETER_BOUND} or * METHOD_TYPE_PARAMETER_BOUND}.
* {@link #METHOD_TYPE_PARAMETER_BOUND METHOD_TYPE_PARAMETER_BOUND}.
* *
* @return a type parameter bound index. * @return a type parameter bound index.
*/ */
@@ -407,22 +336,19 @@ public class TypeReference {
} }
/** /**
* Returns the index of the "super type" of a class that is referenced by * Returns the index of the "super type" of a class that is referenced by this type reference. This method must only
* this type reference. This method must only be used for type references * be used for type references whose sort is {@link #CLASS_EXTENDS CLASS_EXTENDS}.
* whose sort is {@link #CLASS_EXTENDS CLASS_EXTENDS}.
* *
* @return the index of an interface in the 'implements' clause of a class, * @return the index of an interface in the 'implements' clause of a class, or -1 if this type reference references
* or -1 if this type reference references the type of the super * the type of the super class.
* class.
*/ */
public int getSuperTypeIndex() { public int getSuperTypeIndex() {
return (short) ((value & 0x00FFFF00) >> 8); return (short) ((value & 0x00FFFF00) >> 8);
} }
/** /**
* Returns the index of the formal parameter whose type is referenced by * Returns the index of the formal parameter whose type is referenced by this type reference. This method must only
* this type reference. This method must only be used for type references * be used for type references whose sort is {@link #METHOD_FORMAL_PARAMETER METHOD_FORMAL_PARAMETER}.
* whose sort is {@link #METHOD_FORMAL_PARAMETER METHOD_FORMAL_PARAMETER}.
* *
* @return a formal parameter index. * @return a formal parameter index.
*/ */
@@ -431,9 +357,8 @@ public class TypeReference {
} }
/** /**
* Returns the index of the exception, in a 'throws' clause of a method, * Returns the index of the exception, in a 'throws' clause of a method, whose type is referenced by this type
* whose type is referenced by this type reference. This method must only be * reference. This method must only be used for type references whose sort is {@link #THROWS THROWS}.
* used for type references whose sort is {@link #THROWS THROWS}.
* *
* @return the index of an exception in the 'throws' clause of a method. * @return the index of an exception in the 'throws' clause of a method.
*/ */
@@ -442,10 +367,9 @@ public class TypeReference {
} }
/** /**
* Returns the index of the try catch block (using the order in which they * Returns the index of the try catch block (using the order in which they are visited with visitTryCatchBlock),
* are visited with visitTryCatchBlock), whose 'catch' type is referenced by * whose 'catch' type is referenced by this type reference. This method must only be used for type references whose
* this type reference. This method must only be used for type references * sort is {@link #EXCEPTION_PARAMETER EXCEPTION_PARAMETER} .
* whose sort is {@link #EXCEPTION_PARAMETER EXCEPTION_PARAMETER} .
* *
* @return the index of an exception in the 'throws' clause of a method. * @return the index of an exception in the 'throws' clause of a method.
*/ */
@@ -454,13 +378,10 @@ public class TypeReference {
} }
/** /**
* Returns the index of the type argument referenced by this type reference. * Returns the index of the type argument referenced by this type reference. This method must only be used for type
* This method must only be used for type references whose sort is * references whose sort is {@link #CAST CAST}, {@link #CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT
* {@link #CAST CAST}, {@link #CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT * CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT}, {@link #METHOD_INVOCATION_TYPE_ARGUMENT METHOD_INVOCATION_TYPE_ARGUMENT},
* CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT}, * {@link #CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT}, or
* {@link #METHOD_INVOCATION_TYPE_ARGUMENT METHOD_INVOCATION_TYPE_ARGUMENT},
* {@link #CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT
* CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT}, or
* {@link #METHOD_REFERENCE_TYPE_ARGUMENT METHOD_REFERENCE_TYPE_ARGUMENT}. * {@link #METHOD_REFERENCE_TYPE_ARGUMENT METHOD_REFERENCE_TYPE_ARGUMENT}.
* *
* @return a type parameter index. * @return a type parameter index.
@@ -470,8 +391,8 @@ public class TypeReference {
} }
/** /**
* Returns the int encoded value of this type reference, suitable for use in * Returns the int encoded value of this type reference, suitable for use in visit methods related to type
* visit methods related to type annotations, like visitTypeAnnotation. * annotations, like visitTypeAnnotation.
* *
* @return the int encoded value of this type reference. * @return the int encoded value of this type reference.
*/ */

View File

@@ -1,4 +1,2 @@
/** /** 本包下所有代码均是从/java.base/jdk/internal/org/objectweb/asm 拷贝过来的 */
* 本包下所有代码均是从/java.base/jdk/internal/org/objectweb/asm 拷贝过来的
*/
package org.redkale.asm; package org.redkale.asm;

View File

@@ -23,37 +23,33 @@ import org.redkale.source.*;
import org.redkale.util.*; import org.redkale.util.*;
/** /**
* API接口文档生成类作用生成Application实例中所有HttpServer的可用HttpServlet的API接口方法 <br> * API接口文档生成类作用生成Application实例中所有HttpServer的可用HttpServlet的API接口方法 <br>
* 继承 HttpBaseServlet 是为了获取 HttpMapping 信息 <br> * 继承 HttpBaseServlet 是为了获取 HttpMapping 信息 <br>
* https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md * https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md
* *
* <p> * <p>详情见: https://redkale.org
* 详情见: https://redkale.org
* *
* @author zhangjx * @author zhangjx
*/ */
public final class ApiDocCommand { public final class ApiDocCommand {
private static final java.lang.reflect.Type TYPE_RETRESULT_OBJECT = new TypeToken<RetResult<Object>>() { private static final java.lang.reflect.Type TYPE_RETRESULT_OBJECT = new TypeToken<RetResult<Object>>() {}.getType();
}.getType();
private static final java.lang.reflect.Type TYPE_RETRESULT_STRING = new TypeToken<RetResult<String>>() { private static final java.lang.reflect.Type TYPE_RETRESULT_STRING = new TypeToken<RetResult<String>>() {}.getType();
}.getType();
private static final java.lang.reflect.Type TYPE_RETRESULT_INTEGER = new TypeToken<RetResult<Integer>>() { private static final java.lang.reflect.Type TYPE_RETRESULT_INTEGER =
}.getType(); new TypeToken<RetResult<Integer>>() {}.getType();
private static final java.lang.reflect.Type TYPE_RETRESULT_LONG = new TypeToken<RetResult<Long>>() { private static final java.lang.reflect.Type TYPE_RETRESULT_LONG = new TypeToken<RetResult<Long>>() {}.getType();
}.getType();
private final Application app; //Application全局对象 private final Application app; // Application全局对象
public ApiDocCommand(Application app) { public ApiDocCommand(Application app) {
this.app = app; this.app = app;
} }
public String command(String cmd, String[] params) throws Exception { public String command(String cmd, String[] params) throws Exception {
//是否跳过RPC接口 // 是否跳过RPC接口
boolean skipRPC = true; boolean skipRPC = true;
String apiHost = "http://localhost"; String apiHost = "http://localhost";
@@ -75,7 +71,7 @@ public final class ApiDocCommand {
Field prefixField = HttpServlet.class.getDeclaredField("_prefix"); Field prefixField = HttpServlet.class.getDeclaredField("_prefix");
prefixField.setAccessible(true); prefixField.setAccessible(true);
Map<String, Map<String, Map<String, Object>>> typesMap = new LinkedHashMap<>(); Map<String, Map<String, Map<String, Object>>> typesMap = new LinkedHashMap<>();
//https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md // https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md
Map<String, Object> swaggerPathsMap = new LinkedHashMap<>(); Map<String, Object> swaggerPathsMap = new LinkedHashMap<>();
List<Map> swaggerServers = new ArrayList<>(); List<Map> swaggerServers = new ArrayList<>();
List<Map> swaggerTags = new ArrayList<>(); List<Map> swaggerTags = new ArrayList<>();
@@ -88,10 +84,13 @@ public final class ApiDocCommand {
serverList.add(map); serverList.add(map);
HttpServer server = node.getServer(); HttpServer server = node.getServer();
map.put("address", server.getSocketAddress()); map.put("address", server.getSocketAddress());
swaggerServers.add(Utility.ofMap("url", apiHost + ":" + server.getSocketAddress().getPort())); swaggerServers.add(Utility.ofMap(
"url", apiHost + ":" + server.getSocketAddress().getPort()));
List<Map<String, Object>> servletsList = new ArrayList<>(); List<Map<String, Object>> servletsList = new ArrayList<>();
map.put("servlets", servletsList); map.put("servlets", servletsList);
String plainContentType = server.getResponseConfig() == null ? "application/json" : server.getResponseConfig().plainContentType; String plainContentType = server.getResponseConfig() == null
? "application/json"
: server.getResponseConfig().plainContentType;
if (plainContentType == null || plainContentType.isEmpty()) { if (plainContentType == null || plainContentType.isEmpty()) {
plainContentType = "application/json"; plainContentType = "application/json";
} }
@@ -115,7 +114,12 @@ public final class ApiDocCommand {
node.logger.log(Level.INFO, servlet + " be skipped because @WebServlet.name is empty"); node.logger.log(Level.INFO, servlet + " be skipped because @WebServlet.name is empty");
continue; continue;
} }
final String tag = ws.name().isEmpty() ? servlet.getClass().getSimpleName().replace("Servlet", "").toLowerCase() : ws.name(); final String tag = ws.name().isEmpty()
? servlet.getClass()
.getSimpleName()
.replace("Servlet", "")
.toLowerCase()
: ws.name();
final Map<String, Object> servletMap = new LinkedHashMap<>(); final Map<String, Object> servletMap = new LinkedHashMap<>();
String prefix = (String) prefixField.get(servlet); String prefix = (String) prefixField.get(servlet);
String[] urlregs = ws.value(); String[] urlregs = ws.value();
@@ -147,16 +151,16 @@ public final class ApiDocCommand {
continue; continue;
} }
if (!action.inherited() && selfClz != clz) { if (!action.inherited() && selfClz != clz) {
continue; //忽略不被继承的方法 continue; // 忽略不被继承的方法
} }
if (actionUrls.contains(action.url())) { if (actionUrls.contains(action.url())) {
continue; continue;
} }
if (HttpScope.class.isAssignableFrom(action.result())) { if (HttpScope.class.isAssignableFrom(action.result())) {
continue; //忽略模板引擎的方法 continue; // 忽略模板引擎的方法
} }
if (action.rpcOnly() && skipRPC) { if (action.rpcOnly() && skipRPC) {
continue; //不生成RPC接口 continue; // 不生成RPC接口
} }
final List<Map<String, Object>> swaggerParamsList = new ArrayList<>(); final List<Map<String, Object>> swaggerParamsList = new ArrayList<>();
@@ -175,44 +179,51 @@ public final class ApiDocCommand {
f.setAccessible(true); f.setAccessible(true);
resultType = (Type) f.get(servlet); resultType = (Type) f.get(servlet);
} }
// for (final Class rtype : action.results()) { // for (final Class rtype : action.results()) {
// results.add(rtype.getName()); // results.add(rtype.getName());
// if (typesMap.containsKey(rtype.getName())) continue; // if (typesMap.containsKey(rtype.getName())) continue;
// if (rtype.getName().startsWith("java.")) continue; // if (rtype.getName().startsWith("java.")) continue;
// if (rtype.getName().startsWith("javax.")) continue; // if (rtype.getName().startsWith("javax.")) continue;
// final boolean filter = FilterBean.class.isAssignableFrom(rtype); // final boolean filter = FilterBean.class.isAssignableFrom(rtype);
// final Map<String, Map<String, Object>> typeMap = new LinkedHashMap<>(); // final Map<String, Map<String, Object>> typeMap = new
// Class loop = rtype; // LinkedHashMap<>();
// do { // Class loop = rtype;
// if (loop == null || loop.isInterface()) break; // do {
// for (Field field : loop.getDeclaredFields()) { // if (loop == null || loop.isInterface()) break;
// if (Modifier.isFinal(field.getModifiers())) continue; // for (Field field : loop.getDeclaredFields()) {
// if (Modifier.isStatic(field.getModifiers())) continue; // if (Modifier.isFinal(field.getModifiers())) continue;
// // if (Modifier.isStatic(field.getModifiers())) continue;
// Map<String, Object> fieldmap = new LinkedHashMap<>(); //
// fieldmap.put("type", field.getType().isArray() ? (field.getType().getComponentType().getName() + "[]") : field.getGenericType().getTypeName()); // Map<String, Object> fieldmap = new LinkedHashMap<>();
// // fieldmap.put("type", field.getType().isArray() ?
// Comment comment = field.getAnnotation(Comment.class); // (field.getType().getComponentType().getName() + "[]") :
// Column col = field.getAnnotation(Column.class); // field.getGenericType().getTypeName());
// FilterColumn fc = field.getAnnotation(FilterColumn.class); //
// if (comment != null) { // Comment comment = field.getAnnotation(Comment.class);
// fieldmap.put("comment", comment.value()); // Column col = field.getAnnotation(Column.class);
// } else if (col != null) { // FilterColumn fc = field.getAnnotation(FilterColumn.class);
// fieldmap.put("comment", col.comment()); // if (comment != null) {
// } else if (fc != null) { // fieldmap.put("comment", comment.value());
// fieldmap.put("comment", fc.comment()); // } else if (col != null) {
// } // fieldmap.put("comment", col.comment());
// fieldmap.put("primary", !filter && (field.getAnnotation(Id.class) != null)); // } else if (fc != null) {
// fieldmap.put("updatable", (filter || col == null || col.updatable())); // fieldmap.put("comment", fc.comment());
// if (servlet.getClass().getAnnotation(Rest.RestDyn.class) != null) { // }
// if (field.getAnnotation(RestAddress.class) != null) continue; // fieldmap.put("primary", !filter &&
// } // (field.getAnnotation(Id.class) != null));
// // fieldmap.put("updatable", (filter || col == null ||
// typeMap.put(field.getName(), fieldmap); // col.updatable()));
// } // if (servlet.getClass().getAnnotation(Rest.RestDyn.class)
// } while ((loop = loop.getSuperclass()) != Object.class); // != null) {
// typesMap.put(rtype.getName(), typeMap); // if (field.getAnnotation(RestAddress.class) != null)
// } // continue;
// }
//
// typeMap.put(field.getName(), fieldmap);
// }
// } while ((loop = loop.getSuperclass()) != Object.class);
// typesMap.put(rtype.getName(), typeMap);
// }
mappingMap.put("results", results); mappingMap.put("results", results);
boolean hasBodyParam = false; boolean hasBodyParam = false;
Map<String, Object> swaggerRequestBody = new LinkedHashMap<>(); Map<String, Object> swaggerRequestBody = new LinkedHashMap<>();
@@ -235,26 +246,40 @@ public final class ApiDocCommand {
f.setAccessible(true); f.setAccessible(true);
paramGenericType = (Type) f.get(servlet); paramGenericType = (Type) f.get(servlet);
} }
simpleSchemaType(null, node.getLogger(), swaggerComponentsMap, simpleSchemaType(
param.type(), paramGenericType, paramSchemaMap, true); null,
node.getLogger(),
swaggerComponentsMap,
param.type(),
paramGenericType,
paramSchemaMap,
true);
if (param.style() == HttpParam.HttpParameterStyle.BODY) { if (param.style() == HttpParam.HttpParameterStyle.BODY) {
swaggerRequestBody.put("description", param.comment()); swaggerRequestBody.put("description", param.comment());
swaggerRequestBody.put("content", Utility.ofMap(plainContentType, Utility.ofMap("schema", paramSchemaMap))); swaggerRequestBody.put(
"content",
Utility.ofMap(plainContentType, Utility.ofMap("schema", paramSchemaMap)));
} else { } else {
final Map<String, Object> swaggerParamMap = new LinkedHashMap<>(); final Map<String, Object> swaggerParamMap = new LinkedHashMap<>();
swaggerParamMap.put("name", param.name()); swaggerParamMap.put("name", param.name());
swaggerParamMap.put("in", param.style().name().toLowerCase()); swaggerParamMap.put(
"in", param.style().name().toLowerCase());
swaggerParamMap.put("description", param.comment()); swaggerParamMap.put("description", param.comment());
swaggerParamMap.put("required", param.required()); swaggerParamMap.put("required", param.required());
if (param.deprecated()) { if (param.deprecated()) {
swaggerParamMap.put("deprecated", param.deprecated()); swaggerParamMap.put("deprecated", param.deprecated());
} }
//https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#parameterStyle // https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#parameterStyle
swaggerParamMap.put("style", param.style() == HttpParam.HttpParameterStyle.HEADER swaggerParamMap.put(
|| param.name().indexOf('#') == 0 ? "simple" : "form"); "style",
param.style() == HttpParam.HttpParameterStyle.HEADER
|| param.name().indexOf('#') == 0
? "simple"
: "form");
swaggerParamMap.put("explode", true); swaggerParamMap.put("explode", true);
swaggerParamMap.put("schema", paramSchemaMap); swaggerParamMap.put("schema", paramSchemaMap);
Object example = formatExample(null, param.example(), param.type(), paramGenericType); Object example =
formatExample(null, param.example(), param.type(), paramGenericType);
if (example != null) { if (example != null) {
swaggerParamMap.put("example", example); swaggerParamMap.put("example", example);
} else if (!param.example().isEmpty()) { } else if (!param.example().isEmpty()) {
@@ -295,12 +320,18 @@ public final class ApiDocCommand {
} }
Map<String, Object> fieldmap = new LinkedHashMap<>(); Map<String, Object> fieldmap = new LinkedHashMap<>();
fieldmap.put("type", field.getType().isArray() fieldmap.put(
? (field.getType().getComponentType().getName() + "[]") : field.getGenericType().getTypeName()); "type",
field.getType().isArray()
? (field.getType()
.getComponentType()
.getName() + "[]")
: field.getGenericType().getTypeName());
Column col = field.getAnnotation(Column.class); Column col = field.getAnnotation(Column.class);
Comment comment = field.getAnnotation(Comment.class); Comment comment = field.getAnnotation(Comment.class);
org.redkale.util.Comment comment2 = field.getAnnotation(org.redkale.util.Comment.class); org.redkale.util.Comment comment2 =
field.getAnnotation(org.redkale.util.Comment.class);
if (comment != null) { if (comment != null) {
fieldmap.put("comment", comment.value()); fieldmap.put("comment", comment.value());
} else if (comment2 != null) { } else if (comment2 != null) {
@@ -308,8 +339,12 @@ public final class ApiDocCommand {
} else if (col != null) { } else if (col != null) {
fieldmap.put("comment", col.comment()); fieldmap.put("comment", col.comment());
} }
fieldmap.put("primary", !filter && (field.getAnnotation(Id.class) != null fieldmap.put(
|| field.getAnnotation(javax.persistence.Id.class) != null)); "primary",
!filter
&& (field.getAnnotation(Id.class) != null
|| field.getAnnotation(javax.persistence.Id.class)
!= null));
fieldmap.put("updatable", (filter || col == null || col.updatable())); fieldmap.put("updatable", (filter || col == null || col.updatable()));
if (servlet.getClass().getAnnotation(Rest.RestDyn.class) != null) { if (servlet.getClass().getAnnotation(Rest.RestDyn.class) != null) {
@@ -328,15 +363,24 @@ public final class ApiDocCommand {
mappingsList.add(mappingMap); mappingsList.add(mappingMap);
final Map<String, Object> swaggerOperatMap = new LinkedHashMap<>(); final Map<String, Object> swaggerOperatMap = new LinkedHashMap<>();
swaggerOperatMap.put("tags", new String[]{tag}); swaggerOperatMap.put("tags", new String[] {tag});
swaggerOperatMap.put("operationId", action.name()); swaggerOperatMap.put("operationId", action.name());
if (method.getAnnotation(Deprecated.class) != null) { if (method.getAnnotation(Deprecated.class) != null) {
swaggerOperatMap.put("deprecated", true); swaggerOperatMap.put("deprecated", true);
} }
Map<String, Object> respSchemaMap = new LinkedHashMap<>(); Map<String, Object> respSchemaMap = new LinkedHashMap<>();
JsonFactory returnFactory = Rest.createJsonFactory(0, JsonFactory returnFactory = Rest.createJsonFactory(
method.getAnnotationsByType(RestConvert.class), method.getAnnotationsByType(RestConvertCoder.class)); 0,
simpleSchemaType(returnFactory, node.getLogger(), swaggerComponentsMap, action.result(), resultType, respSchemaMap, true); method.getAnnotationsByType(RestConvert.class),
method.getAnnotationsByType(RestConvertCoder.class));
simpleSchemaType(
returnFactory,
node.getLogger(),
swaggerComponentsMap,
action.result(),
resultType,
respSchemaMap,
true);
Map<String, Object> respMap = new LinkedHashMap<>(); Map<String, Object> respMap = new LinkedHashMap<>();
respMap.put("schema", respSchemaMap); respMap.put("schema", respSchemaMap);
@@ -352,16 +396,35 @@ public final class ApiDocCommand {
if (action.rpcOnly()) { if (action.rpcOnly()) {
actiondesc = "[Only for RPC API] " + actiondesc; actiondesc = "[Only for RPC API] " + actiondesc;
} }
swaggerOperatMap.put("responses", Utility.ofMap("200", swaggerOperatMap.put(
Utility.ofMap("description", actiondesc, "content", Utility.ofMap("application/json", respMap)))); "responses",
Utility.ofMap(
"200",
Utility.ofMap(
"description",
actiondesc,
"content",
Utility.ofMap("application/json", respMap))));
String m = action.methods() == null || action.methods().length == 0 ? null : action.methods()[0].toLowerCase(); String m = action.methods() == null || action.methods().length == 0
? null
: action.methods()[0].toLowerCase();
if (m == null) { if (m == null) {
m = hasBodyParam || TYPE_RETRESULT_STRING.equals(resultType) || TYPE_RETRESULT_INTEGER.equals(resultType) m = hasBodyParam
|| TYPE_RETRESULT_LONG.equals(resultType) || action.name().contains("create") || action.name().contains("insert") || TYPE_RETRESULT_STRING.equals(resultType)
|| action.name().contains("update") || action.name().contains("delete") || action.name().contains("send") ? "post" : "get"; || TYPE_RETRESULT_INTEGER.equals(resultType)
|| TYPE_RETRESULT_LONG.equals(resultType)
|| action.name().contains("create")
|| action.name().contains("insert")
|| action.name().contains("update")
|| action.name().contains("delete")
|| action.name().contains("send")
? "post"
: "get";
} }
swaggerPathsMap.put(prefix + action.url(), Utility.ofMap("description", action.comment(), m, swaggerOperatMap)); swaggerPathsMap.put(
prefix + action.url(),
Utility.ofMap("description", action.comment(), m, swaggerOperatMap));
} }
} while ((clz = clz.getSuperclass()) != HttpServlet.class); } while ((clz = clz.getSuperclass()) != HttpServlet.class);
mappingsList.sort((o1, o2) -> ((String) o1.get("url")).compareTo((String) o2.get("url"))); mappingsList.sort((o1, o2) -> ((String) o1.get("url")).compareTo((String) o2.get("url")));
@@ -417,13 +480,22 @@ public final class ApiDocCommand {
return "apidoc success"; return "apidoc success";
} }
private static void simpleSchemaType(JsonFactory factory, Logger logger, private static void simpleSchemaType(
Map<String, Map<String, Object>> componentsMap, Class type, Type genericType, Map<String, Object> schemaMap, boolean recursive) { JsonFactory factory,
Logger logger,
Map<String, Map<String, Object>> componentsMap,
Class type,
Type genericType,
Map<String, Object> schemaMap,
boolean recursive) {
if (type == int.class || type == Integer.class || type == AtomicInteger.class) { if (type == int.class || type == Integer.class || type == AtomicInteger.class) {
schemaMap.put("type", "integer"); schemaMap.put("type", "integer");
schemaMap.put("format", "int32"); schemaMap.put("format", "int32");
} else if (type == long.class || type == Long.class } else if (type == long.class
|| type == AtomicLong.class || type == LongAdder.class || type == BigInteger.class) { || type == Long.class
|| type == AtomicLong.class
|| type == LongAdder.class
|| type == BigInteger.class) {
schemaMap.put("type", "integer"); schemaMap.put("type", "integer");
schemaMap.put("format", "int64"); schemaMap.put("format", "int64");
} else if (type == float.class || type == Float.class) { } else if (type == float.class || type == Float.class) {
@@ -442,13 +514,28 @@ public final class ApiDocCommand {
schemaMap.put("type", "array"); schemaMap.put("type", "array");
Map<String, Object> sbumap = new LinkedHashMap<>(); Map<String, Object> sbumap = new LinkedHashMap<>();
if (type.isArray()) { if (type.isArray()) {
simpleSchemaType(factory, logger, componentsMap, type.getComponentType(), type.getComponentType(), sbumap, false); simpleSchemaType(
factory,
logger,
componentsMap,
type.getComponentType(),
type.getComponentType(),
sbumap,
false);
} else if (genericType instanceof ParameterizedType) { } else if (genericType instanceof ParameterizedType) {
Type subpt = ((ParameterizedType) genericType).getActualTypeArguments()[0]; Type subpt = ((ParameterizedType) genericType).getActualTypeArguments()[0];
if (subpt instanceof Class) { if (subpt instanceof Class) {
simpleSchemaType(factory, logger, componentsMap, (Class) subpt, subpt, sbumap, false); simpleSchemaType(factory, logger, componentsMap, (Class) subpt, subpt, sbumap, false);
} else if (subpt instanceof ParameterizedType && ((ParameterizedType) subpt).getOwnerType() instanceof Class) { } else if (subpt instanceof ParameterizedType
simpleSchemaType(factory, logger, componentsMap, (Class) ((ParameterizedType) subpt).getOwnerType(), subpt, sbumap, false); && ((ParameterizedType) subpt).getOwnerType() instanceof Class) {
simpleSchemaType(
factory,
logger,
componentsMap,
(Class) ((ParameterizedType) subpt).getOwnerType(),
subpt,
sbumap,
false);
} else { } else {
sbumap.put("type", "object"); sbumap.put("type", "object");
} }
@@ -468,8 +555,12 @@ public final class ApiDocCommand {
} }
} }
private static String simpleComponentType(JsonFactory factory, Logger logger, private static String simpleComponentType(
Map<String, Map<String, Object>> componentsMap, Class type, Type genericType) { JsonFactory factory,
Logger logger,
Map<String, Map<String, Object>> componentsMap,
Class type,
Type genericType) {
try { try {
Set<Type> types = new HashSet<>(); Set<Type> types = new HashSet<>();
Encodeable encodeable = JsonFactory.root().loadEncoder(genericType); Encodeable encodeable = JsonFactory.root().loadEncoder(genericType);
@@ -481,7 +572,7 @@ public final class ApiDocCommand {
return ct; return ct;
} }
Map<String, Object> cmap = new LinkedHashMap<>(); Map<String, Object> cmap = new LinkedHashMap<>();
componentsMap.put(ct, cmap); //必须在调用simpleSchemaType之前put不然嵌套情况下死循环 componentsMap.put(ct, cmap); // 必须在调用simpleSchemaType之前put不然嵌套情况下死循环
cmap.put("type", "object"); cmap.put("type", "object");
List<String> requireds = new ArrayList<>(); List<String> requireds = new ArrayList<>();
@@ -489,9 +580,14 @@ public final class ApiDocCommand {
if (encodeable instanceof ObjectEncoder) { if (encodeable instanceof ObjectEncoder) {
for (EnMember member : ((ObjectEncoder) encodeable).getMembers()) { for (EnMember member : ((ObjectEncoder) encodeable).getMembers()) {
Map<String, Object> schemaMap = new LinkedHashMap<>(); Map<String, Object> schemaMap = new LinkedHashMap<>();
simpleSchemaType(factory, logger, componentsMap, simpleSchemaType(
TypeToken.typeToClassOrElse(member.getEncoder().getType(), Object.class), factory,
member.getEncoder().getType(), schemaMap, true); logger,
componentsMap,
TypeToken.typeToClassOrElse(member.getEncoder().getType(), Object.class),
member.getEncoder().getType(),
schemaMap,
true);
String desc = ""; String desc = "";
if (member.getField() != null) { if (member.getField() != null) {
Column col = member.getField().getAnnotation(Column.class); Column col = member.getField().getAnnotation(Column.class);
@@ -502,9 +598,14 @@ public final class ApiDocCommand {
} }
} }
if (desc.isEmpty() && member.getField().getAnnotation(Comment.class) != null) { if (desc.isEmpty() && member.getField().getAnnotation(Comment.class) != null) {
desc = member.getField().getAnnotation(Comment.class).value(); desc = member.getField()
} else if (desc.isEmpty() && member.getField().getAnnotation(org.redkale.util.Comment.class) != null) { .getAnnotation(Comment.class)
desc = member.getField().getAnnotation(org.redkale.util.Comment.class).value(); .value();
} else if (desc.isEmpty()
&& member.getField().getAnnotation(org.redkale.util.Comment.class) != null) {
desc = member.getField()
.getAnnotation(org.redkale.util.Comment.class)
.value();
} }
} else if (member.getMethod() != null) { } else if (member.getMethod() != null) {
Column col = member.getMethod().getAnnotation(Column.class); Column col = member.getMethod().getAnnotation(Column.class);
@@ -515,9 +616,14 @@ public final class ApiDocCommand {
} }
} }
if (desc.isEmpty() && member.getMethod().getAnnotation(Comment.class) != null) { if (desc.isEmpty() && member.getMethod().getAnnotation(Comment.class) != null) {
desc = member.getMethod().getAnnotation(Comment.class).value(); desc = member.getMethod()
} else if (desc.isEmpty() && member.getMethod().getAnnotation(org.redkale.util.Comment.class) != null) { .getAnnotation(Comment.class)
desc = member.getMethod().getAnnotation(org.redkale.util.Comment.class).value(); .value();
} else if (desc.isEmpty()
&& member.getMethod().getAnnotation(org.redkale.util.Comment.class) != null) {
desc = member.getMethod()
.getAnnotation(org.redkale.util.Comment.class)
.value();
} }
} }
if (!desc.isEmpty()) { if (!desc.isEmpty()) {
@@ -537,8 +643,14 @@ public final class ApiDocCommand {
} }
} }
private static String componentKey(JsonFactory factory, Logger logger, Set<Type> types, private static String componentKey(
Map<String, Map<String, Object>> componentsMap, EnMember field, Encodeable encodeable, boolean first) { JsonFactory factory,
Logger logger,
Set<Type> types,
Map<String, Map<String, Object>> componentsMap,
EnMember field,
Encodeable encodeable,
boolean first) {
if (encodeable instanceof ObjectEncoder) { if (encodeable instanceof ObjectEncoder) {
if (types.contains(encodeable.getType())) { if (types.contains(encodeable.getType())) {
return ""; return "";
@@ -547,9 +659,9 @@ public final class ApiDocCommand {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
sb.append(((ObjectEncoder) encodeable).getTypeClass().getSimpleName()); sb.append(((ObjectEncoder) encodeable).getTypeClass().getSimpleName());
for (EnMember member : ((ObjectEncoder) encodeable).getMembers()) { for (EnMember member : ((ObjectEncoder) encodeable).getMembers()) {
if (member.getEncoder() instanceof ArrayEncoder if (member.getEncoder() instanceof ArrayEncoder || member.getEncoder() instanceof CollectionEncoder) {
|| member.getEncoder() instanceof CollectionEncoder) { String subsb =
String subsb = componentKey(factory, logger, types, componentsMap, member, member.getEncoder(), false); componentKey(factory, logger, types, componentsMap, member, member.getEncoder(), false);
if (subsb == null) { if (subsb == null) {
return null; return null;
} }
@@ -558,7 +670,9 @@ public final class ApiDocCommand {
continue; continue;
} }
Class cz = real instanceof Field ? ((Field) real).getType() : ((Method) real).getReturnType(); Class cz = real instanceof Field ? ((Field) real).getType() : ((Method) real).getReturnType();
Type ct = real instanceof Field ? ((Field) real).getGenericType() : ((Method) real).getGenericReturnType(); Type ct = real instanceof Field
? ((Field) real).getGenericType()
: ((Method) real).getGenericReturnType();
if (cz == ct) { if (cz == ct) {
continue; continue;
} }
@@ -569,7 +683,8 @@ public final class ApiDocCommand {
sb.append("_"); sb.append("_");
} }
sb.append(subsb); sb.append(subsb);
} else if (member.getEncoder() instanceof ObjectEncoder || member.getEncoder() instanceof SimpledCoder) { } else if (member.getEncoder() instanceof ObjectEncoder
|| member.getEncoder() instanceof SimpledCoder) {
AccessibleObject real = member.getField() == null ? member.getMethod() : member.getField(); AccessibleObject real = member.getField() == null ? member.getMethod() : member.getField();
if (real == null) { if (real == null) {
continue; continue;
@@ -579,18 +694,33 @@ public final class ApiDocCommand {
} }
types.add(member.getEncoder().getType()); types.add(member.getEncoder().getType());
if (member.getEncoder() instanceof SimpledCoder) { if (member.getEncoder() instanceof SimpledCoder) {
simpleSchemaType(factory, logger, componentsMap, ((SimpledCoder) member.getEncoder()).getType(), simpleSchemaType(
((SimpledCoder) member.getEncoder()).getType(), new LinkedHashMap<>(), true); factory,
logger,
componentsMap,
((SimpledCoder) member.getEncoder()).getType(),
((SimpledCoder) member.getEncoder()).getType(),
new LinkedHashMap<>(),
true);
} else { } else {
simpleSchemaType(factory, logger, componentsMap, ((ObjectEncoder) member.getEncoder()).getTypeClass(), simpleSchemaType(
((ObjectEncoder) member.getEncoder()).getType(), new LinkedHashMap<>(), true); factory,
logger,
componentsMap,
((ObjectEncoder) member.getEncoder()).getTypeClass(),
((ObjectEncoder) member.getEncoder()).getType(),
new LinkedHashMap<>(),
true);
} }
Class cz = real instanceof Field ? ((Field) real).getType() : ((Method) real).getReturnType(); Class cz = real instanceof Field ? ((Field) real).getType() : ((Method) real).getReturnType();
Type ct = real instanceof Field ? ((Field) real).getGenericType() : ((Method) real).getGenericReturnType(); Type ct = real instanceof Field
? ((Field) real).getGenericType()
: ((Method) real).getGenericReturnType();
if (cz == ct) { if (cz == ct) {
continue; continue;
} }
String subsb = componentKey(factory, logger, types, componentsMap, member, member.getEncoder(), false); String subsb =
componentKey(factory, logger, types, componentsMap, member, member.getEncoder(), false);
if (subsb == null) { if (subsb == null) {
return null; return null;
} }
@@ -610,8 +740,9 @@ public final class ApiDocCommand {
return sb.toString(); return sb.toString();
} else if (encodeable instanceof ArrayEncoder || encodeable instanceof CollectionEncoder) { } else if (encodeable instanceof ArrayEncoder || encodeable instanceof CollectionEncoder) {
final boolean array = (encodeable instanceof ArrayEncoder); final boolean array = (encodeable instanceof ArrayEncoder);
Encodeable subEncodeable = array ? ((ArrayEncoder) encodeable).getComponentEncoder() Encodeable subEncodeable = array
: ((CollectionEncoder) encodeable).getComponentEncoder(); ? ((ArrayEncoder) encodeable).getComponentEncoder()
: ((CollectionEncoder) encodeable).getComponentEncoder();
if (subEncodeable instanceof SimpledCoder && field != null) { if (subEncodeable instanceof SimpledCoder && field != null) {
return ""; return "";
} }
@@ -625,8 +756,10 @@ public final class ApiDocCommand {
return sb + (array ? "_Array" : "_Collection"); return sb + (array ? "_Array" : "_Collection");
} else if (encodeable instanceof SimpledCoder) { } else if (encodeable instanceof SimpledCoder) {
Class stype = ((SimpledCoder) encodeable).getType(); Class stype = ((SimpledCoder) encodeable).getType();
if (stype.isPrimitive() || stype == Boolean.class if (stype.isPrimitive()
|| Number.class.isAssignableFrom(stype) || CharSequence.class.isAssignableFrom(stype)) { || stype == Boolean.class
|| Number.class.isAssignableFrom(stype)
|| CharSequence.class.isAssignableFrom(stype)) {
return stype.getSimpleName(); return stype.getSimpleName();
} }
return ""; return "";
@@ -657,21 +790,21 @@ public final class ApiDocCommand {
} else if (type.isPrimitive()) { } else if (type.isPrimitive()) {
return 0; return 0;
} else if (type == boolean[].class || type == Boolean[].class) { } else if (type == boolean[].class || type == Boolean[].class) {
return new boolean[]{true, false}; return new boolean[] {true, false};
} else if (type == byte[].class || type == Byte[].class) { } else if (type == byte[].class || type == Byte[].class) {
return new byte[]{0, 0}; return new byte[] {0, 0};
} else if (type == char[].class || type == Character[].class) { } else if (type == char[].class || type == Character[].class) {
return new char[]{'a', 'b'}; return new char[] {'a', 'b'};
} else if (type == short[].class || type == Short[].class) { } else if (type == short[].class || type == Short[].class) {
return new short[]{0, 0}; return new short[] {0, 0};
} else if (type == int[].class || type == Integer[].class) { } else if (type == int[].class || type == Integer[].class) {
return new int[]{0, 0}; return new int[] {0, 0};
} else if (type == long[].class || type == Long[].class) { } else if (type == long[].class || type == Long[].class) {
return new long[]{0, 0}; return new long[] {0, 0};
} else if (type == float[].class || type == Float[].class) { } else if (type == float[].class || type == Float[].class) {
return new float[]{0, 0}; return new float[] {0, 0};
} else if (type == double[].class || type == Double[].class) { } else if (type == double[].class || type == Double[].class) {
return new double[]{0, 0}; return new double[] {0, 0};
} else if (Number.class.isAssignableFrom(type)) { } else if (Number.class.isAssignableFrom(type)) {
return 0; return 0;
} else if (CharSequence.class.isAssignableFrom(type)) { } else if (CharSequence.class.isAssignableFrom(type)) {
@@ -681,44 +814,58 @@ public final class ApiDocCommand {
try { try {
ParameterizedType pt = (ParameterizedType) genericType; ParameterizedType pt = (ParameterizedType) genericType;
Type valType = pt.getActualTypeArguments()[0]; Type valType = pt.getActualTypeArguments()[0];
return formatExample(factory, example, valType instanceof ParameterizedType return formatExample(
? (Class) ((ParameterizedType) valType).getRawType() : ((Class) valType), valType); factory,
example,
valType instanceof ParameterizedType
? (Class) ((ParameterizedType) valType).getRawType()
: ((Class) valType),
valType);
} catch (Throwable t) { } catch (Throwable t) {
//do nothing // do nothing
} }
} }
} else if (Sheet.class.isAssignableFrom(type)) { //要在Collection前面 } else if (Sheet.class.isAssignableFrom(type)) { // 要在Collection前面
if (genericType instanceof ParameterizedType) { if (genericType instanceof ParameterizedType) {
try { try {
ParameterizedType pt = (ParameterizedType) genericType; ParameterizedType pt = (ParameterizedType) genericType;
Type valType = pt.getActualTypeArguments()[0]; Type valType = pt.getActualTypeArguments()[0];
Class valClass = valType instanceof ParameterizedType ? (Class) ((ParameterizedType) valType).getRawType() : (Class) valType; Class valClass = valType instanceof ParameterizedType
? (Class) ((ParameterizedType) valType).getRawType()
: (Class) valType;
Object val = formatExample(factory, example, valClass, valType); Object val = formatExample(factory, example, valClass, valType);
return new StringWrapper(jsonFactory.getConvert() return new StringWrapper(jsonFactory
.convertTo(jsonFactory.getConvert().convertFrom(genericType, "{'rows':[" + val + "," + val + "]}"))); .getConvert()
.convertTo(jsonFactory
.getConvert()
.convertFrom(genericType, "{'rows':[" + val + "," + val + "]}")));
} catch (Throwable t) { } catch (Throwable t) {
//do nothing // do nothing
} }
} }
} else if (type.isArray()) { } else if (type.isArray()) {
try { try {
Object val = formatExample(factory, example, type.getComponentType(), type.getComponentType()); Object val = formatExample(factory, example, type.getComponentType(), type.getComponentType());
return new StringWrapper(jsonFactory.getConvert() return new StringWrapper(jsonFactory
.convertTo(jsonFactory.getConvert().convertFrom(genericType, "[" + val + "," + val + "]"))); .getConvert()
.convertTo(jsonFactory.getConvert().convertFrom(genericType, "[" + val + "," + val + "]")));
} catch (Throwable t) { } catch (Throwable t) {
//do nothing // do nothing
} }
} else if (Collection.class.isAssignableFrom(type)) { } else if (Collection.class.isAssignableFrom(type)) {
if (genericType instanceof ParameterizedType) { if (genericType instanceof ParameterizedType) {
try { try {
ParameterizedType pt = (ParameterizedType) genericType; ParameterizedType pt = (ParameterizedType) genericType;
Type valType = pt.getActualTypeArguments()[0]; Type valType = pt.getActualTypeArguments()[0];
Class valClass = valType instanceof ParameterizedType ? (Class) ((ParameterizedType) valType).getRawType() : (Class) valType; Class valClass = valType instanceof ParameterizedType
? (Class) ((ParameterizedType) valType).getRawType()
: (Class) valType;
Object val = formatExample(factory, example, valClass, valType); Object val = formatExample(factory, example, valClass, valType);
return new StringWrapper(jsonFactory.getConvert() return new StringWrapper(jsonFactory
.convertTo(jsonFactory.getConvert().convertFrom(genericType, "[" + val + "," + val + "]"))); .getConvert()
.convertTo(jsonFactory.getConvert().convertFrom(genericType, "[" + val + "," + val + "]")));
} catch (Throwable t) { } catch (Throwable t) {
//do nothing // do nothing
} }
} }
} else if (type == RetResult.class) { } else if (type == RetResult.class) {
@@ -726,12 +873,15 @@ public final class ApiDocCommand {
try { try {
ParameterizedType pt = (ParameterizedType) genericType; ParameterizedType pt = (ParameterizedType) genericType;
Type valType = pt.getActualTypeArguments()[0]; Type valType = pt.getActualTypeArguments()[0];
Class valClass = valType instanceof ParameterizedType ? (Class) ((ParameterizedType) valType).getRawType() : (Class) valType; Class valClass = valType instanceof ParameterizedType
? (Class) ((ParameterizedType) valType).getRawType()
: (Class) valType;
Object val = formatExample(factory, example, valClass, valType); Object val = formatExample(factory, example, valClass, valType);
return new StringWrapper(jsonFactory.getConvert() return new StringWrapper(jsonFactory
.convertTo(jsonFactory.getConvert().convertFrom(genericType, "{'result':" + val + "}"))); .getConvert()
.convertTo(jsonFactory.getConvert().convertFrom(genericType, "{'result':" + val + "}")));
} catch (Throwable t) { } catch (Throwable t) {
//do nothing // do nothing
} }
} }
} else if (type != void.class) { } else if (type != void.class) {
@@ -758,12 +908,11 @@ public final class ApiDocCommand {
Creator creator = Creator.create(type); Creator creator = Creator.create(type);
return new StringWrapper(jsonFactory.getConvert().convertTo(creator.create())); return new StringWrapper(jsonFactory.getConvert().convertTo(creator.create()));
} catch (Throwable t) { } catch (Throwable t) {
//do nothing // do nothing
} }
} }
return example; return example;
} }
private static final JsonFactory exampleFactory = JsonFactory.create().withFeatures(0); private static final JsonFactory exampleFactory = JsonFactory.create().withFeatures(0);
} }

View File

@@ -3,6 +3,10 @@
*/ */
package org.redkale.boot; package org.redkale.boot;
import static org.redkale.boot.Application.*;
import static org.redkale.util.RedkaleClassLoader.putReflectionClass;
import static org.redkale.util.RedkaleClassLoader.putReflectionPublicConstructors;
import java.io.BufferedReader; import java.io.BufferedReader;
import java.io.File; import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
@@ -20,13 +24,10 @@ import java.util.List;
import java.util.Properties; import java.util.Properties;
import java.util.Set; import java.util.Set;
import java.util.logging.SimpleFormatter; import java.util.logging.SimpleFormatter;
import static org.redkale.boot.Application.*;
import org.redkale.source.DataSources; import org.redkale.source.DataSources;
import org.redkale.util.AnyValue; import org.redkale.util.AnyValue;
import org.redkale.util.AnyValueWriter; import org.redkale.util.AnyValueWriter;
import org.redkale.util.RedkaleClassLoader; import org.redkale.util.RedkaleClassLoader;
import static org.redkale.util.RedkaleClassLoader.putReflectionClass;
import static org.redkale.util.RedkaleClassLoader.putReflectionPublicConstructors;
import org.redkale.util.RedkaleException; import org.redkale.util.RedkaleException;
import org.redkale.util.Utility; import org.redkale.util.Utility;
@@ -43,46 +44,46 @@ class AppConfig {
*/ */
static final String PARAM_APP_CONF_FILE = "APP_CONF_FILE"; static final String PARAM_APP_CONF_FILE = "APP_CONF_FILE";
//是否用于main方法运行 // 是否用于main方法运行
final boolean singletonMode; final boolean singletonMode;
//是否用于编译模式运行 // 是否用于编译模式运行
final boolean compileMode; final boolean compileMode;
//application.xml原始配置信息 // application.xml原始配置信息
AnyValue config; AnyValue config;
//是否从/META-INF中读取配置 // 是否从/META-INF中读取配置
boolean configFromCache; boolean configFromCache;
//本进程节点ID // 本进程节点ID
String nodeid; String nodeid;
//本进程节点ID // 本进程节点ID
String name; String name;
//本地IP地址 // 本地IP地址
InetSocketAddress localAddress; InetSocketAddress localAddress;
//进程根目录 // 进程根目录
File home; File home;
//配置文件目录 // 配置文件目录
File confFile; File confFile;
//配置文件目录 // 配置文件目录
URI confDir; URI confDir;
//根ClassLoader // 根ClassLoader
RedkaleClassLoader classLoader; RedkaleClassLoader classLoader;
//Server根ClassLoader // Server根ClassLoader
RedkaleClassLoader serverClassLoader; RedkaleClassLoader serverClassLoader;
//本地文件日志配置项 // 本地文件日志配置项
final Properties locaLogProperties = new Properties(); final Properties locaLogProperties = new Properties();
//本地文件除logging配置之外的所有的配置项, 包含system.property.、mimetype.property.开头的 // 本地文件除logging配置之外的所有的配置项, 包含system.property.、mimetype.property.开头的
final Properties localEnvProperties = new Properties(); final Properties localEnvProperties = new Properties();
public AppConfig(boolean singletonMode, boolean compileMode) { public AppConfig(boolean singletonMode, boolean compileMode) {
@@ -101,21 +102,19 @@ class AppConfig {
this.name = checkName(config.getValue("name", "")); this.name = checkName(config.getValue("name", ""));
this.nodeid = checkNodeid(config.getValue("nodeid", String.valueOf(Math.abs(System.nanoTime())))); this.nodeid = checkNodeid(config.getValue("nodeid", String.valueOf(Math.abs(System.nanoTime()))));
this.configFromCache = "true".equals(config.getValue("[config-from-cache]")); this.configFromCache = "true".equals(config.getValue("[config-from-cache]"));
//初始化classLoader、serverClassLoader // 初始化classLoader、serverClassLoader
this.initClassLoader(); this.initClassLoader();
//初始化home、confDir、localAddress等信息 // 初始化home、confDir、localAddress等信息
this.initAppHome(); this.initAppHome();
//读取本地参数配置 // 读取本地参数配置
this.initLocalProperties(); this.initLocalProperties();
//读取本地日志配置 // 读取本地日志配置
this.initLogProperties(); this.initLogProperties();
//读取本地数据库配置 // 读取本地数据库配置
this.initSourceProperties(); this.initSourceProperties();
} }
/** /** 初始化classLoader、serverClassLoader */
* 初始化classLoader、serverClassLoader
*/
private void initClassLoader() { private void initClassLoader() {
ClassLoader currClassLoader = Thread.currentThread().getContextClassLoader(); ClassLoader currClassLoader = Thread.currentThread().getContextClassLoader();
if (currClassLoader instanceof RedkaleClassLoader) { if (currClassLoader instanceof RedkaleClassLoader) {
@@ -124,9 +123,11 @@ class AppConfig {
Set<String> cacheClasses = null; Set<String> cacheClasses = null;
if (!singletonMode && !compileMode) { if (!singletonMode && !compileMode) {
try { try {
InputStream in = Application.class.getResourceAsStream(RedkaleClassLoader.RESOURCE_CACHE_CLASSES_PATH); InputStream in =
Application.class.getResourceAsStream(RedkaleClassLoader.RESOURCE_CACHE_CLASSES_PATH);
if (in != null) { if (in != null) {
BufferedReader reader = new BufferedReader(new InputStreamReader(in, StandardCharsets.UTF_8), 1024); BufferedReader reader =
new BufferedReader(new InputStreamReader(in, StandardCharsets.UTF_8), 1024);
List<String> list = new ArrayList<>(); List<String> list = new ArrayList<>();
reader.lines().forEach(list::add); reader.lines().forEach(list::add);
Collections.sort(list); Collections.sort(list);
@@ -136,7 +137,7 @@ class AppConfig {
in.close(); in.close();
} }
} catch (Exception e) { } catch (Exception e) {
//do nothing // do nothing
} }
} }
if (cacheClasses == null) { if (cacheClasses == null) {
@@ -153,16 +154,16 @@ class AppConfig {
} }
} }
/** /** 初始化home、confDir、localAddress等信息 */
* 初始化home、confDir、localAddress等信息
*/
private void initAppHome() { private void initAppHome() {
final File root = new File(System.getProperty(RESNAME_APP_HOME, "")); final File root = new File(System.getProperty(RESNAME_APP_HOME, ""));
final String rootPath = getCanonicalPath(root); final String rootPath = getCanonicalPath(root);
this.home = new File(rootPath); this.home = new File(rootPath);
String confDir = System.getProperty(RESNAME_APP_CONF_DIR, "conf"); String confDir = System.getProperty(RESNAME_APP_CONF_DIR, "conf");
if (confDir.contains("://") || confDir.startsWith("file:") if (confDir.contains("://")
|| confDir.startsWith("resource:") || confDir.contains("!")) { //graalvm native-image startwith resource:META-INF || confDir.startsWith("file:")
|| confDir.startsWith("resource:")
|| confDir.contains("!")) { // graalvm native-image startwith resource:META-INF
this.confDir = URI.create(confDir); this.confDir = URI.create(confDir);
if (confDir.startsWith("file:")) { if (confDir.startsWith("file:")) {
this.confFile = getCanonicalFile(new File(this.confDir.getPath())); this.confFile = getCanonicalFile(new File(this.confDir.getPath()));
@@ -175,16 +176,15 @@ class AppConfig {
this.confDir = confFile.toURI(); this.confDir = confFile.toURI();
} }
String localaddr = config.getValue("address", "").trim(); String localaddr = config.getValue("address", "").trim();
InetAddress addr = localaddr.isEmpty() ? Utility.localInetAddress() InetAddress addr = localaddr.isEmpty()
: new InetSocketAddress(localaddr, config.getIntValue("port")).getAddress(); ? Utility.localInetAddress()
: new InetSocketAddress(localaddr, config.getIntValue("port")).getAddress();
this.localAddress = new InetSocketAddress(addr, config.getIntValue("port")); this.localAddress = new InetSocketAddress(addr, config.getIntValue("port"));
} }
/** /** 读取本地参数配置 */
* 读取本地参数配置
*/
private void initLocalProperties() { private void initLocalProperties() {
//环境变量的优先级最高 // 环境变量的优先级最高
System.getProperties().forEach((k, v) -> { System.getProperties().forEach((k, v) -> {
if (k.toString().startsWith("redkale.")) { if (k.toString().startsWith("redkale.")) {
localEnvProperties.put(k, v); localEnvProperties.put(k, v);
@@ -198,7 +198,7 @@ class AppConfig {
propsConf = resources.getAnyValue("properties"); propsConf = resources.getAnyValue("properties");
} }
} }
if (propsConf != null) { //设置配置文件中的系统变量 if (propsConf != null) { // 设置配置文件中的系统变量
for (AnyValue prop : propsConf.getAnyValues("property")) { for (AnyValue prop : propsConf.getAnyValues("property")) {
String key = prop.getValue("name", ""); String key = prop.getValue("name", "");
String value = prop.getValue("value"); String value = prop.getValue("value");
@@ -206,12 +206,14 @@ class AppConfig {
localEnvProperties.put(key, value); localEnvProperties.put(key, value);
} }
} }
if (propsConf.getValue("load") != null) { //加载本地配置项文件 if (propsConf.getValue("load") != null) { // 加载本地配置项文件
for (String dfload : propsConf.getValue("load").replace(',', ';').split(";")) { for (String dfload :
propsConf.getValue("load").replace(',', ';').split(";")) {
if (dfload.trim().isEmpty()) { if (dfload.trim().isEmpty()) {
continue; continue;
} }
final URI df = RedkaleClassLoader.getConfResourceAsURI(configFromCache ? null : this.confDir.toString(), dfload.trim()); final URI df = RedkaleClassLoader.getConfResourceAsURI(
configFromCache ? null : this.confDir.toString(), dfload.trim());
if (df == null) { if (df == null) {
continue; continue;
} }
@@ -229,20 +231,18 @@ class AppConfig {
} }
} }
} }
//设置Convert默认配置项 // 设置Convert默认配置项
if (System.getProperty("redkale.convert.pool.size") == null if (System.getProperty("redkale.convert.pool.size") == null
&& localEnvProperties.getProperty("system.property.redkale.convert.pool.size") == null) { && localEnvProperties.getProperty("system.property.redkale.convert.pool.size") == null) {
localEnvProperties.put("system.property.redkale.convert.pool.size", "128"); localEnvProperties.put("system.property.redkale.convert.pool.size", "128");
} }
if (System.getProperty("redkale.convert.writer.buffer.defsize") == null if (System.getProperty("redkale.convert.writer.buffer.defsize") == null
&& localEnvProperties.getProperty("system.property.redkale.convert.writer.buffer.defsize") == null) { && localEnvProperties.getProperty("system.property.redkale.convert.writer.buffer.defsize") == null) {
localEnvProperties.put("system.property.redkale.convert.writer.buffer.defsize", "4096"); localEnvProperties.put("system.property.redkale.convert.writer.buffer.defsize", "4096");
} }
} }
/** /** 读取本地DataSource、CacheSource配置 */
* 读取本地DataSource、CacheSource配置
*/
private void initSourceProperties() { private void initSourceProperties() {
if ("file".equals(this.confDir.getScheme())) { if ("file".equals(this.confDir.getScheme())) {
File sourceFile = new File(new File(confDir), "source.properties"); File sourceFile = new File(new File(confDir), "source.properties");
@@ -257,7 +257,7 @@ class AppConfig {
} }
this.localEnvProperties.putAll(props); this.localEnvProperties.putAll(props);
} else { } else {
//兼容 persistence.xml 【已废弃】 // 兼容 persistence.xml 【已废弃】
File persist = new File(new File(confDir), "persistence.xml"); File persist = new File(new File(confDir), "persistence.xml");
if (persist.isFile() && persist.canRead()) { if (persist.isFile() && persist.canRead()) {
System.err.println("persistence.xml is deprecated, replaced by source.properties"); System.err.println("persistence.xml is deprecated, replaced by source.properties");
@@ -270,23 +270,22 @@ class AppConfig {
} }
} }
} }
} else { //从url或jar文件中resources读取 } else { // 从url或jar文件中resources读取
try { try {
final URI sourceURI = RedkaleClassLoader.getConfResourceAsURI(configFromCache ? null : this.confDir.toString(), "source.properties"); final URI sourceURI = RedkaleClassLoader.getConfResourceAsURI(
configFromCache ? null : this.confDir.toString(), "source.properties");
InputStream in = sourceURI.toURL().openStream(); InputStream in = sourceURI.toURL().openStream();
Properties props = new Properties(); Properties props = new Properties();
props.load(in); props.load(in);
in.close(); in.close();
this.localEnvProperties.putAll(props); this.localEnvProperties.putAll(props);
} catch (Exception e) { } catch (Exception e) {
//没有文件 跳过 // 没有文件 跳过
} }
} }
} }
/** /** 读取本地日志配置 */
* 读取本地日志配置
*/
private void initLogProperties() { private void initLogProperties() {
URI logConfURI; URI logConfURI;
File logConfFile = null; File logConfFile = null;
@@ -317,9 +316,14 @@ class AppConfig {
putReflectionPublicConstructors(SimpleFormatter.class, SimpleFormatter.class.getName()); putReflectionPublicConstructors(SimpleFormatter.class, SimpleFormatter.class.getName());
putReflectionPublicConstructors(LoggingSearchHandler.class, LoggingSearchHandler.class.getName()); putReflectionPublicConstructors(LoggingSearchHandler.class, LoggingSearchHandler.class.getName());
putReflectionPublicConstructors(LoggingFileHandler.class, LoggingFileHandler.class.getName()); putReflectionPublicConstructors(LoggingFileHandler.class, LoggingFileHandler.class.getName());
putReflectionPublicConstructors(LoggingFileHandler.LoggingFormater.class, LoggingFileHandler.LoggingFormater.class.getName()); putReflectionPublicConstructors(
putReflectionPublicConstructors(LoggingFileHandler.LoggingConsoleHandler.class, LoggingFileHandler.LoggingConsoleHandler.class.getName()); LoggingFileHandler.LoggingFormater.class, LoggingFileHandler.LoggingFormater.class.getName());
putReflectionPublicConstructors(LoggingFileHandler.LoggingSncpFileHandler.class, LoggingFileHandler.LoggingSncpFileHandler.class.getName()); putReflectionPublicConstructors(
LoggingFileHandler.LoggingConsoleHandler.class,
LoggingFileHandler.LoggingConsoleHandler.class.getName());
putReflectionPublicConstructors(
LoggingFileHandler.LoggingSncpFileHandler.class,
LoggingFileHandler.LoggingSncpFileHandler.class.getName());
} }
} }
@@ -330,7 +334,9 @@ class AppConfig {
* @throws IOException * @throws IOException
*/ */
static AnyValue loadAppConfig() throws IOException { static AnyValue loadAppConfig() throws IOException {
final String home = new File(System.getProperty(RESNAME_APP_HOME, "")).getCanonicalPath().replace('\\', '/'); final String home = new File(System.getProperty(RESNAME_APP_HOME, ""))
.getCanonicalPath()
.replace('\\', '/');
String sysConfFile = System.getProperty(PARAM_APP_CONF_FILE); String sysConfFile = System.getProperty(PARAM_APP_CONF_FILE);
if (sysConfFile != null) { if (sysConfFile != null) {
String text; String text;
@@ -344,20 +350,22 @@ class AppConfig {
throw new IOException("Read application conf file (" + sysConfFile + ") error "); throw new IOException("Read application conf file (" + sysConfFile + ") error ");
} }
} }
return text.trim().startsWith("<") ? AnyValue.loadFromXml(text, (k, v) -> v.replace("${" + RESNAME_APP_HOME + "}", home)) return text.trim().startsWith("<")
.getAnyValue("application") : AnyValue.loadFromProperties(text).getAnyValue("redkale"); ? AnyValue.loadFromXml(text, (k, v) -> v.replace("${" + RESNAME_APP_HOME + "}", home))
.getAnyValue("application")
: AnyValue.loadFromProperties(text).getAnyValue("redkale");
} }
String confDir = System.getProperty(RESNAME_APP_CONF_DIR, "conf"); String confDir = System.getProperty(RESNAME_APP_CONF_DIR, "conf");
URI appConfFile; URI appConfFile;
boolean fromCache = false; boolean fromCache = false;
if (confDir.contains("://")) { //jar内部资源 if (confDir.contains("://")) { // jar内部资源
appConfFile = URI.create(confDir + (confDir.endsWith("/") ? "" : "/") + "application.xml"); appConfFile = URI.create(confDir + (confDir.endsWith("/") ? "" : "/") + "application.xml");
try { try {
appConfFile.toURL().openStream().close(); appConfFile.toURL().openStream().close();
} catch (IOException e) { //没有application.xml就尝试读application.properties } catch (IOException e) { // 没有application.xml就尝试读application.properties
appConfFile = URI.create(confDir + (confDir.endsWith("/") ? "" : "/") + "application.properties"); appConfFile = URI.create(confDir + (confDir.endsWith("/") ? "" : "/") + "application.properties");
} }
} else if (confDir.charAt(0) == '/' || confDir.indexOf(':') > 0) { //绝对路径 } else if (confDir.charAt(0) == '/' || confDir.indexOf(':') > 0) { // 绝对路径
File f = new File(confDir, "application.xml"); File f = new File(confDir, "application.xml");
if (f.isFile() && f.canRead()) { if (f.isFile() && f.canRead()) {
appConfFile = f.toURI(); appConfFile = f.toURI();
@@ -368,17 +376,20 @@ class AppConfig {
appConfFile = f.toURI(); appConfFile = f.toURI();
confDir = f.getParentFile().getCanonicalPath(); confDir = f.getParentFile().getCanonicalPath();
} else { } else {
appConfFile = RedkaleClassLoader.getConfResourceAsURI(null, "application.xml"); //不能传confDir appConfFile = RedkaleClassLoader.getConfResourceAsURI(null, "application.xml"); // 不能传confDir
try { try {
appConfFile.toURL().openStream().close(); appConfFile.toURL().openStream().close();
} catch (IOException e) { //没有application.xml就尝试读application.properties } catch (IOException e) { // 没有application.xml就尝试读application.properties
appConfFile = RedkaleClassLoader.getConfResourceAsURI(null, "application.properties"); appConfFile = RedkaleClassLoader.getConfResourceAsURI(null, "application.properties");
} }
confDir = appConfFile.toString().replace("/application.xml", "").replace("/application.properties", ""); confDir = appConfFile
.toString()
.replace("/application.xml", "")
.replace("/application.properties", "");
fromCache = true; fromCache = true;
} }
} }
} else { //相对路径 } else { // 相对路径
File f = new File(new File(home, confDir), "application.xml"); File f = new File(new File(home, confDir), "application.xml");
if (f.isFile() && f.canRead()) { if (f.isFile() && f.canRead()) {
appConfFile = f.toURI(); appConfFile = f.toURI();
@@ -389,13 +400,16 @@ class AppConfig {
appConfFile = f.toURI(); appConfFile = f.toURI();
confDir = f.getParentFile().getCanonicalPath(); confDir = f.getParentFile().getCanonicalPath();
} else { } else {
appConfFile = RedkaleClassLoader.getConfResourceAsURI(null, "application.xml"); //不能传confDir appConfFile = RedkaleClassLoader.getConfResourceAsURI(null, "application.xml"); // 不能传confDir
try { try {
appConfFile.toURL().openStream().close(); appConfFile.toURL().openStream().close();
} catch (IOException e) { //没有application.xml就尝试读application.properties } catch (IOException e) { // 没有application.xml就尝试读application.properties
appConfFile = RedkaleClassLoader.getConfResourceAsURI(null, "application.properties"); appConfFile = RedkaleClassLoader.getConfResourceAsURI(null, "application.properties");
} }
confDir = appConfFile.toString().replace("/application.xml", "").replace("/application.properties", ""); confDir = appConfFile
.toString()
.replace("/application.xml", "")
.replace("/application.properties", "");
fromCache = true; fromCache = true;
} }
} }
@@ -404,7 +418,8 @@ class AppConfig {
String text = Utility.readThenClose(appConfFile.toURL().openStream()); String text = Utility.readThenClose(appConfFile.toURL().openStream());
AnyValue conf; AnyValue conf;
if (text.trim().startsWith("<")) { if (text.trim().startsWith("<")) {
conf = AnyValue.loadFromXml(text, (k, v) -> v.replace("${APP_HOME}", home)).getAnyValue("application"); conf = AnyValue.loadFromXml(text, (k, v) -> v.replace("${APP_HOME}", home))
.getAnyValue("application");
} else { } else {
conf = AnyValue.loadFromProperties(text).getAnyValue("redkale"); conf = AnyValue.loadFromProperties(text).getAnyValue("redkale");
} }
@@ -419,7 +434,6 @@ class AppConfig {
* 检查name是否含特殊字符 * 检查name是否含特殊字符
* *
* @param name * @param name
*
* @return * @return
*/ */
private static String checkName(String name) { private static String checkName(String name) {
@@ -428,11 +442,11 @@ class AppConfig {
} }
for (char ch : name.toCharArray()) { for (char ch : name.toCharArray()) {
if (!((ch >= '0' && ch <= '9') if (!((ch >= '0' && ch <= '9')
|| (ch >= 'a' && ch <= 'z') || (ch >= 'a' && ch <= 'z')
|| (ch >= 'A' && ch <= 'Z') || (ch >= 'A' && ch <= 'Z')
|| ch == '_' || ch == '_'
|| ch == '.' || ch == '.'
|| ch == '-')) { //不能含特殊字符 || ch == '-')) { // 不能含特殊字符
throw new RedkaleException("name only 0-9 a-z A-Z _ - ."); throw new RedkaleException("name only 0-9 a-z A-Z _ - .");
} }
} }
@@ -443,7 +457,6 @@ class AppConfig {
* 检查node是否含特殊字符 * 检查node是否含特殊字符
* *
* @param name * @param name
*
* @return * @return
*/ */
private static String checkNodeid(String nodeid) { private static String checkNodeid(String nodeid) {
@@ -452,11 +465,11 @@ class AppConfig {
} }
for (char ch : nodeid.toCharArray()) { for (char ch : nodeid.toCharArray()) {
if (!((ch >= '0' && ch <= '9') if (!((ch >= '0' && ch <= '9')
|| (ch >= 'a' && ch <= 'z') || (ch >= 'a' && ch <= 'z')
|| (ch >= 'A' && ch <= 'Z') || (ch >= 'A' && ch <= 'Z')
|| ch == '_' || ch == '_'
|| ch == '.' || ch == '.'
|| ch == '-')) { //不能含特殊字符 || ch == '-')) { // 不能含特殊字符
throw new RedkaleException("nodeid only 0-9 a-z A-Z _ - ."); throw new RedkaleException("nodeid only 0-9 a-z A-Z _ - .");
} }
} }
@@ -478,5 +491,4 @@ class AppConfig {
return file; return file;
} }
} }
} }

File diff suppressed because it is too large Load Diff

View File

@@ -11,8 +11,7 @@ import org.redkale.util.AnyValue;
* Application启动和关闭时的监听事件 <br> * Application启动和关闭时的监听事件 <br>
* 只能通过application.xml配置 * 只能通过application.xml配置
* *
* <p> * <p>详情见: https://redkale.org
* 详情见: https://redkale.org
* *
* @author zhangjx * @author zhangjx
*/ */
@@ -23,63 +22,54 @@ public interface ApplicationListener {
* *
* @param config 配置参数 * @param config 配置参数
*/ */
default void init(AnyValue config) { default void init(AnyValue config) {}
}
/** /**
* Application在运行start前调用 * Application在运行start前调用
* *
* @param application Application * @param application Application
*/ */
default void onPreStart(Application application) { default void onPreStart(Application application) {}
}
/** /**
* 服务全部停掉前被调用 * 服务全部停掉前被调用
* *
* @param application Application * @param application Application
*/ */
default void onServersPreStop(Application application) { default void onServersPreStop(Application application) {}
}
/** /**
* 服务全部停掉后被调用 * 服务全部停掉后被调用
* *
* @param application Application * @param application Application
*/ */
default void onServersPostStop(Application application) { default void onServersPostStop(Application application) {}
}
/** /**
* Application在运行start后调用 * Application在运行start后调用
* *
* @param application Application * @param application Application
*/ */
default void onPostStart(Application application) { default void onPostStart(Application application) {}
}
/** /**
* Application在运行Compile前调用 * Application在运行Compile前调用
* *
* @param application Application * @param application Application
*/ */
default void onPreCompile(Application application) { default void onPreCompile(Application application) {}
}
/** /**
* Application在运行Compile后调用 * Application在运行Compile后调用
* *
* @param application Application * @param application Application
*/ */
default void onPostCompile(Application application) { default void onPostCompile(Application application) {}
}
/** /**
* Application在运行shutdown前调用 * Application在运行shutdown前调用
* *
* @param application Application * @param application Application
*/ */
default void onPreShutdown(Application application) { default void onPreShutdown(Application application) {}
}
} }

View File

@@ -10,10 +10,7 @@ import org.redkale.inject.ResourceEvent;
import org.redkale.inject.ResourceFactory; import org.redkale.inject.ResourceFactory;
import org.redkale.util.Environment; import org.redkale.util.Environment;
/** /** @author zhangjx */
*
* @author zhangjx
*/
public abstract class BootModule { public abstract class BootModule {
protected final Application application; protected final Application application;
@@ -46,7 +43,7 @@ public abstract class BootModule {
protected void onEnvironmentChanged(String namespace, List<ResourceEvent> events) { protected void onEnvironmentChanged(String namespace, List<ResourceEvent> events) {
if (namespace != null && namespace.contains("logging")) { if (namespace != null && namespace.contains("logging")) {
//日志配置单独处理 // 日志配置单独处理
application.loggingModule.onEnvironmentUpdated(events); application.loggingModule.onEnvironmentUpdated(events);
} else { } else {
application.onEnvironmentChanged(namespace, events); application.onEnvironmentChanged(namespace, events);

View File

@@ -22,8 +22,8 @@ import org.redkale.util.*;
/** /**
* class过滤器 符合条件的class会保留下来存入FilterEntry。 * class过滤器 符合条件的class会保留下来存入FilterEntry。
* <p> *
* 详情见: https://redkale.org * <p>详情见: https://redkale.org
* *
* @author zhangjx * @author zhangjx
* @param <T> 泛型 * @param <T> 泛型
@@ -31,35 +31,35 @@ import org.redkale.util.*;
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public final class ClassFilter<T> { public final class ClassFilter<T> {
private static final Logger logger = Logger.getLogger(ClassFilter.class.getName()); //日志对象 private static final Logger logger = Logger.getLogger(ClassFilter.class.getName()); // 日志对象
private final Set<FilterEntry<T>> entrys = new HashSet<>(); //符合条件的结果 private final Set<FilterEntry<T>> entrys = new HashSet<>(); // 符合条件的结果
private final Set<FilterEntry<T>> expectEntrys = new HashSet<>(); //准备符合条件的结果 private final Set<FilterEntry<T>> expectEntrys = new HashSet<>(); // 准备符合条件的结果
private Predicate<String> expectPredicate; private Predicate<String> expectPredicate;
private boolean refused; //是否拒绝所有数据,设置true则其他规则失效,都是拒绝. private boolean refused; // 是否拒绝所有数据,设置true则其他规则失效,都是拒绝.
private Class superClass; //符合的父类型。不为空时扫描结果的class必须是superClass的子类 private Class superClass; // 符合的父类型。不为空时扫描结果的class必须是superClass的子类
private Class[] excludeSuperClasses; //不符合的父类型。 private Class[] excludeSuperClasses; // 不符合的父类型。
private Class<? extends Annotation> annotationClass;//符合的注解。不为空时扫描结果的class必须包含该注解 private Class<? extends Annotation> annotationClass; // 符合的注解。不为空时扫描结果的class必须包含该注解
private Pattern[] includePatterns; //符合的className正则表达式 private Pattern[] includePatterns; // 符合的className正则表达式
private Pattern[] excludePatterns;//拒绝的className正则表达式 private Pattern[] excludePatterns; // 拒绝的className正则表达式
private Set<String> privilegeIncludes; //特批符合条件的className private Set<String> privilegeIncludes; // 特批符合条件的className
private Set<String> privilegeExcludes;//特批拒绝条件的className private Set<String> privilegeExcludes; // 特批拒绝条件的className
private List<ClassFilter> ors; //或关系的其他ClassFilter private List<ClassFilter> ors; // 或关系的其他ClassFilter
private List<ClassFilter> ands;//与关系的其他ClassFilter private List<ClassFilter> ands; // 与关系的其他ClassFilter
private AnyValue conf; //基本配置信息, 当符合条件时将conf的属性赋值到FilterEntry中去。 private AnyValue conf; // 基本配置信息, 当符合条件时将conf的属性赋值到FilterEntry中去。
private final ClassLoader classLoader; private final ClassLoader classLoader;
@@ -67,11 +67,20 @@ public final class ClassFilter<T> {
this(classLoader, annotationClass, superClass, (Class[]) null, null); this(classLoader, annotationClass, superClass, (Class[]) null, null);
} }
public ClassFilter(RedkaleClassLoader classLoader, Class<? extends Annotation> annotationClass, Class superClass, Class[] excludeSuperClasses) { public ClassFilter(
RedkaleClassLoader classLoader,
Class<? extends Annotation> annotationClass,
Class superClass,
Class[] excludeSuperClasses) {
this(classLoader, annotationClass, superClass, excludeSuperClasses, null); this(classLoader, annotationClass, superClass, excludeSuperClasses, null);
} }
public ClassFilter(RedkaleClassLoader classLoader, Class<? extends Annotation> annotationClass, Class superClass, Class[] excludeSuperClasses, AnyValue conf) { public ClassFilter(
RedkaleClassLoader classLoader,
Class<? extends Annotation> annotationClass,
Class superClass,
Class[] excludeSuperClasses,
AnyValue conf) {
this.annotationClass = annotationClass; this.annotationClass = annotationClass;
this.superClass = superClass; this.superClass = superClass;
this.excludeSuperClasses = excludeSuperClasses; this.excludeSuperClasses = excludeSuperClasses;
@@ -83,7 +92,13 @@ public final class ClassFilter<T> {
return create(null, null, includeRegxs, excludeRegxs, null, null); return create(null, null, includeRegxs, excludeRegxs, null, null);
} }
public static ClassFilter create(RedkaleClassLoader classLoader, Class[] excludeSuperClasses, String includeRegxs, String excludeRegxs, Set<String> includeValues, Set<String> excludeValues) { public static ClassFilter create(
RedkaleClassLoader classLoader,
Class[] excludeSuperClasses,
String includeRegxs,
String excludeRegxs,
Set<String> includeValues,
Set<String> excludeValues) {
ClassFilter filter = new ClassFilter(classLoader, null, null, excludeSuperClasses); ClassFilter filter = new ClassFilter(classLoader, null, null, excludeSuperClasses);
filter.setIncludePatterns(includeRegxs == null ? null : includeRegxs.split(";")); filter.setIncludePatterns(includeRegxs == null ? null : includeRegxs.split(";"));
filter.setExcludePatterns(excludeRegxs == null ? null : excludeRegxs.split(";")); filter.setExcludePatterns(excludeRegxs == null ? null : excludeRegxs.split(";"));
@@ -159,9 +174,9 @@ public final class ClassFilter<T> {
/** /**
* 自动扫描地过滤指定的class * 自动扫描地过滤指定的class
* *
* @param property AnyValue * @param property AnyValue
* @param clazzName String * @param clazzName String
* @param url URL * @param url URL
*/ */
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public final void filter(AnyValue property, String clazzName, URI url) { public final void filter(AnyValue property, String clazzName, URI url) {
@@ -171,9 +186,9 @@ public final class ClassFilter<T> {
/** /**
* 过滤指定的class * 过滤指定的class
* *
* @param property application.xml中对应class节点下的property属性项 * @param property application.xml中对应class节点下的property属性项
* @param clazzName class名称 * @param clazzName class名称
* @param autoscan 为true表示自动扫描的 false表示显著调用filter AutoLoad的注解将被忽略 * @param autoscan 为true表示自动扫描的 false表示显著调用filter AutoLoad的注解将被忽略
*/ */
public final void filter(AnyValue property, String clazzName, boolean autoscan) { public final void filter(AnyValue property, String clazzName, boolean autoscan) {
filter(property, clazzName, autoscan, null); filter(property, clazzName, autoscan, null);
@@ -182,10 +197,10 @@ public final class ClassFilter<T> {
/** /**
* 过滤指定的class * 过滤指定的class
* *
* @param property application.xml中对应class节点下的property属性项 * @param property application.xml中对应class节点下的property属性项
* @param clazzName class名称 * @param clazzName class名称
* @param autoScan 为true表示自动扫描的 false表示显著调用filter AutoLoad的注解将被忽略 * @param autoScan 为true表示自动扫描的 false表示显著调用filter AutoLoad的注解将被忽略
* @param url URL * @param url URL
*/ */
public final void filter(AnyValue property, String clazzName, boolean autoScan, URI url) { public final void filter(AnyValue property, String clazzName, boolean autoScan, URI url) {
boolean r = accept0(property, clazzName); boolean r = accept0(property, clazzName);
@@ -228,28 +243,40 @@ public final class ClassFilter<T> {
} }
AutoLoad auto = (AutoLoad) clazz.getAnnotation(AutoLoad.class); AutoLoad auto = (AutoLoad) clazz.getAnnotation(AutoLoad.class);
org.redkale.util.AutoLoad auto2 = (org.redkale.util.AutoLoad) clazz.getAnnotation(org.redkale.util.AutoLoad.class); org.redkale.util.AutoLoad auto2 =
if ((expectPredicate != null && expectPredicate.test(clazzName)) || (autoScan && auto != null && !auto.value()) (org.redkale.util.AutoLoad) clazz.getAnnotation(org.redkale.util.AutoLoad.class);
|| (autoScan && auto2 != null && !auto2.value())) { //自动扫描且被标记为@AutoLoad(false)的 if ((expectPredicate != null && expectPredicate.test(clazzName))
|| (autoScan && auto != null && !auto.value())
|| (autoScan && auto2 != null && !auto2.value())) { // 自动扫描且被标记为@AutoLoad(false)的
expectEntrys.add(new FilterEntry(clazz, autoScan, true, property)); expectEntrys.add(new FilterEntry(clazz, autoScan, true, property));
} else { } else {
entrys.add(new FilterEntry(clazz, autoScan, false, property)); entrys.add(new FilterEntry(clazz, autoScan, false, property));
} }
} catch (Throwable cfe) { } catch (Throwable cfe) {
if (logger.isLoggable(Level.FINEST) && !clazzName.startsWith("sun.") && !clazzName.startsWith("javax.") if (logger.isLoggable(Level.FINEST)
&& !clazzName.startsWith("com.sun.") && !clazzName.startsWith("jdk.") && !clazzName.startsWith("META-INF") && !clazzName.startsWith("sun.")
&& !clazzName.startsWith("com.mysql.") && !clazzName.startsWith("com.microsoft.") && !clazzName.startsWith("freemarker.") && !clazzName.startsWith("javax.")
&& !clazzName.startsWith("org.redkale") && (clazzName.contains("Service") || clazzName.contains("Servlet"))) { && !clazzName.startsWith("com.sun.")
&& !clazzName.startsWith("jdk.")
&& !clazzName.startsWith("META-INF")
&& !clazzName.startsWith("com.mysql.")
&& !clazzName.startsWith("com.microsoft.")
&& !clazzName.startsWith("freemarker.")
&& !clazzName.startsWith("org.redkale")
&& (clazzName.contains("Service") || clazzName.contains("Servlet"))) {
if (cfe instanceof NoClassDefFoundError) { if (cfe instanceof NoClassDefFoundError) {
String msg = ((NoClassDefFoundError) cfe).getMessage(); String msg = ((NoClassDefFoundError) cfe).getMessage();
if (msg.startsWith("java.lang.NoClassDefFoundError: java") || msg.startsWith("javax/")) { if (msg.startsWith("java.lang.NoClassDefFoundError: java") || msg.startsWith("javax/")) {
return; return;
} }
} }
//&& (!(cfe instanceof NoClassDefFoundError) || (cfe instanceof UnsupportedClassVersionError) // && (!(cfe instanceof NoClassDefFoundError) || (cfe instanceof UnsupportedClassVersionError)
//|| ((NoClassDefFoundError) cfe).getMessage().startsWith("java.lang.NoClassDefFoundError: java"))) { // || ((NoClassDefFoundError) cfe).getMessage().startsWith("java.lang.NoClassDefFoundError: java"))) {
logger.log(Level.FINEST, ClassFilter.class.getSimpleName() logger.log(
+ " filter error for class: " + clazzName + (url == null ? "" : (" in " + url)), cfe); Level.FINEST,
ClassFilter.class.getSimpleName() + " filter error for class: " + clazzName
+ (url == null ? "" : (" in " + url)),
cfe);
} }
} }
} }
@@ -258,7 +285,6 @@ public final class ClassFilter<T> {
* 判断class是否有效 * 判断class是否有效
* *
* @param className String * @param className String
*
* @return boolean * @return boolean
*/ */
public boolean accept(String className) { public boolean accept(String className) {
@@ -268,9 +294,8 @@ public final class ClassFilter<T> {
/** /**
* 判断class是否有效 * 判断class是否有效
* *
* @param property AnyValue * @param property AnyValue
* @param className String * @param className String
*
* @return boolean * @return boolean
*/ */
public boolean accept(AnyValue property, String className) { public boolean accept(AnyValue property, String className) {
@@ -327,9 +352,8 @@ public final class ClassFilter<T> {
* 判断class是否有效 * 判断class是否有效
* *
* @param property AnyValue * @param property AnyValue
* @param clazz Class * @param clazz Class
* @param autoscan boolean * @param autoscan boolean
*
* @return boolean * @return boolean
*/ */
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@@ -374,7 +398,7 @@ public final class ClassFilter<T> {
return ps; return ps;
} }
//将简化版正则转成标准的正则表达式 // 将简化版正则转成标准的正则表达式
// *.platf.* 转成 ^.*\.platf\..*$ // *.platf.* 转成 ^.*\.platf\..*$
// .platf. 转成 ^.*\.platf\..*$ // .platf. 转成 ^.*\.platf\..*$
private static String format(String regx) { private static String format(String regx) {
@@ -385,7 +409,7 @@ public final class ClassFilter<T> {
if (regx.startsWith("*") || regx.startsWith(".")) { if (regx.startsWith("*") || regx.startsWith(".")) {
str = "^.*" + str.substring(1); str = "^.*" + str.substring(1);
} }
return str.replace(new String(new char[]{8}), "\\."); return str.replace(new String(new char[] {8}), "\\.");
} }
public void setSuperClass(Class superClass) { public void setSuperClass(Class superClass) {
@@ -458,7 +482,6 @@ public final class ClassFilter<T> {
public void setPrivilegeExcludes(Set<String> privilegeExcludes) { public void setPrivilegeExcludes(Set<String> privilegeExcludes) {
this.privilegeExcludes = privilegeExcludes == null || privilegeExcludes.isEmpty() ? null : privilegeExcludes; this.privilegeExcludes = privilegeExcludes == null || privilegeExcludes.isEmpty() ? null : privilegeExcludes;
} }
/** /**
@@ -468,7 +491,7 @@ public final class ClassFilter<T> {
*/ */
public static final class FilterEntry<T> implements Comparable<FilterEntry<T>> { public static final class FilterEntry<T> implements Comparable<FilterEntry<T>> {
private final String group; //优先级高于remote属性 private final String group; // 优先级高于remote属性
private final String name; private final String name;
@@ -489,11 +512,12 @@ public final class ClassFilter<T> {
this.property = property; this.property = property;
this.autoload = autoload; this.autoload = autoload;
this.expect = expect; this.expect = expect;
this.group = property == null ? null : property.getValue("group", "").trim(); this.group =
property == null ? null : property.getValue("group", "").trim();
this.name = property == null ? "" : property.getValue("name", ""); this.name = property == null ? "" : property.getValue("name", "");
} }
@Override //@Priority值越大优先级越高, 需要排前面 @Override // @Priority值越大优先级越高, 需要排前面
public int compareTo(FilterEntry o) { public int compareTo(FilterEntry o) {
if (!(o instanceof FilterEntry)) { if (!(o instanceof FilterEntry)) {
return 1; return 1;
@@ -505,7 +529,8 @@ public final class ClassFilter<T> {
@Override @Override
public String toString() { public String toString() {
return this.getClass().getSimpleName() + "[type=" + this.type.getSimpleName() + ", name=" + name + ", group=" + this.group + "]"; return this.getClass().getSimpleName() + "[type=" + this.type.getSimpleName() + ", name=" + name
+ ", group=" + this.group + "]";
} }
@Override @Override
@@ -555,12 +580,9 @@ public final class ClassFilter<T> {
public boolean isExpect() { public boolean isExpect() {
return expect; return expect;
} }
} }
/** /** class加载类 */
* class加载类
*/
public static class Loader { public static class Loader {
protected static final Logger logger = Logger.getLogger(Loader.class.getName()); protected static final Logger logger = Logger.getLogger(Loader.class.getName());
@@ -568,7 +590,7 @@ public final class ClassFilter<T> {
protected static final ConcurrentMap<URI, Set<String>> cache = new ConcurrentHashMap<>(); protected static final ConcurrentMap<URI, Set<String>> cache = new ConcurrentHashMap<>();
private Loader() { private Loader() {
//do nothng // do nothng
} }
public static void close() { public static void close() {
@@ -579,12 +601,12 @@ public final class ClassFilter<T> {
* 加载当前线程的classpath扫描所有class进行过滤 * 加载当前线程的classpath扫描所有class进行过滤
* *
* @param excludeFile 不需要扫描的文件夹, 可以为null * @param excludeFile 不需要扫描的文件夹, 可以为null
* @param loader RedkaleClassloader 不可为null * @param loader RedkaleClassloader 不可为null
* @param filters 过滤器 * @param filters 过滤器
*
* @throws IOException 异常 * @throws IOException 异常
*/ */
public static void load(final File excludeFile, RedkaleClassLoader loader, final ClassFilter... filters) throws IOException { public static void load(final File excludeFile, RedkaleClassLoader loader, final ClassFilter... filters)
throws IOException {
List<URI> urlFiles = new ArrayList<>(2); List<URI> urlFiles = new ArrayList<>(2);
List<URI> urlJares = new ArrayList<>(2); List<URI> urlJares = new ArrayList<>(2);
final URI exurl = excludeFile != null ? excludeFile.toURI() : null; final URI exurl = excludeFile != null ? excludeFile.toURI() : null;
@@ -614,9 +636,9 @@ public final class ClassFilter<T> {
if (className.startsWith("javax.") || className.startsWith("com.sun.")) { if (className.startsWith("javax.") || className.startsWith("com.sun.")) {
continue; continue;
} }
//常见的jar跳过 // 常见的jar跳过
if (className.startsWith("org.redkaledyn.")) { if (className.startsWith("org.redkaledyn.")) {
break; //redkale动态生成的类 break; // redkale动态生成的类
} }
if (className.startsWith("org.junit.")) { if (className.startsWith("org.junit.")) {
break; break;
@@ -697,7 +719,10 @@ public final class ClassFilter<T> {
String rootPath = root.getPath(); String rootPath = root.getPath();
loadClassFiles(excludeFile, root, files); loadClassFiles(excludeFile, root, files);
for (File f : files) { for (File f : files) {
String className = f.getPath().substring(rootPath.length() + 1, f.getPath().length() - 6).replace(File.separatorChar, '.'); String className = f.getPath()
.substring(
rootPath.length() + 1, f.getPath().length() - 6)
.replace(File.separatorChar, '.');
if (className.startsWith("javax.") || className.startsWith("com.sun.")) { if (className.startsWith("javax.") || className.startsWith("com.sun.")) {
continue; continue;
} }
@@ -731,7 +756,7 @@ public final class ClassFilter<T> {
} }
} }
} }
//if (debug) logger.log(Level.INFO, "Scan classes: \r\n{0}", debugstr); // if (debug) logger.log(Level.INFO, "Scan classes: \r\n{0}", debugstr);
} }
private static void loadClassFiles(File exclude, File root, List<File> files) { private static void loadClassFiles(File exclude, File root, List<File> files) {

View File

@@ -8,36 +8,36 @@ import org.redkale.util.Traces;
/** /**
* Handler基类 * Handler基类
* <p> *
* 详情见: https://redkale.org * <p>详情见: https://redkale.org
* *
* @author zhangjx * @author zhangjx
* @since 2.7.0 * @since 2.7.0
*/ */
public abstract class LoggingBaseHandler extends Handler { public abstract class LoggingBaseHandler extends Handler {
//public static final String FORMATTER_FORMAT = "%1$tY-%1$tm-%1$td %1$tH:%1$tM:%1$tS.%tL %4$s %2$s%n%5$s%6$s%n"; // public static final String FORMATTER_FORMAT = "%1$tY-%1$tm-%1$td %1$tH:%1$tM:%1$tS.%tL %4$s %2$s%n%5$s%6$s%n";
//无threadName、TID // 无threadName、TID
public static final String FORMATTER_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"; public static final String FORMATTER_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";
//有threadName // 有threadName
public static final String FORMATTER_FORMAT2 = "[%1$tY-%1$tm-%1$td %1$tH:%1$tM:%1$tS.%tL] [%7$s] %4$s %2$s\r\n%5$s%6$s\r\n"; public static final String FORMATTER_FORMAT2 =
"[%1$tY-%1$tm-%1$td %1$tH:%1$tM:%1$tS.%tL] [%7$s] %4$s %2$s\r\n%5$s%6$s\r\n";
//有threadName、TID // 有threadName、TID
public static final String FORMATTER_FORMAT3 = "[%1$tY-%1$tm-%1$td %1$tH:%1$tM:%1$tS.%tL] [%7$s] %8$s %4$s %2$s\r\n%5$s%6$s\r\n"; public static final String FORMATTER_FORMAT3 =
"[%1$tY-%1$tm-%1$td %1$tH:%1$tM:%1$tS.%tL] [%7$s] %8$s %4$s %2$s\r\n%5$s%6$s\r\n";
static boolean traceEnable = false; //防止设置system.property前调用Traces类导致enable提前初始化 static boolean traceEnable = false; // 防止设置system.property前调用Traces类导致enable提前初始化
/** /** 默认的日志时间格式化类 与SimpleFormatter的区别在于level不使用本地化 */
* 默认的日志时间格式化类
* 与SimpleFormatter的区别在于level不使用本地化
*
*/
public static class LoggingFormater extends Formatter { public static class LoggingFormater extends Formatter {
@Override @Override
public String format(LogRecord log) { public String format(LogRecord log) {
if (log.getThrown() == null && log.getMessage() != null && log.getMessage().startsWith("------")) { if (log.getThrown() == null
&& log.getMessage() != null
&& log.getMessage().startsWith("------")) {
return formatMessage(log) + "\r\n"; return formatMessage(log) + "\r\n";
} }
String source; String source;
@@ -67,33 +67,36 @@ public abstract class LoggingBaseHandler extends Handler {
Object[] params = log.getParameters(); Object[] params = log.getParameters();
if (params != null) { if (params != null) {
if (params.length == 1) { if (params.length == 1) {
return String.format(FORMATTER_FORMAT2, return String.format(
log.getInstant().toEpochMilli(), FORMATTER_FORMAT2,
source, log.getInstant().toEpochMilli(),
log.getLoggerName(), source,
log.getLevel().getName(), log.getLoggerName(),
message, log.getLevel().getName(),
throwable, message,
params[0]); throwable,
params[0]);
} else if (params.length == 2) { } else if (params.length == 2) {
return String.format(FORMATTER_FORMAT3, return String.format(
log.getInstant().toEpochMilli(), FORMATTER_FORMAT3,
source, log.getInstant().toEpochMilli(),
log.getLoggerName(), source,
log.getLevel().getName(), log.getLoggerName(),
message, log.getLevel().getName(),
throwable, message,
params[0], throwable,
params[1]); params[0],
params[1]);
} }
} }
return String.format(FORMATTER_FORMAT, return String.format(
log.getInstant().toEpochMilli(), FORMATTER_FORMAT,
source, log.getInstant().toEpochMilli(),
log.getLoggerName(), source,
log.getLevel().getName(), log.getLoggerName(),
message, log.getLevel().getName(),
throwable); message,
throwable);
} }
} }
@@ -108,9 +111,9 @@ public abstract class LoggingBaseHandler extends Handler {
} }
} }
if (traceid == null) { if (traceid == null) {
log.setParameters(new String[]{Thread.currentThread().getName()}); log.setParameters(new String[] {Thread.currentThread().getName()});
} else { } else {
log.setParameters(new String[]{Thread.currentThread().getName(), traceid}); log.setParameters(new String[] {Thread.currentThread().getName(), traceid});
} }
} }
@@ -118,7 +121,8 @@ public abstract class LoggingBaseHandler extends Handler {
try { try {
ByteArrayOutputStream out = new ByteArrayOutputStream(); ByteArrayOutputStream out = new ByteArrayOutputStream();
final PrintStream ps = new PrintStream(out); final PrintStream ps = new PrintStream(out);
final String handlerName = LoggingFileHandler.LoggingConsoleHandler.class.getName(); //java.util.logging.ConsoleHandler final String handlerName =
LoggingFileHandler.LoggingConsoleHandler.class.getName(); // java.util.logging.ConsoleHandler
ps.println("handlers = " + handlerName); ps.println("handlers = " + handlerName);
ps.println(".level = FINEST"); ps.println(".level = FINEST");
ps.println("jdk.level = INFO"); ps.println("jdk.level = INFO");
@@ -131,8 +135,7 @@ public abstract class LoggingBaseHandler extends Handler {
ps.println(handlerName + ".formatter = " + LoggingFormater.class.getName()); ps.println(handlerName + ".formatter = " + LoggingFormater.class.getName());
LogManager.getLogManager().readConfiguration(new ByteArrayInputStream(out.toByteArray())); LogManager.getLogManager().readConfiguration(new ByteArrayInputStream(out.toByteArray()));
} catch (Exception e) { } catch (Exception e) {
//do nothing // do nothing
} }
} }
} }

View File

@@ -5,9 +5,10 @@
*/ */
package org.redkale.boot; package org.redkale.boot;
import static java.nio.file.StandardCopyOption.*;
import java.io.*; import java.io.*;
import java.nio.file.Files; import java.nio.file.Files;
import static java.nio.file.StandardCopyOption.*;
import java.util.Calendar; import java.util.Calendar;
import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.atomic.*; import java.util.concurrent.atomic.*;
@@ -17,17 +18,15 @@ import org.redkale.util.*;
/** /**
* 自定义的日志输出类 * 自定义的日志输出类
* <p> *
* 详情见: https://redkale.org * <p>详情见: https://redkale.org
* *
* @author zhangjx * @author zhangjx
*/ */
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public class LoggingFileHandler extends LoggingBaseHandler { public class LoggingFileHandler extends LoggingBaseHandler {
/** /** SNCP的日志输出Handler */
* SNCP的日志输出Handler
*/
public static class LoggingSncpFileHandler extends LoggingFileHandler { public static class LoggingSncpFileHandler extends LoggingFileHandler {
@Override @Override
@@ -57,7 +56,7 @@ public class LoggingFileHandler extends LoggingBaseHandler {
this.denyRegx = Pattern.compile(denyregxstr); this.denyRegx = Pattern.compile(denyregxstr);
} }
} catch (Exception e) { } catch (Exception e) {
//do nothing // do nothing
} }
} }
@@ -75,19 +74,19 @@ public class LoggingFileHandler extends LoggingBaseHandler {
protected String pattern; protected String pattern;
protected String patternDateFormat; //需要时间格式化 protected String patternDateFormat; // 需要时间格式化
protected String unusual; //不为null表示将 WARNING、SEVERE 级别的日志写入单独的文件中 protected String unusual; // 不为null表示将 WARNING、SEVERE 级别的日志写入单独的文件中
protected String unusualDateFormat; //需要时间格式化 protected String unusualDateFormat; // 需要时间格式化
private int limit; //文件大小限制 private int limit; // 文件大小限制
private final AtomicInteger logIndex = new AtomicInteger(); private final AtomicInteger logIndex = new AtomicInteger();
private final AtomicInteger logUnusualIndex = new AtomicInteger(); private final AtomicInteger logUnusualIndex = new AtomicInteger();
private int count = 1; //文件限制 private int count = 1; // 文件限制
private long tomorrow; private long tomorrow;
@@ -150,10 +149,18 @@ public class LoggingFileHandler extends LoggingBaseHandler {
for (int i = Math.min(count - 2, logIndex.get() - 1); i > 0; i--) { for (int i = Math.min(count - 2, logIndex.get() - 1); i > 0; i--) {
File greater = new File(logFile.getPath() + "." + i); File greater = new File(logFile.getPath() + "." + i);
if (greater.exists()) { if (greater.exists()) {
Files.move(greater.toPath(), new File(logFile.getPath() + "." + (i + 1)).toPath(), REPLACE_EXISTING, ATOMIC_MOVE); 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); Files.move(
logFile.toPath(),
new File(logFile.getPath() + ".1").toPath(),
REPLACE_EXISTING,
ATOMIC_MOVE);
} else { } else {
if (logFile.exists() && logFile.length() < 1) { if (logFile.exists() && logFile.length() < 1) {
Files.delete(logFile.toPath()); Files.delete(logFile.toPath());
@@ -168,10 +175,18 @@ public class LoggingFileHandler extends LoggingBaseHandler {
for (int i = Math.min(count - 2, logUnusualIndex.get() - 1); i > 0; i--) { for (int i = Math.min(count - 2, logUnusualIndex.get() - 1); i > 0; i--) {
File greater = new File(logUnusualFile.getPath() + "." + i); File greater = new File(logUnusualFile.getPath() + "." + i);
if (greater.exists()) { if (greater.exists()) {
Files.move(greater.toPath(), new File(logUnusualFile.getPath() + "." + (i + 1)).toPath(), REPLACE_EXISTING, ATOMIC_MOVE); Files.move(
greater.toPath(),
new File(logUnusualFile.getPath() + "." + (i + 1)).toPath(),
REPLACE_EXISTING,
ATOMIC_MOVE);
} }
} }
Files.move(logUnusualFile.toPath(), new File(logUnusualFile.getPath() + ".1").toPath(), REPLACE_EXISTING, ATOMIC_MOVE); Files.move(
logUnusualFile.toPath(),
new File(logUnusualFile.getPath() + ".1").toPath(),
REPLACE_EXISTING,
ATOMIC_MOVE);
} else { } else {
if (logUnusualFile.exists() && logUnusualFile.length() < 1) { if (logUnusualFile.exists() && logUnusualFile.length() < 1) {
Files.delete(logUnusualFile.toPath()); Files.delete(logUnusualFile.toPath());
@@ -181,19 +196,25 @@ public class LoggingFileHandler extends LoggingBaseHandler {
} }
if (logStream == null) { if (logStream == null) {
logIndex.incrementAndGet(); logIndex.incrementAndGet();
logFile = new File(patternDateFormat == null ? pattern : Times.formatTime(patternDateFormat, -1, System.currentTimeMillis())); logFile = new File(
patternDateFormat == null
? pattern
: Times.formatTime(patternDateFormat, -1, System.currentTimeMillis()));
logFile.getParentFile().mkdirs(); logFile.getParentFile().mkdirs();
logLength.set(logFile.length()); logLength.set(logFile.length());
logStream = new FileOutputStream(logFile, append); logStream = new FileOutputStream(logFile, append);
} }
if (unusual != null && logUnusualStream == null) { if (unusual != null && logUnusualStream == null) {
logUnusualIndex.incrementAndGet(); logUnusualIndex.incrementAndGet();
logUnusualFile = new File(unusualDateFormat == null ? unusual : Times.formatTime(unusualDateFormat, -1, System.currentTimeMillis())); logUnusualFile = new File(
unusualDateFormat == null
? unusual
: Times.formatTime(unusualDateFormat, -1, System.currentTimeMillis()));
logUnusualFile.getParentFile().mkdirs(); logUnusualFile.getParentFile().mkdirs();
logUnusualLength.set(logUnusualFile.length()); logUnusualLength.set(logUnusualFile.length());
logUnusualStream = new FileOutputStream(logUnusualFile, append); logUnusualStream = new FileOutputStream(logUnusualFile, append);
} }
//----------------------写日志------------------------- // ----------------------写日志-------------------------
String message = getFormatter().format(log); String message = getFormatter().format(log);
String encoding = getEncoding(); String encoding = getEncoding();
byte[] bytes = encoding == null ? message.getBytes() : message.getBytes(encoding); byte[] bytes = encoding == null ? message.getBytes() : message.getBytes(encoding);
@@ -210,7 +231,6 @@ public class LoggingFileHandler extends LoggingBaseHandler {
} }
} }
} }
} }
}.start(); }.start();
} }
@@ -233,9 +253,9 @@ public class LoggingFileHandler extends LoggingBaseHandler {
this.pattern = getPrefix() + this.pattern; this.pattern = getPrefix() + this.pattern;
} }
} }
if (this.pattern != null && this.pattern.contains("%")) { //需要时间格式化 if (this.pattern != null && this.pattern.contains("%")) { // 需要时间格式化
this.patternDateFormat = this.pattern; this.patternDateFormat = this.pattern;
Times.formatTime(this.patternDateFormat, -1, System.currentTimeMillis()); //测试时间格式是否正确 Times.formatTime(this.patternDateFormat, -1, System.currentTimeMillis()); // 测试时间格式是否正确
} }
String unusualstr = manager.getProperty(cname + ".unusual"); String unusualstr = manager.getProperty(cname + ".unusual");
if (unusualstr != null) { if (unusualstr != null) {
@@ -246,9 +266,9 @@ public class LoggingFileHandler extends LoggingBaseHandler {
this.unusual = getPrefix() + unusualstr; this.unusual = getPrefix() + unusualstr;
} }
} }
if (this.unusual != null && this.unusual.contains("%")) { //需要时间格式化 if (this.unusual != null && this.unusual.contains("%")) { // 需要时间格式化
this.unusualDateFormat = this.unusual; this.unusualDateFormat = this.unusual;
Times.formatTime(this.unusualDateFormat, -1, System.currentTimeMillis()); //测试时间格式是否正确 Times.formatTime(this.unusualDateFormat, -1, System.currentTimeMillis()); // 测试时间格式是否正确
} }
String limitstr = manager.getProperty(cname + ".limit"); String limitstr = manager.getProperty(cname + ".limit");
try { try {
@@ -257,7 +277,10 @@ public class LoggingFileHandler extends LoggingBaseHandler {
boolean g = limitstr.indexOf('G') > 0; boolean g = limitstr.indexOf('G') > 0;
boolean m = limitstr.indexOf('M') > 0; boolean m = limitstr.indexOf('M') > 0;
boolean k = limitstr.indexOf('K') > 0; boolean k = limitstr.indexOf('K') > 0;
int ls = Math.abs(Integer.decode(limitstr.replace("G", "").replace("M", "").replace("K", "").replace("B", ""))); int ls = Math.abs(Integer.decode(limitstr.replace("G", "")
.replace("M", "")
.replace("K", "")
.replace("B", "")));
if (g) { if (g) {
ls *= 1024 * 1024 * 1024; ls *= 1024 * 1024 * 1024;
} else if (m) { } else if (m) {
@@ -268,7 +291,7 @@ public class LoggingFileHandler extends LoggingBaseHandler {
this.limit = ls; this.limit = ls;
} }
} catch (Exception e) { } catch (Exception e) {
//do nothing // do nothing
} }
String countstr = manager.getProperty(cname + ".count"); String countstr = manager.getProperty(cname + ".count");
try { try {
@@ -276,7 +299,7 @@ public class LoggingFileHandler extends LoggingBaseHandler {
this.count = Math.max(1, Math.abs(Integer.decode(countstr))); this.count = Math.max(1, Math.abs(Integer.decode(countstr)));
} }
} catch (Exception e) { } catch (Exception e) {
//do nothing // do nothing
} }
String appendstr = manager.getProperty(cname + ".append"); String appendstr = manager.getProperty(cname + ".append");
try { try {
@@ -284,7 +307,7 @@ public class LoggingFileHandler extends LoggingBaseHandler {
this.append = "true".equalsIgnoreCase(appendstr) || "1".equals(appendstr); this.append = "true".equalsIgnoreCase(appendstr) || "1".equals(appendstr);
} }
} catch (Exception e) { } catch (Exception e) {
//do nothing // do nothing
} }
String levelstr = manager.getProperty(cname + ".level"); String levelstr = manager.getProperty(cname + ".level");
try { try {
@@ -293,7 +316,7 @@ public class LoggingFileHandler extends LoggingBaseHandler {
setLevel(l != null ? l : Level.ALL); setLevel(l != null ? l : Level.ALL);
} }
} catch (Exception e) { } catch (Exception e) {
//do nothing // do nothing
} }
String filterstr = manager.getProperty(cname + ".filter"); String filterstr = manager.getProperty(cname + ".filter");
try { try {
@@ -303,7 +326,7 @@ public class LoggingFileHandler extends LoggingBaseHandler {
setFilter((Filter) clz.getDeclaredConstructor().newInstance()); setFilter((Filter) clz.getDeclaredConstructor().newInstance());
} }
} catch (Exception e) { } catch (Exception e) {
//do nothing // do nothing
} }
String formatterstr = manager.getProperty(cname + ".formatter"); String formatterstr = manager.getProperty(cname + ".formatter");
try { try {
@@ -313,7 +336,7 @@ public class LoggingFileHandler extends LoggingBaseHandler {
setFormatter((Formatter) clz.getDeclaredConstructor().newInstance()); setFormatter((Formatter) clz.getDeclaredConstructor().newInstance());
} }
} catch (Exception e) { } catch (Exception e) {
//do nothing // do nothing
} }
if (getFormatter() == null) { if (getFormatter() == null) {
setFormatter(new SimpleFormatter()); setFormatter(new SimpleFormatter());
@@ -325,7 +348,7 @@ public class LoggingFileHandler extends LoggingBaseHandler {
setEncoding(encodingstr); setEncoding(encodingstr);
} }
} catch (Exception e) { } catch (Exception e) {
//do nothing // do nothing
} }
String denyregxstr = manager.getProperty(cname + ".denyregx"); String denyregxstr = manager.getProperty(cname + ".denyregx");
@@ -334,7 +357,7 @@ public class LoggingFileHandler extends LoggingBaseHandler {
denyRegx = Pattern.compile(denyregxstr); denyRegx = Pattern.compile(denyregxstr);
} }
} catch (Exception e) { } catch (Exception e) {
//do nothing // do nothing
} }
} }
@@ -377,5 +400,4 @@ public class LoggingFileHandler extends LoggingBaseHandler {
} }
} }
} }
} }

View File

@@ -22,19 +22,16 @@ import org.redkale.net.sncp.SncpClient;
import org.redkale.util.Environment; import org.redkale.util.Environment;
/** /**
*
* 日志模块组件 * 日志模块组件
* *
* <p> * <p>详情见: https://redkale.org
* 详情见: https://redkale.org
* *
* @author zhangjx * @author zhangjx
*
* @since 2.8.0 * @since 2.8.0
*/ */
class LoggingModule extends BootModule { class LoggingModule extends BootModule {
//日志配置资源 // 日志配置资源
private final Properties loggingProperties = new Properties(); private final Properties loggingProperties = new Properties();
LoggingModule(Application application) { LoggingModule(Application application) {
@@ -69,7 +66,7 @@ class LoggingModule extends BootModule {
/** /**
* 设置日志策略 * 设置日志策略
* *
* @param first 是否首次设置 * @param first 是否首次设置
* @param allProps 配置项全量 * @param allProps 配置项全量
*/ */
public void reconfigLogging(boolean first, Properties allProps) { public void reconfigLogging(boolean first, Properties allProps) {
@@ -80,9 +77,11 @@ class LoggingModule extends BootModule {
allProps.entrySet().forEach(x -> { allProps.entrySet().forEach(x -> {
String key = x.getKey().toString(); String key = x.getKey().toString();
if (key.startsWith("java.util.logging.") || key.contains(".level") || key.equals("handlers")) { if (key.startsWith("java.util.logging.") || key.contains(".level") || key.equals("handlers")) {
String val = envs.getPropertyValue(x.getValue().toString() String val = envs.getPropertyValue(x.getValue()
.replace("%m", "%tY%tm").replace("%d", "%tY%tm%td") //兼容旧时间格式 .toString()
.replace(searchRawHandler, searchReadHandler)); .replace("%m", "%tY%tm")
.replace("%d", "%tY%tm%td") // 兼容旧时间格式
.replace(searchRawHandler, searchReadHandler));
onlyLogProps.put(key.replace(searchRawHandler, searchReadHandler), val); onlyLogProps.put(key.replace(searchRawHandler, searchReadHandler), val);
} }
}); });
@@ -90,32 +89,42 @@ class LoggingModule extends BootModule {
if (application.isCompileMode()) { if (application.isCompileMode()) {
onlyLogProps.setProperty("java.util.logging.FileHandler.formatter", SimpleFormatter.class.getName()); onlyLogProps.setProperty("java.util.logging.FileHandler.formatter", SimpleFormatter.class.getName());
if (onlyLogProps.getProperty("java.util.logging.SimpleFormatter.format") == null) { if (onlyLogProps.getProperty("java.util.logging.SimpleFormatter.format") == null) {
onlyLogProps.setProperty("java.util.logging.SimpleFormatter.format", LoggingFileHandler.FORMATTER_FORMAT.replaceAll("\r\n", "%n")); onlyLogProps.setProperty(
"java.util.logging.SimpleFormatter.format",
LoggingFileHandler.FORMATTER_FORMAT.replaceAll("\r\n", "%n"));
} }
} else { } else {
onlyLogProps.setProperty("java.util.logging.FileHandler.formatter", LoggingFileHandler.LoggingFormater.class.getName()); onlyLogProps.setProperty(
"java.util.logging.FileHandler.formatter", LoggingFileHandler.LoggingFormater.class.getName());
} }
} }
if (onlyLogProps.getProperty("java.util.logging.ConsoleHandler.formatter") == null) { if (onlyLogProps.getProperty("java.util.logging.ConsoleHandler.formatter") == null) {
if (application.isCompileMode()) { if (application.isCompileMode()) {
onlyLogProps.setProperty("java.util.logging.ConsoleHandler.formatter", SimpleFormatter.class.getName()); onlyLogProps.setProperty("java.util.logging.ConsoleHandler.formatter", SimpleFormatter.class.getName());
if (onlyLogProps.getProperty("java.util.logging.SimpleFormatter.format") == null) { if (onlyLogProps.getProperty("java.util.logging.SimpleFormatter.format") == null) {
onlyLogProps.setProperty("java.util.logging.SimpleFormatter.format", LoggingFileHandler.FORMATTER_FORMAT.replaceAll("\r\n", "%n")); onlyLogProps.setProperty(
"java.util.logging.SimpleFormatter.format",
LoggingFileHandler.FORMATTER_FORMAT.replaceAll("\r\n", "%n"));
} }
} else { } else {
onlyLogProps.setProperty("java.util.logging.ConsoleHandler.formatter", LoggingFileHandler.LoggingFormater.class.getName()); onlyLogProps.setProperty(
"java.util.logging.ConsoleHandler.formatter",
LoggingFileHandler.LoggingFormater.class.getName());
} }
} }
if (!application.isCompileMode()) { //ConsoleHandler替换成LoggingConsoleHandler if (!application.isCompileMode()) { // ConsoleHandler替换成LoggingConsoleHandler
final String handlers = onlyLogProps.getProperty("handlers"); final String handlers = onlyLogProps.getProperty("handlers");
if (handlers != null && handlers.contains("java.util.logging.ConsoleHandler")) { if (handlers != null && handlers.contains("java.util.logging.ConsoleHandler")) {
final String consoleHandlerClass = LoggingFileHandler.LoggingConsoleHandler.class.getName(); final String consoleHandlerClass = LoggingFileHandler.LoggingConsoleHandler.class.getName();
onlyLogProps.setProperty("handlers", handlers.replace("java.util.logging.ConsoleHandler", consoleHandlerClass)); onlyLogProps.setProperty(
"handlers", handlers.replace("java.util.logging.ConsoleHandler", consoleHandlerClass));
Properties prop = new Properties(); Properties prop = new Properties();
String prefix = consoleHandlerClass + "."; String prefix = consoleHandlerClass + ".";
onlyLogProps.entrySet().forEach(x -> { onlyLogProps.entrySet().forEach(x -> {
if (x.getKey().toString().startsWith("java.util.logging.ConsoleHandler.")) { if (x.getKey().toString().startsWith("java.util.logging.ConsoleHandler.")) {
prop.put(x.getKey().toString().replace("java.util.logging.ConsoleHandler.", prefix), x.getValue()); prop.put(
x.getKey().toString().replace("java.util.logging.ConsoleHandler.", prefix),
x.getValue());
} }
}); });
prop.entrySet().forEach(x -> { prop.entrySet().forEach(x -> {
@@ -124,14 +133,17 @@ class LoggingModule extends BootModule {
} }
} }
String fileHandlerPattern = onlyLogProps.getProperty("java.util.logging.FileHandler.pattern"); String fileHandlerPattern = onlyLogProps.getProperty("java.util.logging.FileHandler.pattern");
if (fileHandlerPattern != null && fileHandlerPattern.contains("%")) { //带日期格式 if (fileHandlerPattern != null && fileHandlerPattern.contains("%")) { // 带日期格式
final String fileHandlerClass = LoggingFileHandler.class.getName(); final String fileHandlerClass = LoggingFileHandler.class.getName();
Properties prop = new Properties(); Properties prop = new Properties();
final String handlers = onlyLogProps.getProperty("handlers"); final String handlers = onlyLogProps.getProperty("handlers");
if (handlers != null && handlers.contains("java.util.logging.FileHandler")) { if (handlers != null && handlers.contains("java.util.logging.FileHandler")) {
//singletonrun模式下不输出文件日志 // singletonrun模式下不输出文件日志
prop.setProperty("handlers", handlers.replace("java.util.logging.FileHandler", prop.setProperty(
application.isSingletonMode() || application.isCompileMode() ? "" : fileHandlerClass)); "handlers",
handlers.replace(
"java.util.logging.FileHandler",
application.isSingletonMode() || application.isCompileMode() ? "" : fileHandlerClass));
} }
if (!prop.isEmpty()) { if (!prop.isEmpty()) {
String prefix = fileHandlerClass + "."; String prefix = fileHandlerClass + ".";
@@ -143,7 +155,9 @@ class LoggingModule extends BootModule {
prop.entrySet().forEach(x -> onlyLogProps.put(x.getKey(), x.getValue())); prop.entrySet().forEach(x -> onlyLogProps.put(x.getKey(), x.getValue()));
} }
if (!application.isCompileMode()) { if (!application.isCompileMode()) {
onlyLogProps.put(SncpClient.class.getSimpleName() + ".handlers", LoggingFileHandler.LoggingSncpFileHandler.class.getName()); onlyLogProps.put(
SncpClient.class.getSimpleName() + ".handlers",
LoggingFileHandler.LoggingSncpFileHandler.class.getName());
} }
} }
if (application.isCompileMode()) { if (application.isCompileMode()) {
@@ -172,7 +186,7 @@ class LoggingModule extends BootModule {
} }
} }
} }
} catch (IOException e) { //不会发生 } catch (IOException e) { // 不会发生
} }
} }
} }

View File

@@ -2,6 +2,9 @@
*/ */
package org.redkale.boot; package org.redkale.boot;
import static org.redkale.boot.Application.RESNAME_APP_NAME;
import static org.redkale.boot.Application.SYSNAME_APP_NAME;
import java.io.*; import java.io.*;
import java.util.*; import java.util.*;
import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.LinkedBlockingQueue;
@@ -9,8 +12,6 @@ import java.util.concurrent.atomic.AtomicInteger;
import java.util.logging.*; import java.util.logging.*;
import java.util.logging.Formatter; import java.util.logging.Formatter;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import static org.redkale.boot.Application.RESNAME_APP_NAME;
import static org.redkale.boot.Application.SYSNAME_APP_NAME;
import org.redkale.convert.*; import org.redkale.convert.*;
import org.redkale.convert.json.JsonConvert; import org.redkale.convert.json.JsonConvert;
import org.redkale.persistence.*; import org.redkale.persistence.*;
@@ -20,8 +21,8 @@ import org.redkale.util.*;
/** /**
* 基于SearchSource的日志输出类 * 基于SearchSource的日志输出类
* <p> *
* 详情见: https://redkale.org * <p>详情见: https://redkale.org
* *
* @author zhangjx * @author zhangjx
* @since 2.7.0 * @since 2.7.0
@@ -34,9 +35,9 @@ public class LoggingSearchHandler extends LoggingBaseHandler {
protected final AtomicInteger retryCount = new AtomicInteger(3); protected final AtomicInteger retryCount = new AtomicInteger(3);
protected String tag = DEFAULT_TABLE_NAME; //用于表前缀, 默认是 protected String tag = DEFAULT_TABLE_NAME; // 用于表前缀, 默认是
protected String tagDateFormat; //需要时间格式化 protected String tagDateFormat; // 需要时间格式化
protected String pattern; protected String pattern;
@@ -46,7 +47,7 @@ public class LoggingSearchHandler extends LoggingBaseHandler {
protected SearchSource source; protected SearchSource source;
//在LogManager.getLogManager().readConfiguration执行完后通过反射注入Application // 在LogManager.getLogManager().readConfiguration执行完后通过反射注入Application
protected Application application; protected Application application;
public LoggingSearchHandler() { public LoggingSearchHandler() {
@@ -56,7 +57,7 @@ public class LoggingSearchHandler extends LoggingBaseHandler {
private void open() { private void open() {
final String name = "Redkale-Logging-" + getClass().getSimpleName().replace("Logging", "") + "-Thread"; final String name = "Redkale-Logging-" + getClass().getSimpleName().replace("Logging", "") + "-Thread";
final int batchSize = 100; //批量最多100条 final int batchSize = 100; // 批量最多100条
final List<SearchLogRecord> logList = new ArrayList<>(); final List<SearchLogRecord> logList = new ArrayList<>();
final Formatter formatter = new LoggingBaseHandler.LoggingFormater(); final Formatter formatter = new LoggingBaseHandler.LoggingFormater();
final PrintStream outStream = System.out; final PrintStream outStream = System.out;
@@ -72,8 +73,8 @@ public class LoggingSearchHandler extends LoggingBaseHandler {
try { try {
SearchLogRecord log = logqueue.take(); SearchLogRecord log = logqueue.take();
while (source == null && retryCount.get() > 0) initSource(); while (source == null && retryCount.get() > 0) initSource();
//----------------------写日志------------------------- // ----------------------写日志-------------------------
if (source == null) { //source加载失败 if (source == null) { // source加载失败
outStream.print(formatter.format(log.rawLog)); outStream.print(formatter.format(log.rawLog));
} else { } else {
logList.add(log); logList.add(log);
@@ -96,7 +97,6 @@ public class LoggingSearchHandler extends LoggingBaseHandler {
logList.clear(); logList.clear();
} }
} }
} }
}.start(); }.start();
} }
@@ -106,7 +106,7 @@ public class LoggingSearchHandler extends LoggingBaseHandler {
return; return;
} }
try { try {
Utility.sleep(3000); //如果SearchSource自身在打印日志需要停顿一点时间让SearchSource初始化完成 Utility.sleep(3000); // 如果SearchSource自身在打印日志需要停顿一点时间让SearchSource初始化完成
if (application == null) { if (application == null) {
Utility.sleep(3000); Utility.sleep(3000);
} }
@@ -127,7 +127,7 @@ public class LoggingSearchHandler extends LoggingBaseHandler {
} }
} }
private static boolean checkTagName(String name) { //只能是字母、数字、短横、点、%、$和下划线 private static boolean checkTagName(String name) { // 只能是字母、数字、短横、点、%、$和下划线
if (name.isEmpty()) { if (name.isEmpty()) {
return false; return false;
} }
@@ -164,7 +164,7 @@ public class LoggingSearchHandler extends LoggingBaseHandler {
this.tag = tagStr.replace("${" + RESNAME_APP_NAME + "}", System.getProperty(SYSNAME_APP_NAME, "")); this.tag = tagStr.replace("${" + RESNAME_APP_NAME + "}", System.getProperty(SYSNAME_APP_NAME, ""));
if (this.tag.contains("%")) { if (this.tag.contains("%")) {
this.tagDateFormat = this.tag; this.tagDateFormat = this.tag;
Times.formatTime(this.tagDateFormat, -1, System.currentTimeMillis()); //测试时间格式是否正确 Times.formatTime(this.tagDateFormat, -1, System.currentTimeMillis()); // 测试时间格式是否正确
} }
} }
@@ -175,7 +175,7 @@ public class LoggingSearchHandler extends LoggingBaseHandler {
setLevel(l != null ? l : Level.ALL); setLevel(l != null ? l : Level.ALL);
} }
} catch (Exception e) { } catch (Exception e) {
//do nothing // do nothing
} }
String filterStr = manager.getProperty(cname + ".filter"); String filterStr = manager.getProperty(cname + ".filter");
try { try {
@@ -185,7 +185,7 @@ public class LoggingSearchHandler extends LoggingBaseHandler {
setFilter((Filter) clz.getDeclaredConstructor().newInstance()); setFilter((Filter) clz.getDeclaredConstructor().newInstance());
} }
} catch (Exception e) { } catch (Exception e) {
//do nothing // do nothing
} }
String formatterStr = manager.getProperty(cname + ".formatter"); String formatterStr = manager.getProperty(cname + ".formatter");
try { try {
@@ -195,7 +195,7 @@ public class LoggingSearchHandler extends LoggingBaseHandler {
setFormatter((Formatter) clz.getDeclaredConstructor().newInstance()); setFormatter((Formatter) clz.getDeclaredConstructor().newInstance());
} }
} catch (Exception e) { } catch (Exception e) {
//do nothing // do nothing
} }
if (getFormatter() == null) { if (getFormatter() == null) {
setFormatter(new SimpleFormatter()); setFormatter(new SimpleFormatter());
@@ -207,7 +207,7 @@ public class LoggingSearchHandler extends LoggingBaseHandler {
setEncoding(encodingStr); setEncoding(encodingStr);
} }
} catch (Exception e) { } catch (Exception e) {
//do nothing // do nothing
} }
String denyRegxStr = manager.getProperty(cname + ".denyregx"); String denyRegxStr = manager.getProperty(cname + ".denyregx");
@@ -216,7 +216,7 @@ public class LoggingSearchHandler extends LoggingBaseHandler {
denyRegx = Pattern.compile(denyRegxStr); denyRegx = Pattern.compile(denyRegxStr);
} }
} catch (Exception e) { } catch (Exception e) {
//do nothing // do nothing
} }
} }
@@ -239,19 +239,21 @@ public class LoggingSearchHandler extends LoggingBaseHandler {
break; break;
} }
} }
String rawTag = tagDateFormat == null ? tag : Times.formatTime(tagDateFormat, -1, log.getInstant().toEpochMilli()); String rawTag = tagDateFormat == null
? tag
: Times.formatTime(tagDateFormat, -1, log.getInstant().toEpochMilli());
fillLogRecord(log); fillLogRecord(log);
logqueue.offer(new SearchLogRecord(rawTag, log)); logqueue.offer(new SearchLogRecord(rawTag, log));
} }
@Override @Override
public void flush() { public void flush() {
//do nothing // do nothing
} }
@Override @Override
public void close() throws SecurityException { public void close() throws SecurityException {
//do nothing // do nothing
} }
@Entity @Entity
@@ -288,8 +290,8 @@ public class LoggingSearchHandler extends LoggingBaseHandler {
public String methodName; public String methodName;
@ConvertColumn(index = 8) @ConvertColumn(index = 8)
@SearchColumn(text = true, options = "offsets") //, analyzer = "ik_max_word" @SearchColumn(text = true, options = "offsets") // , analyzer = "ik_max_word"
public String message; //log.message +"\r\n"+ log.thrown public String message; // log.message +"\r\n"+ log.thrown
@Transient @Transient
@ConvertDisabled @ConvertDisabled
@@ -299,8 +301,7 @@ public class LoggingSearchHandler extends LoggingBaseHandler {
@ConvertDisabled @ConvertDisabled
String rawTag; String rawTag;
public SearchLogRecord() { public SearchLogRecord() {}
}
protected SearchLogRecord(String tag, LogRecord log) { protected SearchLogRecord(String tag, LogRecord log) {
this.rawLog = log; this.rawLog = log;
@@ -347,7 +348,6 @@ public class LoggingSearchHandler extends LoggingBaseHandler {
public String[] getTables(String table, FilterNode node) { public String[] getTables(String table, FilterNode node) {
throw new UnsupportedOperationException("Not supported yet."); throw new UnsupportedOperationException("Not supported yet.");
} }
} }
} }
} }

View File

@@ -15,14 +15,11 @@ import org.redkale.util.AnyValue;
import org.redkale.util.Environment; import org.redkale.util.Environment;
/** /**
*
* 各组件的引擎类, 由Application管理 * 各组件的引擎类, 由Application管理
* *
* <p> * <p>详情见: https://redkale.org
* 详情见: https://redkale.org
* *
* @author zhangjx * @author zhangjx
*
* @since 2.8.0 * @since 2.8.0
*/ */
public abstract class ModuleEngine { public abstract class ModuleEngine {
@@ -45,10 +42,9 @@ public abstract class ModuleEngine {
* 判断模块的配置项合并策略, 返回null表示模块不识别此配置项 * 判断模块的配置项合并策略, 返回null表示模块不识别此配置项
* *
* @param path 配置项路径 * @param path 配置项路径
* @param key 配置项名称 * @param key 配置项名称
* @param val1 配置项原值 * @param val1 配置项原值
* @param val2 配置项新值 * @param val2 配置项新值
*
* @return MergeEnum * @return MergeEnum
*/ */
public AnyValue.MergeEnum mergeAppConfigStrategy(String path, String key, AnyValue val1, AnyValue val2) { public AnyValue.MergeEnum mergeAppConfigStrategy(String path, String key, AnyValue val1, AnyValue val2) {
@@ -58,44 +54,32 @@ public abstract class ModuleEngine {
/** /**
* 动态扩展类的方法 * 动态扩展类的方法
* *
* @param remote 是否远程模式 * @param remote 是否远程模式
* @param serviceClass 类 * @param serviceClass 类
*
* @return 方法动态扩展器 * @return 方法动态扩展器
*/ */
public AsmMethodBoost createAsmMethodBoost(boolean remote, Class serviceClass) { public AsmMethodBoost createAsmMethodBoost(boolean remote, Class serviceClass) {
return null; return null;
} }
/** /** 进入Application.init方法时被调用 此时状态: 1、远程配置项未获取 2、WorkExecutor未初始化 */
* 进入Application.init方法时被调用
* 此时状态:
* 1、远程配置项未获取
* 2、WorkExecutor未初始化
*/
public void onAppPreInit() { public void onAppPreInit() {
//do nothing // do nothing
} }
/** /** 结束Application.init方法前被调用 */
* 结束Application.init方法前被调用
*/
public void onAppPostInit() { public void onAppPostInit() {
//do nothing // do nothing
} }
/** /** 进入Application.start方法被调用 */
* 进入Application.start方法被调用
*/
public void onAppPreStart() { public void onAppPreStart() {
//do nothing // do nothing
} }
/** /** 结束Application.start方法前被调用 */
* 结束Application.start方法前被调用
*/
public void onAppPostStart() { public void onAppPostStart() {
//do nothing // do nothing
} }
/** /**
@@ -104,47 +88,37 @@ public abstract class ModuleEngine {
* @param allProps 配置项全量 * @param allProps 配置项全量
*/ */
public void onEnvironmentLoaded(Properties allProps) { public void onEnvironmentLoaded(Properties allProps) {
//do nothing // do nothing
} }
/** /**
* 配置项变更时被调用 * 配置项变更时被调用
* *
* @param namespace 命名空间 * @param namespace 命名空间
* @param events 变更项 * @param events 变更项
*/ */
public void onEnvironmentChanged(String namespace, List<ResourceEvent> events) { public void onEnvironmentChanged(String namespace, List<ResourceEvent> events) {
//do nothing // do nothing
} }
/** /** Application 在运行Compile前调用 */
* Application 在运行Compile前调用
*
*/
public void onPreCompile() { public void onPreCompile() {
//do nothing // do nothing
} }
/** /** Application 在运行Compile后调用 */
* Application 在运行Compile后调用
*
*/
public void onPostCompile() { public void onPostCompile() {
//do nothing // do nothing
} }
/** /** 服务全部启动前被调用 */
* 服务全部启动前被调用
*/
public void onServersPreStart() { public void onServersPreStart() {
//do nothing // do nothing
} }
/** /** 服务全部启动后被调用 */
* 服务全部启动后被调用
*/
public void onServersPostStart() { public void onServersPostStart() {
//do nothing // do nothing
} }
/** /**
@@ -153,7 +127,7 @@ public abstract class ModuleEngine {
* @param service Service * @param service Service
*/ */
public void onServicePreInit(Service service) { public void onServicePreInit(Service service) {
//do nothing // do nothing
} }
/** /**
@@ -162,7 +136,7 @@ public abstract class ModuleEngine {
* @param service Service * @param service Service
*/ */
public void onServicePostInit(Service service) { public void onServicePostInit(Service service) {
//do nothing // do nothing
} }
/** /**
@@ -171,7 +145,7 @@ public abstract class ModuleEngine {
* @param service Service * @param service Service
*/ */
public void onServicePreDestroy(Service service) { public void onServicePreDestroy(Service service) {
//do nothing // do nothing
} }
/** /**
@@ -180,34 +154,26 @@ public abstract class ModuleEngine {
* @param service Service * @param service Service
*/ */
public void onServicePostDestroy(Service service) { public void onServicePostDestroy(Service service) {
//do nothing // do nothing
} }
/** /** 服务全部停掉前被调用 */
* 服务全部停掉前被调用
*/
public void onServersPreStop() { public void onServersPreStop() {
//do nothing // do nothing
} }
/** /** 服务全部停掉后被调用 */
* 服务全部停掉后被调用
*/
public void onServersPostStop() { public void onServersPostStop() {
//do nothing // do nothing
} }
/** /** 进入Application.shutdown方法被调用 */
* 进入Application.shutdown方法被调用
*/
public void onAppPreShutdown() { public void onAppPreShutdown() {
//do nothing // do nothing
} }
/** /** 结束Application.shutdown方法前被调用 */
* 结束Application.shutdown方法前被调用
*/
public void onAppPostShutdown() { public void onAppPostShutdown() {
//do nothing // do nothing
} }
} }

View File

@@ -5,6 +5,8 @@
*/ */
package org.redkale.boot; package org.redkale.boot;
import static org.redkale.boot.Application.RESNAME_SNCP_ADDRESS;
import java.lang.annotation.Annotation; import java.lang.annotation.Annotation;
import java.lang.reflect.*; import java.lang.reflect.*;
import java.net.*; import java.net.*;
@@ -15,7 +17,6 @@ import java.util.logging.Level;
import java.util.stream.Stream; import java.util.stream.Stream;
import org.redkale.annotation.*; import org.redkale.annotation.*;
import org.redkale.asm.AsmMethodBoost; import org.redkale.asm.AsmMethodBoost;
import static org.redkale.boot.Application.RESNAME_SNCP_ADDRESS;
import org.redkale.boot.ClassFilter.FilterEntry; import org.redkale.boot.ClassFilter.FilterEntry;
import org.redkale.cluster.spi.ClusterAgent; import org.redkale.cluster.spi.ClusterAgent;
import org.redkale.inject.ResourceFactory; import org.redkale.inject.ResourceFactory;
@@ -31,15 +32,14 @@ import org.redkale.watch.*;
/** /**
* HTTP Server节点的配置Server * HTTP Server节点的配置Server
* *
* <p> * <p>详情见: https://redkale.org
* 详情见: https://redkale.org
* *
* @author zhangjx * @author zhangjx
*/ */
@NodeProtocol("HTTP") @NodeProtocol("HTTP")
public class NodeHttpServer extends NodeServer { public class NodeHttpServer extends NodeServer {
protected final boolean rest; //是否加载REST服务 为true加载rest节点信息并将所有可REST化的Service生成RestServlet protected final boolean rest; // 是否加载REST服务 为true加载rest节点信息并将所有可REST化的Service生成RestServlet
protected final HttpServer httpServer; protected final HttpServer httpServer;
@@ -49,11 +49,13 @@ public class NodeHttpServer extends NodeServer {
super(application, createServer(application, serconf)); super(application, createServer(application, serconf));
this.httpServer = (HttpServer) server; this.httpServer = (HttpServer) server;
this.rest = serconf != null && serconf.getAnyValue("rest") != null; this.rest = serconf != null && serconf.getAnyValue("rest") != null;
} }
private static Server createServer(Application application, AnyValue serconf) { private static Server createServer(Application application, AnyValue serconf) {
return new HttpServer(application, application.getStartTime(), application.getResourceFactory().createChild()); return new HttpServer(
application,
application.getStartTime(),
application.getResourceFactory().createChild());
} }
public HttpServer getHttpServer() { public HttpServer getHttpServer() {
@@ -68,24 +70,40 @@ public class NodeHttpServer extends NodeServer {
@Override @Override
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
protected ClassFilter<Service> createServiceClassFilter() { protected ClassFilter<Service> createServiceClassFilter() {
return createClassFilter(this.sncpGroup, null, Service.class, new Class[]{org.redkale.watch.WatchService.class}, Annotation.class, "services", "service"); return createClassFilter(
this.sncpGroup,
null,
Service.class,
new Class[] {org.redkale.watch.WatchService.class},
Annotation.class,
"services",
"service");
} }
@Override @Override
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
protected ClassFilter<Filter> createFilterClassFilter() { protected ClassFilter<Filter> createFilterClassFilter() {
return createClassFilter(null, null, HttpFilter.class, new Class[]{WatchFilter.class}, null, "filters", "filter"); return createClassFilter(
null, null, HttpFilter.class, new Class[] {WatchFilter.class}, null, "filters", "filter");
} }
@Override @Override
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
protected ClassFilter<Servlet> createServletClassFilter() { protected ClassFilter<Servlet> createServletClassFilter() {
return createClassFilter(null, WebServlet.class, HttpServlet.class, new Class[]{WatchServlet.class}, null, "servlets", "servlet"); return createClassFilter(
null,
WebServlet.class,
HttpServlet.class,
new Class[] {WatchServlet.class},
null,
"servlets",
"servlet");
} }
@Override @Override
protected List<ClassFilter> createOtherClassFilters() { protected List<ClassFilter> createOtherClassFilters() {
this.webSocketFilter = createClassFilter(null, RestWebSocket.class, WebSocket.class, null, null, "rest", "websocket"); this.webSocketFilter =
createClassFilter(null, RestWebSocket.class, WebSocket.class, null, null, "rest", "websocket");
List<ClassFilter> filters = super.createOtherClassFilters(); List<ClassFilter> filters = super.createOtherClassFilters();
if (filters == null) { if (filters == null) {
filters = new ArrayList<>(); filters = new ArrayList<>();
@@ -98,7 +116,7 @@ public class NodeHttpServer extends NodeServer {
protected void loadOthers(List<ClassFilter> otherFilters) throws Exception { protected void loadOthers(List<ClassFilter> otherFilters) throws Exception {
List<ClassFilter> filters = otherFilters; List<ClassFilter> filters = otherFilters;
if (filters != null) { if (filters != null) {
filters.remove(this.webSocketFilter); //webSocketFilter会在loadHttpFilter中处理先剔除 filters.remove(this.webSocketFilter); // webSocketFilter会在loadHttpFilter中处理先剔除
} }
super.loadOthers(filters); super.loadOthers(filters);
} }
@@ -130,7 +148,13 @@ public class NodeHttpServer extends NodeServer {
resourceFactory.register(new ResourceTypeLoader() { resourceFactory.register(new ResourceTypeLoader() {
@Override @Override
public Object load(ResourceFactory rf, String srcResourceName, Object srcObj, String resourceName, Field field, Object attachment) { //主要用于单点的服务 public Object load(
ResourceFactory rf,
String srcResourceName,
Object srcObj,
String resourceName,
Field field,
Object attachment) { // 主要用于单点的服务
try { try {
if (!(srcObj instanceof WebSocketServlet)) { if (!(srcObj instanceof WebSocketServlet)) {
return null; return null;
@@ -149,17 +173,28 @@ public class NodeHttpServer extends NodeServer {
} }
Service nodeService = null; Service nodeService = null;
if (loader != null) { if (loader != null) {
nodeService = (Service) loader.load(sncpResFactory, srcResourceName, srcObj, resourceName, field, attachment); nodeService = (Service)
loader.load(sncpResFactory, srcResourceName, srcObj, resourceName, field, attachment);
} }
regFactory.lock(); regFactory.lock();
try { try {
if (nodeService == null) { if (nodeService == null) {
nodeService = (Service) rf.find(resourceName, WebSocketNode.class); nodeService = (Service) rf.find(resourceName, WebSocketNode.class);
} }
if (sncpResFactory != null && resourceFactory.find(RESNAME_SNCP_ADDRESS, String.class) == null) { if (sncpResFactory != null
resourceFactory.register(RESNAME_SNCP_ADDRESS, InetSocketAddress.class, sncpResFactory.find(RESNAME_SNCP_ADDRESS, InetSocketAddress.class)); && resourceFactory.find(RESNAME_SNCP_ADDRESS, String.class) == null) {
resourceFactory.register(RESNAME_SNCP_ADDRESS, SocketAddress.class, sncpResFactory.find(RESNAME_SNCP_ADDRESS, SocketAddress.class)); resourceFactory.register(
resourceFactory.register(RESNAME_SNCP_ADDRESS, String.class, sncpResFactory.find(RESNAME_SNCP_ADDRESS, String.class)); RESNAME_SNCP_ADDRESS,
InetSocketAddress.class,
sncpResFactory.find(RESNAME_SNCP_ADDRESS, InetSocketAddress.class));
resourceFactory.register(
RESNAME_SNCP_ADDRESS,
SocketAddress.class,
sncpResFactory.find(RESNAME_SNCP_ADDRESS, SocketAddress.class));
resourceFactory.register(
RESNAME_SNCP_ADDRESS,
String.class,
sncpResFactory.find(RESNAME_SNCP_ADDRESS, String.class));
} }
if (nodeService == null) { if (nodeService == null) {
MessageAgent messageAgent = null; MessageAgent messageAgent = null;
@@ -171,9 +206,19 @@ public class NodeHttpServer extends NodeServer {
} catch (Exception ex) { } catch (Exception ex) {
logger.log(Level.WARNING, "WebSocketServlet getMessageAgent error", ex); logger.log(Level.WARNING, "WebSocketServlet getMessageAgent error", ex);
} }
AsmMethodBoost methodBoost = application.createAsmMethodBoost(false, WebSocketNodeService.class); AsmMethodBoost methodBoost =
nodeService = Sncp.createLocalService(serverClassLoader, resourceName, WebSocketNodeService.class, methodBoost, application.createAsmMethodBoost(false, WebSocketNodeService.class);
application.getResourceFactory(), application.getSncpRpcGroups(), sncpClient, messageAgent, (String) null, (AnyValue) null); nodeService = Sncp.createLocalService(
serverClassLoader,
resourceName,
WebSocketNodeService.class,
methodBoost,
application.getResourceFactory(),
application.getSncpRpcGroups(),
sncpClient,
messageAgent,
(String) null,
(AnyValue) null);
regFactory.register(resourceName, WebSocketNode.class, nodeService); regFactory.register(resourceName, WebSocketNode.class, nodeService);
} }
resourceFactory.inject(resourceName, nodeService, self); resourceFactory.inject(resourceName, nodeService, self);
@@ -205,7 +250,7 @@ public class NodeHttpServer extends NodeServer {
if (Modifier.isAbstract(clazz.getModifiers())) { if (Modifier.isAbstract(clazz.getModifiers())) {
continue; continue;
} }
if (entry.isExpect()) { //跳过不自动加载的Filter if (entry.isExpect()) { // 跳过不自动加载的Filter
continue; continue;
} }
RedkaleClassLoader.putReflectionDeclaredConstructors(clazz, clazz.getName()); RedkaleClassLoader.putReflectionDeclaredConstructors(clazz, clazz.getName());
@@ -226,7 +271,8 @@ public class NodeHttpServer extends NodeServer {
protected void loadHttpServlet(final ClassFilter<? extends Servlet> servletFilter) throws Exception { protected void loadHttpServlet(final ClassFilter<? extends Servlet> servletFilter) throws Exception {
RedkaleClassLoader.putReflectionPublicClasses(HttpServlet.class.getName()); RedkaleClassLoader.putReflectionPublicClasses(HttpServlet.class.getName());
RedkaleClassLoader.putReflectionPublicClasses(HttpDispatcherServlet.class.getName()); RedkaleClassLoader.putReflectionPublicClasses(HttpDispatcherServlet.class.getName());
RedkaleClassLoader.putReflectionDeclaredConstructors(HttpResourceServlet.class, HttpResourceServlet.class.getName()); RedkaleClassLoader.putReflectionDeclaredConstructors(
HttpResourceServlet.class, HttpResourceServlet.class.getName());
final AnyValue servletsConf = this.serverConf.getAnyValue("servlets"); final AnyValue servletsConf = this.serverConf.getAnyValue("servlets");
final StringBuilder sb = logger.isLoggable(Level.INFO) ? new StringBuilder() : null; final StringBuilder sb = logger.isLoggable(Level.INFO) ? new StringBuilder() : null;
String prefix0 = servletsConf == null ? "" : servletsConf.getValue("path", ""); String prefix0 = servletsConf == null ? "" : servletsConf.getValue("path", "");
@@ -238,17 +284,22 @@ public class NodeHttpServer extends NodeServer {
} }
final String prefix = prefix0; final String prefix = prefix0;
List<FilterEntry<? extends Servlet>> list = new ArrayList(servletFilter.getFilterEntrys()); List<FilterEntry<? extends Servlet>> list = new ArrayList(servletFilter.getFilterEntrys());
list.sort((FilterEntry<? extends Servlet> o1, FilterEntry<? extends Servlet> o2) -> { //必须保证WebSocketServlet优先加载 因为要确保其他的HttpServlet可以注入本地模式的WebSocketNode list.sort(
boolean ws1 = WebSocketServlet.class.isAssignableFrom(o1.getType()); (FilterEntry<? extends Servlet> o1,
boolean ws2 = WebSocketServlet.class.isAssignableFrom(o2.getType()); FilterEntry<? extends Servlet>
if (ws1 == ws2) { o2) -> { // 必须保证WebSocketServlet优先加载 因为要确保其他的HttpServlet可以注入本地模式的WebSocketNode
Priority p1 = o1.getType().getAnnotation(Priority.class); boolean ws1 = WebSocketServlet.class.isAssignableFrom(o1.getType());
Priority p2 = o2.getType().getAnnotation(Priority.class); boolean ws2 = WebSocketServlet.class.isAssignableFrom(o2.getType());
int v = (p2 == null ? 0 : p2.value()) - (p1 == null ? 0 : p1.value()); if (ws1 == ws2) {
return v == 0 ? o1.getType().getName().compareTo(o2.getType().getName()) : 0; Priority p1 = o1.getType().getAnnotation(Priority.class);
} Priority p2 = o2.getType().getAnnotation(Priority.class);
return ws1 ? -1 : 1; int v = (p2 == null ? 0 : p2.value()) - (p1 == null ? 0 : p1.value());
}); return v == 0
? o1.getType().getName().compareTo(o2.getType().getName())
: 0;
}
return ws1 ? -1 : 1;
});
final long starts = System.currentTimeMillis(); final long starts = System.currentTimeMillis();
final List<AbstractMap.SimpleEntry<String, String[]>> ss = sb == null ? null : new ArrayList<>(); final List<AbstractMap.SimpleEntry<String, String[]>> ss = sb == null ? null : new ArrayList<>();
for (FilterEntry<? extends Servlet> entry : list) { for (FilterEntry<? extends Servlet> entry : list) {
@@ -257,9 +308,9 @@ public class NodeHttpServer extends NodeServer {
continue; continue;
} }
if (clazz.getAnnotation(Rest.RestDyn.class) != null) { if (clazz.getAnnotation(Rest.RestDyn.class) != null) {
continue; //动态生成的跳过 continue; // 动态生成的跳过
} }
if (entry.isExpect()) { //跳过不自动加载的Servlet if (entry.isExpect()) { // 跳过不自动加载的Servlet
continue; continue;
} }
WebServlet ws = clazz.getAnnotation(WebServlet.class); WebServlet ws = clazz.getAnnotation(WebServlet.class);
@@ -284,8 +335,10 @@ public class NodeHttpServer extends NodeServer {
ss.add(new AbstractMap.SimpleEntry<>("HttpServlet (type=" + clazz.getName() + ")", mappings)); ss.add(new AbstractMap.SimpleEntry<>("HttpServlet (type=" + clazz.getName() + ")", mappings));
} }
} }
final CopyOnWriteArrayList<AbstractMap.SimpleEntry<String, String[]>> rests = sb == null ? null : new CopyOnWriteArrayList<>(); final CopyOnWriteArrayList<AbstractMap.SimpleEntry<String, String[]>> rests =
final CopyOnWriteArrayList<AbstractMap.SimpleEntry<String, String[]>> webss = sb == null ? null : new CopyOnWriteArrayList<>(); sb == null ? null : new CopyOnWriteArrayList<>();
final CopyOnWriteArrayList<AbstractMap.SimpleEntry<String, String[]>> webss =
sb == null ? null : new CopyOnWriteArrayList<>();
if (rest && serverConf != null) { if (rest && serverConf != null) {
final List<Object> restedObjects = new ArrayList<>(); final List<Object> restedObjects = new ArrayList<>();
final ReentrantLock restedLock = new ReentrantLock(); final ReentrantLock restedLock = new ReentrantLock();
@@ -356,7 +409,8 @@ public class NodeHttpServer extends NodeServer {
ss.add(new AbstractMap.SimpleEntry<>(sub.toString(), en.getValue())); ss.add(new AbstractMap.SimpleEntry<>(sub.toString(), en.getValue()));
} }
} }
ss.sort((AbstractMap.SimpleEntry<String, String[]> o1, AbstractMap.SimpleEntry<String, String[]> o2) -> o1.getKey().compareTo(o2.getKey())); ss.sort((AbstractMap.SimpleEntry<String, String[]> o1, AbstractMap.SimpleEntry<String, String[]> o2) ->
o1.getKey().compareTo(o2.getKey()));
for (AbstractMap.SimpleEntry<String, String[]> as : ss) { for (AbstractMap.SimpleEntry<String, String[]> as : ss) {
if (as.getKey().length() > max) { if (as.getKey().length() > max) {
max = as.getKey().length(); max = as.getKey().length();
@@ -367,9 +421,14 @@ public class NodeHttpServer extends NodeServer {
for (int i = 0; i < max - as.getKey().length(); i++) { for (int i = 0; i < max - as.getKey().length(); i++) {
sb.append(' '); sb.append(' ');
} }
sb.append(" mapping to ").append(Arrays.toString(as.getValue())).append(LINE_SEPARATOR); sb.append(" mapping to ")
.append(Arrays.toString(as.getValue()))
.append(LINE_SEPARATOR);
} }
sb.append("All HttpServlets load in ").append(System.currentTimeMillis() - starts).append(" ms").append(LINE_SEPARATOR); sb.append("All HttpServlets load in ")
.append(System.currentTimeMillis() - starts)
.append(" ms")
.append(LINE_SEPARATOR);
} }
if (sb != null && sb.length() > 0) { if (sb != null && sb.length() > 0) {
logger.log(Level.INFO, sb.toString().trim()); logger.log(Level.INFO, sb.toString().trim());
@@ -377,16 +436,20 @@ public class NodeHttpServer extends NodeServer {
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
protected void loadRestServlet(final ClassFilter<? extends WebSocket> webSocketFilter, protected void loadRestServlet(
final AnyValue restConf, final List<Object> restedObjects, final ClassFilter<? extends WebSocket> webSocketFilter,
final ReentrantLock restedLock, final StringBuilder sb, final AnyValue restConf,
final CopyOnWriteArrayList<AbstractMap.SimpleEntry<String, String[]>> rests, final List<Object> restedObjects,
final CopyOnWriteArrayList<AbstractMap.SimpleEntry<String, String[]>> webss) throws Exception { final ReentrantLock restedLock,
final StringBuilder sb,
final CopyOnWriteArrayList<AbstractMap.SimpleEntry<String, String[]>> rests,
final CopyOnWriteArrayList<AbstractMap.SimpleEntry<String, String[]>> webss)
throws Exception {
if (!rest) { if (!rest) {
return; return;
} }
if (restConf == null) { if (restConf == null) {
return; //不存在REST服务 return; // 不存在REST服务
} }
String prefix0 = restConf.getValue("path", ""); String prefix0 = restConf.getValue("path", "");
if (!prefix0.isEmpty() && prefix0.charAt(prefix0.length() - 1) == '/') { if (!prefix0.isEmpty() && prefix0.charAt(prefix0.length() - 1) == '/') {
@@ -401,20 +464,22 @@ public class NodeHttpServer extends NodeServer {
if (mqname != null) { if (mqname != null) {
agent0 = application.getResourceFactory().find(mqname, MessageAgent.class); agent0 = application.getResourceFactory().find(mqname, MessageAgent.class);
if (agent0 == null) { if (agent0 == null) {
throw new RedkaleException("not found " + MessageAgent.class.getSimpleName() + " config for (name=" + mqname + ")"); throw new RedkaleException(
"not found " + MessageAgent.class.getSimpleName() + " config for (name=" + mqname + ")");
} }
} }
final MessageAgent messageAgent = agent0; final MessageAgent messageAgent = agent0;
if (messageAgent != null) { if (messageAgent != null) {
prefix0 = ""; //开启MQ时,prefix字段失效 prefix0 = ""; // 开启MQ时,prefix字段失效
} }
final String prefix = prefix0; final String prefix = prefix0;
final boolean autoload = restConf.getBoolValue("autoload", true); final boolean autoload = restConf.getBoolValue("autoload", true);
{ //加载RestService { // 加载RestService
String userTypeStr = restConf.getValue("usertype"); String userTypeStr = restConf.getValue("usertype");
final Class userType = userTypeStr == null ? null : this.serverClassLoader.loadClass(userTypeStr); final Class userType = userTypeStr == null ? null : this.serverClassLoader.loadClass(userTypeStr);
final Class baseServletType = this.serverClassLoader.loadClass(restConf.getValue("base", HttpServlet.class.getName())); final Class baseServletType =
this.serverClassLoader.loadClass(restConf.getValue("base", HttpServlet.class.getName()));
final Set<String> includeValues = new HashSet<>(); final Set<String> includeValues = new HashSet<>();
final Set<String> excludeValues = new HashSet<>(); final Set<String> excludeValues = new HashSet<>();
for (AnyValue item : restConf.getAnyValues("service")) { for (AnyValue item : restConf.getAnyValues("service")) {
@@ -425,11 +490,17 @@ public class NodeHttpServer extends NodeServer {
} }
} }
final ClassFilter restFilter = ClassFilter.create(serverClassLoader, null, application.isCompileMode() ? "" : restConf.getValue("includes", ""), application.isCompileMode() ? "" : restConf.getValue("excludes", ""), includeValues, excludeValues); final ClassFilter restFilter = ClassFilter.create(
serverClassLoader,
null,
application.isCompileMode() ? "" : restConf.getValue("includes", ""),
application.isCompileMode() ? "" : restConf.getValue("excludes", ""),
includeValues,
excludeValues);
final CountDownLatch scdl = new CountDownLatch(super.servletServices.size()); final CountDownLatch scdl = new CountDownLatch(super.servletServices.size());
Stream<Service> stream = super.servletServices.stream(); Stream<Service> stream = super.servletServices.stream();
if (!application.isCompileMode()) { if (!application.isCompileMode()) {
stream = stream.parallel(); //不能并行否则在maven plugin运行环境下ClassLoader不对 stream = stream.parallel(); // 不能并行否则在maven plugin运行环境下ClassLoader不对
} }
stream.forEach((service) -> { stream.forEach((service) -> {
try { try {
@@ -453,13 +524,14 @@ public class NodeHttpServer extends NodeServer {
logger.log(Level.WARNING, stype.getName() + " repeat create rest servlet, so ignore"); logger.log(Level.WARNING, stype.getName() + " repeat create rest servlet, so ignore");
return; return;
} }
restedObjects.add(service); //避免重复创建Rest对象 restedObjects.add(service); // 避免重复创建Rest对象
} finally { } finally {
restedLock.unlock(); restedLock.unlock();
} }
HttpServlet servlet = httpServer.addRestServlet(serverClassLoader, service, userType, baseServletType, prefix); HttpServlet servlet =
httpServer.addRestServlet(serverClassLoader, service, userType, baseServletType, prefix);
if (servlet == null) { if (servlet == null) {
return; //没有HttpMapping方法的HttpServlet调用Rest.createRestServlet就会返回null return; // 没有HttpMapping方法的HttpServlet调用Rest.createRestServlet就会返回null
} }
String prefix2 = prefix; String prefix2 = prefix;
WebServlet ws = servlet.getClass().getAnnotation(WebServlet.class); WebServlet ws = servlet.getClass().getAnnotation(WebServlet.class);
@@ -471,13 +543,16 @@ public class NodeHttpServer extends NodeServer {
if (messageAgent != null) { if (messageAgent != null) {
messageAgent.putService(this, service, servlet); messageAgent.putService(this, service, servlet);
} }
//if (finest) logger.finest("Create RestServlet(resource.name='" + name + "') = " + servlet); // if (finest) logger.finest("Create RestServlet(resource.name='" + name + "') = " + servlet);
if (rests != null) { if (rests != null) {
String[] mappings = servlet.getClass().getAnnotation(WebServlet.class).value(); String[] mappings = servlet.getClass()
.getAnnotation(WebServlet.class)
.value();
for (int i = 0; i < mappings.length; i++) { for (int i = 0; i < mappings.length; i++) {
mappings[i] = prefix2 + mappings[i]; mappings[i] = prefix2 + mappings[i];
} }
rests.add(new AbstractMap.SimpleEntry<>(Sncp.getResourceType(service).getName() + ":" + name, mappings)); rests.add(new AbstractMap.SimpleEntry<>(
Sncp.getResourceType(service).getName() + ":" + name, mappings));
} }
} finally { } finally {
scdl.countDown(); scdl.countDown();
@@ -485,7 +560,7 @@ public class NodeHttpServer extends NodeServer {
}); });
scdl.await(); scdl.await();
} }
if (webSocketFilter != null) { //加载RestWebSocket if (webSocketFilter != null) { // 加载RestWebSocket
final Set<String> includeValues = new HashSet<>(); final Set<String> includeValues = new HashSet<>();
final Set<String> excludeValues = new HashSet<>(); final Set<String> excludeValues = new HashSet<>();
for (AnyValue item : restConf.getAnyValues("websocket")) { for (AnyValue item : restConf.getAnyValues("websocket")) {
@@ -495,7 +570,13 @@ public class NodeHttpServer extends NodeServer {
includeValues.add(item.getValue("value", "")); includeValues.add(item.getValue("value", ""));
} }
} }
final ClassFilter restFilter = ClassFilter.create(serverClassLoader, null, application.isCompileMode() ? "" : restConf.getValue("includes", ""), application.isCompileMode() ? "" : restConf.getValue("excludes", ""), includeValues, excludeValues); final ClassFilter restFilter = ClassFilter.create(
serverClassLoader,
null,
application.isCompileMode() ? "" : restConf.getValue("includes", ""),
application.isCompileMode() ? "" : restConf.getValue("excludes", ""),
includeValues,
excludeValues);
List<FilterEntry<? extends WebSocket>> list = new ArrayList(webSocketFilter.getFilterEntrys()); List<FilterEntry<? extends WebSocket>> list = new ArrayList(webSocketFilter.getFilterEntrys());
for (FilterEntry<? extends WebSocket> en : list) { for (FilterEntry<? extends WebSocket> en : list) {
@@ -528,10 +609,11 @@ public class NodeHttpServer extends NodeServer {
logger.log(Level.WARNING, stype.getName() + " repeat create rest websocket, so ignore"); logger.log(Level.WARNING, stype.getName() + " repeat create rest websocket, so ignore");
continue; continue;
} }
restedObjects.add(stype); //避免重复创建Rest对象 restedObjects.add(stype); // 避免重复创建Rest对象
WebSocketServlet servlet = httpServer.addRestWebSocketServlet(serverClassLoader, stype, messageAgent, prefix, en.getProperty()); WebSocketServlet servlet = httpServer.addRestWebSocketServlet(
serverClassLoader, stype, messageAgent, prefix, en.getProperty());
if (servlet == null) { if (servlet == null) {
continue; //没有RestOnMessage方法的HttpServlet调用Rest.createRestWebSocketServlet就会返回null continue; // 没有RestOnMessage方法的HttpServlet调用Rest.createRestWebSocketServlet就会返回null
} }
String prefix2 = prefix; String prefix2 = prefix;
WebServlet ws = servlet.getClass().getAnnotation(WebServlet.class); WebServlet ws = servlet.getClass().getAnnotation(WebServlet.class);
@@ -543,7 +625,8 @@ public class NodeHttpServer extends NodeServer {
logger.finest(stype.getName() + " create a RestWebSocketServlet"); logger.finest(stype.getName() + " create a RestWebSocketServlet");
} }
if (webss != null) { if (webss != null) {
String[] mappings = servlet.getClass().getAnnotation(WebServlet.class).value(); String[] mappings =
servlet.getClass().getAnnotation(WebServlet.class).value();
for (int i = 0; i < mappings.length; i++) { for (int i = 0; i < mappings.length; i++) {
mappings[i] = prefix2 + mappings[i]; mappings[i] = prefix2 + mappings[i];
} }
@@ -556,7 +639,7 @@ public class NodeHttpServer extends NodeServer {
} }
} }
@Override //loadServlet执行之后调用 @Override // loadServlet执行之后调用
protected void postLoadServlets() { protected void postLoadServlets() {
final ClusterAgent cluster = application.getResourceFactory().find("", ClusterAgent.class); final ClusterAgent cluster = application.getResourceFactory().find("", ClusterAgent.class);
if (!application.isCompileMode() && cluster != null) { if (!application.isCompileMode() && cluster != null) {

View File

@@ -8,21 +8,20 @@ package org.redkale.boot;
/** /**
* NodeServer的拦截类 * NodeServer的拦截类
* *
* <p> * <p>详情见: https://redkale.org
* 详情见: https://redkale.org
* *
* @author zhangjx * @author zhangjx
*/ */
public class NodeInterceptor { public class NodeInterceptor {
/** * /**
* Server.start之前调用 <br> * * Server.start之前调用 <br>
* NodeServer.start的部署是先执行NodeInterceptor.preStart再执行 Server.start 方法 * NodeServer.start的部署是先执行NodeInterceptor.preStart再执行 Server.start 方法
* *
* @param server NodeServer * @param server NodeServer
*/ */
public void preStart(NodeServer server) { public void preStart(NodeServer server) {
//do nothing // do nothing
} }
/** /**
@@ -32,7 +31,6 @@ public class NodeInterceptor {
* @param server NodeServer * @param server NodeServer
*/ */
public void preShutdown(NodeServer server) { public void preShutdown(NodeServer server) {
//do nothing // do nothing
} }
} }

View File

@@ -10,8 +10,7 @@ import java.lang.annotation.*;
/** /**
* 根据application.xml中的server节点中的protocol值来适配Server的加载逻辑, 只能注解在NodeServer子类上 * 根据application.xml中的server节点中的protocol值来适配Server的加载逻辑, 只能注解在NodeServer子类上
* *
* <p> * <p>详情见: https://redkale.org
* 详情见: https://redkale.org
* *
* @author zhangjx * @author zhangjx
*/ */

View File

@@ -5,6 +5,8 @@
*/ */
package org.redkale.boot; package org.redkale.boot;
import static org.redkale.boot.Application.*;
import java.io.*; import java.io.*;
import java.lang.annotation.Annotation; import java.lang.annotation.Annotation;
import java.lang.reflect.*; import java.lang.reflect.*;
@@ -19,7 +21,6 @@ import org.redkale.annotation.*;
import org.redkale.annotation.AutoLoad; import org.redkale.annotation.AutoLoad;
import org.redkale.annotation.Command; import org.redkale.annotation.Command;
import org.redkale.asm.AsmMethodBoost; import org.redkale.asm.AsmMethodBoost;
import static org.redkale.boot.Application.*;
import org.redkale.boot.ClassFilter.FilterEntry; import org.redkale.boot.ClassFilter.FilterEntry;
import org.redkale.cluster.spi.ClusterAgent; import org.redkale.cluster.spi.ClusterAgent;
import org.redkale.inject.ResourceFactory; import org.redkale.inject.ResourceFactory;
@@ -38,70 +39,69 @@ import org.redkale.util.*;
/** /**
* Server节点的初始化配置类 * Server节点的初始化配置类
* *
* * <p>详情见: https://redkale.org
* 详情见: https://redkale.org
* *
* @author zhangjx * @author zhangjx
*/ */
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public abstract class NodeServer { public abstract class NodeServer {
//INFO日志的换行符 // INFO日志的换行符
public static final String LINE_SEPARATOR = "\r\n"; public static final String LINE_SEPARATOR = "\r\n";
//日志输出对象 // 日志输出对象
protected final Logger logger; protected final Logger logger;
//进程主类 // 进程主类
protected final Application application; protected final Application application;
//依赖注入工厂类 // 依赖注入工厂类
protected final ResourceFactory resourceFactory; protected final ResourceFactory resourceFactory;
//当前Server对象 // 当前Server对象
protected final Server server; protected final Server server;
//ClassLoader // ClassLoader
protected RedkaleClassLoader serverClassLoader; protected RedkaleClassLoader serverClassLoader;
protected final Thread serverThread; protected final Thread serverThread;
//server节点的配置 // server节点的配置
protected AnyValue serverConf; protected AnyValue serverConf;
protected final String threadName; protected final String threadName;
//加载server节点后的拦截器 // 加载server节点后的拦截器
protected NodeInterceptor interceptor; protected NodeInterceptor interceptor;
//本地模式的Service对象集合 // 本地模式的Service对象集合
protected final Set<Service> localServices = new LinkedHashSet<>(); protected final Set<Service> localServices = new LinkedHashSet<>();
//远程模式的Service对象集合 // 远程模式的Service对象集合
protected final Set<Service> remoteServices = new LinkedHashSet<>(); protected final Set<Service> remoteServices = new LinkedHashSet<>();
//需要转换成Servlet的Service对象集合, Component的Service不在其内 // 需要转换成Servlet的Service对象集合, Component的Service不在其内
protected final Set<Service> servletServices = new LinkedHashSet<>(); protected final Set<Service> servletServices = new LinkedHashSet<>();
//存在SncpServlet、RestServlet // 存在SncpServlet、RestServlet
protected final Map<Service, Servlet> dynServletMap = new LinkedHashMap<>(); protected final Map<Service, Servlet> dynServletMap = new LinkedHashMap<>();
//MessageAgent对象集合 // MessageAgent对象集合
protected final Map<String, MessageAgent> messageAgents = new HashMap<>(); protected final Map<String, MessageAgent> messageAgents = new HashMap<>();
//需要远程模式Service的MessageAgent对象集合 // 需要远程模式Service的MessageAgent对象集合
protected final Map<String, MessageAgent> sncpRemoteAgents = new HashMap<>(); protected final Map<String, MessageAgent> sncpRemoteAgents = new HashMap<>();
//当前Server的SNCP协议的组 // 当前Server的SNCP协议的组
protected String sncpGroup = null; protected String sncpGroup = null;
//当前Server的SNCP服务Client // 当前Server的SNCP服务Client
protected SncpClient sncpClient; protected SncpClient sncpClient;
//SncpClient的AsyncGroup // SncpClient的AsyncGroup
private AsyncIOGroup sncpAsyncGroup; private AsyncIOGroup sncpAsyncGroup;
//SNCP服务的地址 非SNCP为null // SNCP服务的地址 非SNCP为null
private InetSocketAddress sncpAddress; private InetSocketAddress sncpAddress;
private volatile int maxTypeLength = 0; private volatile int maxTypeLength = 0;
@@ -116,7 +116,8 @@ public abstract class NodeServer {
this.server = server; this.server = server;
this.resourceFactory = server.getResourceFactory(); this.resourceFactory = server.getResourceFactory();
this.logger = Logger.getLogger(this.getClass().getSimpleName()); this.logger = Logger.getLogger(this.getClass().getSimpleName());
if (application.isCompileMode() || application.getServerClassLoader() instanceof RedkaleClassLoader.RedkaleCacheClassLoader) { if (application.isCompileMode()
|| application.getServerClassLoader() instanceof RedkaleClassLoader.RedkaleCacheClassLoader) {
this.serverClassLoader = application.getServerClassLoader(); this.serverClassLoader = application.getServerClassLoader();
} else { } else {
this.serverClassLoader = new RedkaleClassLoader(application.getServerClassLoader()); this.serverClassLoader = new RedkaleClassLoader(application.getServerClassLoader());
@@ -128,8 +129,10 @@ public abstract class NodeServer {
public static <T extends NodeServer> NodeServer create(Class<T> clazz, Application application, AnyValue serconf) { public static <T extends NodeServer> NodeServer create(Class<T> clazz, Application application, AnyValue serconf) {
try { try {
RedkaleClassLoader.putReflectionDeclaredConstructors(clazz, clazz.getName(), Application.class, AnyValue.class); RedkaleClassLoader.putReflectionDeclaredConstructors(
return clazz.getDeclaredConstructor(Application.class, AnyValue.class).newInstance(application, serconf); clazz, clazz.getName(), Application.class, AnyValue.class);
return clazz.getDeclaredConstructor(Application.class, AnyValue.class)
.newInstance(application, serconf);
} catch (Exception e) { } catch (Exception e) {
throw new RedkaleException(e); throw new RedkaleException(e);
} }
@@ -138,29 +141,35 @@ public abstract class NodeServer {
public void init(AnyValue config) throws Exception { public void init(AnyValue config) throws Exception {
this.serverConf = config == null ? AnyValue.create() : config; this.serverConf = config == null ? AnyValue.create() : config;
if (isSNCP()) { // SNCP协议 if (isSNCP()) { // SNCP协议
String host = this.serverConf.getValue("host", isWATCH() ? "127.0.0.1" : "0.0.0.0").replace("0.0.0.0", ""); String host = this.serverConf
.getValue("host", isWATCH() ? "127.0.0.1" : "0.0.0.0")
.replace("0.0.0.0", "");
if (host.isEmpty()) { if (host.isEmpty()) {
host = application.localAddress.getAddress().getHostAddress(); host = application.localAddress.getAddress().getHostAddress();
} }
this.sncpAddress = new InetSocketAddress(host, this.serverConf.getIntValue("port")); this.sncpAddress = new InetSocketAddress(host, this.serverConf.getIntValue("port"));
this.sncpGroup = application.getSncpRpcGroups().getGroup(this.sncpAddress); this.sncpGroup = application.getSncpRpcGroups().getGroup(this.sncpAddress);
//单向SNCP服务不需要对等group // 单向SNCP服务不需要对等group
//if (this.sncpGroup == null) { // if (this.sncpGroup == null) {
// throw new RedkaleException("Server (" + String.valueOf(config).replaceAll("\\s+", " ") + ") not found <group> info"); // throw new RedkaleException("Server (" + String.valueOf(config).replaceAll("\\s+", " ") + ") not found
//} // <group> info");
// }
} }
//单点服务不会有 sncpAddress、sncpGroup // 单点服务不会有 sncpAddress、sncpGroup
if (this.sncpAddress != null) { if (this.sncpAddress != null) {
this.resourceFactory.register(RESNAME_SNCP_ADDRESS, this.sncpAddress); this.resourceFactory.register(RESNAME_SNCP_ADDRESS, this.sncpAddress);
this.resourceFactory.register(RESNAME_SNCP_ADDRESS, SocketAddress.class, this.sncpAddress); this.resourceFactory.register(RESNAME_SNCP_ADDRESS, SocketAddress.class, this.sncpAddress);
this.resourceFactory.register(RESNAME_SNCP_ADDRESS, InetSocketAddress.class, this.sncpAddress); this.resourceFactory.register(RESNAME_SNCP_ADDRESS, InetSocketAddress.class, this.sncpAddress);
this.resourceFactory.register(RESNAME_SNCP_ADDRESS, String.class, this.sncpAddress.getHostString() + ":" + this.sncpAddress.getPort()); this.resourceFactory.register(
RESNAME_SNCP_ADDRESS,
String.class,
this.sncpAddress.getHostString() + ":" + this.sncpAddress.getPort());
} }
if (this.sncpGroup != null) { if (this.sncpGroup != null) {
this.resourceFactory.register(RESNAME_SNCP_GROUP, this.sncpGroup); this.resourceFactory.register(RESNAME_SNCP_GROUP, this.sncpGroup);
} }
{ {
//设置root文件夹 // 设置root文件夹
String webroot = this.serverConf.getValue("root", "root"); String webroot = this.serverConf.getValue("root", "root");
File myroot = new File(webroot); File myroot = new File(webroot);
if (!webroot.contains(":") && !webroot.startsWith("/")) { if (!webroot.contains(":") && !webroot.startsWith("/")) {
@@ -171,20 +180,29 @@ public abstract class NodeServer {
resourceFactory.register(Server.RESNAME_SERVER_ROOT, File.class, myroot.getCanonicalFile()); resourceFactory.register(Server.RESNAME_SERVER_ROOT, File.class, myroot.getCanonicalFile());
resourceFactory.register(Server.RESNAME_SERVER_ROOT, Path.class, myroot.toPath()); resourceFactory.register(Server.RESNAME_SERVER_ROOT, Path.class, myroot.toPath());
//加入指定的classpath // 加入指定的classpath
Server.loadLib(serverClassLoader, logger, this.serverConf.getValue("lib", "")); Server.loadLib(serverClassLoader, logger, this.serverConf.getValue("lib", ""));
this.serverThread.setContextClassLoader(this.serverClassLoader); this.serverThread.setContextClassLoader(this.serverClassLoader);
} }
//必须要进行初始化, 构建Service时需要使用Context中的ExecutorService // 必须要进行初始化, 构建Service时需要使用Context中的ExecutorService
server.init(this.serverConf); server.init(this.serverConf);
if (this.sncpAddress != null) { //初始化SncpClient if (this.sncpAddress != null) { // 初始化SncpClient
this.sncpAsyncGroup = new AsyncIOGroup("Redkale-SncpClient-IOThread-%s", application.getWorkExecutor(), this.sncpAsyncGroup = new AsyncIOGroup(
server.getBufferCapacity(), server.getBufferPoolSize()).skipClose(true); "Redkale-SncpClient-IOThread-%s",
this.sncpClient = new SncpClient(server.getName(), this.sncpAsyncGroup, application.getNodeid(), application.getWorkExecutor(), server.getBufferCapacity(), server.getBufferPoolSize())
this.sncpAddress, new ClientAddress(this.sncpAddress), server.getNetprotocol(), Utility.cpus(), 1000); .skipClose(true);
this.sncpClient = new SncpClient(
server.getName(),
this.sncpAsyncGroup,
application.getNodeid(),
this.sncpAddress,
new ClientAddress(this.sncpAddress),
server.getNetprotocol(),
Utility.cpus(),
1000);
} }
registerResTypeLoader(); //给DataSource、CacheSource注册依赖注入时的监听回调事件。 registerResTypeLoader(); // 给DataSource、CacheSource注册依赖注入时的监听回调事件。
String interceptorClass = this.serverConf.getValue("interceptor", ""); String interceptorClass = this.serverConf.getValue("interceptor", "");
if (!interceptorClass.isEmpty()) { if (!interceptorClass.isEmpty()) {
Class clazz = serverClassLoader.loadClass(interceptorClass); Class clazz = serverClassLoader.loadClass(interceptorClass);
@@ -193,7 +211,7 @@ public abstract class NodeServer {
} }
ClassFilter<Service> serviceFilter = createServiceClassFilter(); ClassFilter<Service> serviceFilter = createServiceClassFilter();
if (application.isSingletonMode()) { //singleton模式下只加载指定的Service if (application.isSingletonMode()) { // singleton模式下只加载指定的Service
final String ssc = System.getProperty("redkale.singleton.serviceclass"); final String ssc = System.getProperty("redkale.singleton.serviceclass");
final String extssc = System.getProperty("redkale.singleton.extserviceclasses"); final String extssc = System.getProperty("redkale.singleton.extserviceclasses");
if (ssc != null) { if (ssc != null) {
@@ -229,9 +247,9 @@ public abstract class NodeServer {
application.loadClassByFilters(filters.toArray(new ClassFilter[filters.size()])); application.loadClassByFilters(filters.toArray(new ClassFilter[filters.size()]));
long e = System.currentTimeMillis() - s; long e = System.currentTimeMillis() - s;
logger.info(this.getClass().getSimpleName() + " load filter class in " + e + " ms"); logger.info(this.getClass().getSimpleName() + " load filter class in " + e + " ms");
loadService(serviceFilter); //必须在servlet之前 loadService(serviceFilter); // 必须在servlet之前
loadOthers(otherFilters); loadOthers(otherFilters);
if (!application.isSingletonMode()) { //非singleton模式下才加载Filter、Servlet if (!application.isSingletonMode()) { // 非singleton模式下才加载Filter、Servlet
loadFilter(filterFilter); loadFilter(filterFilter);
loadServlet(servletFilter); loadServlet(servletFilter);
postLoadServlets(); postLoadServlets();
@@ -241,18 +259,23 @@ public abstract class NodeServer {
} }
} }
protected void loadOthers(List<ClassFilter> otherFilters) throws Exception { protected void loadOthers(List<ClassFilter> otherFilters) throws Exception {}
}
protected abstract void loadFilter(ClassFilter<? extends Filter> filterFilter) throws Exception; protected abstract void loadFilter(ClassFilter<? extends Filter> filterFilter) throws Exception;
protected abstract void loadServlet(ClassFilter<? extends Servlet> servletFilter) throws Exception; protected abstract void loadServlet(ClassFilter<? extends Servlet> servletFilter) throws Exception;
private void registerResTypeLoader() { private void registerResTypeLoader() {
//--------------------- 注册 Local AutoLoad(false) Service --------------------- // --------------------- 注册 Local AutoLoad(false) Service ---------------------
resourceFactory.register(new ResourceTypeLoader() { resourceFactory.register(new ResourceTypeLoader() {
@Override @Override
public Object load(ResourceFactory rf, String srcResourceName, final Object srcObj, final String resourceName, Field field, final Object attachment) { public Object load(
ResourceFactory rf,
String srcResourceName,
final Object srcObj,
final String resourceName,
Field field,
final Object attachment) {
return loadResourceService(rf, srcResourceName, srcObj, resourceName, field, attachment); return loadResourceService(rf, srcResourceName, srcObj, resourceName, field, attachment);
} }
@@ -261,15 +284,21 @@ public abstract class NodeServer {
return Service.class; return Service.class;
} }
}); });
//----------------------------- 注册 WebSocketNode ----------------------------- // ----------------------------- 注册 WebSocketNode -----------------------------
final NodeServer self = this; final NodeServer self = this;
final ResourceFactory appResFactory = application.getResourceFactory(); final ResourceFactory appResFactory = application.getResourceFactory();
resourceFactory.register(new ResourceTypeLoader() { resourceFactory.register(new ResourceTypeLoader() {
@Override @Override
public Object load(ResourceFactory rf, String srcResourceName, final Object srcObj, final String resourceName, Field field, final Object attachment) { public Object load(
ResourceFactory rf,
String srcResourceName,
final Object srcObj,
final String resourceName,
Field field,
final Object attachment) {
try { try {
if ((srcObj instanceof Service) && Sncp.isRemote((Service) srcObj)) { if ((srcObj instanceof Service) && Sncp.isRemote((Service) srcObj)) {
return null; //远程模式不得注入 return null; // 远程模式不得注入
} }
Service nodeService = rf.find(resourceName, WebSocketNode.class); Service nodeService = rf.find(resourceName, WebSocketNode.class);
if (nodeService == null) { if (nodeService == null) {
@@ -277,10 +306,21 @@ public abstract class NodeServer {
if (groups.isEmpty() && isSNCP() && NodeServer.this.sncpGroup != null) { if (groups.isEmpty() && isSNCP() && NodeServer.this.sncpGroup != null) {
groups.add(NodeServer.this.sncpGroup); groups.add(NodeServer.this.sncpGroup);
} }
AsmMethodBoost methodBoost = application.createAsmMethodBoost(false, WebSocketNodeService.class); AsmMethodBoost methodBoost =
nodeService = Sncp.createLocalService(serverClassLoader, resourceName, WebSocketNodeService.class, methodBoost, application.createAsmMethodBoost(false, WebSocketNodeService.class);
application.getResourceFactory(), application.getSncpRpcGroups(), sncpClient, null, (String) null, (AnyValue) null); nodeService = Sncp.createLocalService(
(isSNCP() ? appResFactory : resourceFactory).register(resourceName, WebSocketNode.class, nodeService); serverClassLoader,
resourceName,
WebSocketNodeService.class,
methodBoost,
application.getResourceFactory(),
application.getSncpRpcGroups(),
sncpClient,
null,
(String) null,
(AnyValue) null);
(isSNCP() ? appResFactory : resourceFactory)
.register(resourceName, WebSocketNode.class, nodeService);
((org.redkale.net.http.WebSocketNodeService) nodeService).setName(resourceName); ((org.redkale.net.http.WebSocketNodeService) nodeService).setName(resourceName);
} }
resourceFactory.inject(resourceName, nodeService, self); resourceFactory.inject(resourceName, nodeService, self);
@@ -288,7 +328,7 @@ public abstract class NodeServer {
if (Sncp.isRemote(nodeService)) { if (Sncp.isRemote(nodeService)) {
remoteServices.add(nodeService); remoteServices.add(nodeService);
} else { } else {
rf.inject(resourceName, nodeService); //动态加载的Service也存在按需加载的注入资源 rf.inject(resourceName, nodeService); // 动态加载的Service也存在按需加载的注入资源
localServices.add(nodeService); localServices.add(nodeService);
if (!Sncp.isComponent(nodeService)) { if (!Sncp.isComponent(nodeService)) {
servletServices.add(nodeService); servletServices.add(nodeService);
@@ -313,8 +353,14 @@ public abstract class NodeServer {
}); });
} }
//Service.class的ResourceTypeLoader // Service.class的ResourceTypeLoader
private Object loadResourceService(ResourceFactory rf, String srcResourceName, Object srcObj, String resourceName, Field field, Object attachment) { private Object loadResourceService(
ResourceFactory rf,
String srcResourceName,
Object srcObj,
String resourceName,
Field field,
Object attachment) {
final NodeServer self = this; final NodeServer self = this;
final ResourceFactory appResFactory = application.getResourceFactory(); final ResourceFactory appResFactory = application.getResourceFactory();
Class<Service> serviceImplClass = Service.class; Class<Service> serviceImplClass = Service.class;
@@ -324,7 +370,7 @@ public abstract class NodeServer {
return null; return null;
} }
if ((srcObj instanceof Service) && Sncp.isRemote((Service) srcObj)) { if ((srcObj instanceof Service) && Sncp.isRemote((Service) srcObj)) {
return null; //远程模式不得注入 AutoLoad Service return null; // 远程模式不得注入 AutoLoad Service
} }
boolean auto = true; boolean auto = true;
AutoLoad al = serviceImplClass.getAnnotation(AutoLoad.class); AutoLoad al = serviceImplClass.getAnnotation(AutoLoad.class);
@@ -339,19 +385,37 @@ public abstract class NodeServer {
return null; return null;
} }
//ResourceFactory resfactory = (isSNCP() ? appResFactory : resourceFactory); // ResourceFactory resfactory = (isSNCP() ? appResFactory : resourceFactory);
Service service; Service service;
if (Modifier.isFinal(serviceImplClass.getModifiers()) || Sncp.isComponent(serviceImplClass)) { if (Modifier.isFinal(serviceImplClass.getModifiers()) || Sncp.isComponent(serviceImplClass)) {
service = (Service) serviceImplClass.getConstructor().newInstance(); service = (Service) serviceImplClass.getConstructor().newInstance();
} else if (Utility.isAbstractOrInterface(serviceImplClass)) { //没有具体实现类 } else if (Utility.isAbstractOrInterface(serviceImplClass)) { // 没有具体实现类
AsmMethodBoost methodBoost = application.createAsmMethodBoost(true, serviceImplClass); AsmMethodBoost methodBoost = application.createAsmMethodBoost(true, serviceImplClass);
MessageAgent mqAgent = appResFactory.find("", MessageAgent.class); MessageAgent mqAgent = appResFactory.find("", MessageAgent.class);
service = Sncp.createRemoteService(serverClassLoader, resourceName, serviceImplClass, service = Sncp.createRemoteService(
methodBoost, appResFactory, application.getSncpRpcGroups(), this.sncpClient, mqAgent, null, null); serverClassLoader,
resourceName,
serviceImplClass,
methodBoost,
appResFactory,
application.getSncpRpcGroups(),
this.sncpClient,
mqAgent,
null,
null);
} else { } else {
AsmMethodBoost methodBoost = application.createAsmMethodBoost(false, serviceImplClass); AsmMethodBoost methodBoost = application.createAsmMethodBoost(false, serviceImplClass);
service = Sncp.createLocalService(serverClassLoader, resourceName, serviceImplClass, service = Sncp.createLocalService(
methodBoost, appResFactory, application.getSncpRpcGroups(), sncpClient, null, null, null); serverClassLoader,
resourceName,
serviceImplClass,
methodBoost,
appResFactory,
application.getSncpRpcGroups(),
sncpClient,
null,
null,
null);
} }
appResFactory.register(resourceName, serviceImplClass, service); appResFactory.register(resourceName, serviceImplClass, service);
@@ -360,11 +424,14 @@ public abstract class NodeServer {
if (!application.isCompileMode() && !Sncp.isRemote(service)) { if (!application.isCompileMode() && !Sncp.isRemote(service)) {
service.init(null); service.init(null);
} }
logger.info("Load Service(" + (Sncp.isRemote(service) ? "Remote" : "@Local") logger.info("Load Service(" + (Sncp.isRemote(service) ? "Remote" : "@Local") + " @AutoLoad service = "
+ " @AutoLoad service = " + serviceImplClass.getSimpleName() + ", resourceName = '" + resourceName + "')"); + serviceImplClass.getSimpleName() + ", resourceName = '" + resourceName + "')");
return service; return service;
} catch (Exception e) { } catch (Exception e) {
logger.log(Level.SEVERE, "Load @AutoLoad(false) Service inject " + serviceImplClass + " to " + srcObj + " error", e); logger.log(
Level.SEVERE,
"Load @AutoLoad(false) Service inject " + serviceImplClass + " to " + srcObj + " error",
e);
return null; return null;
} }
} }
@@ -385,8 +452,14 @@ public abstract class NodeServer {
private final boolean localMode; private final boolean localMode;
public ExpectServiceLoader(Class type, Class<? extends Service> serviceImplClass, AtomicInteger serviceCount, public ExpectServiceLoader(
SncpRpcGroups rpcGroups, FilterEntry<? extends Service> entry, String group, boolean localMode) { Class type,
Class<? extends Service> serviceImplClass,
AtomicInteger serviceCount,
SncpRpcGroups rpcGroups,
FilterEntry<? extends Service> entry,
String group,
boolean localMode) {
this.type = type; this.type = type;
this.serviceImplClass = serviceImplClass; this.serviceImplClass = serviceImplClass;
this.serviceCount = serviceCount; this.serviceCount = serviceCount;
@@ -397,43 +470,72 @@ public abstract class NodeServer {
} }
@Override @Override
public Object load(ResourceFactory rf, String srcResourceName, final Object srcObj, final String resourceName, Field field, final Object attachment) { public Object load(
ResourceFactory rf,
String srcResourceName,
final Object srcObj,
final String resourceName,
Field field,
final Object attachment) {
try { try {
final ResourceFactory appResourceFactory = application.getResourceFactory(); final ResourceFactory appResourceFactory = application.getResourceFactory();
ResourceFactory regFactory = isSNCP() ? application.getResourceFactory() : resourceFactory; ResourceFactory regFactory = isSNCP() ? application.getResourceFactory() : resourceFactory;
if (Sncp.loadRemoteMethodActions(Sncp.getResourceType(serviceImplClass)).isEmpty() if (Sncp.loadRemoteMethodActions(Sncp.getResourceType(serviceImplClass))
&& (serviceImplClass.getAnnotation(Priority.class) == null .isEmpty()
&& serviceImplClass.getAnnotation(javax.annotation.Priority.class) == null)) { //class没有可用的方法且没有标记启动优先级的 通常为BaseService && (serviceImplClass.getAnnotation(Priority.class) == null
if (!serviceImplClass.getName().startsWith("org.redkale.") && !serviceImplClass.getSimpleName().contains("Base")) { && serviceImplClass.getAnnotation(javax.annotation.Priority.class)
logger.log(Level.FINE, serviceImplClass + " cannot load because not found less one public non-final method"); == null)) { // class没有可用的方法且没有标记启动优先级的 通常为BaseService
if (!serviceImplClass.getName().startsWith("org.redkale.")
&& !serviceImplClass.getSimpleName().contains("Base")) {
logger.log(
Level.FINE,
serviceImplClass + " cannot load because not found less one public non-final method");
} }
return null; return null;
} }
RedkaleClassLoader.putReflectionPublicMethods(serviceImplClass.getName()); RedkaleClassLoader.putReflectionPublicMethods(serviceImplClass.getName());
MessageAgent mqAgent = getMessageAgent(entry.getProperty()); MessageAgent mqAgent = getMessageAgent(entry.getProperty());
Service service; Service service;
if (Sncp.isComponent(serviceImplClass)) { //Component if (Sncp.isComponent(serviceImplClass)) { // Component
RedkaleClassLoader.putReflectionPublicConstructors(serviceImplClass, serviceImplClass.getName()); RedkaleClassLoader.putReflectionPublicConstructors(serviceImplClass, serviceImplClass.getName());
if (!acceptsComponent(serviceImplClass)) { if (!acceptsComponent(serviceImplClass)) {
return null; return null;
} }
service = serviceImplClass.getDeclaredConstructor().newInstance(); service = serviceImplClass.getDeclaredConstructor().newInstance();
} else if (srcObj instanceof WebSocketServlet || localMode) { //本地模式 } else if (srcObj instanceof WebSocketServlet || localMode) { // 本地模式
AsmMethodBoost methodBoost = application.createAsmMethodBoost(false, serviceImplClass); AsmMethodBoost methodBoost = application.createAsmMethodBoost(false, serviceImplClass);
service = Sncp.createLocalService(serverClassLoader, resourceName, serviceImplClass, service = Sncp.createLocalService(
methodBoost, appResourceFactory, rpcGroups, sncpClient, mqAgent, group, entry.getProperty()); serverClassLoader,
resourceName,
serviceImplClass,
methodBoost,
appResourceFactory,
rpcGroups,
sncpClient,
mqAgent,
group,
entry.getProperty());
} else { } else {
AsmMethodBoost methodBoost = application.createAsmMethodBoost(true, serviceImplClass); AsmMethodBoost methodBoost = application.createAsmMethodBoost(true, serviceImplClass);
service = Sncp.createRemoteService(serverClassLoader, resourceName, serviceImplClass, service = Sncp.createRemoteService(
methodBoost, appResourceFactory, rpcGroups, sncpClient, mqAgent, group, entry.getProperty()); serverClassLoader,
resourceName,
serviceImplClass,
methodBoost,
appResourceFactory,
rpcGroups,
sncpClient,
mqAgent,
group,
entry.getProperty());
} }
final Class restype = Sncp.getResourceType(service); final Class restype = Sncp.getResourceType(service);
if (rf.find(resourceName, restype) == null) { if (rf.find(resourceName, restype) == null) {
regFactory.register(resourceName, restype, service); regFactory.register(resourceName, restype, service);
} else if (isSNCP() && !entry.isAutoload()) { } else if (isSNCP() && !entry.isAutoload()) {
throw new RedkaleException(restype.getSimpleName() throw new RedkaleException(restype.getSimpleName() + "(class:" + serviceImplClass.getName()
+ "(class:" + serviceImplClass.getName() + ", name:" + resourceName + ", group:" + group + ") is repeat."); + ", name:" + resourceName + ", group:" + group + ") is repeat.");
} }
if (Sncp.isRemote(service)) { if (Sncp.isRemote(service)) {
remoteServices.add(service); remoteServices.add(service);
@@ -442,7 +544,7 @@ public abstract class NodeServer {
} }
} else { } else {
if (field != null) { if (field != null) {
rf.inject(resourceName, service); //动态加载的Service也存在按需加载的注入资源 rf.inject(resourceName, service); // 动态加载的Service也存在按需加载的注入资源
} }
localServices.add(service); localServices.add(service);
if (!Sncp.isComponent(service)) { if (!Sncp.isComponent(service)) {
@@ -460,7 +562,6 @@ public abstract class NodeServer {
public Type resourceType() { public Type resourceType() {
return type; return type;
} }
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@@ -470,20 +571,20 @@ public abstract class NodeServer {
final Set<FilterEntry<? extends Service>> entrys = (Set) serviceFilter.getAllFilterEntrys(); final Set<FilterEntry<? extends Service>> entrys = (Set) serviceFilter.getAllFilterEntrys();
final SncpRpcGroups rpcGroups = application.getSncpRpcGroups(); final SncpRpcGroups rpcGroups = application.getSncpRpcGroups();
final AtomicInteger serviceCount = new AtomicInteger(); final AtomicInteger serviceCount = new AtomicInteger();
for (FilterEntry<? extends Service> entry : entrys) { //service实现类 for (FilterEntry<? extends Service> entry : entrys) { // service实现类
final Class<? extends Service> serviceImplClass = entry.getType(); final Class<? extends Service> serviceImplClass = entry.getType();
if (Modifier.isFinal(serviceImplClass.getModifiers())) { if (Modifier.isFinal(serviceImplClass.getModifiers())) {
continue; //修饰final的类跳过 continue; // 修饰final的类跳过
} }
if (!Modifier.isPublic(serviceImplClass.getModifiers())) { if (!Modifier.isPublic(serviceImplClass.getModifiers())) {
continue; continue;
} }
if (Sncp.isSncpDyn(serviceImplClass)) { if (Sncp.isSncpDyn(serviceImplClass)) {
continue; //动态生成的跳过 continue; // 动态生成的跳过
} }
if (entry.isExpect()) { if (entry.isExpect()) {
if (Modifier.isAbstract(serviceImplClass.getModifiers())) { if (Modifier.isAbstract(serviceImplClass.getModifiers())) {
continue; //修饰abstract的类跳过 continue; // 修饰abstract的类跳过
} }
if (DataSource.class.isAssignableFrom(serviceImplClass)) { if (DataSource.class.isAssignableFrom(serviceImplClass)) {
continue; continue;
@@ -493,13 +594,14 @@ public abstract class NodeServer {
} }
} }
if (entry.getName().contains(Resource.PARENT_NAME)) { if (entry.getName().contains(Resource.PARENT_NAME)) {
throw new RedkaleException("<name> value cannot contains '" + Resource.PARENT_NAME + "' in " + entry.getProperty()); throw new RedkaleException(
"<name> value cannot contains '" + Resource.PARENT_NAME + "' in " + entry.getProperty());
} }
if (!entry.isEmptyGroup() && !entry.isRemote() && !rpcGroups.containsGroup(entry.getGroup())) { if (!entry.isEmptyGroup() && !entry.isRemote() && !rpcGroups.containsGroup(entry.getGroup())) {
throw new RedkaleException("Not found group(" + entry.getGroup() + ")"); throw new RedkaleException("Not found group(" + entry.getGroup() + ")");
} }
Service oldOther = resourceFactory.find(entry.getName(), serviceImplClass); Service oldOther = resourceFactory.find(entry.getName(), serviceImplClass);
if (oldOther != null) { //Server加载Service时需要判断是否已在其他协议服务中加载 if (oldOther != null) { // Server加载Service时需要判断是否已在其他协议服务中加载
if (!Sncp.isRemote(oldOther)) { if (!Sncp.isRemote(oldOther)) {
if (!Sncp.isComponent(oldOther)) { if (!Sncp.isComponent(oldOther)) {
servletServices.add(oldOther); servletServices.add(oldOther);
@@ -509,43 +611,46 @@ public abstract class NodeServer {
} }
boolean isLocalGroup0 = rpcGroups.isLocalGroup(this.sncpGroup, this.sncpAddress, entry); boolean isLocalGroup0 = rpcGroups.isLocalGroup(this.sncpGroup, this.sncpAddress, entry);
final String group = isLocalGroup0 ? null : entry.getGroup(); final String group = isLocalGroup0 ? null : entry.getGroup();
final boolean localMode = serviceImplClass.getAnnotation(Local.class) != null || isLocalGroup0;//本地模式 final boolean localMode = serviceImplClass.getAnnotation(Local.class) != null || isLocalGroup0; // 本地模式
if ((localMode || Sncp.isComponent(serviceImplClass)) && Utility.isAbstractOrInterface(serviceImplClass)) { if ((localMode || Sncp.isComponent(serviceImplClass)) && Utility.isAbstractOrInterface(serviceImplClass)) {
continue; //本地模式或Component不能实例化接口和抽象类的Service类 continue; // 本地模式或Component不能实例化接口和抽象类的Service类
} }
if (entry.isExpect()) { if (entry.isExpect()) {
Class t = ResourceFactory.getResourceType(entry.getType()); Class t = ResourceFactory.getResourceType(entry.getType());
if (resourceFactory.findResourceTypeLoader(t) == null) { if (resourceFactory.findResourceTypeLoader(t) == null) {
resourceFactory.register(new ExpectServiceLoader(t, serviceImplClass, serviceCount, rpcGroups, entry, group, localMode)); resourceFactory.register(new ExpectServiceLoader(
t, serviceImplClass, serviceCount, rpcGroups, entry, group, localMode));
} }
} else { } else {
ExpectServiceLoader resourceLoader = new ExpectServiceLoader(serviceImplClass, ExpectServiceLoader resourceLoader = new ExpectServiceLoader(
serviceImplClass, serviceCount, rpcGroups, entry, group, localMode); serviceImplClass, serviceImplClass, serviceCount, rpcGroups, entry, group, localMode);
resourceLoader.load(resourceFactory, null, null, entry.getName(), null, false); resourceLoader.load(resourceFactory, null, null, entry.getName(), null, false);
} }
} }
long et = System.currentTimeMillis(); long et = System.currentTimeMillis();
if (serviceCdl != null) { if (serviceCdl != null) {
serviceCdl.countDown(); serviceCdl.countDown();
serviceCdl.await(); serviceCdl.await();
} }
logger.info(this.getClass().getSimpleName() + " construct services in " + (et - starts) + " ms and await " + (System.currentTimeMillis() - et) + " ms"); logger.info(this.getClass().getSimpleName() + " construct services in " + (et - starts) + " ms and await "
+ (System.currentTimeMillis() - et) + " ms");
final StringBuilder sb = logger.isLoggable(Level.INFO) ? new StringBuilder() : null; final StringBuilder sb = logger.isLoggable(Level.INFO) ? new StringBuilder() : null;
//---------------- inject ---------------- // ---------------- inject ----------------
new ArrayList<>(localServices).forEach(y -> { new ArrayList<>(localServices).forEach(y -> {
resourceFactory.inject(Sncp.getResourceName(y), y, NodeServer.this); resourceFactory.inject(Sncp.getResourceName(y), y, NodeServer.this);
}); });
//远程模式不可inject 里面存在@Resource.required=true依赖 // 远程模式不可inject 里面存在@Resource.required=true依赖
// new ArrayList<>(remoteServices).forEach(y -> { // new ArrayList<>(remoteServices).forEach(y -> {
// resourceFactory.inject(Sncp.getResourceName(y), y, NodeServer.this); // resourceFactory.inject(Sncp.getResourceName(y), y, NodeServer.this);
// calcMaxLength(y); // calcMaxLength(y);
// }); // });
if (sb != null) { if (sb != null) {
remoteServices.forEach(y -> { remoteServices.forEach(y -> {
sb.append(Sncp.toSimpleString(y, maxNameLength, maxTypeLength)).append(" load and inject").append(LINE_SEPARATOR); sb.append(Sncp.toSimpleString(y, maxNameLength, maxTypeLength))
.append(" load and inject")
.append(LINE_SEPARATOR);
}); });
} }
if (isSNCP() && !sncpRemoteAgents.isEmpty()) { if (isSNCP() && !sncpRemoteAgents.isEmpty()) {
@@ -554,7 +659,7 @@ public abstract class NodeServer {
// mqAgent.startSncpRespConsumer(); // mqAgent.startSncpRespConsumer();
}); });
} }
//----------------- init ----------------- // ----------------- init -----------------
List<Service> swlist = new ArrayList<>(localServices); List<Service> swlist = new ArrayList<>(localServices);
swlist.forEach(y -> calcMaxLength(y)); swlist.forEach(y -> calcMaxLength(y));
swlist.sort((o1, o2) -> { swlist.sort((o1, o2) -> {
@@ -569,7 +674,9 @@ public abstract class NodeServer {
if (v1 != v2) { if (v1 != v2) {
return v1 - v2; return v1 - v2;
} }
int rs = Sncp.getResourceType(o1).getName().compareTo(Sncp.getResourceType(o2).getName()); int rs = Sncp.getResourceType(o1)
.getName()
.compareTo(Sncp.getResourceType(o2).getName());
if (rs == 0) { if (rs == 0) {
rs = Sncp.getResourceName(o1).compareTo(Sncp.getResourceName(o2)); rs = Sncp.getResourceName(o1).compareTo(Sncp.getResourceName(o2));
} }
@@ -577,7 +684,7 @@ public abstract class NodeServer {
}); });
localServices.clear(); localServices.clear();
localServices.addAll(swlist); localServices.addAll(swlist);
//this.loadPersistData(); // this.loadPersistData();
long preinits = System.currentTimeMillis(); long preinits = System.currentTimeMillis();
preInitServices(localServices, remoteServices, servletServices); preInitServices(localServices, remoteServices, servletServices);
long preinite = System.currentTimeMillis() - preinits; long preinite = System.currentTimeMillis() - preinits;
@@ -586,7 +693,11 @@ public abstract class NodeServer {
localServices.stream().forEach(y -> { localServices.stream().forEach(y -> {
String serstr = Sncp.toSimpleString(y, maxNameLength, maxTypeLength); String serstr = Sncp.toSimpleString(y, maxNameLength, maxTypeLength);
if (slist != null) { if (slist != null) {
slist.add(new StringBuilder().append(serstr).append(" load").append(LINE_SEPARATOR).toString()); slist.add(new StringBuilder()
.append(serstr)
.append(" load")
.append(LINE_SEPARATOR)
.toString());
} }
}); });
} else { } else {
@@ -598,8 +709,14 @@ public abstract class NodeServer {
long e = System.currentTimeMillis() - s; long e = System.currentTimeMillis() - s;
if (slist != null) { if (slist != null) {
String serstr = Sncp.toSimpleString(y, maxNameLength, maxTypeLength); String serstr = Sncp.toSimpleString(y, maxNameLength, maxTypeLength);
slist.add(new StringBuilder().append(serstr).append(" load and init in ") slist.add(new StringBuilder()
.append(e < 10 ? " " : (e < 100 ? " " : "")).append(e).append(" ms").append(LINE_SEPARATOR).toString()); .append(serstr)
.append(" load and init in ")
.append(e < 10 ? " " : (e < 100 ? " " : ""))
.append(e)
.append(" ms")
.append(LINE_SEPARATOR)
.toString());
} }
}); });
localServices.stream().forEach(y -> { localServices.stream().forEach(y -> {
@@ -609,35 +726,51 @@ public abstract class NodeServer {
long e = System.currentTimeMillis() - s; long e = System.currentTimeMillis() - s;
if (rs && slist != null) { if (rs && slist != null) {
String serstr = Sncp.toSimpleString(y, maxNameLength, maxTypeLength); String serstr = Sncp.toSimpleString(y, maxNameLength, maxTypeLength);
slist.add(new StringBuilder().append(serstr).append(" component-start in ") slist.add(new StringBuilder()
.append(e < 10 ? " " : (e < 100 ? " " : "")).append(e).append(" ms").append(LINE_SEPARATOR).toString()); .append(serstr)
.append(" component-start in ")
.append(e < 10 ? " " : (e < 100 ? " " : ""))
.append(e)
.append(" ms")
.append(LINE_SEPARATOR)
.toString());
} }
} }
}); });
} }
if (slist != null && sb != null) { if (slist != null && sb != null) {
List<String> wlist = new ArrayList<>(slist); //直接使用CopyOnWriteArrayList偶尔会出现莫名的异常(CopyOnWriteArrayList源码1185行) List<String> wlist =
new ArrayList<>(slist); // 直接使用CopyOnWriteArrayList偶尔会出现莫名的异常(CopyOnWriteArrayList源码1185行)
for (String s : wlist) { for (String s : wlist) {
sb.append(s); sb.append(s);
} }
sb.append("All ").append(localServices.size()).append(" Services load in ").append(System.currentTimeMillis() - starts).append(" ms"); sb.append("All ")
.append(localServices.size())
.append(" Services load in ")
.append(System.currentTimeMillis() - starts)
.append(" ms");
} }
if (sb != null && preinite > 10) { if (sb != null && preinite > 10) {
sb.append(ClusterAgent.class.getSimpleName()).append(" register in ").append(preinite).append(" ms" + LINE_SEPARATOR); sb.append(ClusterAgent.class.getSimpleName())
.append(" register in ")
.append(preinite)
.append(" ms" + LINE_SEPARATOR);
} }
if (sb != null && sb.length() > 0) { if (sb != null && sb.length() > 0) {
logger.log(Level.INFO, sb.toString()); logger.log(Level.INFO, sb.toString());
} }
} }
private void calcMaxLength(Service y) { //计算toString中的长度 private void calcMaxLength(Service y) { // 计算toString中的长度
String n = Sncp.getResourceName(y); String n = Sncp.getResourceName(y);
maxNameLength = Math.max(maxNameLength, n == null ? 0 : n.length()); maxNameLength = Math.max(maxNameLength, n == null ? 0 : n.length());
maxTypeLength = Math.max(maxTypeLength, Sncp.getResourceType(y).getName().length() + 1); maxTypeLength =
Math.max(maxTypeLength, Sncp.getResourceType(y).getName().length() + 1);
} }
protected boolean acceptsComponent(Class<? extends Service> serviceImplClass) { protected boolean acceptsComponent(Class<? extends Service> serviceImplClass) {
if (Modifier.isAbstract(serviceImplClass.getModifiers()) || Modifier.isInterface(serviceImplClass.getModifiers())) { if (Modifier.isAbstract(serviceImplClass.getModifiers())
|| Modifier.isInterface(serviceImplClass.getModifiers())) {
return false; return false;
} }
return true; return true;
@@ -658,8 +791,9 @@ public abstract class NodeServer {
return agent; return agent;
} }
//Service.init执行之前调用 // Service.init执行之前调用
protected void preInitServices(Set<Service> localServices, Set<Service> remoteServices, Set<Service> servletServices) { protected void preInitServices(
Set<Service> localServices, Set<Service> remoteServices, Set<Service> servletServices) {
final ClusterAgent cluster = application.getResourceFactory().find("", ClusterAgent.class); final ClusterAgent cluster = application.getResourceFactory().find("", ClusterAgent.class);
if (!application.isCompileMode() && cluster != null) { if (!application.isCompileMode() && cluster != null) {
NodeProtocol pros = getClass().getAnnotation(NodeProtocol.class); NodeProtocol pros = getClass().getAnnotation(NodeProtocol.class);
@@ -674,32 +808,31 @@ public abstract class NodeServer {
} }
} }
//loadServlet执行之后调用 // loadServlet执行之后调用
protected void postLoadServlets() { protected void postLoadServlets() {}
} // Service.destroy执行之前调用
protected void preDestroyServices(
//Service.destroy执行之前调用 Set<Service> localServices, Set<Service> remoteServices, Set<Service> servletServices) {
protected void preDestroyServices(Set<Service> localServices, Set<Service> remoteServices, Set<Service> servletServices) {
final ClusterAgent cluster = application.getResourceFactory().find("", ClusterAgent.class); final ClusterAgent cluster = application.getResourceFactory().find("", ClusterAgent.class);
if (!application.isCompileMode() && cluster != null) { //服务注销 if (!application.isCompileMode() && cluster != null) { // 服务注销
NodeProtocol pros = getClass().getAnnotation(NodeProtocol.class); NodeProtocol pros = getClass().getAnnotation(NodeProtocol.class);
String protocol = pros.value().toUpperCase(); String protocol = pros.value().toUpperCase();
if (cluster.containsProtocol(protocol) && cluster.containsPort(server.getSocketAddress().getPort())) { if (cluster.containsProtocol(protocol)
&& cluster.containsPort(server.getSocketAddress().getPort())) {
cluster.deregister(this, protocol, localServices, remoteServices, servletServices); cluster.deregister(this, protocol, localServices, remoteServices, servletServices);
afterClusterDeregisterOnPreDestroyServices(cluster, protocol); afterClusterDeregisterOnPreDestroyServices(cluster, protocol);
} }
} }
if (!application.isCompileMode() && !this.messageAgents.isEmpty()) { //MQ if (!application.isCompileMode() && !this.messageAgents.isEmpty()) { // MQ
} }
} }
protected void afterClusterDeregisterOnPreDestroyServices(ClusterAgent cluster, String protocol) { protected void afterClusterDeregisterOnPreDestroyServices(ClusterAgent cluster, String protocol) {}
}
//Server.start执行之后调用 // Server.start执行之后调用
protected void postStartServer(Set<Service> localServices, Set<Service> remoteServices, Set<Service> servletServices) { protected void postStartServer(
} Set<Service> localServices, Set<Service> remoteServices, Set<Service> servletServices) {}
protected abstract ClassFilter<Filter> createFilterClassFilter(); protected abstract ClassFilter<Filter> createFilterClassFilter();
@@ -710,12 +843,24 @@ public abstract class NodeServer {
} }
protected ClassFilter<Service> createServiceClassFilter() { protected ClassFilter<Service> createServiceClassFilter() {
return createClassFilter(this.sncpGroup, null, Service.class, return createClassFilter(
(!isSNCP() && application.watching) ? null : new Class[]{org.redkale.watch.WatchService.class}, Annotation.class, "services", "service"); this.sncpGroup,
null,
Service.class,
(!isSNCP() && application.watching) ? null : new Class[] {org.redkale.watch.WatchService.class},
Annotation.class,
"services",
"service");
} }
protected ClassFilter createClassFilter(final String localGroup, Class<? extends Annotation> ref, protected ClassFilter createClassFilter(
Class inter, Class[] excludeSuperClasses, Class<? extends Annotation> ref2, String properties, String property) { final String localGroup,
Class<? extends Annotation> ref,
Class inter,
Class[] excludeSuperClasses,
Class<? extends Annotation> ref2,
String properties,
String property) {
ClassFilter cf = new ClassFilter(this.serverClassLoader, ref, inter, excludeSuperClasses, null); ClassFilter cf = new ClassFilter(this.serverClassLoader, ref, inter, excludeSuperClasses, null);
if (properties == null) { if (properties == null) {
cf.setRefused(true); cf.setRefused(true);
@@ -753,17 +898,17 @@ public abstract class NodeServer {
ClassFilter filter = new ClassFilter(this.serverClassLoader, ref, inter, excludeSuperClasses, prop); ClassFilter filter = new ClassFilter(this.serverClassLoader, ref, inter, excludeSuperClasses, prop);
for (AnyValue av : list.getAnyValues(property)) { // <service>、<filter>、<servlet> 节点 for (AnyValue av : list.getAnyValues(property)) { // <service>、<filter>、<servlet> 节点
final AnyValue[] items = av.getAnyValues("property"); final AnyValue[] items = av.getAnyValues("property");
if (items.length > 0) { //存在 <property>节点 if (items.length > 0) { // 存在 <property>节点
AnyValueWriter dav = AnyValueWriter.create(); AnyValueWriter dav = AnyValueWriter.create();
final AnyValue.Entry<String>[] strings = av.getStringEntrys(); final AnyValue.Entry<String>[] strings = av.getStringEntrys();
if (strings != null) { //将<service>、<filter>、<servlet>节点的属性值传给dav if (strings != null) { // 将<service>、<filter>、<servlet>节点的属性值传给dav
for (AnyValue.Entry<String> en : strings) { for (AnyValue.Entry<String> en : strings) {
dav.addValue(en.name, en.getValue()); dav.addValue(en.name, en.getValue());
} }
} }
final AnyValue.Entry<AnyValue>[] anys = av.getAnyEntrys(); final AnyValue.Entry<AnyValue>[] anys = av.getAnyEntrys();
if (anys != null) { if (anys != null) {
for (AnyValue.Entry<AnyValue> en : anys) { //将<service>、<filter>、<servlet>节点的非property属性节点传给dav for (AnyValue.Entry<AnyValue> en : anys) { // 将<service>、<filter>、<servlet>节点的非property属性节点传给dav
if (!"property".equals(en.name)) { if (!"property".equals(en.name)) {
dav.addValue(en.name, en.getValue()); dav.addValue(en.name, en.getValue());
} }
@@ -785,7 +930,7 @@ public abstract class NodeServer {
String excludes = list.getValue("excludes", ""); String excludes = list.getValue("excludes", "");
filter.setIncludePatterns(includes.split(";")); filter.setIncludePatterns(includes.split(";"));
filter.setExcludePatterns(excludes.split(";")); filter.setExcludePatterns(excludes.split(";"));
} else if (ref2 == null || ref2 == Annotation.class) { //service如果是autoload=false则不需要加载 } else if (ref2 == null || ref2 == Annotation.class) { // service如果是autoload=false则不需要加载
filter.setRefused(true); filter.setRefused(true);
} else if (ref2 != Annotation.class) { } else if (ref2 != Annotation.class) {
filter.setAnnotationClass(ref2); filter.setAnnotationClass(ref2);
@@ -870,7 +1015,11 @@ public abstract class NodeServer {
application.onServicePostDestroy(y); application.onServicePostDestroy(y);
long e = System.currentTimeMillis() - s; long e = System.currentTimeMillis() - s;
if (e > 2 && sb != null) { if (e > 2 && sb != null) {
sb.append(Sncp.toSimpleString(y, maxNameLength, maxTypeLength)).append(" destroy ").append(e).append("ms").append(LINE_SEPARATOR); sb.append(Sncp.toSimpleString(y, maxNameLength, maxTypeLength))
.append(" destroy ")
.append(e)
.append("ms")
.append(LINE_SEPARATOR);
} }
}); });
if (sb != null && sb.length() > 0) { if (sb != null && sb.length() > 0) {
@@ -895,7 +1044,7 @@ public abstract class NodeServer {
localServices.forEach(y -> { localServices.forEach(y -> {
Set<Method> methods = new HashSet<>(); Set<Method> methods = new HashSet<>();
Class loop = y.getClass(); Class loop = y.getClass();
//do { public方法不用递归 // do { public方法不用递归
for (Method m : loop.getMethods()) { for (Method m : loop.getMethods()) {
Command c = m.getAnnotation(Command.class); Command c = m.getAnnotation(Command.class);
org.redkale.util.Command c2 = m.getAnnotation(org.redkale.util.Command.class); org.redkale.util.Command c2 = m.getAnnotation(org.redkale.util.Command.class);
@@ -923,7 +1072,7 @@ public abstract class NodeServer {
} }
methods.add(m); methods.add(m);
} }
//} while ((loop = loop.getSuperclass()) != Object.class); // } while ((loop = loop.getSuperclass()) != Object.class);
if (methods.isEmpty()) { if (methods.isEmpty()) {
return; return;
} }
@@ -942,7 +1091,13 @@ public abstract class NodeServer {
} }
long e = System.currentTimeMillis() - s; long e = System.currentTimeMillis() - s;
if (e > 10 && sb != null) { if (e > 10 && sb != null) {
sb.append(Sncp.toSimpleString(y, maxNameLength, maxTypeLength)).append(" command (").append(cmd).append(") ").append(e).append("ms").append(LINE_SEPARATOR); sb.append(Sncp.toSimpleString(y, maxNameLength, maxTypeLength))
.append(" command (")
.append(cmd)
.append(") ")
.append(e)
.append("ms")
.append(LINE_SEPARATOR);
} }
}); });
if (sb != null && sb.length() > 0) { if (sb != null && sb.length() > 0) {
@@ -970,5 +1125,4 @@ public abstract class NodeServer {
public String getThreadName() { public String getThreadName() {
return this.threadName; return this.threadName;
} }
} }

View File

@@ -18,8 +18,7 @@ import org.redkale.util.*;
/** /**
* SNCP Server节点的配置Server * SNCP Server节点的配置Server
* *
* <p> * <p>详情见: https://redkale.org
* 详情见: https://redkale.org
* *
* @author zhangjx * @author zhangjx
*/ */
@@ -38,7 +37,11 @@ public class NodeSncpServer extends NodeServer {
} }
private static Server createServer(Application application, AnyValue serconf) { private static Server createServer(Application application, AnyValue serconf) {
return new SncpServer(application, application.getStartTime(), serconf, application.getResourceFactory().createChild()); return new SncpServer(
application,
application.getStartTime(),
serconf,
application.getResourceFactory().createChild());
} }
@Override @Override
@@ -49,9 +52,9 @@ public class NodeSncpServer extends NodeServer {
@Override @Override
public void init(AnyValue config) throws Exception { public void init(AnyValue config) throws Exception {
super.init(config); super.init(config);
//------------------------------------------------------------------- // -------------------------------------------------------------------
if (sncpServer == null) { if (sncpServer == null) {
return; //调试时server才可能为null return; // 调试时server才可能为null
} }
final StringBuilder sb = logger.isLoggable(Level.FINE) ? new StringBuilder() : null; final StringBuilder sb = logger.isLoggable(Level.FINE) ? new StringBuilder() : null;
List<SncpServlet> servlets = sncpServer.getSncpServlets(); List<SncpServlet> servlets = sncpServer.getSncpServlets();
@@ -61,11 +64,14 @@ public class NodeSncpServer extends NodeServer {
int maxNameLength = 0; int maxNameLength = 0;
for (SncpServlet en : servlets) { for (SncpServlet en : servlets) {
maxNameLength = Math.max(maxNameLength, en.getResourceName().length() + 1); maxNameLength = Math.max(maxNameLength, en.getResourceName().length() + 1);
maxTypeLength = Math.max(maxTypeLength, en.getResourceType().getName().length()); maxTypeLength =
Math.max(maxTypeLength, en.getResourceType().getName().length());
} }
for (SncpServlet en : servlets) { for (SncpServlet en : servlets) {
if (sb != null) { if (sb != null) {
sb.append("Load ").append(toSimpleString(en, maxTypeLength, maxNameLength)).append(LINE_SEPARATOR); sb.append("Load ")
.append(toSimpleString(en, maxTypeLength, maxNameLength))
.append(LINE_SEPARATOR);
} }
} }
if (sb != null && sb.length() > 0) { if (sb != null && sb.length() > 0) {
@@ -83,7 +89,11 @@ public class NodeSncpServer extends NodeServer {
for (int i = 0; i < len; i++) { for (int i = 0; i < len; i++) {
sb.append(' '); sb.append(' ');
} }
sb.append(", serviceid=").append(servlet.getServiceid()).append(", name='").append(serviceName).append("'"); sb.append(", serviceid=")
.append(servlet.getServiceid())
.append(", name='")
.append(serviceName)
.append("'");
for (int i = 0; i < maxNameLength - serviceName.length(); i++) { for (int i = 0; i < maxNameLength - serviceName.length(); i++) {
sb.append(' '); sb.append(' ');
} }
@@ -108,7 +118,8 @@ public class NodeSncpServer extends NodeServer {
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
protected void loadSncpFilter(final AnyValue servletsConf, final ClassFilter<? extends Filter> classFilter) throws Exception { protected void loadSncpFilter(final AnyValue servletsConf, final ClassFilter<? extends Filter> classFilter)
throws Exception {
final StringBuilder sb = logger.isLoggable(Level.INFO) ? new StringBuilder() : null; final StringBuilder sb = logger.isLoggable(Level.INFO) ? new StringBuilder() : null;
List<FilterEntry<? extends Filter>> list = new ArrayList(classFilter.getFilterEntrys()); List<FilterEntry<? extends Filter>> list = new ArrayList(classFilter.getFilterEntrys());
for (FilterEntry<? extends Filter> entry : list) { for (FilterEntry<? extends Filter> entry : list) {
@@ -116,7 +127,7 @@ public class NodeSncpServer extends NodeServer {
if (Utility.isAbstractOrInterface(clazz)) { if (Utility.isAbstractOrInterface(clazz)) {
continue; continue;
} }
if (entry.isExpect()) { //跳过不自动加载的Filter if (entry.isExpect()) { // 跳过不自动加载的Filter
continue; continue;
} }
RedkaleClassLoader.putReflectionDeclaredConstructors(clazz, clazz.getName()); RedkaleClassLoader.putReflectionDeclaredConstructors(clazz, clazz.getName());
@@ -138,28 +149,35 @@ public class NodeSncpServer extends NodeServer {
RedkaleClassLoader.putReflectionPublicClasses(SncpServlet.class.getName()); RedkaleClassLoader.putReflectionPublicClasses(SncpServlet.class.getName());
if (!application.isSingletonMode()) { if (!application.isSingletonMode()) {
this.servletServices.stream() this.servletServices.stream()
.filter(x -> x.getClass().getAnnotation(Local.class) == null) //Local模式的Service不生成SncpServlet .filter(x -> x.getClass().getAnnotation(Local.class) == null) // Local模式的Service不生成SncpServlet
.forEach(x -> { .forEach(x -> {
SncpServlet servlet = sncpServer.addSncpServlet(x); SncpServlet servlet = sncpServer.addSncpServlet(x);
dynServletMap.put(x, servlet); dynServletMap.put(x, servlet);
String mq = Sncp.getResourceMQ(x); String mq = Sncp.getResourceMQ(x);
if (mq != null) { if (mq != null) {
MessageAgent agent = application.getResourceFactory().find(mq, MessageAgent.class); MessageAgent agent =
agent.putService(this, x, servlet); application.getResourceFactory().find(mq, MessageAgent.class);
} agent.putService(this, x, servlet);
}); }
});
} }
} }
@Override @Override
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
protected ClassFilter<Filter> createFilterClassFilter() { protected ClassFilter<Filter> createFilterClassFilter() {
return createClassFilter(null, null, SncpFilter.class, new Class[]{org.redkale.watch.WatchFilter.class}, null, "filters", "filter"); return createClassFilter(
null,
null,
SncpFilter.class,
new Class[] {org.redkale.watch.WatchFilter.class},
null,
"filters",
"filter");
} }
@Override @Override
protected ClassFilter<Servlet> createServletClassFilter() { protected ClassFilter<Servlet> createServletClassFilter() {
return null; return null;
} }
} }

View File

@@ -13,10 +13,7 @@ import org.redkale.service.Service;
import org.redkale.util.AnyValue; import org.redkale.util.AnyValue;
import org.redkale.watch.*; import org.redkale.watch.*;
/** /** @author zhangjx */
*
* @author zhangjx
*/
@NodeProtocol("WATCH") @NodeProtocol("WATCH")
public class NodeWatchServer extends NodeHttpServer { public class NodeWatchServer extends NodeHttpServer {
@@ -27,7 +24,8 @@ public class NodeWatchServer extends NodeHttpServer {
@Override @Override
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
protected ClassFilter<Service> createServiceClassFilter() { protected ClassFilter<Service> createServiceClassFilter() {
return createClassFilter(this.sncpGroup, null, WatchService.class, null, Annotation.class, "services", "service"); return createClassFilter(
this.sncpGroup, null, WatchService.class, null, Annotation.class, "services", "service");
} }
@Override @Override
@@ -44,7 +42,7 @@ public class NodeWatchServer extends NodeHttpServer {
@Override @Override
protected List<ClassFilter> createOtherClassFilters() { protected List<ClassFilter> createOtherClassFilters() {
return null; //不调用 super.createOtherClassFilters() return null; // 不调用 super.createOtherClassFilters()
} }
@Override @Override

View File

@@ -23,23 +23,28 @@ import org.redkale.util.Utility;
*/ */
public class PrepareCompiler { public class PrepareCompiler {
// public static void main(String[] args) throws Exception { // public static void main(String[] args) throws Exception {
// new PrepareCompiler().run(); // new PrepareCompiler().run();
// } // }
public Application run() throws Exception { public Application run() throws Exception {
//必须设置redkale.resource.skip.check=true // 必须设置redkale.resource.skip.check=true
//因redkale-maven-plugin的maven-core依赖jsr250会覆盖redkale的javax.annotation.Resource导致无法识别Resource.required方法 // 因redkale-maven-plugin的maven-core依赖jsr250会覆盖redkale的javax.annotation.Resource导致无法识别Resource.required方法
System.setProperty("redkale.resource.skip.check", "true"); System.setProperty("redkale.resource.skip.check", "true");
final Application application = new Application(AppConfig.create(false, true)); final Application application = new Application(AppConfig.create(false, true));
application.init(); application.init();
application.onPreCompile(); application.onPreCompile();
application.start(); application.start();
final boolean hasSncp = application.getNodeServers().stream().filter(NodeSncpServer.class::isInstance).findFirst().isPresent(); final boolean hasSncp = application.getNodeServers().stream()
.filter(NodeSncpServer.class::isInstance)
.findFirst()
.isPresent();
final ClassFilter<?> entityFilter = new ClassFilter(application.getClassLoader(), Entity.class, Object.class); final ClassFilter<?> entityFilter = new ClassFilter(application.getClassLoader(), Entity.class, Object.class);
final ClassFilter<?> entityFilter2 = new ClassFilter(application.getClassLoader(), javax.persistence.Entity.class, Object.class); final ClassFilter<?> entityFilter2 =
new ClassFilter(application.getClassLoader(), javax.persistence.Entity.class, Object.class);
final ClassFilter<?> beanFilter = new ClassFilter(application.getClassLoader(), Bean.class, Object.class); final ClassFilter<?> beanFilter = new ClassFilter(application.getClassLoader(), Bean.class, Object.class);
final ClassFilter<?> beanFilter2 = new ClassFilter(application.getClassLoader(), org.redkale.util.Bean.class, Object.class); final ClassFilter<?> beanFilter2 =
new ClassFilter(application.getClassLoader(), org.redkale.util.Bean.class, Object.class);
final ClassFilter<?> filterFilter = new ClassFilter(application.getClassLoader(), null, FilterBean.class); final ClassFilter<?> filterFilter = new ClassFilter(application.getClassLoader(), null, FilterBean.class);
application.loadClassByFilters(entityFilter, beanFilter, filterFilter); application.loadClassByFilters(entityFilter, beanFilter, filterFilter);
@@ -52,7 +57,7 @@ public class PrepareCompiler {
try { try {
List<DataSource> dataSources = application.getResourceFactory().query(DataSource.class); List<DataSource> dataSources = application.getResourceFactory().query(DataSource.class);
dataSources.forEach(source -> source.compile(clz)); dataSources.forEach(source -> source.compile(clz));
//application.dataSources.forEach(source -> source.compile(clz)); // application.dataSources.forEach(source -> source.compile(clz));
JsonFactory.root().loadEncoder(clz); JsonFactory.root().loadEncoder(clz);
if (hasSncp) { if (hasSncp) {
BsonFactory.root().loadEncoder(clz); BsonFactory.root().loadEncoder(clz);
@@ -62,7 +67,7 @@ public class PrepareCompiler {
BsonFactory.root().loadDecoder(clz); BsonFactory.root().loadDecoder(clz);
} }
decoder.convertFrom(new JsonReader("{}")); decoder.convertFrom(new JsonReader("{}"));
} catch (Exception e) { //JsonFactory.loadDecoder可能会失败因为class可能包含抽象类字段,如ColumnValue.value字段 } catch (Exception e) { // JsonFactory.loadDecoder可能会失败因为class可能包含抽象类字段,如ColumnValue.value字段
} }
} }
for (FilterEntry en : entityFilter2.getFilterEntrys()) { for (FilterEntry en : entityFilter2.getFilterEntrys()) {
@@ -73,7 +78,7 @@ public class PrepareCompiler {
try { try {
List<DataSource> dataSources = application.getResourceFactory().query(DataSource.class); List<DataSource> dataSources = application.getResourceFactory().query(DataSource.class);
dataSources.forEach(source -> source.compile(clz)); dataSources.forEach(source -> source.compile(clz));
//application.dataSources.forEach(source -> source.compile(clz)); // application.dataSources.forEach(source -> source.compile(clz));
JsonFactory.root().loadEncoder(clz); JsonFactory.root().loadEncoder(clz);
if (hasSncp) { if (hasSncp) {
BsonFactory.root().loadEncoder(clz); BsonFactory.root().loadEncoder(clz);
@@ -83,7 +88,7 @@ public class PrepareCompiler {
BsonFactory.root().loadDecoder(clz); BsonFactory.root().loadDecoder(clz);
} }
decoder.convertFrom(new JsonReader("{}")); decoder.convertFrom(new JsonReader("{}"));
} catch (Exception e) { //JsonFactory.loadDecoder可能会失败因为class可能包含抽象类字段,如ColumnValue.value字段 } catch (Exception e) { // JsonFactory.loadDecoder可能会失败因为class可能包含抽象类字段,如ColumnValue.value字段
} }
} }
for (FilterEntry en : beanFilter.getFilterEntrys()) { for (FilterEntry en : beanFilter.getFilterEntrys()) {
@@ -101,7 +106,7 @@ public class PrepareCompiler {
BsonFactory.root().loadDecoder(clz); BsonFactory.root().loadDecoder(clz);
} }
decoder.convertFrom(new JsonReader("{}")); decoder.convertFrom(new JsonReader("{}"));
} catch (Exception e) { //JsonFactory.loadDecoder可能会失败因为class可能包含抽象类字段,如ColumnValue.value字段 } catch (Exception e) { // JsonFactory.loadDecoder可能会失败因为class可能包含抽象类字段,如ColumnValue.value字段
} }
} }
for (FilterEntry en : beanFilter2.getFilterEntrys()) { for (FilterEntry en : beanFilter2.getFilterEntrys()) {
@@ -119,7 +124,7 @@ public class PrepareCompiler {
BsonFactory.root().loadDecoder(clz); BsonFactory.root().loadDecoder(clz);
} }
decoder.convertFrom(new JsonReader("{}")); decoder.convertFrom(new JsonReader("{}"));
} catch (Exception e) { //JsonFactory.loadDecoder可能会失败因为class可能包含抽象类字段,如ColumnValue.value字段 } catch (Exception e) { // JsonFactory.loadDecoder可能会失败因为class可能包含抽象类字段,如ColumnValue.value字段
} }
} }
for (FilterEntry en : filterFilter.getFilterEntrys()) { for (FilterEntry en : filterFilter.getFilterEntrys()) {
@@ -130,7 +135,7 @@ public class PrepareCompiler {
try { try {
FilterNodeBean.load(clz); FilterNodeBean.load(clz);
} catch (Exception e) { } catch (Exception e) {
//do nothing // do nothing
} }
} }
application.onPostCompile(); application.onPostCompile();

View File

@@ -1,4 +1,2 @@
/** /** 提供Redkale服务器的启动、初始化和加载功能 */
* 提供Redkale服务器的启动、初始化和加载功能
*/
package org.redkale.boot; package org.redkale.boot;

View File

@@ -5,25 +5,18 @@
*/ */
package org.redkale.boot.watch; package org.redkale.boot.watch;
import org.redkale.service.AbstractService;
import org.redkale.annotation.Comment; import org.redkale.annotation.Comment;
import org.redkale.service.AbstractService;
import org.redkale.watch.WatchService; import org.redkale.watch.WatchService;
/** /** @author zhangjx */
*
* @author zhangjx
*/
public abstract class AbstractWatchService extends AbstractService implements WatchService { public abstract class AbstractWatchService extends AbstractService implements WatchService {
/** /** 缺少参数 */
* 缺少参数
*/
@Comment("缺少参数") @Comment("缺少参数")
public static final int RET_WATCH_PARAMS_ILLEGAL = 1600_0001; public static final int RET_WATCH_PARAMS_ILLEGAL = 1600_0001;
/** /** 执行异常 */
* 执行异常
*/
@Comment("执行异常") @Comment("执行异常")
public static final int RET_WATCH_RUN_EXCEPTION = 1600_0002; public static final int RET_WATCH_RUN_EXCEPTION = 1600_0002;
} }

View File

@@ -12,10 +12,7 @@ import org.redkale.boot.*;
import org.redkale.net.http.*; import org.redkale.net.http.*;
import org.redkale.service.RetResult; import org.redkale.service.RetResult;
/** /** @author zhangjx */
*
* @author zhangjx
*/
@RestService(name = "filter", catalog = "watch", repair = false) @RestService(name = "filter", catalog = "watch", repair = false)
public class FilterWatchService extends AbstractWatchService { public class FilterWatchService extends AbstractWatchService {
@@ -35,9 +32,11 @@ public class FilterWatchService extends AbstractWatchService {
protected Application application; protected Application application;
@RestMapping(name = "addFilter", auth = false, comment = "动态增加Filter") @RestMapping(name = "addFilter", auth = false, comment = "动态增加Filter")
public RetResult addFilter(@RestUploadFile(maxLength = 10 * 1024 * 1024, fileNameRegx = "\\.jar$") byte[] jar, public RetResult addFilter(
@RestParam(name = "server", comment = "Server节点名") final String serverName, @RestUploadFile(maxLength = 10 * 1024 * 1024, fileNameRegx = "\\.jar$") byte[] jar,
@RestParam(name = "type", comment = "Filter类") final String filterType) throws IOException { @RestParam(name = "server", comment = "Server节点") final String serverName,
@RestParam(name = "type", comment = "Filter类名") final String filterType)
throws IOException {
if (filterType == null) { if (filterType == null) {
return new RetResult(RET_FILTER_TYPE_NOT_EXISTS, "Not found Filter Type (" + filterType + ")"); return new RetResult(RET_FILTER_TYPE_NOT_EXISTS, "Not found Filter Type (" + filterType + ")");
} }

View File

@@ -15,10 +15,7 @@ import org.redkale.net.Server;
import org.redkale.net.http.*; import org.redkale.net.http.*;
import org.redkale.service.RetResult; import org.redkale.service.RetResult;
/** /** @author zhangjx */
*
* @author zhangjx
*/
@RestService(name = "server", catalog = "watch", repair = false) @RestService(name = "server", catalog = "watch", repair = false)
public class ServerWatchService extends AbstractWatchService { public class ServerWatchService extends AbstractWatchService {
@@ -34,7 +31,9 @@ public class ServerWatchService extends AbstractWatchService {
@RestMapping(name = "info", comment = "单个Server信息查询") @RestMapping(name = "info", comment = "单个Server信息查询")
public RetResult info(@RestParam(name = "#port:") final int port) { public RetResult info(@RestParam(name = "#port:") final int port) {
Stream<NodeServer> stream = application.getNodeServers().stream(); Stream<NodeServer> stream = application.getNodeServers().stream();
NodeServer node = stream.filter(ns -> ns.getServer().getSocketAddress().getPort() == port).findFirst().orElse(null); NodeServer node = stream.filter(ns -> ns.getServer().getSocketAddress().getPort() == port)
.findFirst()
.orElse(null);
if (node == null) { if (node == null) {
return new RetResult(RET_SERVER_NOT_EXISTS, "Server(port=" + port + ") not found"); return new RetResult(RET_SERVER_NOT_EXISTS, "Server(port=" + port + ") not found");
} }
@@ -52,8 +51,10 @@ public class ServerWatchService extends AbstractWatchService {
} }
@RestMapping(name = "changeAddress", comment = "更改Server的监听地址和端口") @RestMapping(name = "changeAddress", comment = "更改Server的监听地址和端口")
public RetResult changeAddress(@RestParam(name = "#port:") final int oldport, public RetResult changeAddress(
@RestParam(name = "#newhost:") final String newhost, @RestParam(name = "#newport:") final int newport) { @RestParam(name = "#port:") final int oldport,
@RestParam(name = "#newhost:") final String newhost,
@RestParam(name = "#newport:") final int newport) {
if (oldport < 1) { if (oldport < 1) {
return new RetResult(RET_WATCH_PARAMS_ILLEGAL, "not found param `oldport`"); return new RetResult(RET_WATCH_PARAMS_ILLEGAL, "not found param `oldport`");
} }
@@ -61,12 +62,15 @@ public class ServerWatchService extends AbstractWatchService {
return new RetResult(RET_WATCH_PARAMS_ILLEGAL, "not found param `newport`"); return new RetResult(RET_WATCH_PARAMS_ILLEGAL, "not found param `newport`");
} }
Stream<NodeServer> stream = application.getNodeServers().stream(); Stream<NodeServer> stream = application.getNodeServers().stream();
NodeServer node = stream.filter(ns -> ns.getServer().getSocketAddress().getPort() == oldport).findFirst().orElse(null); NodeServer node = stream.filter(ns -> ns.getServer().getSocketAddress().getPort() == oldport)
.findFirst()
.orElse(null);
if (node == null) { if (node == null) {
return new RetResult(RET_SERVER_NOT_EXISTS, "Server(port=" + oldport + ") not found"); return new RetResult(RET_SERVER_NOT_EXISTS, "Server(port=" + oldport + ") not found");
} }
final Server server = node.getServer(); final Server server = node.getServer();
InetSocketAddress newAddr = new InetSocketAddress(newhost == null || newhost.isEmpty() ? server.getSocketAddress().getHostString() : newhost, newport); InetSocketAddress newAddr = new InetSocketAddress(
newhost == null || newhost.isEmpty() ? server.getSocketAddress().getHostString() : newhost, newport);
try { try {
server.changeAddress(application, newAddr); server.changeAddress(application, newAddr);
} catch (IOException e) { } catch (IOException e) {
@@ -96,7 +100,9 @@ public class ServerWatchService extends AbstractWatchService {
rs.put("backlog", server.getBacklog()); rs.put("backlog", server.getBacklog());
rs.put("bufferCapacity", server.getBufferCapacity()); rs.put("bufferCapacity", server.getBufferCapacity());
rs.put("bufferPoolSize", server.getBufferPoolSize()); rs.put("bufferPoolSize", server.getBufferPoolSize());
rs.put("charset", server.getCharset() == null ? "UTF-8" : server.getCharset().name()); rs.put(
"charset",
server.getCharset() == null ? "UTF-8" : server.getCharset().name());
rs.put("maxbody", server.getMaxBody()); rs.put("maxbody", server.getMaxBody());
rs.put("maxconns", server.getMaxConns()); rs.put("maxconns", server.getMaxConns());
rs.put("serverStartTime", server.getServerStartTime()); rs.put("serverStartTime", server.getServerStartTime());

View File

@@ -15,7 +15,6 @@ import org.redkale.net.http.*;
import org.redkale.service.RetResult; import org.redkale.service.RetResult;
/** /**
* <p>
* 详情见: https://redkale.org * 详情见: https://redkale.org
* *
* @author zhangjx * @author zhangjx
@@ -31,10 +30,11 @@ public class ServiceWatchService extends AbstractWatchService {
@RestConvert(type = void.class) @RestConvert(type = void.class)
@RestMapping(name = "setField", auth = false, comment = "设置Service中指定字段的内容") @RestMapping(name = "setField", auth = false, comment = "设置Service中指定字段的内容")
public RetResult setField(@RestParam(name = "name", comment = "Service的资源名") String name, public RetResult setField(
@RestParam(name = "type", comment = "Service的") String type, @RestParam(name = "name", comment = "Service的资源") String name,
@RestParam(name = "field", comment = "字段") String field, @RestParam(name = "type", comment = "Service的类") String type,
@RestParam(name = "value", comment = "字段") String value) { @RestParam(name = "field", comment = "字段") String field,
@RestParam(name = "value", comment = "字段值") String value) {
if (name == null) { if (name == null) {
name = ""; name = "";
} }
@@ -80,9 +80,10 @@ public class ServiceWatchService extends AbstractWatchService {
@RestConvert(type = void.class) @RestConvert(type = void.class)
@RestMapping(name = "getField", auth = false, comment = "查询Service中指定字段的内容") @RestMapping(name = "getField", auth = false, comment = "查询Service中指定字段的内容")
public RetResult getField(@RestParam(name = "name", comment = "Service的资源名") String name, public RetResult getField(
@RestParam(name = "type", comment = "Service的") String type, @RestParam(name = "name", comment = "Service的资源") String name,
@RestParam(name = "field", comment = "字段") String field) { @RestParam(name = "type", comment = "Service的类") String type,
@RestParam(name = "field", comment = "字段名") String field) {
if (name == null) { if (name == null) {
name = ""; name = "";
} }
@@ -127,11 +128,12 @@ public class ServiceWatchService extends AbstractWatchService {
@RestConvert(type = void.class) @RestConvert(type = void.class)
@RestMapping(name = "runMethod", auth = false, comment = "调用Service中指定方法") @RestMapping(name = "runMethod", auth = false, comment = "调用Service中指定方法")
public RetResult runMethod(@RestParam(name = "name", comment = "Service的资源名") String name, public RetResult runMethod(
@RestParam(name = "type", comment = "Service的") String type, @RestParam(name = "name", comment = "Service的资源") String name,
@RestParam(name = "method", comment = "Service的方法") String method, @RestParam(name = "type", comment = "Service的") String type,
@RestParam(name = "params", comment = "方法的参数值") List<String> params, @RestParam(name = "method", comment = "Service的方法名") String method,
@RestParam(name = "paramtypes", comment = "方法的参数数据类型") List<String> paramtypes) { @RestParam(name = "params", comment = "方法的参数") List<String> params,
@RestParam(name = "paramtypes", comment = "方法的参数数据类型") List<String> paramtypes) {
if (name == null) { if (name == null) {
name = ""; name = "";
} }
@@ -188,7 +190,10 @@ public class ServiceWatchService extends AbstractWatchService {
} }
} while ((clazz = clazz.getSuperclass()) != Object.class); } while ((clazz = clazz.getSuperclass()) != Object.class);
if (methodObj == null) { if (methodObj == null) {
return new RetResult(RET_WATCH_RUN_EXCEPTION, "run exception (" + (t == null ? ("not found method(" + method + ")") : String.valueOf(t)) + ")"); return new RetResult(
RET_WATCH_RUN_EXCEPTION,
"run exception (" + (t == null ? ("not found method(" + method + ")") : String.valueOf(t))
+ ")");
} }
methodObj.setAccessible(true); methodObj.setAccessible(true);
if (paramcount < 1) { if (paramcount < 1) {
@@ -209,43 +214,49 @@ public class ServiceWatchService extends AbstractWatchService {
Object dest = null; Object dest = null;
for (NodeServer ns : application.getNodeServers()) { for (NodeServer ns : application.getNodeServers()) {
ResourceFactory resFactory = ns.getResourceFactory(); ResourceFactory resFactory = ns.getResourceFactory();
List list = resFactory.query((n, s) -> name.equals(n) && s != null && s.getClass().getName().endsWith(type)); List list = resFactory.query((n, s) ->
name.equals(n) && s != null && s.getClass().getName().endsWith(type));
if (list == null || list.isEmpty()) { if (list == null || list.isEmpty()) {
continue; continue;
} }
dest = list.get(0); dest = list.get(0);
} }
if (dest == null) { if (dest == null) {
return new RetResult(RET_SERVICE_DEST_NOT_EXISTS, "not found servie (name=" + name + ", type=" + type + ")"); return new RetResult(
RET_SERVICE_DEST_NOT_EXISTS, "not found servie (name=" + name + ", type=" + type + ")");
} }
return dest; return dest;
} }
@RestMapping(name = "loadService", auth = false, comment = "动态增加Service") @RestMapping(name = "loadService", auth = false, comment = "动态增加Service")
public RetResult loadService(@RestParam(name = "type", comment = "Service的类名") String type, public RetResult loadService(
@RestUploadFile(maxLength = 10 * 1024 * 1024, fileNameRegx = "\\.jar$") byte[] jar) { @RestParam(name = "type", comment = "Service的类名") String type,
//待开发 @RestUploadFile(maxLength = 10 * 1024 * 1024, fileNameRegx = "\\.jar$") byte[] jar) {
// 待开发
return RetResult.success(); return RetResult.success();
} }
@RestMapping(name = "reloadService", auth = false, comment = "重新加载Service") @RestMapping(name = "reloadService", auth = false, comment = "重新加载Service")
public RetResult reloadService(@RestParam(name = "name", comment = "Service的资源名") String name, public RetResult reloadService(
@RestParam(name = "type", comment = "Service的") String type) { @RestParam(name = "name", comment = "Service的资源") String name,
//待开发 @RestParam(name = "type", comment = "Service的类名") String type) {
// 待开发
return RetResult.success(); return RetResult.success();
} }
@RestMapping(name = "stopService", auth = false, comment = "动态停止Service") @RestMapping(name = "stopService", auth = false, comment = "动态停止Service")
public RetResult stopService(@RestParam(name = "name", comment = "Service的资源名") String name, public RetResult stopService(
@RestParam(name = "type", comment = "Service的") String type) { @RestParam(name = "name", comment = "Service的资源") String name,
//待开发 @RestParam(name = "type", comment = "Service的类名") String type) {
// 待开发
return RetResult.success(); return RetResult.success();
} }
@RestMapping(name = "findService", auth = false, comment = "查找Service") @RestMapping(name = "findService", auth = false, comment = "查找Service")
public RetResult find(@RestParam(name = "name", comment = "Service的资源名") String name, public RetResult find(
@RestParam(name = "type", comment = "Service的") String type) { @RestParam(name = "name", comment = "Service的资源") String name,
//待开发 @RestParam(name = "type", comment = "Service的类名") String type) {
// 待开发
return RetResult.success(); return RetResult.success();
} }
} }

View File

@@ -1,4 +1,2 @@
/** /** 提供系统默认监控包 */
* 提供系统默认监控包
*/
package org.redkale.boot.watch; package org.redkale.boot.watch;

View File

@@ -11,29 +11,24 @@ import org.redkale.util.ThrowSupplier;
/** /**
* 缓存管理器 * 缓存管理器
* *
* <p> * <p>详情见: https://redkale.org
* 详情见: https://redkale.org
* *
* @author zhangjx * @author zhangjx
*
* @since 2.8.0 * @since 2.8.0
*/ */
public interface CacheManager { public interface CacheManager {
/** /** 默认的hash */
* 默认的hash
*/
public static final String DEFAULT_HASH = "cache-hash"; public static final String DEFAULT_HASH = "cache-hash";
//-------------------------------------- 本地缓存 -------------------------------------- // -------------------------------------- 本地缓存 --------------------------------------
/** /**
* 本地获取缓存数据, 过期返回null * 本地获取缓存数据, 过期返回null
* *
* @param <T> 泛型 * @param <T> 泛型
* @param hash 缓存hash * @param hash 缓存hash
* @param key 缓存键 * @param key 缓存键
* @param type 数据类型 * @param type 数据类型
*
* @return 数据值 * @return 数据值
*/ */
public <T> T localGet(final String hash, final String key, final Type type); public <T> T localGet(final String hash, final String key, final Type type);
@@ -41,10 +36,9 @@ public interface CacheManager {
/** /**
* 本地获取缓存数据, 过期返回null * 本地获取缓存数据, 过期返回null
* *
* @param <T> 泛型 * @param <T> 泛型
* @param key 缓存键 * @param key 缓存键
* @param type 数据类型 * @param type 数据类型
*
* @return 数据值 * @return 数据值
*/ */
default <T> T localGet(final String key, final Type type) { default <T> T localGet(final String key, final Type type) {
@@ -55,8 +49,7 @@ public interface CacheManager {
* 本地获取字符串缓存数据, 过期返回null * 本地获取字符串缓存数据, 过期返回null
* *
* @param hash 缓存hash * @param hash 缓存hash
* @param key 缓存键 * @param key 缓存键
*
* @return 数据值 * @return 数据值
*/ */
default String localGetString(final String hash, final String key) { default String localGetString(final String hash, final String key) {
@@ -67,7 +60,6 @@ public interface CacheManager {
* 本地获取字符串缓存数据, 过期返回null * 本地获取字符串缓存数据, 过期返回null
* *
* @param key 缓存键 * @param key 缓存键
*
* @return 数据值 * @return 数据值
*/ */
default String localGetString(final String key) { default String localGetString(final String key) {
@@ -77,73 +69,83 @@ public interface CacheManager {
/** /**
* 本地获取缓存数据, 过期返回null * 本地获取缓存数据, 过期返回null
* *
* @param <T> 泛型 * @param <T> 泛型
* @param hash 缓存hash * @param hash 缓存hash
* @param key 缓存键 * @param key 缓存键
* @param type 数据类型 * @param type 数据类型
* @param nullable 是否缓存null值 * @param nullable 是否缓存null值
* @param expire 过期时长Duration.ZERO为永不过期 * @param expire 过期时长Duration.ZERO为永不过期
* @param supplier 数据函数 * @param supplier 数据函数
*
* @return 数据值 * @return 数据值
*/ */
public <T> T localGetSet(final String hash, final String key, final Type type, boolean nullable, Duration expire, ThrowSupplier<T> supplier); public <T> T localGetSet(
final String hash,
final String key,
final Type type,
boolean nullable,
Duration expire,
ThrowSupplier<T> supplier);
/** /**
* 本地获取缓存数据, 过期返回null * 本地获取缓存数据, 过期返回null
* *
* @param <T> 泛型 * @param <T> 泛型
* @param key 缓存键 * @param key 缓存键
* @param type 数据类型 * @param type 数据类型
* @param nullable 是否缓存null值 * @param nullable 是否缓存null值
* @param expire 过期时长Duration.ZERO为永不过期 * @param expire 过期时长Duration.ZERO为永不过期
* @param supplier 数据函数 * @param supplier 数据函数
*
* @return 数据值 * @return 数据值
*/ */
default <T> T localGetSet(final String key, final Type type, boolean nullable, Duration expire, ThrowSupplier<T> supplier) { default <T> T localGetSet(
final String key, final Type type, boolean nullable, Duration expire, ThrowSupplier<T> supplier) {
return localGetSet(DEFAULT_HASH, key, type, nullable, expire, supplier); return localGetSet(DEFAULT_HASH, key, type, nullable, expire, supplier);
} }
/** /**
* 本地异步获取缓存数据, 过期返回null * 本地异步获取缓存数据, 过期返回null
* *
* @param <T> 泛型 * @param <T> 泛型
* @param hash 缓存hash * @param hash 缓存hash
* @param key 缓存键 * @param key 缓存键
* @param type 数据类型 * @param type 数据类型
* @param nullable 是否缓存null值 * @param nullable 是否缓存null值
* @param expire 过期时长Duration.ZERO为永不过期 * @param expire 过期时长Duration.ZERO为永不过期
* @param supplier 数据函数 * @param supplier 数据函数
*
* @return 数据值 * @return 数据值
*/ */
public <T> CompletableFuture<T> localGetSetAsync(String hash, String key, Type type, boolean nullable, Duration expire, ThrowSupplier<CompletableFuture<T>> supplier); public <T> CompletableFuture<T> localGetSetAsync(
String hash,
String key,
Type type,
boolean nullable,
Duration expire,
ThrowSupplier<CompletableFuture<T>> supplier);
/** /**
* 本地异步获取缓存数据, 过期返回null * 本地异步获取缓存数据, 过期返回null
* *
* @param <T> 泛型 * @param <T> 泛型
* @param key 缓存键 * @param key 缓存键
* @param type 数据类型 * @param type 数据类型
* @param nullable 是否缓存null值 * @param nullable 是否缓存null值
* @param expire 过期时长Duration.ZERO为永不过期 * @param expire 过期时长Duration.ZERO为永不过期
* @param supplier 数据函数 * @param supplier 数据函数
*
* @return 数据值 * @return 数据值
*/ */
default <T> CompletableFuture<T> localGetSetAsync(String key, Type type, boolean nullable, Duration expire, ThrowSupplier<CompletableFuture<T>> supplier) { default <T> CompletableFuture<T> localGetSetAsync(
String key, Type type, boolean nullable, Duration expire, ThrowSupplier<CompletableFuture<T>> supplier) {
return localGetSetAsync(DEFAULT_HASH, key, type, nullable, expire, supplier); return localGetSetAsync(DEFAULT_HASH, key, type, nullable, expire, supplier);
} }
/** /**
* 本地缓存数据 * 本地缓存数据
* *
* @param <T> 泛型 * @param <T> 泛型
* @param hash 缓存hash * @param hash 缓存hash
* @param key 缓存键 * @param key 缓存键
* @param type 数据类型 * @param type 数据类型
* @param value 数据值 * @param value 数据值
* @param expire 过期时长Duration.ZERO为永不过期 * @param expire 过期时长Duration.ZERO为永不过期
*/ */
public <T> void localSet(String hash, String key, Type type, T value, Duration expire); public <T> void localSet(String hash, String key, Type type, T value, Duration expire);
@@ -151,10 +153,10 @@ public interface CacheManager {
/** /**
* 本地缓存数据 * 本地缓存数据
* *
* @param <T> 泛型 * @param <T> 泛型
* @param key 缓存键 * @param key 缓存键
* @param type 数据类型 * @param type 数据类型
* @param value 数据值 * @param value 数据值
* @param expire 过期时长Duration.ZERO为永不过期 * @param expire 过期时长Duration.ZERO为永不过期
*/ */
default <T> void localSet(String key, Type type, T value, Duration expire) { default <T> void localSet(String key, Type type, T value, Duration expire) {
@@ -164,9 +166,9 @@ public interface CacheManager {
/** /**
* 本地缓存字符串数据 * 本地缓存字符串数据
* *
* @param hash 缓存hash * @param hash 缓存hash
* @param key 缓存键 * @param key 缓存键
* @param value 数据值 * @param value 数据值
* @param expire 过期时长Duration.ZERO为永不过期 * @param expire 过期时长Duration.ZERO为永不过期
*/ */
default void localSetString(final String hash, final String key, final String value, Duration expire) { default void localSetString(final String hash, final String key, final String value, Duration expire) {
@@ -176,8 +178,8 @@ public interface CacheManager {
/** /**
* 本地缓存字符串数据 * 本地缓存字符串数据
* *
* @param key 缓存键 * @param key 缓存键
* @param value 数据值 * @param value 数据值
* @param expire 过期时长Duration.ZERO为永不过期 * @param expire 过期时长Duration.ZERO为永不过期
*/ */
default void localSetString(final String key, final String value, Duration expire) { default void localSetString(final String key, final String value, Duration expire) {
@@ -188,8 +190,7 @@ public interface CacheManager {
* 本地删除缓存数据 * 本地删除缓存数据
* *
* @param hash 缓存hash * @param hash 缓存hash
* @param key 缓存键 * @param key 缓存键
*
* @return 删除数量 * @return 删除数量
*/ */
public long localDel(String hash, String key); public long localDel(String hash, String key);
@@ -198,22 +199,20 @@ public interface CacheManager {
* 本地删除缓存数据 * 本地删除缓存数据
* *
* @param key 缓存键 * @param key 缓存键
*
* @return 删除数量 * @return 删除数量
*/ */
default long localDel(String key) { default long localDel(String key) {
return localDel(DEFAULT_HASH, key); return localDel(DEFAULT_HASH, key);
} }
//-------------------------------------- 远程缓存 -------------------------------------- // -------------------------------------- 远程缓存 --------------------------------------
/** /**
* 远程获取缓存数据, 过期返回null * 远程获取缓存数据, 过期返回null
* *
* @param <T> 泛型 * @param <T> 泛型
* @param hash 缓存hash * @param hash 缓存hash
* @param key 缓存键 * @param key 缓存键
* @param type 数据类型 * @param type 数据类型
*
* @return 数据值 * @return 数据值
*/ */
public <T> T remoteGet(final String hash, final String key, final Type type); public <T> T remoteGet(final String hash, final String key, final Type type);
@@ -221,10 +220,9 @@ public interface CacheManager {
/** /**
* 远程获取缓存数据, 过期返回null * 远程获取缓存数据, 过期返回null
* *
* @param <T> 泛型 * @param <T> 泛型
* @param key 缓存键 * @param key 缓存键
* @param type 数据类型 * @param type 数据类型
*
* @return 数据值 * @return 数据值
*/ */
default <T> T remoteGet(final String key, final Type type) { default <T> T remoteGet(final String key, final Type type) {
@@ -235,8 +233,7 @@ public interface CacheManager {
* 远程获取字符串缓存数据, 过期返回null * 远程获取字符串缓存数据, 过期返回null
* *
* @param hash 缓存hash * @param hash 缓存hash
* @param key 缓存键 * @param key 缓存键
*
* @return 数据值 * @return 数据值
*/ */
default String remoteGetString(final String hash, final String key) { default String remoteGetString(final String hash, final String key) {
@@ -247,7 +244,6 @@ public interface CacheManager {
* 远程获取字符串缓存数据, 过期返回null * 远程获取字符串缓存数据, 过期返回null
* *
* @param key 缓存键 * @param key 缓存键
*
* @return 数据值 * @return 数据值
*/ */
default String remoteGetString(final String key) { default String remoteGetString(final String key) {
@@ -257,11 +253,10 @@ public interface CacheManager {
/** /**
* 远程异步获取缓存数据, 过期返回null * 远程异步获取缓存数据, 过期返回null
* *
* @param <T> 泛型 * @param <T> 泛型
* @param hash 缓存hash * @param hash 缓存hash
* @param key 缓存键 * @param key 缓存键
* @param type 数据类型 * @param type 数据类型
*
* @return 数据值 * @return 数据值
*/ */
public <T> CompletableFuture<T> remoteGetAsync(final String hash, final String key, final Type type); public <T> CompletableFuture<T> remoteGetAsync(final String hash, final String key, final Type type);
@@ -269,10 +264,9 @@ public interface CacheManager {
/** /**
* 远程异步获取缓存数据, 过期返回null * 远程异步获取缓存数据, 过期返回null
* *
* @param <T> 泛型 * @param <T> 泛型
* @param key 缓存键 * @param key 缓存键
* @param type 数据类型 * @param type 数据类型
*
* @return 数据值 * @return 数据值
*/ */
default <T> CompletableFuture<T> remoteGetAsync(final String key, final Type type) { default <T> CompletableFuture<T> remoteGetAsync(final String key, final Type type) {
@@ -283,8 +277,7 @@ public interface CacheManager {
* 远程异步获取字符串缓存数据, 过期返回null * 远程异步获取字符串缓存数据, 过期返回null
* *
* @param hash 缓存hash * @param hash 缓存hash
* @param key 缓存键 * @param key 缓存键
*
* @return 数据值 * @return 数据值
*/ */
default CompletableFuture<String> remoteGetStringAsync(final String hash, final String key) { default CompletableFuture<String> remoteGetStringAsync(final String hash, final String key) {
@@ -295,7 +288,6 @@ public interface CacheManager {
* 远程异步获取字符串缓存数据, 过期返回null * 远程异步获取字符串缓存数据, 过期返回null
* *
* @param key 缓存键 * @param key 缓存键
*
* @return 数据值 * @return 数据值
*/ */
default CompletableFuture<String> remoteGetStringAsync(final String key) { default CompletableFuture<String> remoteGetStringAsync(final String key) {
@@ -305,77 +297,83 @@ public interface CacheManager {
/** /**
* 远程获取缓存数据, 过期返回null * 远程获取缓存数据, 过期返回null
* *
* @param <T> 泛型 * @param <T> 泛型
* @param hash 缓存hash * @param hash 缓存hash
* @param key 缓存键 * @param key 缓存键
* @param type 数据类型 * @param type 数据类型
* @param nullable 是否缓存null值 * @param nullable 是否缓存null值
* @param expire 过期时长Duration.ZERO为永不过期 * @param expire 过期时长Duration.ZERO为永不过期
* @param supplier 数据函数 * @param supplier 数据函数
*
* @return 数据值 * @return 数据值
*/ */
public <T> T remoteGetSet(final String hash, final String key, final Type type, boolean nullable, public <T> T remoteGetSet(
Duration expire, ThrowSupplier<T> supplier); final String hash,
final String key,
final Type type,
boolean nullable,
Duration expire,
ThrowSupplier<T> supplier);
/** /**
* 远程获取缓存数据, 过期返回null * 远程获取缓存数据, 过期返回null
* *
* @param <T> 泛型 * @param <T> 泛型
* @param key 缓存键 * @param key 缓存键
* @param type 数据类型 * @param type 数据类型
* @param nullable 是否缓存null值 * @param nullable 是否缓存null值
* @param expire 过期时长Duration.ZERO为永不过期 * @param expire 过期时长Duration.ZERO为永不过期
* @param supplier 数据函数 * @param supplier 数据函数
*
* @return 数据值 * @return 数据值
*/ */
default <T> T remoteGetSet(final String key, final Type type, boolean nullable, default <T> T remoteGetSet(
Duration expire, ThrowSupplier<T> supplier) { final String key, final Type type, boolean nullable, Duration expire, ThrowSupplier<T> supplier) {
return remoteGetSet(DEFAULT_HASH, key, type, nullable, expire, supplier); return remoteGetSet(DEFAULT_HASH, key, type, nullable, expire, supplier);
} }
/** /**
* 远程异步获取缓存数据, 过期返回null * 远程异步获取缓存数据, 过期返回null
* *
* @param <T> 泛型 * @param <T> 泛型
* @param hash 缓存hash * @param hash 缓存hash
* @param key 缓存键 * @param key 缓存键
* @param type 数据类型 * @param type 数据类型
* @param nullable 是否缓存null值 * @param nullable 是否缓存null值
* @param expire 过期时长Duration.ZERO为永不过期 * @param expire 过期时长Duration.ZERO为永不过期
* @param supplier 数据函数 * @param supplier 数据函数
*
* @return 数据值 * @return 数据值
*/ */
public <T> CompletableFuture<T> remoteGetSetAsync(String hash, String key, Type type, boolean nullable, public <T> CompletableFuture<T> remoteGetSetAsync(
Duration expire, ThrowSupplier<CompletableFuture<T>> supplier); String hash,
String key,
Type type,
boolean nullable,
Duration expire,
ThrowSupplier<CompletableFuture<T>> supplier);
/** /**
* 远程异步获取缓存数据, 过期返回null * 远程异步获取缓存数据, 过期返回null
* *
* @param <T> 泛型 * @param <T> 泛型
* @param key 缓存键 * @param key 缓存键
* @param type 数据类型 * @param type 数据类型
* @param nullable 是否缓存null值 * @param nullable 是否缓存null值
* @param expire 过期时长Duration.ZERO为永不过期 * @param expire 过期时长Duration.ZERO为永不过期
* @param supplier 数据函数 * @param supplier 数据函数
*
* @return 数据值 * @return 数据值
*/ */
default <T> CompletableFuture<T> remoteGetSetAsync(String key, Type type, boolean nullable, default <T> CompletableFuture<T> remoteGetSetAsync(
Duration expire, ThrowSupplier<CompletableFuture<T>> supplier) { String key, Type type, boolean nullable, Duration expire, ThrowSupplier<CompletableFuture<T>> supplier) {
return remoteGetSetAsync(DEFAULT_HASH, key, type, nullable, expire, supplier); return remoteGetSetAsync(DEFAULT_HASH, key, type, nullable, expire, supplier);
} }
/** /**
* 远程缓存数据 * 远程缓存数据
* *
* @param <T> 泛型 * @param <T> 泛型
* @param hash 缓存hash * @param hash 缓存hash
* @param key 缓存键 * @param key 缓存键
* @param type 数据类型 * @param type 数据类型
* @param value 数据值 * @param value 数据值
* @param expire 过期时长Duration.ZERO为永不过期 * @param expire 过期时长Duration.ZERO为永不过期
*/ */
public <T> void remoteSet(final String hash, final String key, final Type type, final T value, Duration expire); public <T> void remoteSet(final String hash, final String key, final Type type, final T value, Duration expire);
@@ -383,10 +381,10 @@ public interface CacheManager {
/** /**
* 远程缓存数据 * 远程缓存数据
* *
* @param <T> 泛型 * @param <T> 泛型
* @param key 缓存键 * @param key 缓存键
* @param type 数据类型 * @param type 数据类型
* @param value 数据值 * @param value 数据值
* @param expire 过期时长Duration.ZERO为永不过期 * @param expire 过期时长Duration.ZERO为永不过期
*/ */
default <T> void remoteSet(final String key, final Type type, final T value, Duration expire) { default <T> void remoteSet(final String key, final Type type, final T value, Duration expire) {
@@ -396,9 +394,9 @@ public interface CacheManager {
/** /**
* 远程缓存字符串数据 * 远程缓存字符串数据
* *
* @param hash 缓存hash * @param hash 缓存hash
* @param key 缓存键 * @param key 缓存键
* @param value 数据值 * @param value 数据值
* @param expire 过期时长Duration.ZERO为永不过期 * @param expire 过期时长Duration.ZERO为永不过期
*/ */
default void remoteSetString(final String hash, final String key, final String value, Duration expire) { default void remoteSetString(final String hash, final String key, final String value, Duration expire) {
@@ -408,8 +406,8 @@ public interface CacheManager {
/** /**
* 远程缓存字符串数据 * 远程缓存字符串数据
* *
* @param key 缓存键 * @param key 缓存键
* @param value 数据值 * @param value 数据值
* @param expire 过期时长Duration.ZERO为永不过期 * @param expire 过期时长Duration.ZERO为永不过期
*/ */
default void remoteSetString(final String key, final String value, Duration expire) { default void remoteSetString(final String key, final String value, Duration expire) {
@@ -419,13 +417,12 @@ public interface CacheManager {
/** /**
* 远程异步缓存数据 * 远程异步缓存数据
* *
* @param <T> 泛型 * @param <T> 泛型
* @param hash 缓存hash * @param hash 缓存hash
* @param key 缓存键 * @param key 缓存键
* @param type 数据类型 * @param type 数据类型
* @param value 数据值 * @param value 数据值
* @param expire 过期时长Duration.ZERO为永不过期 * @param expire 过期时长Duration.ZERO为永不过期
*
* @return void * @return void
*/ */
public <T> CompletableFuture<Void> remoteSetAsync(String hash, String key, Type type, T value, Duration expire); public <T> CompletableFuture<Void> remoteSetAsync(String hash, String key, Type type, T value, Duration expire);
@@ -433,12 +430,11 @@ public interface CacheManager {
/** /**
* 远程异步缓存数据 * 远程异步缓存数据
* *
* @param <T> 泛型 * @param <T> 泛型
* @param key 缓存键 * @param key 缓存键
* @param type 数据类型 * @param type 数据类型
* @param value 数据值 * @param value 数据值
* @param expire 过期时长Duration.ZERO为永不过期 * @param expire 过期时长Duration.ZERO为永不过期
*
* @return void * @return void
*/ */
default <T> CompletableFuture<Void> remoteSetAsync(String key, Type type, T value, Duration expire) { default <T> CompletableFuture<Void> remoteSetAsync(String key, Type type, T value, Duration expire) {
@@ -448,24 +444,23 @@ public interface CacheManager {
/** /**
* 远程异步缓存字符串数据 * 远程异步缓存字符串数据
* *
* @param hash 缓存hash * @param hash 缓存hash
* @param key 缓存键 * @param key 缓存键
* @param value 数据值 * @param value 数据值
* @param expire 过期时长Duration.ZERO为永不过期 * @param expire 过期时长Duration.ZERO为永不过期
*
* @return void * @return void
*/ */
default CompletableFuture<Void> remoteSetStringAsync(final String hash, final String key, final String value, Duration expire) { default CompletableFuture<Void> remoteSetStringAsync(
final String hash, final String key, final String value, Duration expire) {
return remoteSetAsync(hash, key, String.class, value, expire); return remoteSetAsync(hash, key, String.class, value, expire);
} }
/** /**
* 远程异步缓存字符串数据 * 远程异步缓存字符串数据
* *
* @param key 缓存键 * @param key 缓存键
* @param value 数据值 * @param value 数据值
* @param expire 过期时长Duration.ZERO为永不过期 * @param expire 过期时长Duration.ZERO为永不过期
*
* @return void * @return void
*/ */
default CompletableFuture<Void> remoteSetStringAsync(final String key, final String value, Duration expire) { default CompletableFuture<Void> remoteSetStringAsync(final String key, final String value, Duration expire) {
@@ -476,8 +471,7 @@ public interface CacheManager {
* 远程删除缓存数据 * 远程删除缓存数据
* *
* @param hash 缓存hash * @param hash 缓存hash
* @param key 缓存键 * @param key 缓存键
*
* @return 删除数量 * @return 删除数量
*/ */
public long remoteDel(String hash, String key); public long remoteDel(String hash, String key);
@@ -486,7 +480,6 @@ public interface CacheManager {
* 远程删除缓存数据 * 远程删除缓存数据
* *
* @param key 缓存键 * @param key 缓存键
*
* @return 删除数量 * @return 删除数量
*/ */
default long remoteDel(String key) { default long remoteDel(String key) {
@@ -497,8 +490,7 @@ public interface CacheManager {
* 远程异步删除缓存数据 * 远程异步删除缓存数据
* *
* @param hash 缓存hash * @param hash 缓存hash
* @param key 缓存键 * @param key 缓存键
*
* @return 删除数量 * @return 删除数量
*/ */
public CompletableFuture<Long> remoteDelAsync(String hash, String key); public CompletableFuture<Long> remoteDelAsync(String hash, String key);
@@ -507,22 +499,20 @@ public interface CacheManager {
* 远程异步删除缓存数据 * 远程异步删除缓存数据
* *
* @param key 缓存键 * @param key 缓存键
*
* @return 删除数量 * @return 删除数量
*/ */
default CompletableFuture<Long> remoteDelAsync(String key) { default CompletableFuture<Long> remoteDelAsync(String key) {
return remoteDelAsync(DEFAULT_HASH, key); return remoteDelAsync(DEFAULT_HASH, key);
} }
//-------------------------------------- both缓存 -------------------------------------- // -------------------------------------- both缓存 --------------------------------------
/** /**
* 本地或远程获取缓存数据, 过期返回null * 本地或远程获取缓存数据, 过期返回null
* *
* @param <T> 泛型 * @param <T> 泛型
* @param hash 缓存hash * @param hash 缓存hash
* @param key 缓存键 * @param key 缓存键
* @param type 数据类型 * @param type 数据类型
*
* @return 数据值 * @return 数据值
*/ */
public <T> T bothGet(final String hash, final String key, final Type type); public <T> T bothGet(final String hash, final String key, final Type type);
@@ -530,10 +520,9 @@ public interface CacheManager {
/** /**
* 本地或远程获取缓存数据, 过期返回null * 本地或远程获取缓存数据, 过期返回null
* *
* @param <T> 泛型 * @param <T> 泛型
* @param key 缓存键 * @param key 缓存键
* @param type 数据类型 * @param type 数据类型
*
* @return 数据值 * @return 数据值
*/ */
default <T> T bothGet(final String key, final Type type) { default <T> T bothGet(final String key, final Type type) {
@@ -544,8 +533,7 @@ public interface CacheManager {
* 本地或远程获取字符串缓存数据, 过期返回null * 本地或远程获取字符串缓存数据, 过期返回null
* *
* @param hash 缓存hash * @param hash 缓存hash
* @param key 缓存键 * @param key 缓存键
*
* @return 数据值 * @return 数据值
*/ */
default String bothGetString(final String hash, final String key) { default String bothGetString(final String hash, final String key) {
@@ -556,7 +544,6 @@ public interface CacheManager {
* 本地或远程获取字符串缓存数据, 过期返回null * 本地或远程获取字符串缓存数据, 过期返回null
* *
* @param key 缓存键 * @param key 缓存键
*
* @return 数据值 * @return 数据值
*/ */
default String bothGetString(final String key) { default String bothGetString(final String key) {
@@ -566,11 +553,10 @@ public interface CacheManager {
/** /**
* 本地或远程异步获取缓存数据, 过期返回null * 本地或远程异步获取缓存数据, 过期返回null
* *
* @param <T> 泛型 * @param <T> 泛型
* @param hash 缓存hash * @param hash 缓存hash
* @param key 缓存键 * @param key 缓存键
* @param type 数据类型 * @param type 数据类型
*
* @return 数据值 * @return 数据值
*/ */
public <T> CompletableFuture<T> bothGetAsync(final String hash, final String key, final Type type); public <T> CompletableFuture<T> bothGetAsync(final String hash, final String key, final Type type);
@@ -578,10 +564,9 @@ public interface CacheManager {
/** /**
* 本地或远程异步获取缓存数据, 过期返回null * 本地或远程异步获取缓存数据, 过期返回null
* *
* @param <T> 泛型 * @param <T> 泛型
* @param key 缓存键 * @param key 缓存键
* @param type 数据类型 * @param type 数据类型
*
* @return 数据值 * @return 数据值
*/ */
default <T> CompletableFuture<T> bothGetAsync(final String key, final Type type) { default <T> CompletableFuture<T> bothGetAsync(final String key, final Type type) {
@@ -592,8 +577,7 @@ public interface CacheManager {
* 本地或远程异步获取字符串缓存数据, 过期返回null * 本地或远程异步获取字符串缓存数据, 过期返回null
* *
* @param hash 缓存hash * @param hash 缓存hash
* @param key 缓存键 * @param key 缓存键
*
* @return 数据值 * @return 数据值
*/ */
default CompletableFuture<String> bothGetStringAsync(final String hash, final String key) { default CompletableFuture<String> bothGetStringAsync(final String hash, final String key) {
@@ -604,7 +588,6 @@ public interface CacheManager {
* 本地或远程异步获取字符串缓存数据, 过期返回null * 本地或远程异步获取字符串缓存数据, 过期返回null
* *
* @param key 缓存键 * @param key 缓存键
*
* @return 数据值 * @return 数据值
*/ */
default CompletableFuture<String> bothGetStringAsync(final String key) { default CompletableFuture<String> bothGetStringAsync(final String key) {
@@ -614,119 +597,145 @@ public interface CacheManager {
/** /**
* 本地或远程获取缓存数据, 过期返回null * 本地或远程获取缓存数据, 过期返回null
* *
* @param <T> 泛型 * @param <T> 泛型
* @param hash 缓存hash * @param hash 缓存hash
* @param key 缓存键 * @param key 缓存键
* @param type 数据类型 * @param type 数据类型
* @param nullable 是否缓存null值 * @param nullable 是否缓存null值
* @param localExpire 本地过期时长Duration.ZERO为永不过期为null表示不本地缓存 * @param localExpire 本地过期时长Duration.ZERO为永不过期为null表示不本地缓存
* @param remoteExpire 远程过期时长Duration.ZERO为永不过期为null表示不远程缓存 * @param remoteExpire 远程过期时长Duration.ZERO为永不过期为null表示不远程缓存
* @param supplier 数据函数 * @param supplier 数据函数
*
* @return 数据值 * @return 数据值
*/ */
public <T> T bothGetSet(String hash, String key, Type type, boolean nullable, public <T> T bothGetSet(
Duration localExpire, Duration remoteExpire, ThrowSupplier<T> supplier); String hash,
String key,
Type type,
boolean nullable,
Duration localExpire,
Duration remoteExpire,
ThrowSupplier<T> supplier);
/** /**
* 本地或远程获取缓存数据, 过期返回null * 本地或远程获取缓存数据, 过期返回null
* *
* @param <T> 泛型 * @param <T> 泛型
* @param key 缓存键 * @param key 缓存键
* @param type 数据类型 * @param type 数据类型
* @param nullable 是否缓存null值 * @param nullable 是否缓存null值
* @param localExpire 本地过期时长Duration.ZERO为永不过期为null表示不本地缓存 * @param localExpire 本地过期时长Duration.ZERO为永不过期为null表示不本地缓存
* @param remoteExpire 远程过期时长Duration.ZERO为永不过期为null表示不远程缓存 * @param remoteExpire 远程过期时长Duration.ZERO为永不过期为null表示不远程缓存
* @param supplier 数据函数 * @param supplier 数据函数
*
* @return 数据值 * @return 数据值
*/ */
default <T> T bothGetSet(String key, Type type, boolean nullable, default <T> T bothGetSet(
Duration localExpire, Duration remoteExpire, ThrowSupplier<T> supplier) { String key,
Type type,
boolean nullable,
Duration localExpire,
Duration remoteExpire,
ThrowSupplier<T> supplier) {
return bothGetSet(DEFAULT_HASH, key, type, nullable, localExpire, remoteExpire, supplier); return bothGetSet(DEFAULT_HASH, key, type, nullable, localExpire, remoteExpire, supplier);
} }
/** /**
* 本地或远程异步获取缓存数据, 过期返回null * 本地或远程异步获取缓存数据, 过期返回null
* *
* @param <T> 泛型 * @param <T> 泛型
* @param hash 缓存hash * @param hash 缓存hash
* @param key 缓存键 * @param key 缓存键
* @param type 数据类型 * @param type 数据类型
* @param nullable 是否缓存null值 * @param nullable 是否缓存null值
* @param localExpire 本地过期时长Duration.ZERO为永不过期为null表示不本地缓存 * @param localExpire 本地过期时长Duration.ZERO为永不过期为null表示不本地缓存
* @param remoteExpire 远程过期时长Duration.ZERO为永不过期为null表示不远程缓存 * @param remoteExpire 远程过期时长Duration.ZERO为永不过期为null表示不远程缓存
* @param supplier 数据函数 * @param supplier 数据函数
*
* @return 数据值 * @return 数据值
*/ */
public <T> CompletableFuture<T> bothGetSetAsync(String hash, String key, Type type, boolean nullable, public <T> CompletableFuture<T> bothGetSetAsync(
Duration localExpire, Duration remoteExpire, ThrowSupplier<CompletableFuture<T>> supplier); String hash,
String key,
Type type,
boolean nullable,
Duration localExpire,
Duration remoteExpire,
ThrowSupplier<CompletableFuture<T>> supplier);
/** /**
* 本地或远程异步获取缓存数据, 过期返回null * 本地或远程异步获取缓存数据, 过期返回null
* *
* @param <T> 泛型 * @param <T> 泛型
* @param key 缓存键 * @param key 缓存键
* @param type 数据类型 * @param type 数据类型
* @param nullable 是否缓存null值 * @param nullable 是否缓存null值
* @param localExpire 本地过期时长Duration.ZERO为永不过期为null表示不本地缓存 * @param localExpire 本地过期时长Duration.ZERO为永不过期为null表示不本地缓存
* @param remoteExpire 远程过期时长Duration.ZERO为永不过期为null表示不远程缓存 * @param remoteExpire 远程过期时长Duration.ZERO为永不过期为null表示不远程缓存
* @param supplier 数据函数 * @param supplier 数据函数
*
* @return 数据值 * @return 数据值
*/ */
default <T> CompletableFuture<T> bothGetSetAsync(String key, Type type, boolean nullable, default <T> CompletableFuture<T> bothGetSetAsync(
Duration localExpire, Duration remoteExpire, ThrowSupplier<CompletableFuture<T>> supplier) { String key,
Type type,
boolean nullable,
Duration localExpire,
Duration remoteExpire,
ThrowSupplier<CompletableFuture<T>> supplier) {
return bothGetSetAsync(DEFAULT_HASH, key, type, nullable, localExpire, remoteExpire, supplier); return bothGetSetAsync(DEFAULT_HASH, key, type, nullable, localExpire, remoteExpire, supplier);
} }
/** /**
* 本地和远程缓存数据 * 本地和远程缓存数据
* *
* @param <T> 泛型 * @param <T> 泛型
* @param hash 缓存hash * @param hash 缓存hash
* @param key 缓存键 * @param key 缓存键
* @param type 数据类型 * @param type 数据类型
* @param value 数据值 * @param value 数据值
* @param localExpire 本地过期时长Duration.ZERO为永不过期为null表示不本地缓存 * @param localExpire 本地过期时长Duration.ZERO为永不过期为null表示不本地缓存
* @param remoteExpire 远程过期时长Duration.ZERO为永不过期为null表示不远程缓存 * @param remoteExpire 远程过期时长Duration.ZERO为永不过期为null表示不远程缓存
*/ */
public <T> void bothSet(final String hash, final String key, final Type type, final T value, Duration localExpire, Duration remoteExpire); public <T> void bothSet(
final String hash,
final String key,
final Type type,
final T value,
Duration localExpire,
Duration remoteExpire);
/** /**
* 本地和远程缓存数据 * 本地和远程缓存数据
* *
* @param <T> 泛型 * @param <T> 泛型
* @param key 缓存键 * @param key 缓存键
* @param type 数据类型 * @param type 数据类型
* @param value 数据值 * @param value 数据值
* @param localExpire 本地过期时长Duration.ZERO为永不过期为null表示不本地缓存 * @param localExpire 本地过期时长Duration.ZERO为永不过期为null表示不本地缓存
* @param remoteExpire 远程过期时长Duration.ZERO为永不过期为null表示不远程缓存 * @param remoteExpire 远程过期时长Duration.ZERO为永不过期为null表示不远程缓存
*/ */
default <T> void bothSet(final String key, final Type type, final T value, Duration localExpire, Duration remoteExpire) { default <T> void bothSet(
final String key, final Type type, final T value, Duration localExpire, Duration remoteExpire) {
bothSet(DEFAULT_HASH, key, type, value, localExpire, remoteExpire); bothSet(DEFAULT_HASH, key, type, value, localExpire, remoteExpire);
} }
/** /**
* 本地和远程缓存字符串数据 * 本地和远程缓存字符串数据
* *
* @param hash 缓存hash * @param hash 缓存hash
* @param key 缓存键 * @param key 缓存键
* @param value 数据值 * @param value 数据值
* @param localExpire 本地过期时长Duration.ZERO为永不过期为null表示不本地缓存 * @param localExpire 本地过期时长Duration.ZERO为永不过期为null表示不本地缓存
* @param remoteExpire 远程过期时长Duration.ZERO为永不过期为null表示不远程缓存 * @param remoteExpire 远程过期时长Duration.ZERO为永不过期为null表示不远程缓存
*/ */
default void bothSetString(final String hash, final String key, final String value, Duration localExpire, Duration remoteExpire) { default void bothSetString(
final String hash, final String key, final String value, Duration localExpire, Duration remoteExpire) {
bothSet(hash, key, String.class, value, localExpire, remoteExpire); bothSet(hash, key, String.class, value, localExpire, remoteExpire);
} }
/** /**
* 本地和远程缓存字符串数据 * 本地和远程缓存字符串数据
* *
* @param key 缓存键 * @param key 缓存键
* @param value 数据值 * @param value 数据值
* @param localExpire 本地过期时长Duration.ZERO为永不过期为null表示不本地缓存 * @param localExpire 本地过期时长Duration.ZERO为永不过期为null表示不本地缓存
* @param remoteExpire 远程过期时长Duration.ZERO为永不过期为null表示不远程缓存 * @param remoteExpire 远程过期时长Duration.ZERO为永不过期为null表示不远程缓存
*/ */
default void bothSetString(final String key, final String value, Duration localExpire, Duration remoteExpire) { default void bothSetString(final String key, final String value, Duration localExpire, Duration remoteExpire) {
@@ -736,60 +745,60 @@ public interface CacheManager {
/** /**
* 本地和远程异步缓存数据 * 本地和远程异步缓存数据
* *
* @param <T> 泛型 * @param <T> 泛型
* @param hash 缓存hash * @param hash 缓存hash
* @param key 缓存键 * @param key 缓存键
* @param type 数据类型 * @param type 数据类型
* @param value 数据值 * @param value 数据值
* @param localExpire 本地过期时长Duration.ZERO为永不过期为null表示不本地缓存 * @param localExpire 本地过期时长Duration.ZERO为永不过期为null表示不本地缓存
* @param remoteExpire 远程过期时长Duration.ZERO为永不过期为null表示不远程缓存 * @param remoteExpire 远程过期时长Duration.ZERO为永不过期为null表示不远程缓存
*
* @return void * @return void
*/ */
public <T> CompletableFuture<Void> bothSetAsync(String hash, String key, Type type, T value, Duration localExpire, Duration remoteExpire); public <T> CompletableFuture<Void> bothSetAsync(
String hash, String key, Type type, T value, Duration localExpire, Duration remoteExpire);
/** /**
* 本地和远程异步缓存数据 * 本地和远程异步缓存数据
* *
* @param <T> 泛型 * @param <T> 泛型
* @param key 缓存键 * @param key 缓存键
* @param type 数据类型 * @param type 数据类型
* @param value 数据值 * @param value 数据值
* @param localExpire 本地过期时长Duration.ZERO为永不过期为null表示不本地缓存 * @param localExpire 本地过期时长Duration.ZERO为永不过期为null表示不本地缓存
* @param remoteExpire 远程过期时长Duration.ZERO为永不过期为null表示不远程缓存 * @param remoteExpire 远程过期时长Duration.ZERO为永不过期为null表示不远程缓存
*
* @return void * @return void
*/ */
default <T> CompletableFuture<Void> bothSetAsync(String key, Type type, T value, Duration localExpire, Duration remoteExpire) { default <T> CompletableFuture<Void> bothSetAsync(
String key, Type type, T value, Duration localExpire, Duration remoteExpire) {
return bothSetAsync(DEFAULT_HASH, key, type, value, localExpire, remoteExpire); return bothSetAsync(DEFAULT_HASH, key, type, value, localExpire, remoteExpire);
} }
/** /**
* 本地和远程异步缓存字符串数据 * 本地和远程异步缓存字符串数据
* *
* @param hash 缓存hash * @param hash 缓存hash
* @param key 缓存键 * @param key 缓存键
* @param value 数据值 * @param value 数据值
* @param localExpire 本地过期时长Duration.ZERO为永不过期为null表示不本地缓存 * @param localExpire 本地过期时长Duration.ZERO为永不过期为null表示不本地缓存
* @param remoteExpire 远程过期时长Duration.ZERO为永不过期为null表示不远程缓存 * @param remoteExpire 远程过期时长Duration.ZERO为永不过期为null表示不远程缓存
*
* @return void * @return void
*/ */
default CompletableFuture<Void> bothSetStringAsync(String hash, String key, String value, Duration localExpire, Duration remoteExpire) { default CompletableFuture<Void> bothSetStringAsync(
String hash, String key, String value, Duration localExpire, Duration remoteExpire) {
return bothSetAsync(hash, key, String.class, value, localExpire, remoteExpire); return bothSetAsync(hash, key, String.class, value, localExpire, remoteExpire);
} }
/** /**
* 本地和远程异步缓存字符串数据 * 本地和远程异步缓存字符串数据
* *
* @param key 缓存键 * @param key 缓存键
* @param value 数据值 * @param value 数据值
* @param localExpire 本地过期时长Duration.ZERO为永不过期为null表示不本地缓存 * @param localExpire 本地过期时长Duration.ZERO为永不过期为null表示不本地缓存
* @param remoteExpire 远程过期时长Duration.ZERO为永不过期为null表示不远程缓存 * @param remoteExpire 远程过期时长Duration.ZERO为永不过期为null表示不远程缓存
*
* @return void * @return void
*/ */
default CompletableFuture<Void> bothSetStringAsync(String key, String value, Duration localExpire, Duration remoteExpire) { default CompletableFuture<Void> bothSetStringAsync(
String key, String value, Duration localExpire, Duration remoteExpire) {
return bothSetAsync(DEFAULT_HASH, key, String.class, value, localExpire, remoteExpire); return bothSetAsync(DEFAULT_HASH, key, String.class, value, localExpire, remoteExpire);
} }
@@ -797,8 +806,7 @@ public interface CacheManager {
* 本地和远程删除缓存数据 * 本地和远程删除缓存数据
* *
* @param hash 缓存hash * @param hash 缓存hash
* @param key 缓存键 * @param key 缓存键
*
* @return 删除数量 * @return 删除数量
*/ */
public long bothDel(String hash, String key); public long bothDel(String hash, String key);
@@ -807,7 +815,6 @@ public interface CacheManager {
* 本地和远程删除缓存数据 * 本地和远程删除缓存数据
* *
* @param key 缓存键 * @param key 缓存键
*
* @return 删除数量 * @return 删除数量
*/ */
default long bothDel(String key) { default long bothDel(String key) {
@@ -818,8 +825,7 @@ public interface CacheManager {
* 本地和远程异步删除缓存数据 * 本地和远程异步删除缓存数据
* *
* @param hash 缓存hash * @param hash 缓存hash
* @param key 缓存键 * @param key 缓存键
*
* @return 删除数量 * @return 删除数量
*/ */
public CompletableFuture<Long> bothDelAsync(String hash, String key); public CompletableFuture<Long> bothDelAsync(String hash, String key);
@@ -828,11 +834,9 @@ public interface CacheManager {
* 本地和远程异步删除缓存数据 * 本地和远程异步删除缓存数据
* *
* @param key 缓存键 * @param key 缓存键
*
* @return 删除数量 * @return 删除数量
*/ */
default CompletableFuture<Long> bothDelAsync(String key) { default CompletableFuture<Long> bothDelAsync(String key) {
return bothDelAsync(DEFAULT_HASH, key); return bothDelAsync(DEFAULT_HASH, key);
} }
} }

View File

@@ -3,21 +3,18 @@
*/ */
package org.redkale.cache; package org.redkale.cache;
import java.lang.annotation.Documented;
import static java.lang.annotation.ElementType.METHOD; import static java.lang.annotation.ElementType.METHOD;
import java.lang.annotation.Retention;
import static java.lang.annotation.RetentionPolicy.RUNTIME; import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target; import java.lang.annotation.Target;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import org.redkale.service.LoadMode; import org.redkale.service.LoadMode;
/** /**
*
* 标记在Service的缓存接口, 方法有以下限制: <br> * 标记在Service的缓存接口, 方法有以下限制: <br>
* 1、方法返回类型不能是void/CompletableFuture&#60;Void&#62; * 1、方法返回类型不能是void/CompletableFuture&#60;Void&#62; 2、方法返回类型必须可json序列化 3、方法必须是protected/public 4、方法不能是final/static
* 2、方法返回类型必须可json序列化
* 3、方法必须是protected/public
* 4、方法不能是final/static
* *
* @since 2.8.0 * @since 2.8.0
*/ */
@@ -43,8 +40,7 @@ public @interface Cached {
/** /**
* 本地缓存过期时长, 0表示永不过期 -1表示不作本地缓存。<br> * 本地缓存过期时长, 0表示永不过期 -1表示不作本地缓存。<br>
* 参数值支持方式:<br> * 参数值支持方式:<br>
* 100: 设置数值 * 100: 设置数值 ${env.cache.expires}: 读取系统配置项
* ${env.cache.expires}: 读取系统配置项
* *
* @return 过期时长 * @return 过期时长
*/ */
@@ -53,8 +49,7 @@ public @interface Cached {
/** /**
* 远程缓存过期时长, 0表示永不过期 -1表示不作远程缓存。<br> * 远程缓存过期时长, 0表示永不过期 -1表示不作远程缓存。<br>
* 参数值支持方式:<br> * 参数值支持方式:<br>
* 100: 设置数值 * 100: 设置数值 ${env.cache.expires}: 读取系统配置项
* ${env.cache.expires}: 读取系统配置项
* *
* @return 过期时长 * @return 过期时长
*/ */

View File

@@ -8,6 +8,7 @@ import java.lang.reflect.Type;
import java.time.Duration; import java.time.Duration;
import java.util.Objects; import java.util.Objects;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
import org.redkale.annotation.ClassDepends;
import org.redkale.annotation.Nullable; import org.redkale.annotation.Nullable;
import org.redkale.annotation.Resource; import org.redkale.annotation.Resource;
import org.redkale.cache.CacheManager; import org.redkale.cache.CacheManager;
@@ -16,17 +17,13 @@ import org.redkale.util.Environment;
import org.redkale.util.MultiHashKey; import org.redkale.util.MultiHashKey;
import org.redkale.util.ThrowSupplier; import org.redkale.util.ThrowSupplier;
import org.redkale.util.TypeToken; import org.redkale.util.TypeToken;
import org.redkale.annotation.ClassDepends;
/** /**
*
* 缓存的方法对象 * 缓存的方法对象
* *
* <p> * <p>详情见: https://redkale.org
* 详情见: https://redkale.org
* *
* @author zhangjx * @author zhangjx
*
* @since 2.8.0 * @since 2.8.0
*/ */
@ClassDepends @ClassDepends
@@ -40,46 +37,52 @@ public class CacheAction {
private final CacheEntry cached; private final CacheEntry cached;
//Supplier对象的类型 // Supplier对象的类型
private final Type resultType; private final Type resultType;
//缓存方法是否异步 // 缓存方法是否异步
private final boolean async; private final boolean async;
//是否可以缓存null // 是否可以缓存null
private final boolean nullable; private final boolean nullable;
//宿主对象的类 // 宿主对象的类
private final Class serviceClass; private final Class serviceClass;
//无法获取动态的Method只能存方法名 // 无法获取动态的Method只能存方法名
private final String methodName; private final String methodName;
//获取动态的字段名 // 获取动态的字段名
private final String fieldName; private final String fieldName;
//方法参数类型 // 方法参数类型
@Nullable @Nullable
private final Class[] paramTypes; private final Class[] paramTypes;
//方法参数名 // 方法参数名
@Nullable @Nullable
private final String[] paramNames; private final String[] paramNames;
//缓存的hash // 缓存的hash
private String hash; private String hash;
//缓存的key // 缓存的key
private MultiHashKey dynKey; private MultiHashKey dynKey;
//本地缓存过期时长Duration.ZERO为永不过期为null表示不本地缓存 // 本地缓存过期时长Duration.ZERO为永不过期为null表示不本地缓存
private Duration localExpire; private Duration localExpire;
//远程缓存过期时长Duration.ZERO为永不过期为null表示不远程缓存 // 远程缓存过期时长Duration.ZERO为永不过期为null表示不远程缓存
private Duration remoteExpire; private Duration remoteExpire;
CacheAction(CacheEntry cached, Type returnType, Class serviceClass, Class[] paramTypes, CacheAction(
String[] paramNames, String methodName, String fieldName) { CacheEntry cached,
Type returnType,
Class serviceClass,
Class[] paramTypes,
String[] paramNames,
String methodName,
String fieldName) {
this.cached = cached; this.cached = cached;
this.nullable = cached.isNullable(); this.nullable = cached.isNullable();
this.serviceClass = Objects.requireNonNull(serviceClass); this.serviceClass = Objects.requireNonNull(serviceClass);
@@ -92,10 +95,9 @@ public class CacheAction {
} }
void init() { void init() {
this.hash = cached.getHash().trim().isEmpty() this.hash = cached.getHash().trim().isEmpty() || CacheManager.DEFAULT_HASH.equals(cached.getHash())
|| CacheManager.DEFAULT_HASH.equals(cached.getHash()) ? CacheManager.DEFAULT_HASH
? CacheManager.DEFAULT_HASH : environment.getPropertyValue(cached.getHash());
: environment.getPropertyValue(cached.getHash());
String key = environment.getPropertyValue(cached.getKey()); String key = environment.getPropertyValue(cached.getKey());
this.dynKey = MultiHashKey.create(paramNames, key); this.dynKey = MultiHashKey.create(paramNames, key);
this.localExpire = createDuration(cached.getLocalExpire()); this.localExpire = createDuration(cached.getLocalExpire());
@@ -106,9 +108,11 @@ public class CacheAction {
public <T> T get(ThrowSupplier<T> supplier, Object... args) { public <T> T get(ThrowSupplier<T> supplier, Object... args) {
if (async) { if (async) {
ThrowSupplier supplier0 = supplier; ThrowSupplier supplier0 = supplier;
return (T) manager.bothGetSetAsync(hash, dynKey.keyFor(args), resultType, nullable, localExpire, remoteExpire, supplier0); return (T) manager.bothGetSetAsync(
hash, dynKey.keyFor(args), resultType, nullable, localExpire, remoteExpire, supplier0);
} else { } else {
return manager.bothGetSet(hash, dynKey.keyFor(args), resultType, nullable, localExpire, remoteExpire, supplier); return manager.bothGetSet(
hash, dynKey.keyFor(args), resultType, nullable, localExpire, remoteExpire, supplier);
} }
} }
@@ -140,14 +144,13 @@ public class CacheAction {
@Override @Override
public String toString() { public String toString() {
return "{" return "{"
+ "\"serviceClass\":" + serviceClass.getName() + "\"serviceClass\":" + serviceClass.getName()
+ ",\"methodName\":\"" + methodName + "\"" + ",\"methodName\":\"" + methodName + "\""
+ ",\"fieldName\":\"" + fieldName + "\"" + ",\"fieldName\":\"" + fieldName + "\""
+ ",\"paramTypes\":" + JsonConvert.root().convertTo(paramTypes) + ",\"paramTypes\":" + JsonConvert.root().convertTo(paramTypes)
+ ",\"paramNames\":" + JsonConvert.root().convertTo(paramNames) + ",\"paramNames\":" + JsonConvert.root().convertTo(paramNames)
+ ",\"resultType\":\"" + resultType + "\"" + ",\"resultType\":\"" + resultType + "\""
+ ",\"cache\":" + cached + ",\"cache\":" + cached
+ "}"; + "}";
} }
} }

View File

@@ -3,6 +3,8 @@
*/ */
package org.redkale.cache.spi; package org.redkale.cache.spi;
import static org.redkale.asm.Opcodes.*;
import java.lang.annotation.Annotation; import java.lang.annotation.Annotation;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.lang.reflect.Method; import java.lang.reflect.Method;
@@ -21,7 +23,6 @@ import org.redkale.asm.Handle;
import org.redkale.asm.Label; import org.redkale.asm.Label;
import org.redkale.asm.MethodVisitor; import org.redkale.asm.MethodVisitor;
import org.redkale.asm.Opcodes; import org.redkale.asm.Opcodes;
import static org.redkale.asm.Opcodes.*;
import org.redkale.asm.Type; import org.redkale.asm.Type;
import org.redkale.cache.Cached; import org.redkale.cache.Cached;
import org.redkale.inject.ResourceFactory; import org.redkale.inject.ResourceFactory;
@@ -31,14 +32,10 @@ import org.redkale.util.RedkaleException;
import org.redkale.util.ThrowSupplier; import org.redkale.util.ThrowSupplier;
import org.redkale.util.TypeToken; import org.redkale.util.TypeToken;
/** /** @author zhangjx */
*
* @author zhangjx
*/
public class CacheAsmMethodBoost extends AsmMethodBoost { public class CacheAsmMethodBoost extends AsmMethodBoost {
private static final java.lang.reflect.Type FUTURE_VOID = new TypeToken<CompletableFuture<Void>>() { private static final java.lang.reflect.Type FUTURE_VOID = new TypeToken<CompletableFuture<Void>>() {}.getType();
}.getType();
private static final List<Class<? extends Annotation>> FILTER_ANN = List.of(Cached.class, DynForCache.class); private static final List<Class<? extends Annotation>> FILTER_ANN = List.of(Cached.class, DynForCache.class);
@@ -54,8 +51,14 @@ public class CacheAsmMethodBoost extends AsmMethodBoost {
} }
@Override @Override
public String doMethod(ClassLoader classLoader, ClassWriter cw, public String doMethod(
String newDynName, String fieldPrefix, List filterAnns, Method method, final String newMethodName) { ClassLoader classLoader,
ClassWriter cw,
String newDynName,
String fieldPrefix,
List filterAnns,
Method method,
final String newMethodName) {
Map<String, CacheAction> actions = this.actionMap; Map<String, CacheAction> actions = this.actionMap;
if (actions == null) { if (actions == null) {
actions = new LinkedHashMap<>(); actions = new LinkedHashMap<>();
@@ -72,10 +75,12 @@ public class CacheAsmMethodBoost extends AsmMethodBoost {
return newMethodName; return newMethodName;
} }
if (Modifier.isFinal(method.getModifiers()) || Modifier.isStatic(method.getModifiers())) { if (Modifier.isFinal(method.getModifiers()) || Modifier.isStatic(method.getModifiers())) {
throw new RedkaleException("@" + Cached.class.getSimpleName() + " cannot on final or static method, but on " + method); throw new RedkaleException(
"@" + Cached.class.getSimpleName() + " cannot on final or static method, but on " + method);
} }
if (!Modifier.isProtected(method.getModifiers()) && !Modifier.isPublic(method.getModifiers())) { if (!Modifier.isProtected(method.getModifiers()) && !Modifier.isPublic(method.getModifiers())) {
throw new RedkaleException("@" + Cached.class.getSimpleName() + " must on protected or public method, but on " + method); throw new RedkaleException(
"@" + Cached.class.getSimpleName() + " must on protected or public method, but on " + method);
} }
if (method.getReturnType() == void.class || FUTURE_VOID.equals(method.getGenericReturnType())) { if (method.getReturnType() == void.class || FUTURE_VOID.equals(method.getGenericReturnType())) {
throw new RedkaleException("@" + Cached.class.getSimpleName() + " cannot on void method, but on " + method); throw new RedkaleException("@" + Cached.class.getSimpleName() + " cannot on void method, but on " + method);
@@ -84,10 +89,10 @@ public class CacheAsmMethodBoost extends AsmMethodBoost {
final String rsMethodName = method.getName() + "_afterCache"; final String rsMethodName = method.getName() + "_afterCache";
final String dynFieldName = fieldPrefix + "_" + method.getName() + "CacheAction" + actionIndex; final String dynFieldName = fieldPrefix + "_" + method.getName() + "CacheAction" + actionIndex;
final AsmMethodBean methodBean = getMethodBean(method); final AsmMethodBean methodBean = getMethodBean(method);
{ //定义一个新方法调用 this.rsMethodName { // 定义一个新方法调用 this.rsMethodName
final String cacheDynDesc = Type.getDescriptor(DynForCache.class); final String cacheDynDesc = Type.getDescriptor(DynForCache.class);
final MethodVisitor mv = createMethodVisitor(cw, method, newMethodName, methodBean); final MethodVisitor mv = createMethodVisitor(cw, method, newMethodName, methodBean);
//mv.setDebug(true); // mv.setDebug(true);
AnnotationVisitor av = mv.visitAnnotation(cacheDynDesc, true); AnnotationVisitor av = mv.visitAnnotation(cacheDynDesc, true);
av.visit("dynField", dynFieldName); av.visit("dynField", dynFieldName);
Asms.visitAnnotation(av, cached); Asms.visitAnnotation(av, cached);
@@ -98,13 +103,13 @@ public class CacheAsmMethodBoost extends AsmMethodBoost {
mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ALOAD, 0);
List<Integer> insns = visitVarInsnParamTypes(mv, method, 0); List<Integer> insns = visitVarInsnParamTypes(mv, method, 0);
String dynDesc = methodBean.getDesc(); String dynDesc = methodBean.getDesc();
dynDesc = "(L" + newDynName + ";" + dynDesc.substring(1, dynDesc.lastIndexOf(')') + 1) + Type.getDescriptor(ThrowSupplier.class); dynDesc = "(L" + newDynName + ";" + dynDesc.substring(1, dynDesc.lastIndexOf(')') + 1)
mv.visitInvokeDynamicInsn("get", dynDesc, Asms.createLambdaMetaHandle(), + Type.getDescriptor(ThrowSupplier.class);
new Object[]{ mv.visitInvokeDynamicInsn("get", dynDesc, Asms.createLambdaMetaHandle(), new Object[] {
org.redkale.asm.Type.getType("()Ljava/lang/Object;"), org.redkale.asm.Type.getType("()Ljava/lang/Object;"),
new Handle(Opcodes.H_INVOKESPECIAL, newDynName, "lambda$" + actionIndex, methodBean.getDesc(), false), new Handle(Opcodes.H_INVOKESPECIAL, newDynName, "lambda$" + actionIndex, methodBean.getDesc(), false),
org.redkale.asm.Type.getType("()" + Type.getDescriptor(method.getReturnType())) org.redkale.asm.Type.getType("()" + Type.getDescriptor(method.getReturnType()))
}); });
mv.visitVarInsn(ASTORE, 1 + method.getParameterCount()); mv.visitVarInsn(ASTORE, 1 + method.getParameterCount());
Label l1 = new Label(); Label l1 = new Label();
mv.visitLabel(l1); mv.visitLabel(l1);
@@ -132,15 +137,24 @@ public class CacheAsmMethodBoost extends AsmMethodBoost {
mv.visitVarInsn(ILOAD, insn); mv.visitVarInsn(ILOAD, insn);
} }
Class bigclaz = TypeToken.primitiveToWrapper(pt); Class bigclaz = TypeToken.primitiveToWrapper(pt);
mv.visitMethodInsn(INVOKESTATIC, bigclaz.getName().replace('.', '/'), "valueOf", mv.visitMethodInsn(
"(" + Type.getDescriptor((Class) pt) + ")" + Type.getDescriptor(bigclaz), false); INVOKESTATIC,
bigclaz.getName().replace('.', '/'),
"valueOf",
"(" + Type.getDescriptor((Class) pt) + ")" + Type.getDescriptor(bigclaz),
false);
} else { } else {
mv.visitVarInsn(ALOAD, insn); mv.visitVarInsn(ALOAD, insn);
} }
mv.visitInsn(AASTORE); mv.visitInsn(AASTORE);
} }
String throwFuncDesc = Type.getDescriptor(ThrowSupplier.class); String throwFuncDesc = Type.getDescriptor(ThrowSupplier.class);
mv.visitMethodInsn(INVOKEVIRTUAL, CacheAction.class.getName().replace('.', '/'), "get", "(" + throwFuncDesc + "[Ljava/lang/Object;)Ljava/lang/Object;", false); mv.visitMethodInsn(
INVOKEVIRTUAL,
CacheAction.class.getName().replace('.', '/'),
"get",
"(" + throwFuncDesc + "[Ljava/lang/Object;)Ljava/lang/Object;",
false);
mv.visitTypeInsn(CHECKCAST, method.getReturnType().getName().replace('.', '/')); mv.visitTypeInsn(CHECKCAST, method.getReturnType().getName().replace('.', '/'));
mv.visitInsn(ARETURN); mv.visitInsn(ARETURN);
Label l2 = new Label(); Label l2 = new Label();
@@ -151,14 +165,22 @@ public class CacheAsmMethodBoost extends AsmMethodBoost {
mv.visitMaxs(20, 20); mv.visitMaxs(20, 20);
mv.visitEnd(); mv.visitEnd();
CacheAction action = new CacheAction(new CacheEntry(cached), method.getGenericReturnType(), serviceType, CacheAction action = new CacheAction(
method.getParameterTypes(), methodBean.fieldNameArray(), method.getName(), dynFieldName); new CacheEntry(cached),
method.getGenericReturnType(),
serviceType,
method.getParameterTypes(),
methodBean.fieldNameArray(),
method.getName(),
dynFieldName);
actions.put(dynFieldName, action); actions.put(dynFieldName, action);
} }
{ //ThrowSupplier { // ThrowSupplier
final MethodVisitor mv = cw.visitMethod(ACC_PRIVATE + ACC_SYNTHETIC, final MethodVisitor mv = cw.visitMethod(
"lambda$" + actionIndex, methodBean.getDesc(), null, new String[]{"java/lang/Throwable"}); ACC_PRIVATE + ACC_SYNTHETIC, "lambda$" + actionIndex, methodBean.getDesc(), null, new String[] {
//mv.setDebug(true); "java/lang/Throwable"
});
// mv.setDebug(true);
Label l0 = new Label(); Label l0 = new Label();
mv.visitLabel(l0); mv.visitLabel(l0);
mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ALOAD, 0);
@@ -171,12 +193,17 @@ public class CacheAsmMethodBoost extends AsmMethodBoost {
mv.visitMaxs(5, 5); mv.visitMaxs(5, 5);
mv.visitEnd(); mv.visitEnd();
} }
{ //定义字段 { // 定义字段
FieldVisitor fv = cw.visitField(ACC_PRIVATE, dynFieldName, Type.getDescriptor(CacheAction.class), null, null); FieldVisitor fv =
cw.visitField(ACC_PRIVATE, dynFieldName, Type.getDescriptor(CacheAction.class), null, null);
fv.visitEnd(); fv.visitEnd();
} }
if (actions.size() == 1) { if (actions.size() == 1) {
cw.visitInnerClass("java/lang/invoke/MethodHandles$Lookup", "java/lang/invoke/MethodHandles", "Lookup", ACC_PUBLIC + ACC_FINAL + ACC_STATIC); cw.visitInnerClass(
"java/lang/invoke/MethodHandles$Lookup",
"java/lang/invoke/MethodHandles",
"Lookup",
ACC_PUBLIC + ACC_FINAL + ACC_STATIC);
} }
return rsMethodName; return rsMethodName;
} }
@@ -184,7 +211,7 @@ public class CacheAsmMethodBoost extends AsmMethodBoost {
@Override @Override
public void doInstance(ResourceFactory resourceFactory, Object service) { public void doInstance(ResourceFactory resourceFactory, Object service) {
Class clazz = service.getClass(); Class clazz = service.getClass();
if (actionMap == null) { //为null表示没有调用过doMethod 动态类在编译是已经生成好了 if (actionMap == null) { // 为null表示没有调用过doMethod 动态类在编译是已经生成好了
actionMap = new LinkedHashMap<>(); actionMap = new LinkedHashMap<>();
Map<String, AsmMethodBean> methodBeans = AsmMethodBoost.getMethodBeans(clazz); Map<String, AsmMethodBean> methodBeans = AsmMethodBoost.getMethodBeans(clazz);
for (final Method method : clazz.getDeclaredMethods()) { for (final Method method : clazz.getDeclaredMethods()) {
@@ -192,8 +219,14 @@ public class CacheAsmMethodBoost extends AsmMethodBoost {
if (cached != null) { if (cached != null) {
String dynFieldName = cached.dynField(); String dynFieldName = cached.dynField();
AsmMethodBean methodBean = AsmMethodBean.get(methodBeans, method); AsmMethodBean methodBean = AsmMethodBean.get(methodBeans, method);
CacheAction action = new CacheAction(new CacheEntry(cached), method.getGenericReturnType(), serviceType, CacheAction action = new CacheAction(
method.getParameterTypes(), methodBean.fieldNameArray(), method.getName(), dynFieldName); new CacheEntry(cached),
method.getGenericReturnType(),
serviceType,
method.getParameterTypes(),
methodBean.fieldNameArray(),
method.getName(),
dynFieldName);
actionMap.put(dynFieldName, action); actionMap.put(dynFieldName, action);
} }
} }
@@ -210,7 +243,6 @@ public class CacheAsmMethodBoost extends AsmMethodBoost {
throw new RedkaleException("field (" + field + ") in " + clazz.getName() + " set error", e); throw new RedkaleException("field (" + field + ") in " + clazz.getName() + " set error", e);
} }
}); });
//do nothing // do nothing
} }
} }

View File

@@ -7,10 +7,7 @@ import java.util.concurrent.TimeUnit;
import org.redkale.cache.Cached; import org.redkale.cache.Cached;
import org.redkale.convert.json.JsonConvert; import org.redkale.convert.json.JsonConvert;
/** /** @author zhangjx */
*
* @author zhangjx
*/
public class CacheEntry { public class CacheEntry {
private String key; private String key;
@@ -25,8 +22,7 @@ public class CacheEntry {
private boolean nullable; private boolean nullable;
public CacheEntry() { public CacheEntry() {}
}
public CacheEntry(DynForCache cached) { public CacheEntry(DynForCache cached) {
this.key = cached.key(); this.key = cached.key();

View File

@@ -7,15 +7,11 @@ import org.redkale.cache.CacheManager;
import org.redkale.util.InstanceProvider; import org.redkale.util.InstanceProvider;
/** /**
*
* 自定义的CacheManager加载器, 如果标记&#64;Priority加载器的优先级需要大于1000 1000以下预留给官方加载器 * 自定义的CacheManager加载器, 如果标记&#64;Priority加载器的优先级需要大于1000 1000以下预留给官方加载器
* *
* <p> * <p>详情见: https://redkale.org
* 详情见: https://redkale.org
* *
* @author zhangjx * @author zhangjx
* @since 2.8.0 * @since 2.8.0
*/ */
public interface CacheManagerProvider extends InstanceProvider<CacheManager> { public interface CacheManagerProvider extends InstanceProvider<CacheManager> {}
}

View File

@@ -42,38 +42,38 @@ import org.redkale.util.Utility;
@ResourceType(CacheManager.class) @ResourceType(CacheManager.class)
public class CacheManagerService implements CacheManager, Service { public class CacheManagerService implements CacheManager, Service {
//是否开启缓存 // 是否开启缓存
protected boolean enabled = true; protected boolean enabled = true;
//配置 // 配置
protected AnyValue config; protected AnyValue config;
//数据类型与CacheValue泛型的对应关系 // 数据类型与CacheValue泛型的对应关系
private final ConcurrentHashMap<Type, Type> cacheValueTypes = new ConcurrentHashMap<>(); private final ConcurrentHashMap<Type, Type> cacheValueTypes = new ConcurrentHashMap<>();
//本地缓存Source // 本地缓存Source
protected final CacheMemorySource localSource = new CacheMemorySource("cache-local"); protected final CacheMemorySource localSource = new CacheMemorySource("cache-local");
//缓存hash集合, 用于定时遍历删除过期数据 // 缓存hash集合, 用于定时遍历删除过期数据
protected final ConcurrentSkipListSet<String> hashNames = new ConcurrentSkipListSet<>(); protected final ConcurrentSkipListSet<String> hashNames = new ConcurrentSkipListSet<>();
//缓存无效时使用的同步锁 // 缓存无效时使用的同步锁
private final ConcurrentHashMap<String, CacheValue> syncLock = new ConcurrentHashMap<>(); private final ConcurrentHashMap<String, CacheValue> syncLock = new ConcurrentHashMap<>();
//缓存无效时使用的异步锁 // 缓存无效时使用的异步锁
private final ConcurrentHashMap<String, CacheAsyncEntry> asyncLock = new ConcurrentHashMap<>(); private final ConcurrentHashMap<String, CacheAsyncEntry> asyncLock = new ConcurrentHashMap<>();
@Resource(required = false) @Resource(required = false)
protected Application application; protected Application application;
//远程缓存Source // 远程缓存Source
protected CacheSource remoteSource; protected CacheSource remoteSource;
protected CacheManagerService(@Nullable CacheSource remoteSource) { protected CacheManagerService(@Nullable CacheSource remoteSource) {
this.remoteSource = remoteSource; this.remoteSource = remoteSource;
} }
//一般用于独立组件 // 一般用于独立组件
public static CacheManagerService create(@Nullable CacheSource remoteSource) { public static CacheManagerService create(@Nullable CacheSource remoteSource) {
return new CacheManagerService(remoteSource); return new CacheManagerService(remoteSource);
} }
@@ -105,7 +105,6 @@ public class CacheManagerService implements CacheManager, Service {
this.remoteSource = source; this.remoteSource = source;
} }
} }
} }
@Override @Override
@@ -124,15 +123,14 @@ public class CacheManagerService implements CacheManager, Service {
return this; return this;
} }
//-------------------------------------- 本地缓存 -------------------------------------- // -------------------------------------- 本地缓存 --------------------------------------
/** /**
* 本地获取缓存数据, 过期返回null * 本地获取缓存数据, 过期返回null
* *
* @param <T> 泛型 * @param <T> 泛型
* @param hash 缓存hash * @param hash 缓存hash
* @param key 缓存键 * @param key 缓存键
* @param type 数据类型 * @param type 数据类型
*
* @return 数据值 * @return 数据值
*/ */
@Override @Override
@@ -144,47 +142,58 @@ public class CacheManagerService implements CacheManager, Service {
/** /**
* 本地获取缓存数据, 过期返回null * 本地获取缓存数据, 过期返回null
* *
* @param <T> 泛型 * @param <T> 泛型
* @param hash 缓存hash * @param hash 缓存hash
* @param key 缓存键 * @param key 缓存键
* @param type 数据类型 * @param type 数据类型
* @param nullable 是否缓存null值 * @param nullable 是否缓存null值
* @param expire 过期时长Duration.ZERO为永不过期 * @param expire 过期时长Duration.ZERO为永不过期
* @param supplier 数据函数 * @param supplier 数据函数
*
* @return 数据值 * @return 数据值
*/ */
@Override @Override
public <T> T localGetSet(final String hash, final String key, final Type type, boolean nullable, Duration expire, ThrowSupplier<T> supplier) { public <T> T localGetSet(
final String hash,
final String key,
final Type type,
boolean nullable,
Duration expire,
ThrowSupplier<T> supplier) {
return getSet(localSource::get, this::localSetCache, hash, key, type, nullable, expire, supplier); return getSet(localSource::get, this::localSetCache, hash, key, type, nullable, expire, supplier);
} }
/** /**
* 本地异步获取缓存数据, 过期返回null * 本地异步获取缓存数据, 过期返回null
* *
* @param <T> 泛型 * @param <T> 泛型
* @param hash 缓存hash * @param hash 缓存hash
* @param key 缓存键 * @param key 缓存键
* @param type 数据类型 * @param type 数据类型
* @param nullable 是否缓存null值 * @param nullable 是否缓存null值
* @param expire 过期时长Duration.ZERO为永不过期 * @param expire 过期时长Duration.ZERO为永不过期
* @param supplier 数据函数 * @param supplier 数据函数
*
* @return 数据值 * @return 数据值
*/ */
@Override @Override
public <T> CompletableFuture<T> localGetSetAsync(String hash, String key, Type type, boolean nullable, Duration expire, ThrowSupplier<CompletableFuture<T>> supplier) { public <T> CompletableFuture<T> localGetSetAsync(
return getSetAsync(localSource::getAsync, this::localSetCacheAsync, hash, key, type, nullable, expire, supplier); String hash,
String key,
Type type,
boolean nullable,
Duration expire,
ThrowSupplier<CompletableFuture<T>> supplier) {
return getSetAsync(
localSource::getAsync, this::localSetCacheAsync, hash, key, type, nullable, expire, supplier);
} }
/** /**
* 本地缓存数据 * 本地缓存数据
* *
* @param <T> 泛型 * @param <T> 泛型
* @param hash 缓存hash * @param hash 缓存hash
* @param key 缓存键 * @param key 缓存键
* @param type 数据类型 * @param type 数据类型
* @param value 数据值 * @param value 数据值
* @param expire 过期时长Duration.ZERO为永不过期 * @param expire 过期时长Duration.ZERO为永不过期
*/ */
@Override @Override
@@ -196,8 +205,7 @@ public class CacheManagerService implements CacheManager, Service {
* 本地删除缓存数据 * 本地删除缓存数据
* *
* @param hash 缓存hash * @param hash 缓存hash
* @param key 缓存键 * @param key 缓存键
*
* @return 删除数量 * @return 删除数量
*/ */
@Override @Override
@@ -206,15 +214,14 @@ public class CacheManagerService implements CacheManager, Service {
return localSource.del(idFor(hash, key)); return localSource.del(idFor(hash, key));
} }
//-------------------------------------- 远程缓存 -------------------------------------- // -------------------------------------- 远程缓存 --------------------------------------
/** /**
* 远程获取缓存数据, 过期返回null * 远程获取缓存数据, 过期返回null
* *
* @param <T> 泛型 * @param <T> 泛型
* @param hash 缓存hash * @param hash 缓存hash
* @param key 缓存键 * @param key 缓存键
* @param type 数据类型 * @param type 数据类型
*
* @return 数据值 * @return 数据值
*/ */
@Override @Override
@@ -226,11 +233,10 @@ public class CacheManagerService implements CacheManager, Service {
/** /**
* 远程异步获取缓存数据, 过期返回null * 远程异步获取缓存数据, 过期返回null
* *
* @param <T> 泛型 * @param <T> 泛型
* @param hash 缓存hash * @param hash 缓存hash
* @param key 缓存键 * @param key 缓存键
* @param type 数据类型 * @param type 数据类型
*
* @return 数据值 * @return 数据值
*/ */
@Override @Override
@@ -243,47 +249,58 @@ public class CacheManagerService implements CacheManager, Service {
/** /**
* 远程获取缓存数据, 过期返回null * 远程获取缓存数据, 过期返回null
* *
* @param <T> 泛型 * @param <T> 泛型
* @param hash 缓存hash * @param hash 缓存hash
* @param key 缓存键 * @param key 缓存键
* @param type 数据类型 * @param type 数据类型
* @param nullable 是否缓存null值 * @param nullable 是否缓存null值
* @param expire 过期时长Duration.ZERO为永不过期 * @param expire 过期时长Duration.ZERO为永不过期
* @param supplier 数据函数 * @param supplier 数据函数
*
* @return 数据值 * @return 数据值
*/ */
@Override @Override
public <T> T remoteGetSet(final String hash, final String key, final Type type, boolean nullable, Duration expire, ThrowSupplier<T> supplier) { public <T> T remoteGetSet(
final String hash,
final String key,
final Type type,
boolean nullable,
Duration expire,
ThrowSupplier<T> supplier) {
return getSet(remoteSource::get, this::remoteSetCache, hash, key, type, nullable, expire, supplier); return getSet(remoteSource::get, this::remoteSetCache, hash, key, type, nullable, expire, supplier);
} }
/** /**
* 远程异步获取缓存数据, 过期返回null * 远程异步获取缓存数据, 过期返回null
* *
* @param <T> 泛型 * @param <T> 泛型
* @param hash 缓存hash * @param hash 缓存hash
* @param key 缓存键 * @param key 缓存键
* @param type 数据类型 * @param type 数据类型
* @param nullable 是否缓存null值 * @param nullable 是否缓存null值
* @param expire 过期时长Duration.ZERO为永不过期 * @param expire 过期时长Duration.ZERO为永不过期
* @param supplier 数据函数 * @param supplier 数据函数
*
* @return 数据值 * @return 数据值
*/ */
@Override @Override
public <T> CompletableFuture<T> remoteGetSetAsync(String hash, String key, Type type, boolean nullable, Duration expire, ThrowSupplier<CompletableFuture<T>> supplier) { public <T> CompletableFuture<T> remoteGetSetAsync(
return getSetAsync(remoteSource::getAsync, this::remoteSetCacheAsync, hash, key, type, nullable, expire, supplier); String hash,
String key,
Type type,
boolean nullable,
Duration expire,
ThrowSupplier<CompletableFuture<T>> supplier) {
return getSetAsync(
remoteSource::getAsync, this::remoteSetCacheAsync, hash, key, type, nullable, expire, supplier);
} }
/** /**
* 远程缓存数据 * 远程缓存数据
* *
* @param <T> 泛型 * @param <T> 泛型
* @param hash 缓存hash * @param hash 缓存hash
* @param key 缓存键 * @param key 缓存键
* @param type 数据类型 * @param type 数据类型
* @param value 数据值 * @param value 数据值
* @param expire 过期时长Duration.ZERO为永不过期 * @param expire 过期时长Duration.ZERO为永不过期
*/ */
@Override @Override
@@ -294,11 +311,11 @@ public class CacheManagerService implements CacheManager, Service {
/** /**
* 远程异步缓存数据 * 远程异步缓存数据
* *
* @param <T> 泛型 * @param <T> 泛型
* @param hash 缓存hash * @param hash 缓存hash
* @param key 缓存键 * @param key 缓存键
* @param type 数据类型 * @param type 数据类型
* @param value 数据值 * @param value 数据值
* @param expire 过期时长Duration.ZERO为永不过期 * @param expire 过期时长Duration.ZERO为永不过期
*/ */
@Override @Override
@@ -310,8 +327,7 @@ public class CacheManagerService implements CacheManager, Service {
* 远程删除缓存数据 * 远程删除缓存数据
* *
* @param hash 缓存hash * @param hash 缓存hash
* @param key 缓存键 * @param key 缓存键
*
* @return 删除数量 * @return 删除数量
*/ */
@Override @Override
@@ -324,8 +340,7 @@ public class CacheManagerService implements CacheManager, Service {
* 远程异步删除缓存数据 * 远程异步删除缓存数据
* *
* @param hash 缓存hash * @param hash 缓存hash
* @param key 缓存键 * @param key 缓存键
*
* @return 删除数量 * @return 删除数量
*/ */
@Override @Override
@@ -334,15 +349,14 @@ public class CacheManagerService implements CacheManager, Service {
return remoteSource.delAsync(idFor(hash, key)); return remoteSource.delAsync(idFor(hash, key));
} }
//-------------------------------------- both缓存 -------------------------------------- // -------------------------------------- both缓存 --------------------------------------
/** /**
* 远程获取缓存数据, 过期返回null * 远程获取缓存数据, 过期返回null
* *
* @param <T> 泛型 * @param <T> 泛型
* @param hash 缓存hash * @param hash 缓存hash
* @param key 缓存键 * @param key 缓存键
* @param type 数据类型 * @param type 数据类型
*
* @return 数据值 * @return 数据值
*/ */
@Override @Override
@@ -353,11 +367,10 @@ public class CacheManagerService implements CacheManager, Service {
/** /**
* 远程异步获取缓存数据, 过期返回null * 远程异步获取缓存数据, 过期返回null
* *
* @param <T> 泛型 * @param <T> 泛型
* @param hash 缓存hash * @param hash 缓存hash
* @param key 缓存键 * @param key 缓存键
* @param type 数据类型 * @param type 数据类型
*
* @return 数据值 * @return 数据值
*/ */
@Override @Override
@@ -368,21 +381,25 @@ public class CacheManagerService implements CacheManager, Service {
/** /**
* 远程获取缓存数据, 过期返回null * 远程获取缓存数据, 过期返回null
* *
* @param <T> 泛型 * @param <T> 泛型
* @param hash 缓存hash * @param hash 缓存hash
* @param key 缓存键 * @param key 缓存键
* @param type 数据类型 * @param type 数据类型
* * @param nullable 是否缓存null值
* @param nullable 是否缓存null值 * @param localExpire 本地过期时长Duration.ZERO为永不过期为null表示不本地缓存
* @param localExpire 本地过期时长Duration.ZERO为永不过期为null表示不本地缓存
* @param remoteExpire 远程过期时长Duration.ZERO为永不过期为null表示不远程缓存 * @param remoteExpire 远程过期时长Duration.ZERO为永不过期为null表示不远程缓存
* @param supplier 数据函数 * @param supplier 数据函数
*
* @return 数据值 * @return 数据值
*/ */
@Override @Override
public <T> T bothGetSet(final String hash, final String key, final Type type, boolean nullable, public <T> T bothGetSet(
Duration localExpire, Duration remoteExpire, ThrowSupplier<T> supplier) { final String hash,
final String key,
final Type type,
boolean nullable,
Duration localExpire,
Duration remoteExpire,
ThrowSupplier<T> supplier) {
if (!enabled) { if (!enabled) {
try { try {
return supplier.get(); return supplier.get();
@@ -392,39 +409,52 @@ public class CacheManagerService implements CacheManager, Service {
throw new RedkaleException(t); throw new RedkaleException(t);
} }
} }
if (remoteExpire == null) { //只有本地缓存 if (remoteExpire == null) { // 只有本地缓存
Objects.requireNonNull(localExpire); Objects.requireNonNull(localExpire);
return localGetSet(hash, key, type, nullable, localExpire, supplier); return localGetSet(hash, key, type, nullable, localExpire, supplier);
} }
if (localExpire == null) { //只有远程缓存 if (localExpire == null) { // 只有远程缓存
Objects.requireNonNull(remoteExpire); Objects.requireNonNull(remoteExpire);
return remoteGetSet(hash, key, type, nullable, remoteExpire, supplier); return remoteGetSet(hash, key, type, nullable, remoteExpire, supplier);
} }
return getSet(this::bothGetCache, (i, e, t, v) -> { return getSet(
localSetCache(i, localExpire, t, v); this::bothGetCache,
if (remoteSource != null) { (i, e, t, v) -> {
remoteSetCache(i, remoteExpire, t, v); localSetCache(i, localExpire, t, v);
} if (remoteSource != null) {
}, hash, key, type, nullable, localExpire, supplier); remoteSetCache(i, remoteExpire, t, v);
}
},
hash,
key,
type,
nullable,
localExpire,
supplier);
} }
/** /**
* 远程异步获取缓存数据, 过期返回null * 远程异步获取缓存数据, 过期返回null
* *
* @param <T> 泛型 * @param <T> 泛型
* @param hash 缓存hash * @param hash 缓存hash
* @param key 缓存键 * @param key 缓存键
* @param type 数据类型 * @param type 数据类型
* @param nullable 是否缓存null值 * @param nullable 是否缓存null值
* @param localExpire 本地过期时长Duration.ZERO为永不过期为null表示不本地缓存 * @param localExpire 本地过期时长Duration.ZERO为永不过期为null表示不本地缓存
* @param remoteExpire 远程过期时长Duration.ZERO为永不过期为null表示不远程缓存 * @param remoteExpire 远程过期时长Duration.ZERO为永不过期为null表示不远程缓存
* @param supplier 数据函数 * @param supplier 数据函数
*
* @return 数据值 * @return 数据值
*/ */
@Override @Override
public <T> CompletableFuture<T> bothGetSetAsync(String hash, String key, Type type, boolean nullable, public <T> CompletableFuture<T> bothGetSetAsync(
Duration localExpire, Duration remoteExpire, ThrowSupplier<CompletableFuture<T>> supplier) { String hash,
String key,
Type type,
boolean nullable,
Duration localExpire,
Duration remoteExpire,
ThrowSupplier<CompletableFuture<T>> supplier) {
if (!enabled) { if (!enabled) {
try { try {
return supplier.get(); return supplier.get();
@@ -432,37 +462,51 @@ public class CacheManagerService implements CacheManager, Service {
return CompletableFuture.failedFuture(t); return CompletableFuture.failedFuture(t);
} }
} }
if (remoteExpire == null) { //只有本地缓存 if (remoteExpire == null) { // 只有本地缓存
Objects.requireNonNull(localExpire); Objects.requireNonNull(localExpire);
return localGetSetAsync(hash, key, type, nullable, localExpire, supplier); return localGetSetAsync(hash, key, type, nullable, localExpire, supplier);
} }
if (localExpire == null) { //只有远程缓存 if (localExpire == null) { // 只有远程缓存
Objects.requireNonNull(remoteExpire); Objects.requireNonNull(remoteExpire);
return remoteGetSetAsync(hash, key, type, nullable, remoteExpire, supplier); return remoteGetSetAsync(hash, key, type, nullable, remoteExpire, supplier);
} }
return getSetAsync(this::bothGetCacheAsync, (i, e, t, v) -> { return getSetAsync(
localSetCache(i, localExpire, t, v); this::bothGetCacheAsync,
if (remoteSource != null) { (i, e, t, v) -> {
return remoteSetCacheAsync(i, remoteExpire, t, v); localSetCache(i, localExpire, t, v);
} else { if (remoteSource != null) {
return CompletableFuture.completedFuture(null); return remoteSetCacheAsync(i, remoteExpire, t, v);
} } else {
}, hash, key, type, nullable, localExpire, supplier); return CompletableFuture.completedFuture(null);
}
},
hash,
key,
type,
nullable,
localExpire,
supplier);
} }
/** /**
* 远程缓存数据 * 远程缓存数据
* *
* @param <T> 泛型 * @param <T> 泛型
* @param hash 缓存hash * @param hash 缓存hash
* @param key 缓存键 * @param key 缓存键
* @param type 数据类型 * @param type 数据类型
* @param value 数据值 * @param value 数据值
* @param localExpire 本地过期时长Duration.ZERO为永不过期为null表示不本地缓存 * @param localExpire 本地过期时长Duration.ZERO为永不过期为null表示不本地缓存
* @param remoteExpire 远程过期时长Duration.ZERO为永不过期为null表示不远程缓存 * @param remoteExpire 远程过期时长Duration.ZERO为永不过期为null表示不远程缓存
*/ */
@Override @Override
public <T> void bothSet(final String hash, final String key, final Type type, final T value, Duration localExpire, Duration remoteExpire) { public <T> void bothSet(
final String hash,
final String key,
final Type type,
final T value,
Duration localExpire,
Duration remoteExpire) {
checkEnable(); checkEnable();
if (localExpire != null) { if (localExpire != null) {
setCache(localSource, hash, key, type, value, localExpire); setCache(localSource, hash, key, type, value, localExpire);
@@ -475,18 +519,18 @@ public class CacheManagerService implements CacheManager, Service {
/** /**
* 远程异步缓存数据 * 远程异步缓存数据
* *
* @param <T> 泛型 * @param <T> 泛型
* @param hash 缓存hash * @param hash 缓存hash
* @param key 缓存键 * @param key 缓存键
* @param type 数据类型 * @param type 数据类型
* @param value 数据值 * @param value 数据值
* @param localExpire 本地过期时长Duration.ZERO为永不过期为null表示不本地缓存 * @param localExpire 本地过期时长Duration.ZERO为永不过期为null表示不本地缓存
* @param remoteExpire 远程过期时长Duration.ZERO为永不过期为null表示不远程缓存 * @param remoteExpire 远程过期时长Duration.ZERO为永不过期为null表示不远程缓存
*
* @return void * @return void
*/ */
@Override @Override
public <T> CompletableFuture<Void> bothSetAsync(String hash, String key, Type type, T value, Duration localExpire, Duration remoteExpire) { public <T> CompletableFuture<Void> bothSetAsync(
String hash, String key, Type type, T value, Duration localExpire, Duration remoteExpire) {
checkEnable(); checkEnable();
if (localExpire != null) { if (localExpire != null) {
setCache(localSource, hash, key, type, value, localExpire); setCache(localSource, hash, key, type, value, localExpire);
@@ -502,8 +546,7 @@ public class CacheManagerService implements CacheManager, Service {
* 远程删除缓存数据 * 远程删除缓存数据
* *
* @param hash 缓存hash * @param hash 缓存hash
* @param key 缓存键 * @param key 缓存键
*
* @return 删除数量 * @return 删除数量
*/ */
@Override @Override
@@ -522,15 +565,14 @@ public class CacheManagerService implements CacheManager, Service {
* 远程异步删除缓存数据 * 远程异步删除缓存数据
* *
* @param hash 缓存hash * @param hash 缓存hash
* @param key 缓存键 * @param key 缓存键
*
* @return 删除数量 * @return 删除数量
*/ */
@Override @Override
public CompletableFuture<Long> bothDelAsync(String hash, String key) { public CompletableFuture<Long> bothDelAsync(String hash, String key) {
checkEnable(); checkEnable();
String id = idFor(hash, key); String id = idFor(hash, key);
long v = localSource.del(id); //内存操作,无需异步 long v = localSource.del(id); // 内存操作,无需异步
if (remoteSource != null) { if (remoteSource != null) {
return remoteSource.delAsync(id); return remoteSource.delAsync(id);
} else { } else {
@@ -538,24 +580,30 @@ public class CacheManagerService implements CacheManager, Service {
} }
} }
//-------------------------------------- 内部方法 -------------------------------------- // -------------------------------------- 内部方法 --------------------------------------
/** /**
* 获取缓存数据, 过期返回null * 获取缓存数据, 过期返回null
* *
* @param <T> 泛型 * @param <T> 泛型
* @param getter 获取数据函数 * @param getter 获取数据函数
* @param setter 设置数据函数 * @param setter 设置数据函数
* @param hash 缓存hash * @param hash 缓存hash
* @param key 缓存键 * @param key 缓存键
* @param type 数据类型 * @param type 数据类型
* @param nullable 是否缓存null值 * @param nullable 是否缓存null值
* @param expire 过期时长Duration.ZERO为永不过期 * @param expire 过期时长Duration.ZERO为永不过期
* @param supplier 数据函数 * @param supplier 数据函数
*
* @return 数据值 * @return 数据值
*/ */
protected <T> T getSet(GetterFunc<CacheValue<T>> getter, SetterSyncFunc setter, protected <T> T getSet(
String hash, String key, Type type, boolean nullable, Duration expire, ThrowSupplier<T> supplier) { GetterFunc<CacheValue<T>> getter,
SetterSyncFunc setter,
String hash,
String key,
Type type,
boolean nullable,
Duration expire,
ThrowSupplier<T> supplier) {
checkEnable(); checkEnable();
Objects.requireNonNull(expire); Objects.requireNonNull(expire);
Objects.requireNonNull(supplier); Objects.requireNonNull(supplier);
@@ -594,20 +642,26 @@ public class CacheManagerService implements CacheManager, Service {
/** /**
* 异步获取缓存数据, 过期返回null * 异步获取缓存数据, 过期返回null
* *
* @param <T> 泛型 * @param <T> 泛型
* @param getter 获取数据函数 * @param getter 获取数据函数
* @param setter 设置数据函数 * @param setter 设置数据函数
* @param hash 缓存hash * @param hash 缓存hash
* @param key 缓存键 * @param key 缓存键
* @param type 数据类型 * @param type 数据类型
* @param nullable 是否缓存null值 * @param nullable 是否缓存null值
* @param expire 过期时长Duration.ZERO为永不过期 * @param expire 过期时长Duration.ZERO为永不过期
* @param supplier 数据函数 * @param supplier 数据函数
*
* @return 数据值 * @return 数据值
*/ */
protected <T> CompletableFuture<T> getSetAsync(GetterFunc<CompletableFuture<CacheValue<T>>> getter, SetterAsyncFunc setter, protected <T> CompletableFuture<T> getSetAsync(
String hash, String key, Type type, boolean nullable, Duration expire, ThrowSupplier<CompletableFuture<T>> supplier) { GetterFunc<CompletableFuture<CacheValue<T>>> getter,
SetterAsyncFunc setter,
String hash,
String key,
Type type,
boolean nullable,
Duration expire,
ThrowSupplier<CompletableFuture<T>> supplier) {
checkEnable(); checkEnable();
Objects.requireNonNull(supplier); Objects.requireNonNull(supplier);
final Type cacheType = loadCacheType(type); final Type cacheType = loadCacheType(type);
@@ -628,7 +682,7 @@ public class CacheManagerService implements CacheManager, Service {
CacheValue<T> cacheVal = toCacheValue(nullable, v); CacheValue<T> cacheVal = toCacheValue(nullable, v);
if (CacheValue.isValid(cacheVal)) { if (CacheValue.isValid(cacheVal)) {
setter.set(id, expire, cacheType, cacheVal) setter.set(id, expire, cacheType, cacheVal)
.whenComplete((v2, e2) -> entry.success(CacheValue.get(cacheVal))); .whenComplete((v2, e2) -> entry.success(CacheValue.get(cacheVal)));
} else { } else {
entry.success(CacheValue.get(cacheVal)); entry.success(CacheValue.get(cacheVal));
} }
@@ -641,11 +695,13 @@ public class CacheManagerService implements CacheManager, Service {
}); });
} }
protected <T> CompletableFuture<Void> localSetCacheAsync(String id, Duration expire, Type cacheType, CacheValue<T> cacheVal) { protected <T> CompletableFuture<Void> localSetCacheAsync(
String id, Duration expire, Type cacheType, CacheValue<T> cacheVal) {
return setCacheAsync(localSource, id, expire, cacheType, cacheVal); return setCacheAsync(localSource, id, expire, cacheType, cacheVal);
} }
protected <T> CompletableFuture<Void> remoteSetCacheAsync(String id, Duration expire, Type cacheType, CacheValue<T> cacheVal) { protected <T> CompletableFuture<Void> remoteSetCacheAsync(
String id, Duration expire, Type cacheType, CacheValue<T> cacheVal) {
return setCacheAsync(remoteSource, id, expire, cacheType, cacheVal); return setCacheAsync(remoteSource, id, expire, cacheType, cacheVal);
} }
@@ -657,7 +713,8 @@ public class CacheManagerService implements CacheManager, Service {
setCache(remoteSource, id, expire, cacheType, cacheVal); setCache(remoteSource, id, expire, cacheType, cacheVal);
} }
protected <T> void setCache(CacheSource source, String id, Duration expire, Type cacheType, CacheValue<T> cacheVal) { protected <T> void setCache(
CacheSource source, String id, Duration expire, Type cacheType, CacheValue<T> cacheVal) {
checkEnable(); checkEnable();
Objects.requireNonNull(expire); Objects.requireNonNull(expire);
long millis = expire.toMillis(); long millis = expire.toMillis();
@@ -668,7 +725,8 @@ public class CacheManagerService implements CacheManager, Service {
} }
} }
protected <T> CompletableFuture<Void> setCacheAsync(CacheSource source, String id, Duration expire, Type cacheType, CacheValue<T> cacheVal) { protected <T> CompletableFuture<Void> setCacheAsync(
CacheSource source, String id, Duration expire, Type cacheType, CacheValue<T> cacheVal) {
checkEnable(); checkEnable();
Objects.requireNonNull(expire); Objects.requireNonNull(expire);
long millis = expire.toMillis(); long millis = expire.toMillis();
@@ -683,7 +741,8 @@ public class CacheManagerService implements CacheManager, Service {
setCache(source, idFor(hash, key), expire, loadCacheType(type, value), CacheValue.create(value)); setCache(source, idFor(hash, key), expire, loadCacheType(type, value), CacheValue.create(value));
} }
protected <T> CompletableFuture<Void> setCacheAsync(CacheSource source, String hash, String key, Type type, T value, Duration expire) { protected <T> CompletableFuture<Void> setCacheAsync(
CacheSource source, String hash, String key, Type type, T value, Duration expire) {
return setCacheAsync(source, idFor(hash, key), expire, loadCacheType(type, value), CacheValue.create(value)); return setCacheAsync(source, idFor(hash, key), expire, loadCacheType(type, value), CacheValue.create(value));
} }
@@ -694,14 +753,14 @@ public class CacheManagerService implements CacheManager, Service {
/** /**
* 远程异步获取缓存数据, 过期返回null * 远程异步获取缓存数据, 过期返回null
* *
* @param <T> 泛型 * @param <T> 泛型
* @param hash 缓存hash * @param hash 缓存hash
* @param key 缓存键 * @param key 缓存键
* @param type 数据类型 * @param type 数据类型
*
* @return 数据值 * @return 数据值
*/ */
protected <T> CompletableFuture<CacheValue<T>> bothGetCacheAsync(final String hash, final String key, final Type type) { protected <T> CompletableFuture<CacheValue<T>> bothGetCacheAsync(
final String hash, final String key, final Type type) {
return bothGetCacheAsync(idFor(hash, key), loadCacheType(type)); return bothGetCacheAsync(idFor(hash, key), loadCacheType(type));
} }
@@ -721,15 +780,14 @@ public class CacheManagerService implements CacheManager, Service {
/** /**
* 远程异步获取缓存数据, 过期返回null * 远程异步获取缓存数据, 过期返回null
* *
* @param <T> 泛型 * @param <T> 泛型
* @param id 缓存键 * @param id 缓存键
* @param cacheType 数据类型 * @param cacheType 数据类型
*
* @return 数据值 * @return 数据值
*/ */
protected <T> CompletableFuture<CacheValue<T>> bothGetCacheAsync(final String id, final Type cacheType) { protected <T> CompletableFuture<CacheValue<T>> bothGetCacheAsync(final String id, final Type cacheType) {
checkEnable(); checkEnable();
CacheValue<T> val = localSource.get(id, cacheType); //内存操作,无需异步 CacheValue<T> val = localSource.get(id, cacheType); // 内存操作,无需异步
if (CacheValue.isValid(val)) { if (CacheValue.isValid(val)) {
return CompletableFuture.completedFuture(val); return CompletableFuture.completedFuture(val);
} }
@@ -750,8 +808,7 @@ public class CacheManagerService implements CacheManager, Service {
* 创建一个锁key * 创建一个锁key
* *
* @param hash 缓存hash * @param hash 缓存hash
* @param key 缓存键 * @param key 缓存键
*
* @return key * @return key
*/ */
protected String idFor(String hash, String key) { protected String idFor(String hash, String key) {
@@ -761,10 +818,9 @@ public class CacheManagerService implements CacheManager, Service {
/** /**
* 将原始数据函数转换成获取CacheValue数据函数 * 将原始数据函数转换成获取CacheValue数据函数
* *
* @param <T> 泛型 * @param <T> 泛型
* @param nullable 是否缓存null值 * @param nullable 是否缓存null值
* @param value 缓存值 * @param value 缓存值
*
* @return CacheValue函数 * @return CacheValue函数
*/ */
protected <T> CacheValue<T> toCacheValue(boolean nullable, T value) { protected <T> CacheValue<T> toCacheValue(boolean nullable, T value) {
@@ -777,10 +833,9 @@ public class CacheManagerService implements CacheManager, Service {
/** /**
* 将原始数据函数转换成获取CacheValue数据函数 * 将原始数据函数转换成获取CacheValue数据函数
* *
* @param <T> 泛型 * @param <T> 泛型
* @param nullable 是否缓存null值 * @param nullable 是否缓存null值
* @param supplier 数据函数 * @param supplier 数据函数
*
* @return CacheValue函数 * @return CacheValue函数
*/ */
protected <T> ThrowSupplier<CacheValue<T>> toCacheSupplier(boolean nullable, ThrowSupplier<T> supplier) { protected <T> ThrowSupplier<CacheValue<T>> toCacheSupplier(boolean nullable, ThrowSupplier<T> supplier) {
@@ -790,9 +845,8 @@ public class CacheManagerService implements CacheManager, Service {
/** /**
* 创建数据类型创建对应CacheValue泛型 * 创建数据类型创建对应CacheValue泛型
* *
* @param type 数据类型为null则取value的类型 * @param type 数据类型为null则取value的类型
* @param value 数据值 * @param value 数据值
*
* @return CacheValue泛型 * @return CacheValue泛型
*/ */
protected Type loadCacheType(Type type, final Object value) { protected Type loadCacheType(Type type, final Object value) {
@@ -803,11 +857,11 @@ public class CacheManagerService implements CacheManager, Service {
* 创建数据类型创建对应CacheValue泛型 * 创建数据类型创建对应CacheValue泛型
* *
* @param type 数据类型 * @param type 数据类型
*
* @return CacheValue泛型 * @return CacheValue泛型
*/ */
protected Type loadCacheType(Type type) { protected Type loadCacheType(Type type) {
return cacheValueTypes.computeIfAbsent(type, t -> TypeToken.createParameterizedType(null, CacheValue.class, type)); return cacheValueTypes.computeIfAbsent(
type, t -> TypeToken.createParameterizedType(null, CacheValue.class, type));
} }
private static final Object NIL = new Object(); private static final Object NIL = new Object();
@@ -890,6 +944,5 @@ public class CacheManagerService implements CacheManager, Service {
lock.unlock(); lock.unlock();
} }
} }
} }
} }

View File

@@ -16,13 +16,10 @@ import org.redkale.util.AnyValue;
import org.redkale.util.InstanceProvider; import org.redkale.util.InstanceProvider;
import org.redkale.util.RedkaleClassLoader; import org.redkale.util.RedkaleClassLoader;
/** /** @author zhangjx */
*
* @author zhangjx
*/
public class CacheModuleEngine extends ModuleEngine { public class CacheModuleEngine extends ModuleEngine {
//全局缓存管理器 // 全局缓存管理器
private CacheManager cacheManager; private CacheManager cacheManager;
private AnyValue config; private AnyValue config;
@@ -35,10 +32,9 @@ public class CacheModuleEngine extends ModuleEngine {
* 判断模块的配置项合并策略, 返回null表示模块不识别此配置项 * 判断模块的配置项合并策略, 返回null表示模块不识别此配置项
* *
* @param path 配置项路径 * @param path 配置项路径
* @param key 配置项名称 * @param key 配置项名称
* @param val1 配置项原值 * @param val1 配置项原值
* @param val2 配置项新值 * @param val2 配置项新值
*
* @return MergeEnum * @return MergeEnum
*/ */
@Override @Override
@@ -52,9 +48,8 @@ public class CacheModuleEngine extends ModuleEngine {
/** /**
* 动态扩展类的方法 * 动态扩展类的方法
* *
* @param remote 是否远程模式 * @param remote 是否远程模式
* @param serviceClass 类 * @param serviceClass 类
*
* @return 方法动态扩展器 * @return 方法动态扩展器
*/ */
@Override @Override
@@ -62,12 +57,10 @@ public class CacheModuleEngine extends ModuleEngine {
return new CacheAsmMethodBoost(remote, serviceClass); return new CacheAsmMethodBoost(remote, serviceClass);
} }
/** /** 结束Application.init方法前被调用 */
* 结束Application.init方法前被调用
*/
@Override @Override
public void onAppPostInit() { public void onAppPostInit() {
//设置缓存管理器 // 设置缓存管理器
this.config = application.getAppConfig().getAnyValue("cache"); this.config = application.getAppConfig().getAnyValue("cache");
this.cacheManager = createManager(this.config); this.cacheManager = createManager(this.config);
if (!application.isCompileMode()) { if (!application.isCompileMode()) {
@@ -79,9 +72,7 @@ public class CacheModuleEngine extends ModuleEngine {
this.resourceFactory.register("", CacheManager.class, this.cacheManager); this.resourceFactory.register("", CacheManager.class, this.cacheManager);
} }
/** /** 进入Application.shutdown方法被调用 */
* 进入Application.shutdown方法被调用
*/
@Override @Override
public void onAppPreShutdown() { public void onAppPreShutdown() {
if (!application.isCompileMode() && this.cacheManager instanceof Service) { if (!application.isCompileMode() && this.cacheManager instanceof Service) {
@@ -90,13 +81,15 @@ public class CacheModuleEngine extends ModuleEngine {
} }
private CacheManager createManager(AnyValue conf) { private CacheManager createManager(AnyValue conf) {
Iterator<CacheManagerProvider> it = ServiceLoader.load(CacheManagerProvider.class, application.getClassLoader()).iterator(); Iterator<CacheManagerProvider> it = ServiceLoader.load(CacheManagerProvider.class, application.getClassLoader())
.iterator();
RedkaleClassLoader.putServiceLoader(CacheManagerProvider.class); RedkaleClassLoader.putServiceLoader(CacheManagerProvider.class);
List<CacheManagerProvider> providers = new ArrayList<>(); List<CacheManagerProvider> providers = new ArrayList<>();
while (it.hasNext()) { while (it.hasNext()) {
CacheManagerProvider provider = it.next(); CacheManagerProvider provider = it.next();
if (provider != null && provider.acceptsConf(conf)) { if (provider != null && provider.acceptsConf(conf)) {
RedkaleClassLoader.putReflectionPublicConstructors(provider.getClass(), provider.getClass().getName()); RedkaleClassLoader.putReflectionPublicConstructors(
provider.getClass(), provider.getClass().getName());
providers.add(provider); providers.add(provider);
} }
} }

View File

@@ -7,15 +7,12 @@ import org.redkale.convert.ConvertColumn;
import org.redkale.convert.json.JsonConvert; import org.redkale.convert.json.JsonConvert;
/** /**
*
* 内部缓存对象 * 内部缓存对象
* *
* <p> * <p>详情见: https://redkale.org
* 详情见: https://redkale.org
* *
* @author zhangjx * @author zhangjx
* @param <T> 泛型 * @param <T> 泛型
*
* @since 2.8.0 * @since 2.8.0
*/ */
public class CacheValue<T> { public class CacheValue<T> {
@@ -23,8 +20,7 @@ public class CacheValue<T> {
@ConvertColumn(index = 1) @ConvertColumn(index = 1)
private T val; private T val;
public CacheValue() { public CacheValue() {}
}
protected CacheValue(T value) { protected CacheValue(T value) {
this.val = value; this.val = value;

View File

@@ -3,20 +3,19 @@
*/ */
package org.redkale.cache.spi; package org.redkale.cache.spi;
import java.lang.annotation.Documented;
import static java.lang.annotation.ElementType.METHOD; import static java.lang.annotation.ElementType.METHOD;
import java.lang.annotation.Retention;
import static java.lang.annotation.RetentionPolicy.RUNTIME; import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target; import java.lang.annotation.Target;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import org.redkale.service.LoadMode; import org.redkale.service.LoadMode;
/** /**
* {@link org.redkale.cache.Cached}注解的动态扩展版,会多一个字段信息 * {@link org.redkale.cache.Cached}注解的动态扩展版,会多一个字段信息 用于识别方法是否已经动态处理过
* 用于识别方法是否已经动态处理过
* *
* @author zhangjx * @author zhangjx
*
* @since 2.8.0 * @since 2.8.0
*/ */
@Documented @Documented

View File

@@ -8,13 +8,11 @@ import java.util.concurrent.CompletableFuture;
/** /**
* cluster模式下的rpc client * cluster模式下的rpc client
* *
* * <p>详情见: https://redkale.org
* 详情见: https://redkale.org
* *
* @author zhangjx * @author zhangjx
* @param <R> message * @param <R> message
* @param <P> result * @param <P> result
*
* @since 2.8.0 * @since 2.8.0
*/ */
public interface ClusterRpcClient<R, P> { public interface ClusterRpcClient<R, P> {
@@ -23,7 +21,6 @@ public interface ClusterRpcClient<R, P> {
* 发送消息,需要响应 * 发送消息,需要响应
* *
* @param message 消息体 * @param message 消息体
*
* @return 应答消息 * @return 应答消息
*/ */
public CompletableFuture<P> sendMessage(final R message); public CompletableFuture<P> sendMessage(final R message);
@@ -32,9 +29,7 @@ public interface ClusterRpcClient<R, P> {
* 发送消息,无需响应 * 发送消息,无需响应
* *
* @param message 消息体 * @param message 消息体
*
* @return 应答 * @return 应答
*/ */
public CompletableFuture<Void> produceMessage(R message); public CompletableFuture<Void> produceMessage(R message);
} }

Some files were not shown because too many files have changed in this diff Show More