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")

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,9 +118,8 @@ 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>
@@ -137,18 +131,15 @@ public @interface Column {
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")
@@ -37,10 +33,9 @@ import static java.lang.annotation.RetentionPolicy.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 "";

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,12 +1,9 @@
/** /**
* <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;
@@ -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

@@ -12,11 +12,9 @@ import java.lang.annotation.*;
* 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})

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

@@ -13,7 +13,6 @@ import java.lang.annotation.*;
* &#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,17 +316,13 @@ 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) {

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,11 +60,9 @@ 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) {
@@ -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);
@@ -97,21 +94,26 @@ public abstract class AsmMethodBoost<T> {
* @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) {}
}
/** /**
* 实例对象进行操作,通常用于给动态的字段赋值 * 实例对象进行操作,通常用于给动态的字段赋值
@@ -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,7 +169,8 @@ 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();
@@ -177,7 +184,8 @@ public abstract class AsmMethodBoost<T> {
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);
} }
} }
} }
@@ -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,7 +369,8 @@ 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;
} }
@@ -368,7 +395,8 @@ 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))
.accept(new MethodParamClassVisitor(Opcodes.ASM6, clazz, map), 0);
} catch (Exception e) { // 无需理会 } catch (Exception e) { // 无需理会
} }
Class superClass = clazz.getSuperclass(); Class superClass = clazz.getSuperclass();

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
* the length of the bytecode of the method corresponding to
* these code attributes, or &#60;tt&#62;null&#60;/tt&#62; if these attributes
* are not code attributes.
* @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. * attributes are not code attributes.
* @return the size of all the attributes in this attribute list. This size * @param maxLocals the maximum number of local variables of the method corresponding to these code attributes, or
* includes the size of the attribute headers. * -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
* the length of the bytecode of the method corresponding to
* these code attributes, or &#60;tt&#62;null&#60;/tt&#62; if these attributes
* are not code attributes.
* @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. * attributes are not code attributes.
* @param out * @param maxLocals the maximum number of local variables of the method corresponding to these code attributes, or
* where the attributes must be written. * -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
// removed.
// see also changes in ClassReader.accept. // 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");
} }
@@ -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) {
@@ -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.
* May be &#60;tt&#62;null&#60;/tt&#62;.
* @param debug
* additional debug information to compute the correspondance
* between source and compiled elements of the class. May be
* &#60;tt&#62;null&#60;/tt&#62;. * &#60;tt&#62;null&#60;/tt&#62;.
* @param debug 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;
@@ -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);
} }
} }

View File

@@ -118,20 +118,13 @@ class Frame {
* and STACK type kinds). * and STACK type kinds).
*/ */
/** /** Mask to get the dimension of a frame type. This dimension is a signed integer between -8 and 7. */
* Mask to get the dimension of a frame type. This dimension is a signed
* integer between -8 and 7.
*/
static final int DIM = 0xF0000000; static final int DIM = 0xF0000000;
/** /** Constant to be added to a type to get a type with one more dimension. */
* Constant to be added to a type to get a type with one more dimension.
*/
static final int ARRAY_OF = 0x10000000; static final int ARRAY_OF = 0x10000000;
/** /** Constant to be added to a type to get a type with one less dimension. */
* Constant to be added to a type to get a type with one less dimension.
*/
static final int ELEMENT_OF = 0xF0000000; static final int ELEMENT_OF = 0xF0000000;
/** /**
@@ -144,125 +137,85 @@ class Frame {
static final int KIND = 0xF000000; static final int KIND = 0xF000000;
/** /**
* Flag used for LOCAL and STACK types. Indicates that if this type happens * Flag used for LOCAL and STACK types. Indicates that if this type happens to be a long or double type (during the
* to be a long or double type (during the computations of input frames), * computations of input frames), then it must be set to TOP because the second word of this value has been reused
* then it must be set to TOP because the second word of this value has been * to store other data in the basic block. Hence the first word no longer stores a valid long or double value.
* reused to store other data in the basic block. Hence the first word no
* longer stores a valid long or double value.
*/ */
static final int TOP_IF_LONG_OR_DOUBLE = 0x800000; static final int TOP_IF_LONG_OR_DOUBLE = 0x800000;
/** /** Mask to get the value of a frame type. */
* Mask to get the value of a frame type.
*/
static final int VALUE = 0x7FFFFF; static final int VALUE = 0x7FFFFF;
/** /** Mask to get the kind of base types. */
* Mask to get the kind of base types.
*/
static final int BASE_KIND = 0xFF00000; static final int BASE_KIND = 0xFF00000;
/** /** Mask to get the value of base types. */
* Mask to get the value of base types.
*/
static final int BASE_VALUE = 0xFFFFF; static final int BASE_VALUE = 0xFFFFF;
/** /** Kind of the types that are not relative to an input stack map frame. */
* Kind of the types that are not relative to an input stack map frame.
*/
static final int BASE = 0x1000000; static final int BASE = 0x1000000;
/** /** Base kind of the base reference types. The BASE_VALUE of such types is an index into the type table. */
* Base kind of the base reference types. The BASE_VALUE of such types is an
* index into the type table.
*/
static final int OBJECT = BASE | 0x700000; static final int OBJECT = BASE | 0x700000;
/** /**
* Base kind of the uninitialized base types. The BASE_VALUE of such types * Base kind of the uninitialized base types. The BASE_VALUE of such types in an index into the type table (the Item
* in an index into the type table (the Item at that index contains both an * at that index contains both an instruction offset and an internal class name).
* instruction offset and an internal class name).
*/ */
static final int UNINITIALIZED = BASE | 0x800000; static final int UNINITIALIZED = BASE | 0x800000;
/** /**
* Kind of the types that are relative to the local variable types of an * Kind of the types that are relative to the local variable types of an input stack map frame. The value of such
* input stack map frame. The value of such types is a local variable index. * types is a local variable index.
*/ */
private static final int LOCAL = 0x2000000; private static final int LOCAL = 0x2000000;
/** /**
* Kind of the types that are relative to the stack of an input stack * Kind of the types that are relative to the stack of an input stack map frame. The value of such types is a
* map frame. The value of such types is a position relatively to the top of * position relatively to the top of this stack.
* this stack.
*/ */
private static final int STACK = 0x3000000; private static final int STACK = 0x3000000;
/** /** The TOP type. This is a BASE type. */
* The TOP type. This is a BASE type.
*/
static final int TOP = BASE | 0; static final int TOP = BASE | 0;
/** /** The BOOLEAN type. This is a BASE type mainly used for array types. */
* The BOOLEAN type. This is a BASE type mainly used for array types.
*/
static final int BOOLEAN = BASE | 9; static final int BOOLEAN = BASE | 9;
/** /** The BYTE type. This is a BASE type mainly used for array types. */
* The BYTE type. This is a BASE type mainly used for array types.
*/
static final int BYTE = BASE | 10; static final int BYTE = BASE | 10;
/** /** The CHAR type. This is a BASE type mainly used for array types. */
* The CHAR type. This is a BASE type mainly used for array types.
*/
static final int CHAR = BASE | 11; static final int CHAR = BASE | 11;
/** /** The SHORT type. This is a BASE type mainly used for array types. */
* The SHORT type. This is a BASE type mainly used for array types.
*/
static final int SHORT = BASE | 12; static final int SHORT = BASE | 12;
/** /** The INTEGER type. This is a BASE type. */
* The INTEGER type. This is a BASE type.
*/
static final int INTEGER = BASE | 1; static final int INTEGER = BASE | 1;
/** /** The FLOAT type. This is a BASE type. */
* The FLOAT type. This is a BASE type.
*/
static final int FLOAT = BASE | 2; static final int FLOAT = BASE | 2;
/** /** The DOUBLE type. This is a BASE type. */
* The DOUBLE type. This is a BASE type.
*/
static final int DOUBLE = BASE | 3; static final int DOUBLE = BASE | 3;
/** /** The LONG type. This is a BASE type. */
* The LONG type. This is a BASE type.
*/
static final int LONG = BASE | 4; static final int LONG = BASE | 4;
/** /** The NULL type. This is a BASE type. */
* The NULL type. This is a BASE type.
*/
static final int NULL = BASE | 5; static final int NULL = BASE | 5;
/** /** The UNINITIALIZED_THIS type. This is a BASE type. */
* The UNINITIALIZED_THIS type. This is a BASE type.
*/
static final int UNINITIALIZED_THIS = BASE | 6; static final int UNINITIALIZED_THIS = BASE | 6;
/** /**
* The stack size variation corresponding to each JVM instruction. This * The stack size variation corresponding to each JVM instruction. This stack variation is equal to the size of the
* stack variation is equal to the size of the values produced by an * values produced by an instruction, minus the size of the values consumed by this instruction.
* instruction, minus the size of the values consumed by this instruction.
*/ */
static final int[] SIZE; static final int[] SIZE;
/** /** Computes the stack size variation corresponding to each JVM instruction. */
* Computes the stack size variation corresponding to each JVM instruction.
*/
static { static {
int i; int i;
int[] b = new int[202]; int[] b = new int[202];
@@ -489,41 +442,29 @@ class Frame {
// System.err.println(); // System.err.println();
} }
/** /** The label (i.e. basic block) to which these input and output stack map frames correspond. */
* The label (i.e. basic block) to which these input and output stack map
* frames correspond.
*/
Label owner; Label owner;
/** /** The input stack map frame locals. */
* The input stack map frame locals.
*/
int[] inputLocals; int[] inputLocals;
/** /** The input stack map frame stack. */
* The input stack map frame stack.
*/
int[] inputStack; int[] inputStack;
/** /** The output stack map frame locals. */
* The output stack map frame locals.
*/
private int[] outputLocals; private int[] outputLocals;
/** /** The output stack map frame stack. */
* The output stack map frame stack.
*/
private int[] outputStack; private int[] outputStack;
/** /**
* Relative size of the output stack. The exact semantics of this field * Relative size of the output stack. The exact semantics of this field depends on the algorithm that is used.
* depends on the algorithm that is used.
* *
* When only the maximum stack size is computed, this field is the size of * <p>When only the maximum stack size is computed, this field is the size of the output stack relatively to the top
* the output stack relatively to the top of the input stack. * of 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 actual number of types in
* actual number of types in {@link #outputStack}. * {@link #outputStack}.
*/ */
int outputStackTop; int outputStackTop;
@@ -535,45 +476,31 @@ class Frame {
private int initializationCount; private int initializationCount;
/** /**
* The types that are initialized in the basic block. A constructor * The types that are initialized in the basic block. A constructor invocation on an UNINITIALIZED or
* invocation on an UNINITIALIZED or UNINITIALIZED_THIS type must replace * UNINITIALIZED_THIS type must replace <i>every occurence</i> of this type in the local variables and in the
* <i>every occurence</i> of this type in the local variables and in the * operand stack. This cannot be done during the first phase of the algorithm since, during this phase, the local
* operand stack. This cannot be done during the first phase of the * variables and the operand stack are not completely computed. It is therefore necessary to store the types on
* algorithm since, during this phase, the local variables and the operand * which constructors are invoked in the basic block, in order to do this replacement during the second phase of the
* stack are not completely computed. It is therefore necessary to store the * algorithm, where the frames are fully computed. Note that this array can contain types that are relative to input
* types on which constructors are invoked in the basic block, in order to * locals or to the input stack (see below for the description of the algorithm).
* do this replacement during the second phase of the algorithm, where the
* frames are fully computed. Note that this array can contain types that
* are relative to input locals or to the input stack (see below for the
* description of the algorithm).
*/ */
private int[] initializations; private int[] initializations;
/** /**
* Sets this frame to the given value. * Sets this frame to the given value.
* *
* @param cw * @param cw the ClassWriter to which this label belongs.
* the ClassWriter to which this label belongs. * @param nLocal the number of local variables.
* @param nLocal * @param local the local variable types. Primitive types are represented by {@link Opcodes#TOP},
* the number of local variables. * {@link Opcodes#INTEGER}, {@link Opcodes#FLOAT}, {@link Opcodes#LONG},
* @param local * {@link Opcodes#DOUBLE},{@link Opcodes#NULL} or {@link Opcodes#UNINITIALIZED_THIS} (long and double are
* the local variable types. Primitive types are represented by * represented by a single element). Reference types are represented by String objects (representing internal
* {@link Opcodes#TOP}, {@link Opcodes#INTEGER}, * names), and uninitialized types by Label objects (this label designates the NEW instruction that created this
* {@link Opcodes#FLOAT}, {@link Opcodes#LONG}, * uninitialized value).
* {@link Opcodes#DOUBLE},{@link Opcodes#NULL} or * @param nStack the number of operand stack elements.
* {@link Opcodes#UNINITIALIZED_THIS} (long and double are * @param stack the operand stack types (same format as the "local" array).
* 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.
* @param stack
* the operand stack types (same format as the "local" array).
*/ */
final void set(ClassWriter cw, final int nLocal, final Object[] local, final void set(ClassWriter cw, final int nLocal, final Object[] local, final int nStack, final Object[] stack) {
final int nStack, final Object[] stack) {
int i = convert(cw, nLocal, local, inputLocals); int i = convert(cw, nLocal, local, inputLocals);
while (i < local.length) { while (i < local.length) {
inputLocals[i++] = TOP; inputLocals[i++] = TOP;
@@ -591,30 +518,20 @@ class Frame {
} }
/** /**
* Converts types from the MethodWriter.visitFrame() format to the Frame * Converts types from the MethodWriter.visitFrame() format to the Frame format.
* format.
* *
* @param cw * @param cw the ClassWriter to which this label belongs.
* the ClassWriter to which this label belongs. * @param nInput the number of types to convert.
* @param nInput * @param input the types to convert. Primitive types are represented by {@link Opcodes#TOP},
* the number of types to convert. * {@link Opcodes#INTEGER}, {@link Opcodes#FLOAT}, {@link Opcodes#LONG},
* @param input * {@link Opcodes#DOUBLE},{@link Opcodes#NULL} or {@link Opcodes#UNINITIALIZED_THIS} (long and double are
* the types to convert. Primitive types are represented by * represented by a single element). Reference types are represented by String objects (representing internal
* {@link Opcodes#TOP}, {@link Opcodes#INTEGER}, * names), and uninitialized types by Label objects (this label designates the NEW instruction that created this
* {@link Opcodes#FLOAT}, {@link Opcodes#LONG}, * uninitialized value).
* {@link Opcodes#DOUBLE},{@link Opcodes#NULL} or * @param output where to store the converted types.
* {@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 output
* where to store the converted types.
* @return the number of output elements. * @return the number of output elements.
*/ */
private static int convert(ClassWriter cw, int nInput, Object[] input, private static int convert(ClassWriter cw, int nInput, Object[] input, int[] output) {
int[] output) {
int i = 0; int i = 0;
for (int j = 0; j < nInput; ++j) { for (int j = 0; j < nInput; ++j) {
if (input[j] instanceof Integer) { if (input[j] instanceof Integer) {
@@ -623,25 +540,19 @@ class Frame {
output[i++] = TOP; output[i++] = TOP;
} }
} else if (input[j] instanceof String) { } else if (input[j] instanceof String) {
output[i++] = type(cw, Type.getObjectType((String) input[j]) output[i++] = type(cw, Type.getObjectType((String) input[j]).getDescriptor());
.getDescriptor());
} else { } else {
output[i++] = UNINITIALIZED output[i++] = UNINITIALIZED | cw.addUninitializedType("", ((Label) input[j]).position);
| cw.addUninitializedType("",
((Label) input[j]).position);
} }
} }
return i; return i;
} }
/** /**
* Sets this frame to the value of the given frame. WARNING: after this * Sets this frame to the value of the given frame. WARNING: after this method is called the two frames share the
* method is called the two frames share the same data structures. It is * same data structures. It is recommended to discard the given frame f to avoid unexpected side effects.
* recommended to discard the given frame f to avoid unexpected side
* effects.
* *
* @param f * @param f The new frame value.
* The new frame value.
*/ */
final void set(final Frame f) { final void set(final Frame f) {
inputLocals = f.inputLocals; inputLocals = f.inputLocals;
@@ -656,8 +567,7 @@ class Frame {
/** /**
* Returns the output frame local variable type at the given index. * Returns the output frame local variable type at the given index.
* *
* @param local * @param local the index of the local that must be returned.
* the index of the local that must be returned.
* @return the output frame local variable type at the given index. * @return the output frame local variable type at the given index.
*/ */
private int get(final int local) { private int get(final int local) {
@@ -679,10 +589,8 @@ class Frame {
/** /**
* Sets the output frame local variable type at the given index. * Sets the output frame local variable type at the given index.
* *
* @param local * @param local the index of the local that must be set.
* the index of the local that must be set. * @param type the value of the local that must be set.
* @param type
* the value of the local that must be set.
*/ */
private void set(final int local, final int type) { private void set(final int local, final int type) {
// creates and/or resizes the output local variables array if necessary // creates and/or resizes the output local variables array if necessary
@@ -702,8 +610,7 @@ class Frame {
/** /**
* Pushes a new type onto the output frame stack. * Pushes a new type onto the output frame stack.
* *
* @param type * @param type the type that must be pushed.
* the type that must be pushed.
*/ */
private void push(final int type) { private void push(final int type) {
// creates and/or resizes the output stack array if necessary // creates and/or resizes the output stack array if necessary
@@ -728,12 +635,9 @@ class Frame {
/** /**
* Pushes a new type onto the output frame stack. * Pushes a new type onto the output frame stack.
* *
* @param cw * @param cw the ClassWriter to which this label belongs.
* the ClassWriter to which this label belongs. * @param desc the descriptor of the type to be pushed. Can also be a method descriptor (in this case this method
* @param desc * pushes its return type onto the output frame stack).
* the descriptor of the type to be pushed. Can also be a method
* descriptor (in this case this method pushes its return type
* onto the output frame stack).
*/ */
private void push(final ClassWriter cw, final String desc) { private void push(final ClassWriter cw, final String desc) {
int type = type(cw, desc); int type = type(cw, desc);
@@ -748,10 +652,8 @@ class Frame {
/** /**
* Returns the int encoding of the given type. * Returns the int encoding of the given type.
* *
* @param cw * @param cw the ClassWriter to which this label belongs.
* the ClassWriter to which this label belongs. * @param desc a type descriptor.
* @param desc
* a type descriptor.
* @return the int encoding of the given type. * @return the int encoding of the given type.
*/ */
static int type(final ClassWriter cw, final String desc) { static int type(final ClassWriter cw, final String desc) {
@@ -836,8 +738,7 @@ class Frame {
/** /**
* Pops the given number of types from the output frame stack. * Pops the given number of types from the output frame stack.
* *
* @param elements * @param elements the number of types that must be popped.
* the number of types that must be popped.
*/ */
private void pop(final int elements) { private void pop(final int elements) {
if (outputStackTop >= elements) { if (outputStackTop >= elements) {
@@ -854,10 +755,8 @@ class Frame {
/** /**
* Pops a type from the output frame stack. * Pops a type from the output frame stack.
* *
* @param desc * @param desc the descriptor of the type to be popped. Can also be a method descriptor (in this case this method
* the descriptor of the type to be popped. Can also be a method * pops the types corresponding to the method arguments).
* descriptor (in this case this method pops the types
* corresponding to the method arguments).
*/ */
private void pop(final String desc) { private void pop(final String desc) {
char c = desc.charAt(0); char c = desc.charAt(0);
@@ -871,11 +770,9 @@ class Frame {
} }
/** /**
* Adds a new type to the list of types on which a constructor is invoked in * Adds a new type to the list of types on which a constructor is invoked in the basic block.
* the basic block.
* *
* @param var * @param var a type on a which a constructor is invoked.
* a type on a which a constructor is invoked.
*/ */
private void init(final int var) { private void init(final int var) {
// creates and/or resizes the initializations array if necessary // creates and/or resizes the initializations array if necessary
@@ -893,15 +790,13 @@ class Frame {
} }
/** /**
* Replaces the given type with the appropriate type if it is one of the * Replaces the given type with the appropriate type if it is one of the types on which a constructor is invoked in
* types on which a constructor is invoked in the basic block. * the basic block.
* *
* @param cw * @param cw the ClassWriter to which this label belongs.
* the ClassWriter to which this label belongs. * @param t a type
* @param t * @return t or, if t is one of the types on which a constructor is invoked in the basic block, the type
* a type * corresponding to this constructor.
* @return t or, if t is one of the types on which a constructor is invoked
* in the basic block, the type corresponding to this constructor.
*/ */
private int init(final ClassWriter cw, final int t) { private int init(final ClassWriter cw, final int t) {
int s; int s;
@@ -930,20 +825,14 @@ class Frame {
} }
/** /**
* Initializes the input frame of the first basic block from the method * Initializes the input frame of the first basic block from the method descriptor.
* descriptor.
* *
* @param cw * @param cw the ClassWriter to which this label belongs.
* the ClassWriter to which this label belongs. * @param access the access flags of the method to which this label belongs.
* @param access * @param args the formal parameter types of this method.
* the access flags of the method to which this label belongs. * @param maxLocals the maximum number of local variables of this method.
* @param args
* the formal parameter types of this method.
* @param maxLocals
* the maximum number of local variables of this method.
*/ */
final void initInputFrame(final ClassWriter cw, final int access, final void initInputFrame(final ClassWriter cw, final int access, final Type[] args, final int maxLocals) {
final Type[] args, final int maxLocals) {
inputLocals = new int[maxLocals]; inputLocals = new int[maxLocals];
inputStack = new int[0]; inputStack = new int[0];
int i = 0; int i = 0;
@@ -969,17 +858,12 @@ class Frame {
/** /**
* Simulates the action of the given instruction on the output stack frame. * Simulates the action of the given instruction on the output stack frame.
* *
* @param opcode * @param opcode the opcode of the instruction.
* the opcode of the instruction. * @param arg the operand of the instruction, if any.
* @param arg * @param cw the class writer to which this label belongs.
* the operand of the instruction, if any. * @param item the operand of the instructions, if any.
* @param cw
* the class writer to which this label belongs.
* @param item
* the operand of the instructions, if any.
*/ */
void execute(final int opcode, final int arg, final ClassWriter cw, void execute(final int opcode, final int arg, final ClassWriter cw, final Item item) {
final Item item) {
int t1, t2, t3, t4; int t1, t2, t3, t4;
switch (opcode) { switch (opcode) {
case Opcodes.NOP: case Opcodes.NOP:
@@ -1308,8 +1192,7 @@ class Frame {
break; break;
case Opcodes.JSR: case Opcodes.JSR:
case Opcodes.RET: case Opcodes.RET:
throw new RuntimeException( throw new RuntimeException("JSR/RET are not supported with computeFrames option");
"JSR/RET are not supported with computeFrames option");
case Opcodes.GETSTATIC: case Opcodes.GETSTATIC:
push(cw, item.strVal3); push(cw, item.strVal3);
break; break;
@@ -1331,8 +1214,7 @@ class Frame {
pop(item.strVal3); pop(item.strVal3);
if (opcode != Opcodes.INVOKESTATIC) { if (opcode != Opcodes.INVOKESTATIC) {
t1 = pop(); t1 = pop();
if (opcode == Opcodes.INVOKESPECIAL if (opcode == Opcodes.INVOKESPECIAL && item.strVal2.charAt(0) == '<') {
&& item.strVal2.charAt(0) == '<') {
init(t1); init(t1);
} }
} }
@@ -1402,19 +1284,13 @@ class Frame {
} }
/** /**
* Merges the input frame of the given basic block with the input and output * Merges the input frame of the given basic block with the input and output frames of this basic block. Returns
* frames of this basic block. Returns &#60;tt&#62;true&#60;/tt&#62; if the input frame of * &#60;tt&#62;true&#60;/tt&#62; if the input frame of the given label has been changed by this operation.
* the given label has been changed by this operation.
* *
* @param cw * @param cw the ClassWriter to which this label belongs.
* the ClassWriter to which this label belongs. * @param frame the basic block whose input frame must be updated.
* @param frame * @param edge the kind of the {@link Edge} between this label and 'label'. See {@link Edge#info}.
* the basic block whose input frame must be updated. * @return &#60;tt&#62;true&#60;/tt&#62; if the input frame of the given label has been changed by this operation.
* @param edge
* the kind of the {@link Edge} between this label and 'label'.
* See {@link Edge#info}.
* @return &#60;tt&#62;true&#60;/tt&#62; if the input frame of the given label has been
* changed by this operation.
*/ */
final boolean merge(final ClassWriter cw, final Frame frame, final int edge) { final boolean merge(final ClassWriter cw, final Frame frame, final int edge) {
boolean changed = false; boolean changed = false;
@@ -1443,8 +1319,7 @@ class Frame {
} else { } else {
t = dim + inputStack[nStack - (s & VALUE)]; t = dim + inputStack[nStack - (s & VALUE)];
} }
if ((s & TOP_IF_LONG_OR_DOUBLE) != 0 if ((s & TOP_IF_LONG_OR_DOUBLE) != 0 && (t == LONG || t == DOUBLE)) {
&& (t == LONG || t == DOUBLE)) {
t = TOP; t = TOP;
} }
} }
@@ -1496,8 +1371,7 @@ class Frame {
} else { } else {
t = dim + inputStack[nStack - (s & VALUE)]; t = dim + inputStack[nStack - (s & VALUE)];
} }
if ((s & TOP_IF_LONG_OR_DOUBLE) != 0 if ((s & TOP_IF_LONG_OR_DOUBLE) != 0 && (t == LONG || t == DOUBLE)) {
&& (t == LONG || t == DOUBLE)) {
t = TOP; t = TOP;
} }
} }
@@ -1510,23 +1384,16 @@ class Frame {
} }
/** /**
* Merges the type at the given index in the given type array with the given * Merges the type at the given index in the given type array with the given type. Returns
* type. Returns &#60;tt&#62;true&#60;/tt&#62; if the type array has been modified by this * &#60;tt&#62;true&#60;/tt&#62; if the type array has been modified by this operation.
* operation.
* *
* @param cw * @param cw the ClassWriter to which this label belongs.
* the ClassWriter to which this label belongs. * @param t the type with which the type array element must be merged.
* @param t * @param types an array of types.
* the type with which the type array element must be merged. * @param index the index of the type that must be merged in 'types'.
* @param types * @return &#60;tt&#62;true&#60;/tt&#62; if the type array has been modified by this operation.
* an array of types.
* @param index
* the index of the type that must be merged in 'types'.
* @return &#60;tt&#62;true&#60;/tt&#62; if the type array has been modified by this
* operation.
*/ */
private static boolean merge(final ClassWriter cw, int t, private static boolean merge(final ClassWriter cw, int t, final int[] types, final int index) {
final int[] types, final int index) {
int u = types[index]; int u = types[index];
if (u == t) { if (u == t) {
// if the types are equal, merge(u,t)=u, so there is no change // if the types are equal, merge(u,t)=u, so there is no change
@@ -1555,8 +1422,7 @@ class Frame {
// if t is also a reference type, and if u and t have the // if t is also a reference type, and if u and t have the
// same dimension merge(u,t) = dim(t) | common parent of the // same dimension merge(u,t) = dim(t) | common parent of the
// element types of u and t // element types of u and t
v = (t & DIM) | OBJECT v = (t & DIM) | OBJECT | cw.getMergedType(t & BASE_VALUE, u & BASE_VALUE);
| cw.getMergedType(t & BASE_VALUE, u & BASE_VALUE);
} else { } else {
// if u and t are array types, but not with the same element // if u and t are array types, but not with the same element
// type, merge(u,t) = dim(u) - 1 | java/lang/Object // type, merge(u,t) = dim(u) - 1 | java/lang/Object
@@ -1568,12 +1434,9 @@ class Frame {
// is min(udim, tdim) | java/lang/Object, where udim is the // is min(udim, tdim) | java/lang/Object, where udim is the
// array dimension of u, minus 1 if u is an array type with a // array dimension of u, minus 1 if u is an array type with a
// primitive element type (and similarly for tdim). // primitive element type (and similarly for tdim).
int tdim = (((t & DIM) == 0 || (t & BASE_KIND) == OBJECT) ? 0 int tdim = (((t & DIM) == 0 || (t & BASE_KIND) == OBJECT) ? 0 : ELEMENT_OF) + (t & DIM);
: ELEMENT_OF) + (t & DIM); int udim = (((u & DIM) == 0 || (u & BASE_KIND) == OBJECT) ? 0 : ELEMENT_OF) + (u & DIM);
int udim = (((u & DIM) == 0 || (u & BASE_KIND) == OBJECT) ? 0 v = Math.min(tdim, udim) | OBJECT | cw.addType("java/lang/Object");
: ELEMENT_OF) + (u & DIM);
v = Math.min(tdim, udim) | OBJECT
| cw.addType("java/lang/Object");
} else { } else {
// if t is any other type, merge(u,t)=TOP // if t is any other type, merge(u,t)=TOP
v = TOP; v = TOP;

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,8 +163,7 @@ 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
@@ -203,8 +172,7 @@ public final class Handle {
} }
/** /**
* 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:

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,18 +183,13 @@ 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;
@@ -250,8 +206,7 @@ final class Item {
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:
@@ -259,39 +214,31 @@ final class Item {
// ClassWriter.IMETH: // ClassWriter.IMETH:
// ClassWriter.HANDLE_BASE + 1..9 // ClassWriter.HANDLE_BASE + 1..9
default: default:
hashCode = 0x7FFFFFFF & (type + strVal1.hashCode() hashCode = 0x7FFFFFFF & (type + strVal1.hashCode() * strVal2.hashCode() * strVal3.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,14 +247,12 @@ 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) {
@@ -331,17 +276,14 @@ final class Item {
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) return i.strVal1.equals(strVal1) && i.strVal2.equals(strVal2) && i.strVal3.equals(strVal3);
&& 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,9 +237,7 @@ 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
* the position of first byte of the bytecode instruction that
* 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. * &#60;tt&#62;false&#60;/tt&#62; if it must be stored with 2 bytes.
* @throws IllegalArgumentException * @throws IllegalArgumentException if this label has not been created by the given code writer.
* 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
*/ */
@@ -70,10 +70,7 @@ public class MethodDebugVisitor extends MethodVisitor {
} }
} }
/** /** @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,7 +137,8 @@ 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) + ");");
} }
} }
@@ -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,19 +300,12 @@ 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>
* 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}. * {@link Opcodes#T_INT} or {@link Opcodes#T_LONG}.
*/ */
public void visitIntInsn(int opcode, int operand) { public void visitIntInsn(int opcode, int operand) {
@@ -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
* CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT},
* {@link TypeReference#METHOD_INVOCATION_TYPE_ARGUMENT
* METHOD_INVOCATION_TYPE_ARGUMENT},
* {@link TypeReference#CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT
* CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT}, or
* {@link TypeReference#METHOD_REFERENCE_TYPE_ARGUMENT
* METHOD_REFERENCE_TYPE_ARGUMENT}. See {@link TypeReference}. * METHOD_REFERENCE_TYPE_ARGUMENT}. See {@link TypeReference}.
* @param typePath * @param typePath the path to the annotated type argument, wildcard bound, array element type, or static inner type
* the path to the annotated type argument, wildcard bound, array * within 'typeRef'. May be &#60;tt&#62;null&#60;/tt&#62; if the annotation targets 'typeRef' as a whole.
* element type, or static inner type within 'typeRef'. May be * @param desc the class descriptor of the annotation class.
* &#60;tt&#62;null&#60;/tt&#62; if the annotation targets 'typeRef' as a whole. * @param visible &#60;tt&#62;true&#60;/tt&#62; if the annotation is visible at runtime.
* @param desc * @return a visitor to visit the annotation values, or &#60;tt&#62;null&#60;/tt&#62; if this visitor is not
* the class descriptor of the annotation class. * interested in visiting this annotation.
* @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
* LOCAL_VARIABLE} or {@link TypeReference#RESOURCE_VARIABLE
* RESOURCE_VARIABLE}. See {@link TypeReference}. * RESOURCE_VARIABLE}. See {@link TypeReference}.
* @param typePath * @param typePath the path to the annotated type argument, wildcard bound, array element type, or static inner type
* the path to the annotated type argument, wildcard bound, array * within 'typeRef'. May be &#60;tt&#62;null&#60;/tt&#62; if the annotation targets 'typeRef' as a whole.
* element type, or static inner type within 'typeRef'. May be * @param start the fist 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 (inclusive).
* @param start * @param end the last instructions corresponding to the continuous ranges that make the scope of this local
* the fist instructions corresponding to the continuous ranges * variable (exclusive). This array must have the same size as the 'start' array.
* that make the scope of this local variable (inclusive). * @param index the local variable's index in each range. This array must have the same size as the 'start' array.
* @param end * @param desc the class descriptor of the annotation class.
* the last instructions corresponding to the continuous ranges * @param visible &#60;tt&#62;true&#60;/tt&#62; if the annotation is visible at runtime.
* that make the scope of this local variable (exclusive). This * @return a visitor to visit the annotation values, or &#60;tt&#62;null&#60;/tt&#62; if this visitor is not
* array must have the same size as the 'start' array. * interested in visiting this annotation.
* @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 * @param modules the qualified names of the modules that can access to the public classes of the exported package
* the public classes of the exported package or * or &#60;tt&#62;null&#60;/tt&#62;.
* &#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 * @param modules the qualified names of the modules that can use deep reflection to the classes of the open package
* reflection to the classes of the open package or * or &#60;tt&#62;null&#60;/tt&#62;.
* &#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,119 +59,87 @@
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
@@ -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;
} }

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) {
@@ -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();
@@ -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();
@@ -421,13 +337,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.
* 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,8 +362,7 @@ 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
@@ -474,14 +384,11 @@ 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) {
@@ -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,8 +474,7 @@ 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.
*/ */
@@ -610,10 +512,9 @@ public class Type {
} }
/** /**
* 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;
@@ -838,8 +721,7 @@ 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.
@@ -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) {
@@ -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() {

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,13 +198,9 @@ 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 #RESOURCE_VARIABLE RESOURCE_VARIABLE},
* {@link #INSTANCEOF INSTANCEOF}, {@link #NEW NEW},
* {@link #CONSTRUCTOR_REFERENCE CONSTRUCTOR_REFERENCE}, or
* {@link #METHOD_REFERENCE METHOD_REFERENCE}. * {@link #METHOD_REFERENCE METHOD_REFERENCE}.
* @return a type reference of the given sort. * @return a type reference of the given 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 * @param sort {@link #CAST CAST}, {@link #CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT
* {@link #CAST CAST}, * CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT}, {@link #METHOD_INVOCATION_TYPE_ARGUMENT
* {@link #CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT * METHOD_INVOCATION_TYPE_ARGUMENT}, {@link #CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT
* CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT}, * CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT}, or {@link #METHOD_REFERENCE_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}. * METHOD_REFERENCE_TYPE_ARGUMENT}.
* @param argIndex * @param argIndex the type argument index.
* 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,27 +294,17 @@ 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},
* {@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}. * METHOD_REFERENCE_TYPE_ARGUMENT}.
*/ */
public int getSort() { public int getSort() {
@@ -380,11 +312,9 @@ public class TypeReference {
} }
/** /**
* 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

@@ -27,24 +27,20 @@ import org.redkale.util.*;
* 继承 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全局对象
@@ -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();
@@ -181,7 +185,8 @@ public final class ApiDocCommand {
// 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
// LinkedHashMap<>();
// Class loop = rtype; // Class loop = rtype;
// do { // do {
// if (loop == null || loop.isInterface()) break; // if (loop == null || loop.isInterface()) break;
@@ -190,7 +195,9 @@ public final class ApiDocCommand {
// if (Modifier.isStatic(field.getModifiers())) continue; // if (Modifier.isStatic(field.getModifiers())) continue;
// //
// Map<String, Object> fieldmap = new LinkedHashMap<>(); // Map<String, Object> fieldmap = new LinkedHashMap<>();
// fieldmap.put("type", field.getType().isArray() ? (field.getType().getComponentType().getName() + "[]") : field.getGenericType().getTypeName()); // fieldmap.put("type", field.getType().isArray() ?
// (field.getType().getComponentType().getName() + "[]") :
// field.getGenericType().getTypeName());
// //
// Comment comment = field.getAnnotation(Comment.class); // Comment comment = field.getAnnotation(Comment.class);
// Column col = field.getAnnotation(Column.class); // Column col = field.getAnnotation(Column.class);
@@ -202,10 +209,14 @@ public final class ApiDocCommand {
// } else if (fc != null) { // } else if (fc != null) {
// fieldmap.put("comment", fc.comment()); // fieldmap.put("comment", fc.comment());
// } // }
// fieldmap.put("primary", !filter && (field.getAnnotation(Id.class) != null)); // fieldmap.put("primary", !filter &&
// fieldmap.put("updatable", (filter || col == null || col.updatable())); // (field.getAnnotation(Id.class) != null));
// if (servlet.getClass().getAnnotation(Rest.RestDyn.class) != null) { // fieldmap.put("updatable", (filter || col == null ||
// if (field.getAnnotation(RestAddress.class) != null) continue; // col.updatable()));
// if (servlet.getClass().getAnnotation(Rest.RestDyn.class)
// != null) {
// if (field.getAnnotation(RestAddress.class) != null)
// continue;
// } // }
// //
// typeMap.put(field.getName(), fieldmap); // typeMap.put(field.getName(), fieldmap);
@@ -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) {
@@ -334,9 +369,18 @@ public final class ApiDocCommand {
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);
@@ -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(
factory,
logger,
componentsMap,
TypeToken.typeToClassOrElse(member.getEncoder().getType(), Object.class), TypeToken.typeToClassOrElse(member.getEncoder().getType(), Object.class),
member.getEncoder().getType(), schemaMap, true); 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,7 +740,8 @@ 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
? ((ArrayEncoder) encodeable).getComponentEncoder()
: ((CollectionEncoder) 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 "";
@@ -681,8 +814,13 @@ 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
} }
@@ -692,10 +830,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, "{'rows':[" + val + "," + val + "]}"))); .getConvert()
.convertTo(jsonFactory
.getConvert()
.convertFrom(genericType, "{'rows':[" + val + "," + val + "]}")));
} catch (Throwable t) { } catch (Throwable t) {
// do nothing // do nothing
} }
@@ -703,7 +846,8 @@ public final class ApiDocCommand {
} 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
.getConvert()
.convertTo(jsonFactory.getConvert().convertFrom(genericType, "[" + val + "," + val + "]"))); .convertTo(jsonFactory.getConvert().convertFrom(genericType, "[" + val + "," + val + "]")));
} catch (Throwable t) { } catch (Throwable t) {
// do nothing // do nothing
@@ -713,9 +857,12 @@ 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
.getConvert()
.convertTo(jsonFactory.getConvert().convertFrom(genericType, "[" + val + "," + val + "]"))); .convertTo(jsonFactory.getConvert().convertFrom(genericType, "[" + val + "," + val + "]")));
} catch (Throwable t) { } catch (Throwable t) {
// do nothing // do nothing
@@ -726,9 +873,12 @@ 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
.getConvert()
.convertTo(jsonFactory.getConvert().convertFrom(genericType, "{'result':" + val + "}"))); .convertTo(jsonFactory.getConvert().convertFrom(genericType, "{'result':" + val + "}")));
} catch (Throwable t) { } catch (Throwable t) {
// do nothing // do nothing
@@ -765,5 +915,4 @@ public final class ApiDocCommand {
} }
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;
@@ -113,9 +114,7 @@ class AppConfig {
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);
@@ -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,14 +176,13 @@ 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()
? Utility.localInetAddress()
: new InetSocketAddress(localaddr, config.getIntValue("port")).getAddress(); : 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) -> {
@@ -207,11 +207,13 @@ class AppConfig {
} }
} }
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;
} }
@@ -240,9 +242,7 @@ class AppConfig {
} }
} }
/** /** 读取本地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");
@@ -272,7 +272,8 @@ 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);
@@ -284,9 +285,7 @@ class AppConfig {
} }
} }
/** /** 读取本地日志配置 */
* 读取本地日志配置
*/
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,8 +350,10 @@ 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;
@@ -374,7 +382,10 @@ class AppConfig {
} 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;
} }
} }
@@ -395,7 +406,10 @@ class AppConfig {
} 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) {
@@ -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) {
@@ -478,5 +491,4 @@ class AppConfig {
return file; return file;
} }
} }
} }

View File

@@ -50,8 +50,8 @@ import org.redkale.util.*;
import org.redkale.watch.WatchServlet; import org.redkale.watch.WatchServlet;
/** /**
*
* 进程启动类,全局对象。 <br> * 进程启动类,全局对象。 <br>
*
* <pre> * <pre>
* 程序启动执行步骤: * 程序启动执行步骤:
* 1、读取application.xml * 1、读取application.xml
@@ -59,26 +59,20 @@ import org.redkale.watch.WatchServlet;
* 3、优先加载所有SNCP协议的服务再加载其他协议服务 最后加载WATCH协议的服务 * 3、优先加载所有SNCP协议的服务再加载其他协议服务 最后加载WATCH协议的服务
* 4、最后进行Service、Servlet与其他资源之间的依赖注入 * 4、最后进行Service、Servlet与其他资源之间的依赖注入
* </pre> * </pre>
* <p> *
* 详情见: https://redkale.org * <p>详情见: https://redkale.org
* *
* @author zhangjx * @author zhangjx
*/ */
public final class Application { public final class Application {
/** /** 当前进程启动的时间, 类型: long */
* 当前进程启动的时间, 类型: long
*/
public static final String RESNAME_APP_TIME = "APP_TIME"; public static final String RESNAME_APP_TIME = "APP_TIME";
/** /** 当前进程服务的名称, 类型String */
* 当前进程服务的名称, 类型String
*/
public static final String RESNAME_APP_NAME = "APP_NAME"; public static final String RESNAME_APP_NAME = "APP_NAME";
/** /** 当前进程的根目录, 类型String、File、Path、URI */
* 当前进程的根目录, 类型String、File、Path、URI
*/
public static final String RESNAME_APP_HOME = "APP_HOME"; public static final String RESNAME_APP_HOME = "APP_HOME";
/** /**
@@ -87,14 +81,10 @@ public final class Application {
*/ */
public static final String RESNAME_APP_CONF_DIR = "APP_CONF_DIR"; public static final String RESNAME_APP_CONF_DIR = "APP_CONF_DIR";
/** /** 当前进程节点的nodeid 类型String */
* 当前进程节点的nodeid 类型String
*/
public static final String RESNAME_APP_NODEID = "APP_NODEID"; public static final String RESNAME_APP_NODEID = "APP_NODEID";
/** /** 当前进程节点的IP地址 类型InetSocketAddress、InetAddress、String */
* 当前进程节点的IP地址 类型InetSocketAddress、InetAddress、String
*/
public static final String RESNAME_APP_ADDR = "APP_ADDR"; public static final String RESNAME_APP_ADDR = "APP_ADDR";
/** /**
@@ -108,28 +98,19 @@ public final class Application {
* 使用RESNAME_APP_CLIENT_IOGROUP代替 * 使用RESNAME_APP_CLIENT_IOGROUP代替
* *
* @since 2.3.0 * @since 2.3.0
*
*/ */
public static final String RESNAME_APP_CLIENT_ASYNCGROUP = "APP_CLIENT_ASYNCGROUP"; public static final String RESNAME_APP_CLIENT_ASYNCGROUP = "APP_CLIENT_ASYNCGROUP";
/** /** 当前Service所属的SNCP Server的地址 类型: SocketAddress、InetSocketAddress、String <br> */
* 当前Service所属的SNCP Server的地址 类型: SocketAddress、InetSocketAddress、String <br>
*/
public static final String RESNAME_SNCP_ADDRESS = "SNCP_ADDRESS"; public static final String RESNAME_SNCP_ADDRESS = "SNCP_ADDRESS";
/** /** 当前Service所属的SNCP Server所属的组 类型: String<br> */
* 当前Service所属的SNCP Server所属的组 类型: String<br>
*/
public static final String RESNAME_SNCP_GROUP = "SNCP_GROUP"; public static final String RESNAME_SNCP_GROUP = "SNCP_GROUP";
/** /** "SERVER_ROOT" 当前Server的ROOT目录类型String、File、Path */
* "SERVER_ROOT" 当前Server的ROOT目录类型String、File、Path
*/
public static final String RESNAME_SERVER_ROOT = Server.RESNAME_SERVER_ROOT; public static final String RESNAME_SERVER_ROOT = Server.RESNAME_SERVER_ROOT;
/** /** 当前Server的ResourceFactory */
* 当前Server的ResourceFactory
*/
public static final String RESNAME_SERVER_RESFACTORY = "SERVER_RESFACTORY"; public static final String RESNAME_SERVER_RESFACTORY = "SERVER_RESFACTORY";
public static final String SYSNAME_APP_NAME = "redkale.application.name"; public static final String SYSNAME_APP_NAME = "redkale.application.name";
@@ -146,8 +127,7 @@ public final class Application {
RESNAME_APP_TIME, RESNAME_APP_TIME,
RESNAME_APP_HOME, RESNAME_APP_HOME,
RESNAME_APP_ADDR, RESNAME_APP_ADDR,
RESNAME_APP_CONF_DIR RESNAME_APP_CONF_DIR));
));
// UDP协议的ByteBuffer Capacity // UDP协议的ByteBuffer Capacity
private static final int UDP_CAPACITY = 1024; private static final int UDP_CAPACITY = 1024;
@@ -242,8 +222,7 @@ public final class Application {
* 3、日志配置初始化 <br> * 3、日志配置初始化 <br>
* 4、本地和远程配置文件读取 <br> * 4、本地和远程配置文件读取 <br>
* 5、ClusterAgent和MessageAgent实例化 <br> * 5、ClusterAgent和MessageAgent实例化 <br>
* 6、Work线程池初始化 * 6、Work线程池初始化 7、原生sql解析器初始化 <br>
* 7、原生sql解析器初始化 <br>
* *
* @param singletonMode 是否测试模式 * @param singletonMode 是否测试模式
* @param compileMode 是否编译模式 * @param compileMode 是否编译模式
@@ -273,7 +252,8 @@ public final class Application {
this.resourceFactory.register(RESNAME_APP_NODEID, String.class, this.nodeid); this.resourceFactory.register(RESNAME_APP_NODEID, String.class, this.nodeid);
if (Utility.isNumeric(this.nodeid)) { // 兼容旧类型 if (Utility.isNumeric(this.nodeid)) { // 兼容旧类型
this.resourceFactory.register(RESNAME_APP_NODEID, int.class, Math.abs(((Long) Long.parseLong(this.nodeid)).intValue())); this.resourceFactory.register(
RESNAME_APP_NODEID, int.class, Math.abs(((Long) Long.parseLong(this.nodeid)).intValue()));
} }
this.resourceFactory.register(RESNAME_APP_TIME, long.class, this.startTime); this.resourceFactory.register(RESNAME_APP_TIME, long.class, this.startTime);
@@ -286,7 +266,8 @@ public final class Application {
this.resourceFactory.register(RESNAME_APP_ADDR, InetSocketAddress.class, this.localAddress); this.resourceFactory.register(RESNAME_APP_ADDR, InetSocketAddress.class, this.localAddress);
this.resourceFactory.register(RESNAME_APP_ADDR, InetAddress.class, this.localAddress.getAddress()); this.resourceFactory.register(RESNAME_APP_ADDR, InetAddress.class, this.localAddress.getAddress());
this.resourceFactory.register(RESNAME_APP_ADDR, String.class, this.localAddress.getAddress().getHostAddress()); this.resourceFactory.register(
RESNAME_APP_ADDR, String.class, this.localAddress.getAddress().getHostAddress());
this.resourceFactory.register(RESNAME_APP_CONF_DIR, URI.class, this.confDir); this.resourceFactory.register(RESNAME_APP_CONF_DIR, URI.class, this.confDir);
this.resourceFactory.register(RESNAME_APP_CONF_DIR, File.class, appConfig.confFile); this.resourceFactory.register(RESNAME_APP_CONF_DIR, File.class, appConfig.confFile);
@@ -316,9 +297,12 @@ public final class Application {
this.resourceFactory.register(BsonFactory.root().getConvert()); this.resourceFactory.register(BsonFactory.root().getConvert());
this.resourceFactory.register(JsonFactory.root().getConvert()); this.resourceFactory.register(JsonFactory.root().getConvert());
this.resourceFactory.register(ProtobufFactory.root().getConvert()); this.resourceFactory.register(ProtobufFactory.root().getConvert());
this.resourceFactory.register("bsonconvert", Convert.class, BsonFactory.root().getConvert()); this.resourceFactory.register(
this.resourceFactory.register("jsonconvert", Convert.class, JsonFactory.root().getConvert()); "bsonconvert", Convert.class, BsonFactory.root().getConvert());
this.resourceFactory.register("protobufconvert", Convert.class, ProtobufFactory.root().getConvert()); this.resourceFactory.register(
"jsonconvert", Convert.class, JsonFactory.root().getConvert());
this.resourceFactory.register(
"protobufconvert", Convert.class, ProtobufFactory.root().getConvert());
// 系统内部模块组件 // 系统内部模块组件
moduleEngines.add(this.sourceModule); // 放第一很多module依赖于source moduleEngines.add(this.sourceModule); // 放第一很多module依赖于source
@@ -332,26 +316,41 @@ public final class Application {
loggingModule.reconfigLogging(true, appConfig.locaLogProperties); loggingModule.reconfigLogging(true, appConfig.locaLogProperties);
// 打印基础信息日志 // 打印基础信息日志
logger.log(Level.INFO, colorMessage(logger, 36, 1, logger.log(
"-------------------------------- Redkale " + Redkale.getDotedVersion() + " --------------------------------")); Level.INFO,
colorMessage(
logger,
36,
1,
"-------------------------------- Redkale " + Redkale.getDotedVersion()
+ " --------------------------------"));
final String confDirStr = this.confDir.toString(); final String confDirStr = this.confDir.toString();
logger.log(Level.INFO, "APP_OS = " + System.getProperty("os.name") + " " logger.log(
Level.INFO,
"APP_OS = " + System.getProperty("os.name") + " "
+ System.getProperty("os.version") + " " + System.getProperty("os.arch") + "\r\n" + System.getProperty("os.version") + " " + System.getProperty("os.arch") + "\r\n"
+ "APP_JAVA = " + System.getProperty("java.runtime.name", + "APP_JAVA = "
+ System.getProperty(
"java.runtime.name",
System.getProperty("org.graalvm.nativeimage.kind") != null ? "Nativeimage" : "") System.getProperty("org.graalvm.nativeimage.kind") != null ? "Nativeimage" : "")
+ " " + System.getProperty("java.runtime.version", + " "
System.getProperty("java.vendor.version", System.getProperty("java.vm.version"))) + "\r\n" //graalvm.nativeimage 模式下无 java.runtime.xxx 属性 + System.getProperty(
"java.runtime.version",
System.getProperty("java.vendor.version", System.getProperty("java.vm.version")))
+ "\r\n" // graalvm.nativeimage 模式下无 java.runtime.xxx 属性
+ "APP_PID = " + ProcessHandle.current().pid() + "\r\n" + "APP_PID = " + ProcessHandle.current().pid() + "\r\n"
+ RESNAME_APP_NAME + " = " + this.name + "\r\n" + RESNAME_APP_NAME + " = " + this.name + "\r\n"
+ RESNAME_APP_NODEID + " = " + this.nodeid + "\r\n" + RESNAME_APP_NODEID + " = " + this.nodeid + "\r\n"
+ "APP_LOADER = " + this.classLoader.getClass().getSimpleName() + "\r\n" + "APP_LOADER = " + this.classLoader.getClass().getSimpleName() + "\r\n"
+ RESNAME_APP_ADDR + " = " + this.localAddress.getHostString() + ":" + this.localAddress.getPort() + "\r\n" + RESNAME_APP_ADDR + " = " + this.localAddress.getHostString() + ":"
+ this.localAddress.getPort() + "\r\n"
+ RESNAME_APP_HOME + " = " + this.home.getPath().replace('\\', '/') + "\r\n" + RESNAME_APP_HOME + " = " + this.home.getPath().replace('\\', '/') + "\r\n"
+ RESNAME_APP_CONF_DIR + " = " + confDirStr.substring(confDirStr.indexOf('!') + 1)); + RESNAME_APP_CONF_DIR + " = " + confDirStr.substring(confDirStr.indexOf('!') + 1));
if (!compileMode && !(classLoader instanceof RedkaleClassLoader.RedkaleCacheClassLoader)) { if (!compileMode && !(classLoader instanceof RedkaleClassLoader.RedkaleCacheClassLoader)) {
String lib = environment.getPropertyValue(config.getValue("lib", "${APP_HOME}/libs/*").trim()); String lib = environment.getPropertyValue(
config.getValue("lib", "${APP_HOME}/libs/*").trim());
lib = Utility.isEmpty(lib) ? confDirStr : (lib + ";" + confDirStr); lib = Utility.isEmpty(lib) ? confDirStr : (lib + ";" + confDirStr);
Server.loadLib(classLoader, logger, lib.isEmpty() ? confDirStr : (lib + ";" + confDirStr)); Server.loadLib(classLoader, logger, lib.isEmpty() ? confDirStr : (lib + ";" + confDirStr));
} }
@@ -381,7 +380,13 @@ public final class Application {
this.resourceFactory.register(new ResourceTypeLoader() { this.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 {
field.set(srcObj, application); field.set(srcObj, application);
return application; return application;
@@ -404,9 +409,16 @@ public final class Application {
this.resourceFactory.register(new ResourceTypeLoader() { this.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 {
boolean serv = RESNAME_SERVER_RESFACTORY.equals(resourceName) || resourceName.equalsIgnoreCase("server"); boolean serv =
RESNAME_SERVER_RESFACTORY.equals(resourceName) || resourceName.equalsIgnoreCase("server");
ResourceFactory rs = serv ? rf : (resourceName.isEmpty() ? application.resourceFactory : null); ResourceFactory rs = serv ? rf : (resourceName.isEmpty() ? application.resourceFactory : null);
field.set(srcObj, rs); field.set(srcObj, rs);
return rs; return rs;
@@ -429,7 +441,13 @@ public final class Application {
this.resourceFactory.register(new ResourceTypeLoader() { this.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 {
NodeServer server = null; NodeServer server = null;
for (NodeServer ns : application.getNodeServers()) { for (NodeServer ns : application.getNodeServers()) {
@@ -462,7 +480,13 @@ public final class Application {
this.resourceFactory.register(new ResourceTypeLoader() { this.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 {
NodeServer server = null; NodeServer server = null;
for (NodeServer ns : application.getNodeServers()) { for (NodeServer ns : application.getNodeServers()) {
@@ -495,7 +519,13 @@ public final class Application {
this.resourceFactory.register(new ResourceTypeLoader() { this.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 {
NodeServer server = null; NodeServer server = null;
for (NodeServer ns : application.getNodeServers()) { for (NodeServer ns : application.getNodeServers()) {
@@ -530,7 +560,13 @@ public final class Application {
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 {
java.net.http.HttpClient.Builder builder = java.net.http.HttpClient.newBuilder(); java.net.http.HttpClient.Builder builder = java.net.http.HttpClient.newBuilder();
if (resourceName.endsWith(".1.1")) { if (resourceName.endsWith(".1.1")) {
@@ -558,7 +594,13 @@ public final class Application {
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 {
WebClient httpClient = WebClient.create(workExecutor, clientAsyncGroup); WebClient httpClient = WebClient.create(workExecutor, clientAsyncGroup);
field.set(srcObj, httpClient); field.set(srcObj, httpClient);
@@ -580,12 +622,19 @@ public final class Application {
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 {
ClusterAgent clusterAgent = resourceFactory.find("", ClusterAgent.class); ClusterAgent clusterAgent = resourceFactory.find("", ClusterAgent.class);
MessageAgent messageAgent = resourceFactory.find(resourceName, MessageAgent.class); MessageAgent messageAgent = resourceFactory.find(resourceName, MessageAgent.class);
if (messageAgent != null) { if (messageAgent != null) {
if (clusterAgent == null || !Objects.equals(clusterAgent.getName(), resourceName) if (clusterAgent == null
|| !Objects.equals(clusterAgent.getName(), resourceName)
|| messageAgent.isRpcFirst()) { || messageAgent.isRpcFirst()) {
HttpRpcClient rpcClient = messageAgent.getHttpRpcClient(); HttpRpcClient rpcClient = messageAgent.getHttpRpcClient();
field.set(srcObj, rpcClient); field.set(srcObj, rpcClient);
@@ -638,9 +687,7 @@ public final class Application {
} }
} }
/** /** 设置WorkExecutor */
* 设置WorkExecutor
*/
private void initWorkExecutor() { private void initWorkExecutor() {
int bufferCapacity = 32 * 1024; int bufferCapacity = 32 * 1024;
int bufferPoolSize = Utility.cpus() * 8; int bufferPoolSize = Utility.cpus() * 8;
@@ -669,7 +716,9 @@ public final class Application {
clientWorkExecutor = WorkThread.createWorkExecutor(clientThreads, "Redkale-DefaultClient-WorkThread-%s"); clientWorkExecutor = WorkThread.createWorkExecutor(clientThreads, "Redkale-DefaultClient-WorkThread-%s");
executorLog.append(", threads=").append(clientThreads).append("}"); executorLog.append(", threads=").append(clientThreads).append("}");
} }
AsyncIOGroup ioGroup = new AsyncIOGroup("Redkale-DefaultClient-IOThread-%s", clientWorkExecutor, bufferCapacity, bufferPoolSize).skipClose(true); AsyncIOGroup ioGroup = new AsyncIOGroup(
"Redkale-DefaultClient-IOThread-%s", clientWorkExecutor, bufferCapacity, bufferPoolSize)
.skipClose(true);
this.clientAsyncGroup = ioGroup.start(); this.clientAsyncGroup = ioGroup.start();
if (executorLog.length() > 0) { if (executorLog.length() > 0) {
@@ -719,7 +768,8 @@ public final class Application {
} }
RedkaleClassLoader.putReflectionDeclaredConstructors(clazz, clazz.getName()); RedkaleClassLoader.putReflectionDeclaredConstructors(clazz, clazz.getName());
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
ApplicationListener listener = (ApplicationListener) clazz.getDeclaredConstructor().newInstance(); ApplicationListener listener =
(ApplicationListener) clazz.getDeclaredConstructor().newInstance();
resourceFactory.inject(listener); resourceFactory.inject(listener);
listener.init(config); listener.init(config);
this.listeners.add(listener); this.listeners.add(listener);
@@ -728,7 +778,8 @@ public final class Application {
} }
private static String colorMessage(Logger logger, int color, int type, String msg) { private static String colorMessage(Logger logger, int color, int type, String msg) {
final boolean linux = System.getProperty("os.name").toLowerCase(Locale.ENGLISH).contains("linux"); final boolean linux =
System.getProperty("os.name").toLowerCase(Locale.ENGLISH).contains("linux");
if (linux) { // Windows PowerShell 也能正常着色 if (linux) { // Windows PowerShell 也能正常着色
boolean supported = true; boolean supported = true;
Logger l = logger; Logger l = logger;
@@ -781,7 +832,8 @@ public final class Application {
while (loop) { while (loop) {
ByteArrayOutputStream out = new ByteArrayOutputStream(); ByteArrayOutputStream out = new ByteArrayOutputStream();
SocketAddress address = readUdpData(channel, buffer, out); SocketAddress address = readUdpData(channel, buffer, out);
String[] args = JsonConvert.root().convertFrom(String[].class, out.toString(StandardCharsets.UTF_8)); String[] args =
JsonConvert.root().convertFrom(String[].class, out.toString(StandardCharsets.UTF_8));
final String cmd = args[0]; final String cmd = args[0];
String[] params = args.length == 1 ? new String[0] : Arrays.copyOfRange(args, 1, args.length); String[] params = args.length == 1 ? new String[0] : Arrays.copyOfRange(args, 1, args.length);
// 接收到命令必须要有回应, 无结果输出则回应回车换行符 // 接收到命令必须要有回应, 无结果输出则回应回车换行符
@@ -790,7 +842,11 @@ public final class Application {
long s = System.currentTimeMillis(); long s = System.currentTimeMillis();
logger.info(application.getClass().getSimpleName() + " shutdowning"); logger.info(application.getClass().getSimpleName() + " shutdowning");
application.shutdown(); application.shutdown();
sendUdpData(channel, address, buffer, "--- shutdown finish ---".getBytes(StandardCharsets.UTF_8)); sendUdpData(
channel,
address,
buffer,
"--- shutdown finish ---".getBytes(StandardCharsets.UTF_8));
long e = System.currentTimeMillis() - s; long e = System.currentTimeMillis() - s;
logger.info(application.getClass().getSimpleName() + " shutdown in " + e + " ms"); logger.info(application.getClass().getSimpleName() + " shutdown in " + e + " ms");
channel.close(); channel.close();
@@ -821,7 +877,8 @@ public final class Application {
if (o instanceof CharSequence) { if (o instanceof CharSequence) {
sb.append(o).append("\r\n"); sb.append(o).append("\r\n");
} else { } else {
sb.append(JsonConvert.root().convertTo(o)).append("\r\n"); sb.append(JsonConvert.root().convertTo(o))
.append("\r\n");
} }
} }
} }
@@ -843,7 +900,8 @@ public final class Application {
} }
// 数据包前4个字节为数据内容的长度 // 数据包前4个字节为数据内容的长度
private static void sendUdpData(final DatagramChannel channel, SocketAddress dest, ByteBuffer buffer, byte[] bytes) throws IOException { private static void sendUdpData(final DatagramChannel channel, SocketAddress dest, ByteBuffer buffer, byte[] bytes)
throws IOException {
buffer.clear(); buffer.clear();
int count = (bytes.length + 4) / UDP_CAPACITY + ((bytes.length + 4) % UDP_CAPACITY > 0 ? 1 : 0); int count = (bytes.length + 4) / UDP_CAPACITY + ((bytes.length + 4) % UDP_CAPACITY > 0 ? 1 : 0);
int start = 0; int start = 0;
@@ -871,7 +929,8 @@ public final class Application {
} }
} }
private static SocketAddress readUdpData(final DatagramChannel channel, ByteBuffer buffer, ByteArrayOutputStream out) throws IOException { private static SocketAddress readUdpData(
final DatagramChannel channel, ByteBuffer buffer, ByteArrayOutputStream out) throws IOException {
out.reset(); out.reset();
buffer.clear(); buffer.clear();
SocketAddress src = null; SocketAddress src = null;
@@ -963,27 +1022,21 @@ public final class Application {
return list.size() == 1 ? list.get(0) : AsmMethodBoost.create(remote, list); return list.size() == 1 ? list.get(0) : AsmMethodBoost.create(remote, list);
} }
/** /** 进入Application.init方法时被调用 */
* 进入Application.init方法时被调用
*/
private void onAppPreInit() { private void onAppPreInit() {
for (ModuleEngine item : moduleEngines) { for (ModuleEngine item : moduleEngines) {
item.onAppPreInit(); item.onAppPreInit();
} }
} }
/** /** 结束Application.init方法前被调用 */
* 结束Application.init方法前被调用
*/
private void onAppPostInit() { private void onAppPostInit() {
for (ModuleEngine item : moduleEngines) { for (ModuleEngine item : moduleEngines) {
item.onAppPostInit(); item.onAppPostInit();
} }
} }
/** /** 进入Application.start方法被调用 */
* 进入Application.start方法被调用
*/
private void onAppPreStart() { private void onAppPreStart() {
for (ApplicationListener listener : this.listeners) { for (ApplicationListener listener : this.listeners) {
listener.onPreStart(this); listener.onPreStart(this);
@@ -993,9 +1046,7 @@ public final class Application {
} }
} }
/** /** 结束Application.start方法前被调用 */
* 结束Application.start方法前被调用
*/
private void onAppPostStart() { private void onAppPostStart() {
for (ApplicationListener listener : this.listeners) { for (ApplicationListener listener : this.listeners) {
listener.onPostStart(this); listener.onPostStart(this);
@@ -1029,63 +1080,49 @@ public final class Application {
} }
} }
/** /** 服务全部启动前被调用 */
* 服务全部启动前被调用
*/
private void onServersPreStart() { private void onServersPreStart() {
for (ModuleEngine item : moduleEngines) { for (ModuleEngine item : moduleEngines) {
item.onServersPreStart(); item.onServersPreStart();
} }
} }
/** /** 服务全部启动后被调用 */
* 服务全部启动后被调用
*/
private void onServersPostStart() { private void onServersPostStart() {
for (ModuleEngine item : moduleEngines) { for (ModuleEngine item : moduleEngines) {
item.onServersPostStart(); item.onServersPostStart();
} }
} }
/** /** 执行Service.init方法前被调用 */
* 执行Service.init方法前被调用
*/
void onServicePreInit(Service service) { void onServicePreInit(Service service) {
for (ModuleEngine item : moduleEngines) { for (ModuleEngine item : moduleEngines) {
item.onServicePreInit(service); item.onServicePreInit(service);
} }
} }
/** /** 执行Service.init方法后被调用 */
* 执行Service.init方法后被调用
*/
void onServicePostInit(Service service) { void onServicePostInit(Service service) {
for (ModuleEngine item : moduleEngines) { for (ModuleEngine item : moduleEngines) {
item.onServicePostInit(service); item.onServicePostInit(service);
} }
} }
/** /** 执行Service.destroy方法前被调用 */
* 执行Service.destroy方法前被调用
*/
void onServicePreDestroy(Service service) { void onServicePreDestroy(Service service) {
for (ModuleEngine item : moduleEngines) { for (ModuleEngine item : moduleEngines) {
item.onServicePreDestroy(service); item.onServicePreDestroy(service);
} }
} }
/** /** 执行Service.destroy方法后被调用 */
* 执行Service.destroy方法后被调用
*/
void onServicePostDestroy(Service service) { void onServicePostDestroy(Service service) {
for (ModuleEngine item : moduleEngines) { for (ModuleEngine item : moduleEngines) {
item.onServicePostDestroy(service); item.onServicePostDestroy(service);
} }
} }
/** /** 服务全部停掉前被调用 */
* 服务全部停掉前被调用
*/
private void onServersPreStop() { private void onServersPreStop() {
for (ApplicationListener listener : listeners) { for (ApplicationListener listener : listeners) {
listener.onServersPreStop(this); listener.onServersPreStop(this);
@@ -1095,9 +1132,7 @@ public final class Application {
} }
} }
/** /** 服务全部停掉后被调用 */
* 服务全部停掉后被调用
*/
private void onServersPostStop() { private void onServersPostStop() {
for (ApplicationListener listener : listeners) { for (ApplicationListener listener : listeners) {
listener.onServersPostStop(this); listener.onServersPostStop(this);
@@ -1107,9 +1142,7 @@ public final class Application {
} }
} }
/** /** 进入Application.shutdown方法被调用 */
* 进入Application.shutdown方法被调用
*/
private void onAppPreShutdown() { private void onAppPreShutdown() {
for (ApplicationListener listener : this.listeners) { for (ApplicationListener listener : this.listeners) {
try { try {
@@ -1123,9 +1156,7 @@ public final class Application {
} }
} }
/** /** 结束Application.shutdown方法前被调用 */
* 结束Application.shutdown方法前被调用
*/
private void onAppPostShutdown() { private void onAppPostShutdown() {
for (ModuleEngine item : moduleEngines) { for (ModuleEngine item : moduleEngines) {
item.onAppPostShutdown(); item.onAppPostShutdown();
@@ -1187,8 +1218,13 @@ public final class Application {
long intms = System.currentTimeMillis() - startTime; long intms = System.currentTimeMillis() - startTime;
String ms = String.valueOf(intms); String ms = String.valueOf(intms);
int repeat = ms.length() > 7 ? 0 : (7 - ms.length()) / 2; int repeat = ms.length() > 7 ? 0 : (7 - ms.length()) / 2;
logger.info(colorMessage(logger, 36, 1, "-".repeat(repeat) + "------------------------ Redkale started in " logger.info(colorMessage(
+ ms + " ms " + (ms.length() / 2 == 0 ? " " : "") + "-".repeat(repeat) + "------------------------") + "\r\n"); logger,
36,
1,
"-".repeat(repeat) + "------------------------ Redkale started in " + ms + " ms "
+ (ms.length() / 2 == 0 ? " " : "") + "-".repeat(repeat) + "------------------------")
+ "\r\n");
LoggingBaseHandler.traceEnable = true; LoggingBaseHandler.traceEnable = true;
if (!singletonMode && !compileMode) { if (!singletonMode && !compileMode) {
@@ -1202,11 +1238,11 @@ public final class Application {
* @param <T> 泛型 * @param <T> 泛型
* @param serviceClass 指定的service类 * @param serviceClass 指定的service类
* @param extServiceClasses 需要排除的service类 * @param extServiceClasses 需要排除的service类
*
* @return Service对象 * @return Service对象
* @throws Exception 异常 * @throws Exception 异常
*/ */
public static <T extends Service> T singleton(Class<T> serviceClass, Class<? extends Service>... extServiceClasses) throws Exception { public static <T extends Service> T singleton(Class<T> serviceClass, Class<? extends Service>... extServiceClasses)
throws Exception {
return singleton("", serviceClass, extServiceClasses); return singleton("", serviceClass, extServiceClasses);
} }
@@ -1217,11 +1253,11 @@ public final class Application {
* @param name Service的资源名 * @param name Service的资源名
* @param serviceClass 指定的service类 * @param serviceClass 指定的service类
* @param extServiceClasses 需要排除的service类 * @param extServiceClasses 需要排除的service类
*
* @return Service对象 * @return Service对象
* @throws Exception 异常 * @throws Exception 异常
*/ */
public static <T extends Service> T singleton(String name, Class<T> serviceClass, Class<? extends Service>... extServiceClasses) throws Exception { public static <T extends Service> T singleton(
String name, Class<T> serviceClass, Class<? extends Service>... extServiceClasses) throws Exception {
if (serviceClass == null) { if (serviceClass == null) {
throw new IllegalArgumentException("serviceClass is null"); throw new IllegalArgumentException("serviceClass is null");
} }
@@ -1359,8 +1395,13 @@ public final class Application {
long intms = System.currentTimeMillis() - f; long intms = System.currentTimeMillis() - f;
String ms = String.valueOf(intms); String ms = String.valueOf(intms);
int repeat = ms.length() > 7 ? 0 : (7 - ms.length()) / 2; int repeat = ms.length() > 7 ? 0 : (7 - ms.length()) / 2;
logger.info(colorMessage(logger, 36, 1, "-".repeat(repeat) + "------------------------ Redkale shutdown in " logger.info(colorMessage(
+ ms + " ms " + (ms.length() / 2 == 0 ? " " : "") + "-".repeat(repeat) + "------------------------") + "\r\n" + "\r\n"); logger,
36,
1,
"-".repeat(repeat) + "------------------------ Redkale shutdown in " + ms + " ms "
+ (ms.length() / 2 == 0 ? " " : "") + "-".repeat(repeat) + "------------------------")
+ "\r\n" + "\r\n");
LoggingBaseHandler.traceEnable = true; LoggingBaseHandler.traceEnable = true;
} }
@@ -1390,8 +1431,10 @@ public final class Application {
for (final AnyValue serconf : serverConfs) { for (final AnyValue serconf : serverConfs) {
Thread thread = new Thread() { Thread thread = new Thread() {
{ {
setName("Redkale-" + serconf.getValue("protocol", "Server").toUpperCase().replaceFirst("\\..+", "") setName("Redkale-"
+ ":" + serconf.getIntValue("port") + "-Thread"); + serconf.getValue("protocol", "Server")
.toUpperCase()
.replaceFirst("\\..+", "") + ":" + serconf.getIntValue("port") + "-Thread");
this.setDaemon(true); this.setDaemon(true);
} }
@@ -1400,7 +1443,9 @@ public final class Application {
try { try {
// Thread ctd = Thread.currentThread(); // Thread ctd = Thread.currentThread();
// ctd.setContextClassLoader(new URLClassLoader(new URL[0], ctd.getContextClassLoader())); // ctd.setContextClassLoader(new URLClassLoader(new URL[0], ctd.getContextClassLoader()));
final String protocol = serconf.getValue("protocol", "").replaceFirst("\\..+", "").toUpperCase(); final String protocol = serconf.getValue("protocol", "")
.replaceFirst("\\..+", "")
.toUpperCase();
NodeServer server = null; NodeServer server = null;
if ("SNCP".equals(protocol)) { if ("SNCP".equals(protocol)) {
server = NodeSncpServer.createNodeServer(Application.this, serconf); server = NodeSncpServer.createNodeServer(Application.this, serconf);
@@ -1420,7 +1465,8 @@ public final class Application {
nodeLock.lock(); nodeLock.lock();
try { try {
if (!inited.getAndSet(true)) { // 加载自定义的协议SOCKS if (!inited.getAndSet(true)) { // 加载自定义的协议SOCKS
ClassFilter profilter = new ClassFilter(classLoader, NodeProtocol.class, NodeServer.class); ClassFilter profilter =
new ClassFilter(classLoader, NodeProtocol.class, NodeServer.class);
loadClassByFilters(profilter); loadClassByFilters(profilter);
final Set<FilterEntry<NodeServer>> entrys = profilter.getFilterEntrys(); final Set<FilterEntry<NodeServer>> entrys = profilter.getFilterEntrys();
for (FilterEntry<NodeServer> entry : entrys) { for (FilterEntry<NodeServer> entry : entrys) {
@@ -1433,7 +1479,8 @@ public final class Application {
final Class<? extends NodeServer> old = nodeClasses.get(p); final Class<? extends NodeServer> old = nodeClasses.get(p);
if (old != null && old != type) { if (old != null && old != type) {
throw new RedkaleException("Protocol(" + p + ") had NodeServer-Class(" throw new RedkaleException("Protocol(" + p + ") had NodeServer-Class("
+ old.getName() + ") but repeat NodeServer-Class(" + type.getName() + ")"); + old.getName() + ") but repeat NodeServer-Class("
+ type.getName() + ")");
} }
nodeClasses.put(p, type); nodeClasses.put(p, type);
} }
@@ -1448,7 +1495,10 @@ public final class Application {
} }
} }
if (server == null) { if (server == null) {
logger.log(Level.SEVERE, "Not found Server Class for protocol({0})", serconf.getValue("protocol")); logger.log(
Level.SEVERE,
"Not found Server Class for protocol({0})",
serconf.getValue("protocol"));
Utility.sleep(100); Utility.sleep(100);
System.exit(1); System.exit(1);
} }
@@ -1457,7 +1507,9 @@ public final class Application {
if (!singletonMode && !compileMode) { if (!singletonMode && !compileMode) {
server.start(); server.start();
} else if (compileMode) { } else if (compileMode) {
server.getServer().getDispatcherServlet().init(server.getServer().getContext(), serconf); server.getServer()
.getDispatcherServlet()
.init(server.getServer().getContext(), serconf);
} }
servers.add(server); servers.add(server);
serverCdl.countDown(); serverCdl.countDown();
@@ -1600,5 +1652,4 @@ public final class Application {
public boolean isSingletonMode() { public boolean isSingletonMode() {
return singletonMode; return singletonMode;
} }
} }

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;

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> 泛型
@@ -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(";"));
@@ -228,18 +243,27 @@ 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);
if ((expectPredicate != null && expectPredicate.test(clazzName))
|| (autoScan && auto != null && !auto.value())
|| (autoScan && auto2 != null && !auto2.value())) { // 自动扫描且被标记为@AutoLoad(false)的 || (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/")) {
@@ -248,8 +272,11 @@ public final class ClassFilter<T> {
} }
// && (!(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) {
@@ -270,7 +296,6 @@ public final class ClassFilter<T> {
* *
* @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) {
@@ -329,7 +354,6 @@ public final class ClassFilter<T> {
* @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")
@@ -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;
} }
/** /**
@@ -489,7 +512,8 @@ 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", "");
} }
@@ -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());
@@ -581,10 +603,10 @@ public final class ClassFilter<T> {
* @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;
@@ -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;
} }

View File

@@ -8,8 +8,8 @@ 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
@@ -21,23 +21,23 @@ 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\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,7 +67,8 @@ 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(
FORMATTER_FORMAT2,
log.getInstant().toEpochMilli(), log.getInstant().toEpochMilli(),
source, source,
log.getLoggerName(), log.getLoggerName(),
@@ -76,7 +77,8 @@ public abstract class LoggingBaseHandler extends Handler {
throwable, throwable,
params[0]); params[0]);
} else if (params.length == 2) { } else if (params.length == 2) {
return String.format(FORMATTER_FORMAT3, return String.format(
FORMATTER_FORMAT3,
log.getInstant().toEpochMilli(), log.getInstant().toEpochMilli(),
source, source,
log.getLoggerName(), log.getLoggerName(),
@@ -87,7 +89,8 @@ public abstract class LoggingBaseHandler extends Handler {
params[1]); params[1]);
} }
} }
return String.format(FORMATTER_FORMAT, return String.format(
FORMATTER_FORMAT,
log.getInstant().toEpochMilli(), log.getInstant().toEpochMilli(),
source, source,
log.getLoggerName(), log.getLoggerName(),
@@ -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");
@@ -134,5 +138,4 @@ public abstract class LoggingBaseHandler extends Handler {
// 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
@@ -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,14 +196,20 @@ 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);
@@ -210,7 +231,6 @@ public class LoggingFileHandler extends LoggingBaseHandler {
} }
} }
} }
} }
}.start(); }.start();
} }
@@ -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) {
@@ -377,5 +400,4 @@ public class LoggingFileHandler extends LoggingBaseHandler {
} }
} }
} }
} }

View File

@@ -22,14 +22,11 @@ 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 {
@@ -80,8 +77,10 @@ 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("%m", "%tY%tm")
.replace("%d", "%tY%tm%td") // 兼容旧时间格式
.replace(searchRawHandler, searchReadHandler)); .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 -> {
@@ -130,7 +139,10 @@ class LoggingModule extends BootModule {
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(
"handlers",
handlers.replace(
"java.util.logging.FileHandler",
application.isSingletonMode() || application.isCompileMode() ? "" : fileHandlerClass)); application.isSingletonMode() || application.isCompileMode() ? "" : fileHandlerClass));
} }
if (!prop.isEmpty()) { if (!prop.isEmpty()) {
@@ -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()) {

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
@@ -96,7 +97,6 @@ public class LoggingSearchHandler extends LoggingBaseHandler {
logList.clear(); logList.clear();
} }
} }
} }
}.start(); }.start();
} }
@@ -239,7 +239,9 @@ 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));
} }
@@ -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 {
@@ -48,7 +45,6 @@ public abstract class ModuleEngine {
* @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) {
@@ -60,40 +56,28 @@ 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
} }
@@ -117,32 +101,22 @@ public abstract class ModuleEngine {
// 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
} }
@@ -183,30 +157,22 @@ public abstract class ModuleEngine {
// 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,8 +32,7 @@ import org.redkale.watch.*;
/** /**
* HTTP Server节点的配置Server * HTTP Server节点的配置Server
* *
* <p> * <p>详情见: https://redkale.org
* 详情见: https://redkale.org
* *
* @author zhangjx * @author zhangjx
*/ */
@@ -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<>();
@@ -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);
@@ -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,14 +284,19 @@ 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(
(FilterEntry<? extends Servlet> o1,
FilterEntry<? extends Servlet>
o2) -> { // 必须保证WebSocketServlet优先加载 因为要确保其他的HttpServlet可以注入本地模式的WebSocketNode
boolean ws1 = WebSocketServlet.class.isAssignableFrom(o1.getType()); boolean ws1 = WebSocketServlet.class.isAssignableFrom(o1.getType());
boolean ws2 = WebSocketServlet.class.isAssignableFrom(o2.getType()); boolean ws2 = WebSocketServlet.class.isAssignableFrom(o2.getType());
if (ws1 == ws2) { if (ws1 == ws2) {
Priority p1 = o1.getType().getAnnotation(Priority.class); Priority p1 = o1.getType().getAnnotation(Priority.class);
Priority p2 = o2.getType().getAnnotation(Priority.class); Priority p2 = o2.getType().getAnnotation(Priority.class);
int v = (p2 == null ? 0 : p2.value()) - (p1 == null ? 0 : p1.value()); int v = (p2 == null ? 0 : p2.value()) - (p1 == null ? 0 : p1.value());
return v == 0 ? o1.getType().getName().compareTo(o2.getType().getName()) : 0; return v == 0
? o1.getType().getName().compareTo(o2.getType().getName())
: 0;
} }
return ws1 ? -1 : 1; return ws1 ? -1 : 1;
}); });
@@ -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,11 +436,15 @@ 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 List<Object> restedObjects,
final ReentrantLock restedLock,
final StringBuilder sb,
final CopyOnWriteArrayList<AbstractMap.SimpleEntry<String, String[]>> rests, final CopyOnWriteArrayList<AbstractMap.SimpleEntry<String, String[]>> rests,
final CopyOnWriteArrayList<AbstractMap.SimpleEntry<String, String[]>> webss) throws Exception { final CopyOnWriteArrayList<AbstractMap.SimpleEntry<String, String[]>> webss)
throws Exception {
if (!rest) { if (!rest) {
return; return;
} }
@@ -401,7 +464,8 @@ 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;
@@ -414,7 +478,8 @@ public class NodeHttpServer extends NodeServer {
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,7 +490,13 @@ 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()) {
@@ -457,7 +528,8 @@ public class NodeHttpServer extends NodeServer {
} 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
} }
@@ -473,11 +545,14 @@ public class NodeHttpServer extends NodeServer {
} }
// 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();
@@ -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) {
@@ -529,7 +610,8 @@ public class NodeHttpServer extends NodeServer {
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
} }
@@ -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];
} }

View File

@@ -8,15 +8,14 @@ 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
@@ -34,5 +33,4 @@ public class NodeInterceptor {
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,8 +39,7 @@ import org.redkale.util.*;
/** /**
* Server节点的初始化配置类 * Server节点的初始化配置类
* *
* * <p>详情见: https://redkale.org
* 详情见: https://redkale.org
* *
* @author zhangjx * @author zhangjx
*/ */
@@ -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,7 +141,9 @@ 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();
} }
@@ -146,7 +151,8 @@ public abstract class NodeServer {
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
@@ -154,7 +160,10 @@ public abstract class NodeServer {
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);
@@ -178,10 +187,19 @@ public abstract class NodeServer {
// 必须要进行初始化, 构建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注册依赖注入时的监听回调事件。
@@ -241,8 +259,7 @@ 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;
@@ -252,7 +269,13 @@ public abstract class NodeServer {
// --------------------- 注册 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);
} }
@@ -266,7 +289,13 @@ public abstract class NodeServer {
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; // 远程模式不得注入
@@ -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);
@@ -314,7 +354,13 @@ 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;
@@ -346,12 +392,30 @@ public abstract class NodeServer {
} 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,16 +470,27 @@ 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))
.isEmpty()
&& (serviceImplClass.getAnnotation(Priority.class) == null && (serviceImplClass.getAnnotation(Priority.class) == null
&& serviceImplClass.getAnnotation(javax.annotation.Priority.class) == null)) { //class没有可用的方法且没有标记启动优先级的 通常为BaseService && serviceImplClass.getAnnotation(javax.annotation.Priority.class)
if (!serviceImplClass.getName().startsWith("org.redkale.") && !serviceImplClass.getSimpleName().contains("Base")) { == null)) { // class没有可用的方法且没有标记启动优先级的 通常为BaseService
logger.log(Level.FINE, serviceImplClass + " cannot load because not found less one public non-final method"); 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;
} }
@@ -421,19 +505,37 @@ public abstract class NodeServer {
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);
@@ -460,7 +562,6 @@ public abstract class NodeServer {
public Type resourceType() { public Type resourceType() {
return type; return type;
} }
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@@ -493,7 +594,8 @@ 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() + ")");
@@ -516,21 +618,22 @@ public abstract class NodeServer {
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 ----------------
@@ -545,7 +648,9 @@ public abstract class NodeServer {
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()) {
@@ -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));
} }
@@ -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,21 +726,35 @@ 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());
@@ -633,11 +764,13 @@ public abstract class NodeServer {
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;
@@ -659,7 +792,8 @@ public abstract class NodeServer {
} }
// 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);
@@ -675,17 +809,17 @@ public abstract class NodeServer {
} }
// loadServlet执行之后调用 // loadServlet执行之后调用
protected void postLoadServlets() { protected void postLoadServlets() {}
}
// Service.destroy执行之前调用 // Service.destroy执行之前调用
protected void preDestroyServices(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);
} }
@@ -694,12 +828,11 @@ public abstract class NodeServer {
} }
} }
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);
@@ -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) {
@@ -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
@@ -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) {
@@ -144,7 +155,8 @@ public class NodeSncpServer extends NodeServer {
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 =
application.getResourceFactory().find(mq, MessageAgent.class);
agent.putService(this, x, servlet); agent.putService(this, x, servlet);
} }
}); });
@@ -154,12 +166,18 @@ public class NodeSncpServer extends NodeServer {
@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

View File

@@ -34,12 +34,17 @@ public class PrepareCompiler {
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);

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(
@RestUploadFile(maxLength = 10 * 1024 * 1024, fileNameRegx = "\\.jar$") byte[] jar,
@RestParam(name = "server", comment = "Server节点名") final String serverName, @RestParam(name = "server", comment = "Server节点名") final String serverName,
@RestParam(name = "type", comment = "Filter类名") final String filterType) throws IOException { @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,7 +30,8 @@ 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 = "name", comment = "Service的资源名") String name,
@RestParam(name = "type", comment = "Service的类名") String type, @RestParam(name = "type", comment = "Service的类名") String type,
@RestParam(name = "field", comment = "字段名") String field, @RestParam(name = "field", comment = "字段名") String field,
@RestParam(name = "value", comment = "字段值") String value) { @RestParam(name = "value", comment = "字段值") String value) {
@@ -80,7 +80,8 @@ 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 = "name", comment = "Service的资源名") String name,
@RestParam(name = "type", comment = "Service的类名") String type, @RestParam(name = "type", comment = "Service的类名") String type,
@RestParam(name = "field", comment = "字段名") String field) { @RestParam(name = "field", comment = "字段名") String field) {
if (name == null) { if (name == null) {
@@ -127,7 +128,8 @@ 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 = "name", comment = "Service的资源名") String name,
@RestParam(name = "type", comment = "Service的类名") String type, @RestParam(name = "type", comment = "Service的类名") String type,
@RestParam(name = "method", comment = "Service的方法名") String method, @RestParam(name = "method", comment = "Service的方法名") String method,
@RestParam(name = "params", comment = "方法的参数值") List<String> params, @RestParam(name = "params", comment = "方法的参数值") List<String> params,
@@ -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,41 +214,47 @@ 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(
@RestParam(name = "type", comment = "Service的类名") String type,
@RestUploadFile(maxLength = 10 * 1024 * 1024, fileNameRegx = "\\.jar$") byte[] jar) { @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 = "name", comment = "Service的资源名") String name,
@RestParam(name = "type", comment = "Service的类名") String type) { @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 = "name", comment = "Service的资源名") String name,
@RestParam(name = "type", comment = "Service的类名") String type) { @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 = "name", comment = "Service的资源名") String name,
@RestParam(name = "type", comment = "Service的类名") String type) { @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,18 +11,14 @@ 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";
// -------------------------------------- 本地缓存 -------------------------------------- // -------------------------------------- 本地缓存 --------------------------------------
@@ -33,7 +29,6 @@ public interface CacheManager {
* @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);
@@ -44,7 +39,6 @@ public interface CacheManager {
* @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) {
@@ -56,7 +50,6 @@ public interface CacheManager {
* *
* @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) {
@@ -84,10 +76,15 @@ public interface CacheManager {
* @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
@@ -98,10 +95,10 @@ public interface CacheManager {
* @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);
} }
@@ -115,10 +112,15 @@ public interface CacheManager {
* @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
@@ -129,10 +131,10 @@ public interface CacheManager {
* @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);
} }
@@ -189,7 +191,6 @@ 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,7 +199,6 @@ public interface CacheManager {
* 本地删除缓存数据 * 本地删除缓存数据
* *
* @param key 缓存键 * @param key 缓存键
*
* @return 删除数量 * @return 删除数量
*/ */
default long localDel(String key) { default long localDel(String key) {
@@ -213,7 +213,6 @@ public interface CacheManager {
* @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);
@@ -224,7 +223,6 @@ public interface CacheManager {
* @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) {
@@ -236,7 +234,6 @@ public interface CacheManager {
* *
* @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) {
@@ -261,7 +257,6 @@ public interface CacheManager {
* @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);
@@ -272,7 +267,6 @@ public interface CacheManager {
* @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) {
@@ -284,7 +278,6 @@ public interface CacheManager {
* *
* @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) {
@@ -312,11 +304,15 @@ public interface CacheManager {
* @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
@@ -327,11 +323,10 @@ public interface CacheManager {
* @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);
} }
@@ -345,11 +340,15 @@ public interface CacheManager {
* @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
@@ -360,11 +359,10 @@ public interface CacheManager {
* @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);
} }
@@ -425,7 +423,6 @@ public interface CacheManager {
* @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);
@@ -438,7 +435,6 @@ public interface CacheManager {
* @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) {
@@ -452,10 +448,10 @@ public interface CacheManager {
* @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);
} }
@@ -465,7 +461,6 @@ public interface CacheManager {
* @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) {
@@ -477,7 +472,6 @@ 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) {
@@ -498,7 +491,6 @@ 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,7 +499,6 @@ public interface CacheManager {
* 远程异步删除缓存数据 * 远程异步删除缓存数据
* *
* @param key 缓存键 * @param key 缓存键
*
* @return 删除数量 * @return 删除数量
*/ */
default CompletableFuture<Long> remoteDelAsync(String key) { default CompletableFuture<Long> remoteDelAsync(String key) {
@@ -522,7 +513,6 @@ public interface CacheManager {
* @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);
@@ -533,7 +523,6 @@ public interface CacheManager {
* @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) {
@@ -545,7 +534,6 @@ public interface CacheManager {
* *
* @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) {
@@ -570,7 +557,6 @@ public interface CacheManager {
* @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);
@@ -581,7 +567,6 @@ public interface CacheManager {
* @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) {
@@ -593,7 +578,6 @@ public interface CacheManager {
* *
* @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) {
@@ -622,11 +605,16 @@ public interface CacheManager {
* @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
@@ -638,11 +626,15 @@ public interface CacheManager {
* @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);
} }
@@ -657,11 +649,16 @@ public interface CacheManager {
* @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
@@ -673,11 +670,15 @@ public interface CacheManager {
* @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);
} }
@@ -692,7 +693,13 @@ public interface CacheManager {
* @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);
/** /**
* 本地和远程缓存数据 * 本地和远程缓存数据
@@ -704,7 +711,8 @@ public interface CacheManager {
* @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);
} }
@@ -717,7 +725,8 @@ public interface CacheManager {
* @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);
} }
@@ -743,10 +752,10 @@ public interface CacheManager {
* @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);
/** /**
* 本地和远程异步缓存数据 * 本地和远程异步缓存数据
@@ -757,10 +766,10 @@ public interface CacheManager {
* @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);
} }
@@ -772,10 +781,10 @@ public interface CacheManager {
* @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);
} }
@@ -786,10 +795,10 @@ public interface CacheManager {
* @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);
} }
@@ -798,7 +807,6 @@ 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) {
@@ -819,7 +826,6 @@ 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
@@ -78,8 +75,14 @@ public class CacheAction {
// 远程缓存过期时长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,8 +95,7 @@ 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());
@@ -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);
} }
} }
@@ -149,5 +153,4 @@ public class CacheAction {
+ ",\"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);
@@ -98,9 +103,9 @@ 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()))
@@ -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,13 +165,21 @@ 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[] {
"java/lang/Throwable"
});
// mv.setDebug(true); // mv.setDebug(true);
Label l0 = new Label(); Label l0 = new Label();
mv.visitLabel(l0); mv.visitLabel(l0);
@@ -172,11 +194,16 @@ public class CacheAsmMethodBoost extends AsmMethodBoost {
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;
} }
@@ -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);
} }
} }
@@ -212,5 +245,4 @@ public class CacheAsmMethodBoost extends AsmMethodBoost {
}); });
// 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

@@ -105,7 +105,6 @@ public class CacheManagerService implements CacheManager, Service {
this.remoteSource = source; this.remoteSource = source;
} }
} }
} }
@Override @Override
@@ -132,7 +131,6 @@ public class CacheManagerService implements CacheManager, Service {
* @param hash 缓存hash * @param hash 缓存hash
* @param key 缓存键 * @param key 缓存键
* @param type 数据类型 * @param type 数据类型
*
* @return 数据值 * @return 数据值
*/ */
@Override @Override
@@ -151,11 +149,16 @@ public class CacheManagerService implements CacheManager, Service {
* @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);
} }
@@ -169,12 +172,18 @@ public class CacheManagerService implements CacheManager, Service {
* @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);
} }
/** /**
@@ -197,7 +206,6 @@ public class CacheManagerService implements CacheManager, Service {
* *
* @param hash 缓存hash * @param hash 缓存hash
* @param key 缓存键 * @param key 缓存键
*
* @return 删除数量 * @return 删除数量
*/ */
@Override @Override
@@ -214,7 +222,6 @@ public class CacheManagerService implements CacheManager, Service {
* @param hash 缓存hash * @param hash 缓存hash
* @param key 缓存键 * @param key 缓存键
* @param type 数据类型 * @param type 数据类型
*
* @return 数据值 * @return 数据值
*/ */
@Override @Override
@@ -230,7 +237,6 @@ public class CacheManagerService implements CacheManager, Service {
* @param hash 缓存hash * @param hash 缓存hash
* @param key 缓存键 * @param key 缓存键
* @param type 数据类型 * @param type 数据类型
*
* @return 数据值 * @return 数据值
*/ */
@Override @Override
@@ -250,11 +256,16 @@ public class CacheManagerService implements CacheManager, Service {
* @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);
} }
@@ -268,12 +279,18 @@ public class CacheManagerService implements CacheManager, Service {
* @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);
} }
/** /**
@@ -311,7 +328,6 @@ public class CacheManagerService implements CacheManager, Service {
* *
* @param hash 缓存hash * @param hash 缓存hash
* @param key 缓存键 * @param key 缓存键
*
* @return 删除数量 * @return 删除数量
*/ */
@Override @Override
@@ -325,7 +341,6 @@ public class CacheManagerService implements CacheManager, Service {
* *
* @param hash 缓存hash * @param hash 缓存hash
* @param key 缓存键 * @param key 缓存键
*
* @return 删除数量 * @return 删除数量
*/ */
@Override @Override
@@ -342,7 +357,6 @@ public class CacheManagerService implements CacheManager, Service {
* @param hash 缓存hash * @param hash 缓存hash
* @param key 缓存键 * @param key 缓存键
* @param type 数据类型 * @param type 数据类型
*
* @return 数据值 * @return 数据值
*/ */
@Override @Override
@@ -357,7 +371,6 @@ public class CacheManagerService implements CacheManager, Service {
* @param hash 缓存hash * @param hash 缓存hash
* @param key 缓存键 * @param key 缓存键
* @param type 数据类型 * @param type 数据类型
*
* @return 数据值 * @return 数据值
*/ */
@Override @Override
@@ -372,17 +385,21 @@ public class CacheManagerService implements CacheManager, Service {
* @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();
@@ -400,12 +417,20 @@ public class CacheManagerService implements CacheManager, Service {
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(
this::bothGetCache,
(i, e, t, v) -> {
localSetCache(i, localExpire, t, v); localSetCache(i, localExpire, t, v);
if (remoteSource != null) { if (remoteSource != null) {
remoteSetCache(i, remoteExpire, t, v); remoteSetCache(i, remoteExpire, t, v);
} }
}, hash, key, type, nullable, localExpire, supplier); },
hash,
key,
type,
nullable,
localExpire,
supplier);
} }
/** /**
@@ -419,12 +444,17 @@ public class CacheManagerService implements CacheManager, Service {
* @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();
@@ -440,14 +470,22 @@ public class CacheManagerService implements CacheManager, Service {
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(
this::bothGetCacheAsync,
(i, e, t, v) -> {
localSetCache(i, localExpire, t, v); localSetCache(i, localExpire, t, v);
if (remoteSource != null) { if (remoteSource != null) {
return remoteSetCacheAsync(i, remoteExpire, t, v); return remoteSetCacheAsync(i, remoteExpire, t, v);
} else { } else {
return CompletableFuture.completedFuture(null); return CompletableFuture.completedFuture(null);
} }
}, hash, key, type, nullable, localExpire, supplier); },
hash,
key,
type,
nullable,
localExpire,
supplier);
} }
/** /**
@@ -462,7 +500,13 @@ public class CacheManagerService implements CacheManager, Service {
* @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);
@@ -482,11 +526,11 @@ public class CacheManagerService implements CacheManager, Service {
* @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);
@@ -503,7 +547,6 @@ public class CacheManagerService implements CacheManager, Service {
* *
* @param hash 缓存hash * @param hash 缓存hash
* @param key 缓存键 * @param key 缓存键
*
* @return 删除数量 * @return 删除数量
*/ */
@Override @Override
@@ -523,7 +566,6 @@ public class CacheManagerService implements CacheManager, Service {
* *
* @param hash 缓存hash * @param hash 缓存hash
* @param key 缓存键 * @param key 缓存键
*
* @return 删除数量 * @return 删除数量
*/ */
@Override @Override
@@ -551,11 +593,17 @@ public class CacheManagerService implements CacheManager, Service {
* @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);
@@ -603,11 +651,17 @@ public class CacheManagerService implements CacheManager, Service {
* @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);
@@ -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));
} }
@@ -698,10 +757,10 @@ public class CacheManagerService implements CacheManager, Service {
* @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));
} }
@@ -724,7 +783,6 @@ public class CacheManagerService implements CacheManager, Service {
* @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) {
@@ -751,7 +809,6 @@ public class CacheManagerService implements CacheManager, Service {
* *
* @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) {
@@ -764,7 +821,6 @@ public class CacheManagerService implements CacheManager, Service {
* @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) {
@@ -780,7 +836,6 @@ public class CacheManagerService implements CacheManager, Service {
* @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) {
@@ -792,7 +847,6 @@ public class CacheManagerService implements CacheManager, Service {
* *
* @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,10 +16,7 @@ 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 {
// 全局缓存管理器 // 全局缓存管理器
@@ -38,7 +35,6 @@ public class CacheModuleEngine extends ModuleEngine {
* @param key 配置项名称 * @param key 配置项名称
* @param val1 配置项原值 * @param val1 配置项原值
* @param val2 配置项新值 * @param val2 配置项新值
*
* @return MergeEnum * @return MergeEnum
*/ */
@Override @Override
@@ -54,7 +50,6 @@ public class CacheModuleEngine extends ModuleEngine {
* *
* @param remote 是否远程模式 * @param remote 是否远程模式
* @param serviceClass 类 * @param serviceClass 类
*
* @return 方法动态扩展器 * @return 方法动态扩展器
*/ */
@Override @Override
@@ -62,9 +57,7 @@ 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() {
// 设置缓存管理器 // 设置缓存管理器
@@ -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