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>
<maven-plugin.version>3.2.0</maven-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-surefire-plugin.version>3.0.0-M5</maven-surefire-plugin.version>
<maven-failsafe-plugin.version>3.0.0-M5</maven-failsafe-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-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>
<dependencies>
@@ -167,6 +169,21 @@
</executions>
</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>
</build>

21
pom.xml
View File

@@ -1,5 +1,6 @@
<?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>
<groupId>org.redkale</groupId>
<artifactId>redkale</artifactId>
@@ -19,6 +20,9 @@
<maven-compiler-plugin.version>3.9.0</maven-compiler-plugin.version>
<maven-surefire-plugin.version>3.0.0</maven-surefire-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>
<licenses>
@@ -136,6 +140,21 @@
<artifactId>maven-failsafe-plugin</artifactId>
<version>${maven-failsafe-plugin.version}</version>
</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>
</build>

View File

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

View File

@@ -9,9 +9,7 @@ import java.lang.annotation.*;
/**
* @since Common Annotations 1.0
*
* @see org.redkale.annotation.Resource
*
* @deprecated replace by {@link org.redkale.annotation.Resource}
*/
@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
* terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
* which accompanies this distribution.
* The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
* and the Eclipse Distribution License is available at
* <p>This program and the accompanying materials are made available under the terms of the Eclipse Public License v1.0
* and Eclipse Distribution License v. 1.0 which accompanies this distribution. The Eclipse Public License is available
* at http://www.eclipse.org/legal/epl-v10.html and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* Contributors:
* Linda DeMichiel - Java Persistence 2.1
* Linda DeMichiel - Java Persistence 2.0
* <p>Contributors: Linda DeMichiel - Java Persistence 2.1 Linda DeMichiel - Java Persistence 2.0
*
***************************************************************************** */
* <p>****************************************************************************
*/
package javax.persistence;
import java.lang.annotation.*;
import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.*;
/**
* Specifies whether an entity should be cached if caching is enabled
* when the value of the <code>persistence.xml</code> caching element
* is <code>ENABLE_SELECTIVE</code> or <code>DISABLE_SELECTIVE</code>.
* The value of the <code>Cacheable</code> annotation is inherited by
* subclasses; it can be overridden by specifying
* <code>Cacheable</code> on a subclass.
* Specifies whether an entity should be cached if caching is enabled when the value of the <code>persistence.xml</code>
* caching element is <code>ENABLE_SELECTIVE</code> or <code>DISABLE_SELECTIVE</code>. The value of the <code>Cacheable
* </code> annotation is inherited by subclasses; it can be overridden by specifying <code>Cacheable</code> on a
* subclass.
*
* <p>
* <code>Cacheable(false)</code> means that the entity and its state must
* not be cached by the provider.
* <p><code>Cacheable(false)</code> means that the entity and its state must not be cached by the provider.
*
* @since Java Persistence 2.0
*
* @deprecated replace by {@link org.redkale.persistence.Cacheable}
* @see org.redkale.persistence.Cacheable
*/
@@ -61,5 +55,4 @@ public @interface Cacheable {
* @return boolean
*/
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
* terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
* which accompanies this distribution.
* The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
* and the Eclipse Distribution License is available at
* <p>This program and the accompanying materials are made available under the terms of the Eclipse Public License v1.0
* and Eclipse Distribution License v. 1.0 which accompanies this distribution. The Eclipse Public License is available
* at http://www.eclipse.org/legal/epl-v10.html and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* Contributors:
* Linda DeMichiel - Java Persistence 2.1
* Linda DeMichiel - Java Persistence 2.0
* <p>Contributors: Linda DeMichiel - Java Persistence 2.1 Linda DeMichiel - Java Persistence 2.0
*
***************************************************************************** */
* <p>****************************************************************************
*/
package javax.persistence;
import java.lang.annotation.*;
import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.*;
/**
* Specifies the mapped column for a persistent property or field.
* If no <code>Column</code> annotation is specified, the default values apply.
* Specifies the mapped column for a persistent property or field. If no <code>Column</code> annotation is specified,
* the default values apply.
*
* <blockquote><pre>
* <blockquote>
*
* <pre>
* Example 1:
*
* &#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)
* public BigDecimal getCost() { return cost; }
*
* </pre></blockquote>
* </pre>
*
* </blockquote>
*
* @since Java Persistence 1.0
*
* @deprecated replace by {@link org.redkale.persistence.Column}
*
* @see org.redkale.persistence.Column
*/
@Deprecated(since = "2.8.0")
@@ -57,8 +57,7 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME;
public @interface Column {
/**
* (Optional) The name of the column. Defaults to
* the property or field name.
* (Optional) The name of the column. Defaults to the property or field name.
*
* @return String
*/
@@ -72,12 +71,10 @@ public @interface Column {
String comment() default "";
/**
* (Optional) Whether the column is a unique key. This is a
* shortcut for the <code>UniqueConstraint</code> annotation at the table
* level and is useful for when the unique key constraint
* corresponds to only a single column. This constraint applies
* in addition to any constraint entailed by primary key mapping and
* to constraints specified at the table level.
* (Optional) Whether the column is a unique key. This is a shortcut for the <code>UniqueConstraint</code>
* annotation at the table level and is useful for when the unique key constraint corresponds to only a single
* column. This constraint applies in addition to any constraint entailed by primary key mapping and to constraints
* specified at the table level.
*
* @return boolean
*/
@@ -98,24 +95,22 @@ public @interface Column {
String example() default "";
/**
* (Optional) Whether the column is included in SQL INSERT
* statements generated by the persistence provider.
* (Optional) Whether the column is included in SQL INSERT statements generated by the persistence provider.
*
* @return boolean
*/
boolean insertable() default true;
/**
* (Optional) Whether the column is included in SQL UPDATE
* statements generated by the persistence provider.
* (Optional) Whether the column is included in SQL UPDATE statements generated by the persistence provider.
*
* @return boolean
*/
boolean updatable() default true;
/**
* (Optional) The name of the table that contains the column.
* If absent the column is assumed to be in the primary table.
* (Optional) The name of the table that contains the column. If absent the column is assumed to be in the primary
* table.
*
* @return String
*/
@@ -123,9 +118,8 @@ public @interface Column {
String table() default "";
/**
* (Optional) The column length. (Applies only if a
* string-valued column is used.)
* if type==String and length == 65535 then sqltype is TEXT <br>
* (Optional) The column length. (Applies only if a string-valued column is used.) 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 &#62; 16777215 then sqltype is LONGTEXT <br>
* if type==byte[] and length &#60;= 65535 then sqltype is BLOB <br>
@@ -137,18 +131,15 @@ public @interface Column {
int length() default 255;
/**
* (Optional) The precision for a decimal (exact numeric)
* column. (Applies only if a decimal column is used.)
* Value must be set by developer if used when generating
* the DDL for the column.
* (Optional) The precision for a decimal (exact numeric) column. (Applies only if a decimal column is used.) Value
* must be set by developer if used when generating the DDL for the column.
*
* @return int
*/
int precision() default 0;
/**
* (Optional) The scale for a decimal (exact numeric) column.
* (Applies only if a decimal column is used.)
* (Optional) The scale for a decimal (exact numeric) column. (Applies only if a decimal column is used.)
*
* @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
* terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
* which accompanies this distribution.
* The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
* and the Eclipse Distribution License is available at
* <p>This program and the accompanying materials are made available under the terms of the Eclipse Public License v1.0
* and Eclipse Distribution License v. 1.0 which accompanies this distribution. The Eclipse Public License is available
* at http://www.eclipse.org/legal/epl-v10.html and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* Contributors:
* Linda DeMichiel - Java Persistence 2.1
* Linda DeMichiel - Java Persistence 2.0
* <p>Contributors: Linda DeMichiel - Java Persistence 2.1 Linda DeMichiel - Java Persistence 2.0
*
******************************************************************************/
* <p>****************************************************************************
*/
package javax.persistence;
import java.lang.annotation.*;
import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.*;
/**
* Specifies that the class is an entity. This annotation is applied to the
* entity class.
* Specifies that the class is an entity. This annotation is applied to the entity class.
*
* @since Java Persistence 1.0
*
* @deprecated replace by {@link org.redkale.persistence.Entity}
*
* @see org.redkale.persistence.Entity
*/
@Deprecated(since = "2.8.0")
@@ -37,10 +33,9 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME;
public @interface Entity {
/**
* (Optional) The entity name. Defaults to the unqualified
* name of the entity class. This name is used to refer to the
* entity in queries. The name must not be a reserved literal
* in the Java Persistence query language.
* (Optional) The entity name. Defaults to the unqualified name of the entity class. This name is used to refer to
* the entity in queries. The name must not be a reserved literal in the Java Persistence query language.
*
* @return String
*/
String name() default "";

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
* terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
* which accompanies this distribution.
* The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
* and the Eclipse Distribution License is available at
* <p>This program and the accompanying materials are made available under the terms of the Eclipse Public License v1.0
* and Eclipse Distribution License v. 1.0 which accompanies this distribution. The Eclipse Public License is available
* at http://www.eclipse.org/legal/epl-v10.html and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* Contributors:
* Linda DeMichiel - Java Persistence 2.1
* Linda DeMichiel - Java Persistence 2.0
* <p>Contributors: Linda DeMichiel - Java Persistence 2.1 Linda DeMichiel - Java Persistence 2.0
*
******************************************************************************/
* <p>****************************************************************************
*/
package javax.persistence;
import java.lang.annotation.*;
import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.*;
/**
* Specifies the primary key of an entity.
* 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>;
* <code>java.util.Date</code>;
* <code>java.sql.Date</code>;
* <code>java.math.BigDecimal</code>;
* <code>java.math.BigInteger</code>.
* Specifies the primary key of an entity. 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>;
* <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
* to be the primary key of the primary table. If no <code>Column</code> annotation
* is specified, the primary key column name is assumed to be the name
* of the primary key property or field.
* <p>The mapped column for the primary key of the entity is assumed to be the primary key of the primary table. If no
* <code>Column</code> annotation is specified, the primary key column name is assumed to be the name of the primary key
* property or field.
*
* <pre>
* Example:
@@ -42,17 +35,12 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME;
* public Long getId() { return id; }
* </pre>
*
* @see Column
* see GeneratedValue
*
* @see Column see GeneratedValue
* @since Java Persistence 1.0
*
* @deprecated replace by {@link org.redkale.persistence.Id}
*
* @see org.redkale.persistence.Id
*/
@Deprecated(since = "2.8.0")
@Target({METHOD, FIELD})
@Retention(RUNTIME)
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
* terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
* which accompanies this distribution.
* The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
* and the Eclipse Distribution License is available at
* <p>This program and the accompanying materials are made available under the terms of the Eclipse Public License v1.0
* and Eclipse Distribution License v. 1.0 which accompanies this distribution. The Eclipse Public License is available
* at http://www.eclipse.org/legal/epl-v10.html and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* Contributors:
* Linda DeMichiel - Java Persistence 2.1
* <p>Contributors: Linda DeMichiel - Java Persistence 2.1
*
***************************************************************************** */
* <p>****************************************************************************
*/
package javax.persistence;
import java.lang.annotation.*;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.*;
/**
* 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>
* The syntax of the <code>columnList</code> element is a
* <code>column_list</code>, as follows:
* <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>The syntax of the <code>columnList</code> element is a <code>column_list</code>, as follows:
*
* <pre>
* column::= index_column [,index_column]*
* index_column::= column_name [ASC | DESC]
* </pre>
*
* <p>
* If <code>ASC</code> or <code>DESC</code> is not specified,
* <code>ASC</code> (ascending order) is assumed.
* <p>If <code>ASC</code> or <code>DESC</code> is not specified, <code>ASC</code> (ascending order) is assumed.
*
* @since Java Persistence 2.1
*
* @deprecated replace by {@link org.redkale.persistence.Index}
*
* @see org.redkale.persistence.Index
*
*/
@Deprecated(since = "2.8.0")
@Target({})
@@ -56,8 +49,7 @@ public @interface Index {
String name() default "";
/**
* (Required) The names of the columns to be included in the index,
* in order.
* (Required) The names of the columns to be included in the index, in order.
*
* @return String
*/
@@ -69,5 +61,4 @@ public @interface Index {
* @return boolean
*/
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
* terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
* which accompanies this distribution.
* The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
* and the Eclipse Distribution License is available at
* <p>This program and the accompanying materials are made available under the terms of the Eclipse Public License v1.0
* and Eclipse Distribution License v. 1.0 which accompanies this distribution. The Eclipse Public License is available
* at http://www.eclipse.org/legal/epl-v10.html and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* Contributors:
* Linda DeMichiel - Java Persistence 2.1
* Linda DeMichiel - Java Persistence 2.0
* <p>Contributors: Linda DeMichiel - Java Persistence 2.1 Linda DeMichiel - Java Persistence 2.0
*
***************************************************************************** */
* <p>****************************************************************************
*/
package javax.persistence;
import java.lang.annotation.*;
import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.*;
/**
* Specifies the primary table for the annotated entity. Additional
* tables may be specified using SecondaryTable or SecondaryTables annotation.
* Specifies the primary table for the annotated entity. Additional tables may be specified using SecondaryTable or
* SecondaryTables annotation.
*
* <p>
* If no <code>Table</code> annotation is specified for an entity
* class, the default values apply.
* <p>If no <code>Table</code> annotation is specified for an entity class, the default values apply.
*
* <pre>
* Example:
@@ -36,9 +33,7 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME;
* </pre>
*
* @since Java Persistence 1.0
*
* @deprecated replace by {@link org.redkale.persistence.Table}
*
* @see org.redkale.persistence.Table
*/
@Deprecated(since = "2.8.0")
@@ -48,38 +43,36 @@ public @interface Table {
/**
* (Optional) The name of the table.
* <p>
* Defaults to the entity name.
*
* <p>Defaults to the entity name.
*
* @return String
*/
String name() default "";
/** (Optional) The catalog of the table.
* <p>
* Defaults to the default catalog.
/**
* (Optional) The catalog of the table.
*
* <p>Defaults to the default catalog.
*
* @return String
*/
String catalog() default "";
/**
* (Optional) Unique constraints that are to be placed on
* 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>JoinColumn</code>
* annotations and constraints entailed by primary key mappings.
* <p>
* Defaults to no additional constraints.
* (Optional) Unique constraints that are to be placed on 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>
* JoinColumn</code> annotations and constraints entailed by primary key mappings.
*
* <p>Defaults to no additional constraints.
*
* @return UniqueConstraint[]
*/
UniqueConstraint[] uniqueConstraints() default {};
/**
* (Optional) Indexes for the table. These are only used if
* table generation is in effect. Note that it is not necessary
* to specify an index for a primary key, as the primary key
* index will be created automatically.
* (Optional) Indexes for the table. These are only used if table generation is in effect. Note that it is not
* necessary to specify an index for a primary key, as the primary key index will be created automatically.
*
* @return indexes
* @since Java Persistence 2.1
@@ -92,5 +85,4 @@ public @interface Table {
* @return String
*/
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
* terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
* which accompanies this distribution.
* The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
* and the Eclipse Distribution License is available at
* <p>This program and the accompanying materials are made available under the terms of the Eclipse Public License v1.0
* and Eclipse Distribution License v. 1.0 which accompanies this distribution. The Eclipse Public License is available
* at http://www.eclipse.org/legal/epl-v10.html and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* Contributors:
* Linda DeMichiel - Java Persistence 2.1
* Linda DeMichiel - Java Persistence 2.0
* <p>Contributors: Linda DeMichiel - Java Persistence 2.1 Linda DeMichiel - Java Persistence 2.0
*
******************************************************************************/
* <p>****************************************************************************
*/
package javax.persistence;
import java.lang.annotation.*;
import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.*;
/**
* Specifies that the property or field is not persistent. It is used
* to annotate a property or field of an entity class, mapped
* superclass, or embeddable class.
* Specifies that the property or field is not persistent. It is used to annotate a property or field of an entity
* class, mapped superclass, or embeddable class.
*
* <pre>
* Example:
@@ -36,13 +34,10 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME;
* </pre>
*
* @since Java Persistence 1.0
*
* @deprecated replace by {@link org.redkale.persistence.Transient}
*
* @see org.redkale.persistence.Transient
*/
@Deprecated(since = "2.8.0")
@Target({METHOD, FIELD})
@Retention(RUNTIME)
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
* terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
* which accompanies this distribution.
* The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
* and the Eclipse Distribution License is available at
* <p>This program and the accompanying materials are made available under the terms of the Eclipse Public License v1.0
* and Eclipse Distribution License v. 1.0 which accompanies this distribution. The Eclipse Public License is available
* at http://www.eclipse.org/legal/epl-v10.html and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* Contributors:
* Linda DeMichiel - Java Persistence 2.1
* Linda DeMichiel - Java Persistence 2.0
* <p>Contributors: Linda DeMichiel - Java Persistence 2.1 Linda DeMichiel - Java Persistence 2.0
*
***************************************************************************** */
* <p>****************************************************************************
*/
package javax.persistence;
import java.lang.annotation.*;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.*;
/**
* Specifies that a unique constraint is to be included in
* the generated DDL for a primary or secondary table.
* Specifies that a unique constraint is to be included in the generated DDL for a primary or secondary table.
*
* <pre>
* Example:
@@ -34,26 +32,24 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME;
* </pre>
*
* @since Java Persistence 1.0
*
* @deprecated replace by {@link org.redkale.persistence.UniqueConstraint}
*
* @see org.redkale.persistence.UniqueConstraint
*
*/
@Deprecated(since = "2.8.0")
@Target({})
@Retention(RUNTIME)
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
* @since Java Persistence 2.0
*/
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[]
*/

View File

@@ -1,12 +1,9 @@
/**
* <p>
* see: https://redkale.org
*
* @author zhangjx
*
*/
module org.redkale {
requires java.base;
requires java.logging;
requires java.net.http;
@@ -54,5 +51,4 @@ module org.redkale {
uses org.redkale.source.spi.CacheSourceProvider;
uses org.redkale.source.spi.DataSourceProvider;
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.RetentionPolicy.RUNTIME;
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
*
* @author zhangjx
*/
@Documented

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -12,11 +12,9 @@ import java.lang.annotation.*;
* 2、返回类型是void且参数存在CompletionHandler类型 <br>
* 阻塞模式的方法会在work线程池中运行 非阻塞在IO线程中运行。
*
* <p>
* 详情见: https://redkale.org
* <p>详情见: https://redkale.org
*
* @author zhangjx
*
* @since 2.8.0
*/
@Target({ElementType.TYPE, ElementType.METHOD})

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -66,50 +66,34 @@ package org.redkale.asm;
*/
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;
/**
* The number of values in this annotation.
*/
/** The number of values in this annotation. */
private int size;
/**
* &#60;tt&#62;true&#60;tt&#62; if values are named, &#60;tt&#62;false&#60;/tt&#62; otherwise. Annotation
* writers used for annotation default and annotation arrays use unnamed
* values.
* &#60;tt&#62;true&#60;tt&#62; if values are named, &#60;tt&#62;false&#60;/tt&#62; otherwise. Annotation writers
* used for annotation default and annotation arrays use unnamed values.
*/
private final boolean named;
/**
* The annotation values in bytecode form. This byte vector only contains
* the values themselves, i.e. the number of values must be stored as a
* unsigned short just before these bytes.
* The annotation values in bytecode form. This byte vector only contains the values themselves, i.e. the number of
* values must be stored as a unsigned short just before these bytes.
*/
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;
/**
* 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;
/**
* Next annotation writer. This field is used to store annotation lists.
*/
/** Next annotation writer. This field is used to store annotation lists. */
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;
// ------------------------------------------------------------------------
@@ -119,20 +103,14 @@ final class AnnotationWriter extends AnnotationVisitor {
/**
* Constructs a new {@link AnnotationWriter}.
*
* @param cw
* 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 bv
* 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.
* @param cw 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 bv 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,
final ByteVector bv, final ByteVector parent, final int offset) {
AnnotationWriter(
final ClassWriter cw, final boolean named, final ByteVector bv, final ByteVector parent, final int offset) {
super(Opcodes.ASM6);
this.cw = cw;
this.named = named;
@@ -219,8 +197,7 @@ final class AnnotationWriter extends AnnotationVisitor {
}
@Override
public void visitEnum(final String name, final String desc,
final String value) {
public void visitEnum(final String name, final String desc, final String value) {
++size;
if (named) {
bv.putShort(cw.newUTF8(name));
@@ -229,8 +206,7 @@ final class AnnotationWriter extends AnnotationVisitor {
}
@Override
public AnnotationVisitor visitAnnotation(final String name,
final String desc) {
public AnnotationVisitor visitAnnotation(final String name, final String desc) {
++size;
if (named) {
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
* vector.
* Puts the annotations of this annotation writer list into the given byte vector.
*
* @param out
* where the annotations must be put.
* @param out where the annotations must be put.
*/
void put(final ByteVector out) {
int n = 0;
@@ -311,15 +285,11 @@ final class AnnotationWriter extends AnnotationVisitor {
/**
* Puts the given annotation lists into the given byte vector.
*
* @param panns
* an array of annotation writer lists.
* @param off
* index of the first annotation to be written.
* @param out
* where the annotations must be put.
* @param panns an array of annotation writer lists.
* @param off 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,
final ByteVector out) {
static void put(final AnnotationWriter[] panns, final int off, final ByteVector out) {
int size = 1 + 2 * (panns.length - off);
for (int i = off; i < panns.length; ++i) {
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.
* LOCAL_VARIABLE and RESOURCE_VARIABLE target types are not supported.
* Puts the given type reference and type path into the given bytevector. LOCAL_VARIABLE and RESOURCE_VARIABLE
* target types are not supported.
*
* @param typeRef
* 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 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.
* @param typeRef 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
* 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) {
switch (typeRef >>> 24) {

View File

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

View File

@@ -3,17 +3,6 @@
*/
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_PROTECTED;
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.LRETURN;
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.util.Utility;
@@ -35,7 +36,6 @@ import org.redkale.util.Utility;
* 生产动态字节码的方法扩展器, 可以进行方法加强动作
*
* @param <T> 泛型
*
* @since 2.8.0
*/
public abstract class AsmMethodBoost<T> {
@@ -60,11 +60,9 @@ public abstract class AsmMethodBoost<T> {
}
/**
*
* 返回一个类所有方法的字节信息, key为: method.getName+':'+Type.getMethodDescriptor(method)
*
* @param clazz Class
*
* @return Map
*/
public static Map<String, AsmMethodBean> getMethodBeans(Class clazz) {
@@ -82,7 +80,6 @@ public abstract class AsmMethodBoost<T> {
* 获取需屏蔽的方法上的注解
*
* @param method 方法
*
* @return 需要屏蔽的注解
*/
public abstract List<Class<? extends Annotation>> filterMethodAnnotations(Method method);
@@ -97,21 +94,26 @@ public abstract class AsmMethodBoost<T> {
* @param filterAnns 需要过滤的注解
* @param method 操作的方法
* @param newMethodName 新的方法名, 可能为null
*
* @return 下一个新的方法名不做任何处理应返回参数newMethodName
*/
public abstract String doMethod(ClassLoader classLoader, ClassWriter cw, String newDynName,
String fieldPrefix, List<Class<? extends Annotation>> filterAnns, Method method, @Nullable String newMethodName);
public abstract String doMethod(
ClassLoader classLoader,
ClassWriter cw,
String newDynName,
String fieldPrefix,
List<Class<? extends Annotation>> filterAnns,
Method method,
@Nullable String newMethodName);
/** 处理所有动态方法后调用
/**
* 处理所有动态方法后调用
*
* @param classLoader ClassLoader
* @param cw 动态字节码Writer
* @param newDynName 动态新类名
* @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);
}
protected MethodVisitor createMethodVisitor(ClassWriter cw, Method method, String newMethodName, AsmMethodBean methodBean) {
return new MethodDebugVisitor(cw.visitMethod(getAcc(method, newMethodName),
getNowMethodName(method, newMethodName), Type.getMethodDescriptor(method),
getMethodSignature(method, methodBean), getMethodExceptions(method, methodBean)));
protected MethodVisitor createMethodVisitor(
ClassWriter cw, Method method, String newMethodName, AsmMethodBean methodBean) {
return new MethodDebugVisitor(cw.visitMethod(
getAcc(method, newMethodName),
getNowMethodName(method, newMethodName),
Type.getMethodDescriptor(method),
getMethodSignature(method, methodBean),
getMethodExceptions(method, methodBean)));
}
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) {
// 给方法加上原有的Annotation
final Annotation[] anns = method.getAnnotations();
@@ -177,7 +184,8 @@ public abstract class AsmMethodBoost<T> {
final Annotation[][] annss = method.getParameterAnnotations();
for (int k = 0; k < annss.length; 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;
}
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();
if (methodBean != null && paramTypes.length > 0) {
mv.visitLabel(l2);
List<AsmMethodParam> params = methodBean.getParams();
for (int i = 0; i < paramTypes.length; 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) {
mv.visitInsn(RETURN);
} else {
@@ -245,7 +261,6 @@ public abstract class AsmMethodBoost<T> {
* 生产动态字节码的方法扩展器, 可以进行方法加强动作
*
* @param <T> 泛型
*
* @since 2.8.0
*/
static class AsmMethodBoosts<T> extends AsmMethodBoost<T> {
@@ -280,8 +295,14 @@ public abstract class AsmMethodBoost<T> {
}
@Override
public String doMethod(ClassLoader classLoader, ClassWriter cw, String newDynName, String fieldPrefix,
List<Class<? extends Annotation>> filterAnns, Method method, String newMethodName) {
public String doMethod(
ClassLoader classLoader,
ClassWriter cw,
String newDynName,
String fieldPrefix,
List<Class<? extends Annotation>> filterAnns,
Method method,
String newMethodName) {
String newName = newMethodName;
for (AsmMethodBoost item : items) {
if (item != null) {
@@ -308,7 +329,6 @@ public abstract class AsmMethodBoost<T> {
}
}
}
}
static class MethodParamClassVisitor extends ClassVisitor {
@@ -324,7 +344,12 @@ public abstract class AsmMethodBoost<T> {
}
@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);
if (java.lang.reflect.Modifier.isStatic(methodAccess)) {
return null;
@@ -333,7 +358,8 @@ public abstract class AsmMethodBoost<T> {
if (methodBeanMap.containsKey(key)) {
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();
methodBeanMap.put(key, bean);
return new MethodVisitor(Opcodes.ASM6) {
@@ -343,7 +369,8 @@ public abstract class AsmMethodBoost<T> {
}
@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) {
return;
}
@@ -368,7 +395,8 @@ public abstract class AsmMethodBoost<T> {
return map;
}
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) { // 无需理会
}
Class superClass = clazz.getSuperclass();

View File

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

View File

@@ -3,8 +3,6 @@
*/
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.CHECKCAST;
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.INVOKEVIRTUAL;
import static org.redkale.asm.Opcodes.SIPUSH;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import org.redkale.util.RedkaleException;
/**
* ASM简单的工具方法 <br>
*
* <p>
* 详情见: https://redkale.org
* <p>详情见: https://redkale.org
*
* @author zhangjx
*
* @since 2.8.0
*/
public final class Asms {
private Asms() {
}
private Asms() {}
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) {
try {
for (Method anm : ann.annotationType().getMethods()) {
final String mname = anm.getName();
if ("equals".equals(mname) || "hashCode".equals(mname) || "toString".equals(mname) || "annotationType".equals(mname)) {
if ("equals".equals(mname)
|| "hashCode".equals(mname)
|| "toString".equals(mname)
|| "annotationType".equals(mname)) {
continue;
}
final Object r = anm.invoke(ann);
@@ -62,7 +68,9 @@ public final class Asms {
} else if (r instanceof Annotation[]) {
AnnotationVisitor av1 = av.visitArray(mname);
for (Annotation item : (Annotation[]) r) {
visitAnnotation(av1.visitAnnotation(null, Type.getDescriptor(((Annotation) item).annotationType())), item);
visitAnnotation(
av1.visitAnnotation(null, Type.getDescriptor(((Annotation) item).annotationType())),
item);
}
av1.visitEnd();
} else if (r instanceof Class) {
@@ -70,7 +78,9 @@ public final class Asms {
} else if (r instanceof Enum) {
av.visitEnum(mname, Type.getDescriptor(r.getClass()), ((Enum) r).name());
} else if (r instanceof Annotation) {
visitAnnotation(av.visitAnnotation(null, Type.getDescriptor(((Annotation) r).annotationType())), (Annotation) r);
visitAnnotation(
av.visitAnnotation(null, Type.getDescriptor(((Annotation) r).annotationType())),
(Annotation) r);
} else {
av.visit(mname, r);
}

View File

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

View File

@@ -59,48 +59,37 @@
package org.redkale.asm;
/**
* A dynamically extensible vector of bytes. This class is roughly equivalent to
* a DataOutputStream on top of a ByteArrayOutputStream, but is more efficient.
* A dynamically extensible vector of bytes. This class is roughly equivalent to a DataOutputStream on top of a
* ByteArrayOutputStream, but is more efficient.
*
* @author Eric Bruneton
*/
public class ByteVector {
/**
* The content of this vector.
*/
/** The content of this vector. */
byte[] data;
/**
* Actual number of bytes in this vector.
*/
/** Actual number of bytes in this vector. */
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() {
data = new byte[64];
}
/**
* Constructs a new {@link ByteVector ByteVector} with the given initial
* size.
* Constructs a new {@link ByteVector ByteVector} with the given initial size.
*
* @param initialSize
* the initial size of the byte vector to be constructed.
* @param initialSize the initial size of the byte vector to be constructed.
*/
public ByteVector(final int initialSize) {
data = new byte[initialSize];
}
/**
* Puts a byte into this byte vector. The byte vector is automatically
* enlarged if necessary.
* Puts a byte into this byte vector. The byte vector is automatically enlarged if necessary.
*
* @param b
* a byte.
* @param b a byte.
* @return this byte vector.
*/
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
* enlarged if necessary.
* Puts two bytes into this byte vector. The byte vector is automatically enlarged if necessary.
*
* @param b1
* a byte.
* @param b2
* another byte.
* @param b1 a byte.
* @param b2 another byte.
* @return this byte vector.
*/
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
* enlarged if necessary.
* Puts a short into this byte vector. The byte vector is automatically enlarged if necessary.
*
* @param s
* a short.
* @param s a short.
* @return this byte vector.
*/
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
* automatically enlarged if necessary.
* Puts a byte and a short into this byte vector. The byte vector is automatically enlarged if necessary.
*
* @param b
* a byte.
* @param s
* a short.
* @param b a byte.
* @param s a short.
* @return this byte vector.
*/
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
* enlarged if necessary.
* Puts an int into this byte vector. The byte vector is automatically enlarged if necessary.
*
* @param i
* an int.
* @param i an int.
* @return this byte vector.
*/
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
* enlarged if necessary.
* Puts a long into this byte vector. The byte vector is automatically enlarged if necessary.
*
* @param l
* a long.
* @param l a long.
* @return this byte vector.
*/
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
* automatically enlarged if necessary.
* Puts an UTF8 string into this byte vector. The byte vector is automatically enlarged if necessary.
*
* @param s
* a String whose UTF8 encoded length must be less than 65536.
* @param s a String whose UTF8 encoded length must be less than 65536.
* @return this byte vector.
*/
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
* automatically enlarged if necessary. The string length is encoded in two
* bytes before the encoded characters, if there is space for that (i.e. if
* this.length - i - 2 >= 0).
* Puts an UTF8 string into this byte vector. The byte vector is automatically enlarged if necessary. The string
* length is encoded in two bytes before the encoded characters, if there is space for that (i.e. if this.length - i
* - 2 >= 0).
*
* @param s
* the String to encode.
* @param i
* the index of the first character to encode. The previous
* 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.
* @param s the String to encode.
* @param i the index of the first character to encode. The previous 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.
*/
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
* automatically enlarged if necessary.
* Puts an array of bytes into this byte vector. The byte vector is automatically enlarged if necessary.
*
* @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 into this byte vector.
* @param off
* index of the fist byte of b that must be copied.
* @param len
* number of bytes of b that must be copied.
* @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
* into this byte vector.
* @param off 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.
*/
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.
*
* @param size
* number of additional bytes that this byte vector should be
* able to receive.
* @param size number of additional bytes that this byte vector should be able to receive.
*/
private void enlarge(final int size) {
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;
/**
* A visitor to visit a Java class. The methods of this class must be called in
* the following order: &#60;tt&#62;visit&#60;/tt&#62; [ &#60;tt&#62;visitSource&#60;/tt&#62; ] [
* &#60;tt&#62;visitModule&#60;/tt&#62; ][ &#60;tt&#62;visitOuterClass&#60;/tt&#62; ] ( &#60;tt&#62;visitAnnotation&#60;/tt&#62; |
* A visitor to visit a Java class. The methods of this class must be called in the following order:
* &#60;tt&#62;visit&#60;/tt&#62; [ &#60;tt&#62;visitSource&#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;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;visitEnd&#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;.
*
* @author Eric Bruneton
*/
public abstract class ClassVisitor {
/**
* The ASM API version implemented by this visitor. The value of this field
* must be one of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
* The ASM API version implemented by this visitor. The value of this field must be one of {@link Opcodes#ASM4},
* {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
*/
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;
/**
* Constructs a new {@link ClassVisitor}.
*
* @param api
* the ASM API version implemented by this visitor. Must be one
* of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
* @param api the ASM API version implemented by this visitor. Must be one of {@link Opcodes#ASM4},
* {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
*/
public ClassVisitor(final int api) {
this(api, null);
@@ -96,12 +92,9 @@ public abstract class ClassVisitor {
/**
* Constructs a new {@link ClassVisitor}.
*
* @param api
* the ASM API version implemented by this visitor. Must be one
* 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 api the ASM API version implemented by this visitor. Must be one 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.
*/
public ClassVisitor(final int api, final ClassVisitor cv) {
this.api = api;
@@ -111,30 +104,19 @@ public abstract class ClassVisitor {
/**
* Visits the header of the class.
*
* @param version
* the class version.
* @param access
* the class's access flags (see {@link Opcodes}). This parameter
* also indicates if the class is deprecated.
* @param name
* the internal name of the class (see
* {@link Type#getInternalName() getInternalName}).
* @param signature
* the signature of this class. May be &#60;tt&#62;null&#60;/tt&#62; if the class
* is not a generic one, and does not extend or implement generic
* 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;.
* @param version the class version.
* @param access the class's access flags (see {@link Opcodes}). This parameter also indicates if the class is
* deprecated.
* @param name the internal name of the class (see {@link Type#getInternalName() getInternalName}).
* @param signature the signature of this class. May be &#60;tt&#62;null&#60;/tt&#62; if the class is not a generic
* one, and does not extend or implement generic 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,
String superName, String[] interfaces) {
public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) {
if (cv != null) {
cv.visit(version, access, name, signature, superName, interfaces);
}
@@ -143,13 +125,10 @@ public abstract class ClassVisitor {
/**
* Visits the source of the class.
*
* @param source
* 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
* @param source 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;.
*/
public void visitSource(String source, String debug) {
if (cv != null) {
@@ -159,15 +138,12 @@ public abstract class ClassVisitor {
/**
* Visit the module corresponding to the class.
* @param name
* module name
* @param access
* module flags, among {@code ACC_OPEN}, {@code ACC_SYNTHETIC}
* and {@code ACC_MANDATED}.
* @param version
* 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.
*
* @param name module name
* @param access module flags, among {@code ACC_OPEN}, {@code ACC_SYNTHETIC} and {@code ACC_MANDATED}.
* @param version 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) {
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
* if the class has an enclosing class.
* Visits the enclosing class of the class. This method must be called only if the class has an enclosing class.
*
* @param owner
* 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 enclosed in a method of its
* 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.
* @param owner 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
* enclosed in a method of its 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) {
if (cv != null) {
@@ -203,12 +173,10 @@ public abstract class ClassVisitor {
/**
* Visits an annotation of the class.
*
* @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.
* @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 visitAnnotation(String desc, boolean visible) {
if (cv != null) {
@@ -220,27 +188,18 @@ public abstract class ClassVisitor {
/**
* Visits an annotation on a type in the class signature.
*
* @param typeRef
* a reference to the annotated type. The sort of this type
* reference must be {@link TypeReference#CLASS_TYPE_PARAMETER
* CLASS_TYPE_PARAMETER},
* {@link TypeReference#CLASS_TYPE_PARAMETER_BOUND
* CLASS_TYPE_PARAMETER_BOUND} or
* {@link TypeReference#CLASS_EXTENDS CLASS_EXTENDS}. See
* {@link TypeReference}.
* @param typePath
* the path to the annotated type argument, wildcard bound, array
* element type, or static inner type within 'typeRef'. May be
* &#60;tt&#62;null&#60;/tt&#62; if the annotation targets 'typeRef' as a whole.
* @param desc
* the class descriptor of the annotation class.
* @param visible
* &#60;tt&#62;true&#60;/tt&#62; if the annotation is visible at runtime.
* @return a visitor to visit the annotation values, or &#60;tt&#62;null&#60;/tt&#62; if
* this visitor is not interested in visiting this annotation.
* @param typeRef a reference to the annotated type. The sort of this type reference must be
* {@link TypeReference#CLASS_TYPE_PARAMETER CLASS_TYPE_PARAMETER},
* {@link TypeReference#CLASS_TYPE_PARAMETER_BOUND CLASS_TYPE_PARAMETER_BOUND} or
* {@link TypeReference#CLASS_EXTENDS CLASS_EXTENDS}. See {@link TypeReference}.
* @param typePath the path to the annotated type argument, wildcard bound, array element type, or static inner type
* within 'typeRef'. May be &#60;tt&#62;null&#60;/tt&#62; if the annotation targets 'typeRef' as a whole.
* @param desc the class descriptor of the annotation class.
* @param visible &#60;tt&#62;true&#60;/tt&#62; if the annotation is visible at runtime.
* @return a visitor to visit the annotation values, or &#60;tt&#62;null&#60;/tt&#62; if this visitor is not
* interested in visiting this annotation.
*/
public AnnotationVisitor visitTypeAnnotation(int typeRef,
TypePath typePath, String desc, boolean visible) {
public AnnotationVisitor visitTypeAnnotation(int typeRef, TypePath typePath, String desc, boolean visible) {
if (cv != null) {
return cv.visitTypeAnnotation(typeRef, typePath, desc, visible);
}
@@ -250,8 +209,7 @@ public abstract class ClassVisitor {
/**
* Visits a non standard attribute of the class.
*
* @param attr
* an attribute.
* @param attr an attribute.
*/
public void visitAttribute(Attribute attr) {
if (cv != null) {
@@ -260,25 +218,16 @@ public abstract class ClassVisitor {
}
/**
* Visits information about an inner class. This inner class is not
* necessarily a member of the class being visited.
* Visits information about an inner class. This inner class is not necessarily a member of the class being visited.
*
* @param name
* the internal name of an inner class (see
* {@link Type#getInternalName() getInternalName}).
* @param outerName
* the internal name of the class to which the inner class
* belongs (see {@link Type#getInternalName() getInternalName}).
* 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.
* @param name the internal name of an inner class (see {@link Type#getInternalName() getInternalName}).
* @param outerName the internal name of the class to which the inner class belongs (see
* {@link Type#getInternalName() getInternalName}). 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,
String innerName, int access) {
public void visitInnerClass(String name, String outerName, String innerName, int access) {
if (cv != null) {
cv.visitInnerClass(name, outerName, innerName, access);
}
@@ -287,32 +236,22 @@ public abstract class ClassVisitor {
/**
* Visits a field of the class.
*
* @param access
* the field's access flags (see {@link Opcodes}). This parameter
* also indicates if the field is synthetic and/or deprecated.
* @param name
* the field's name.
* @param desc
* the field's descriptor (see {@link Type Type}).
* @param signature
* the field's signature. May be &#60;tt&#62;null&#60;/tt&#62; if the field's
* type does not use generic types.
* @param value
* the field's initial value. This parameter, which may be
* &#60;tt&#62;null&#60;/tt&#62; if the field does not have an initial value,
* must be an {@link Integer}, a {@link Float}, a {@link Long}, a
* {@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.
* @param access the field's access flags (see {@link Opcodes}). This parameter also indicates if the field is
* synthetic and/or deprecated.
* @param name the field's name.
* @param desc the field's descriptor (see {@link Type Type}).
* @param signature the field's signature. May be &#60;tt&#62;null&#60;/tt&#62; if the field's type does not use
* generic types.
* @param value the field's initial value. This parameter, which may be &#60;tt&#62;null&#60;/tt&#62; if the field
* does not have an initial value, must be an {@link Integer}, a {@link Float}, a {@link Long}, a {@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,
String signature, Object value) {
public FieldVisitor visitField(int access, String name, String desc, String signature, Object value) {
if (cv != null) {
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
* {@link MethodVisitor} instance (or &#60;tt&#62;null&#60;/tt&#62;) each time it is called,
* i.e., it should not return a previously returned visitor.
* Visits a method of the class. This method <i>must</i> return a new {@link MethodVisitor} instance (or
* &#60;tt&#62;null&#60;/tt&#62;) each time it is called, i.e., it should not return a previously returned visitor.
*
* @param access
* the method's access flags (see {@link Opcodes}). This
* parameter also indicates if the method is synthetic and/or
* deprecated.
* @param name
* the method's name.
* @param desc
* the method's descriptor (see {@link Type Type}).
* @param signature
* the method's signature. May be &#60;tt&#62;null&#60;/tt&#62; if the 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.
* @param access the method's access flags (see {@link Opcodes}). This parameter also indicates if the method is
* synthetic and/or deprecated.
* @param name the method's name.
* @param desc the method's descriptor (see {@link Type Type}).
* @param signature the method's signature. May be &#60;tt&#62;null&#60;/tt&#62; if the 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,
String signature, String[] exceptions) {
public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
if (cv != null) {
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
* called, is used to inform the visitor that all the fields and methods of
* the class have been visited.
* Visits the end of the class. This method, which is the last one to be called, is used to inform the visitor that
* all the fields and methods of the class have been visited.
*/
public void visitEnd() {
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 {
/**
* Prototypes of the attributes that must be parsed for this class.
*/
/** Prototypes of the attributes that must be parsed for this class. */
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;
/**
* The buffer used to read strings.
*/
/** The buffer used to read strings. */
char[] buffer;
/**
* The start index of each bootstrap method.
*/
/** The start index of each bootstrap method. */
int[] bootstrapMethods;
/**
* The access flags of the method currently being parsed.
*/
/** The access flags of the method currently being parsed. */
int access;
/**
* The name of the method currently being parsed.
*/
/** The name of the method currently being parsed. */
String name;
/**
* The descriptor of the method currently being parsed.
*/
/** The descriptor of the method currently being parsed. */
String desc;
/**
* The label objects, indexed by bytecode offset, of the method currently
* being parsed (only bytecode offsets for which a label is needed have a
* non null associated Label object).
* The label objects, indexed by bytecode offset, of the method currently being parsed (only bytecode offsets for
* which a label is needed have a non null associated Label object).
*/
Label[] labels;
/**
* The target of the type annotation currently being parsed.
*/
/** The target of the type annotation currently being parsed. */
int typeRef;
/**
* The path of the type annotation currently being parsed.
*/
/** The path of the type annotation currently being parsed. */
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;
/**
* The labels corresponding to the start of the local variable ranges in the
* local variable type annotation currently being parsed.
* The labels corresponding to the start of the local variable ranges in the local variable type annotation
* currently being parsed.
*/
Label[] start;
/**
* The labels corresponding to the end of the local variable ranges in the
* local variable type annotation currently being parsed.
* The labels corresponding to the end of the local variable ranges in the local variable type annotation currently
* being parsed.
*/
Label[] end;
/**
* The local variable indices for each local variable range in the local
* variable type annotation currently being parsed.
* The local variable indices for each local variable range in the local variable type annotation currently being
* parsed.
*/
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;
/**
* 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;
/**
* The number locals in the latest stack map frame that has been parsed,
* minus the number of locals in the previous frame.
* The number locals in the latest stack map frame that has been parsed, minus the number of locals in the previous
* frame.
*/
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;
/**
* 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;
/**
* 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;
}

View File

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

View File

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

View File

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

View File

@@ -65,64 +65,37 @@ package org.redkale.asm;
*/
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;
/**
* Access flags of this field.
*/
/** Access flags of this field. */
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;
/**
* 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;
/**
* 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;
/**
* 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;
/**
* 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;
/**
* 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;
/**
* 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;
/**
* 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;
/**
* 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;
// ------------------------------------------------------------------------
@@ -132,21 +105,20 @@ final class FieldWriter extends FieldVisitor {
/**
* Constructs a new {@link FieldWriter}.
*
* @param cw
* the class writer to which this field must be added.
* @param access
* the field's access flags (see {@link Opcodes}).
* @param name
* the field's name.
* @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;.
* @param cw the class writer to which this field must be added.
* @param access the field's access flags (see {@link Opcodes}).
* @param name the field's name.
* @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,
final String desc, final String signature, final Object value) {
FieldWriter(
final ClassWriter cw,
final int access,
final String name,
final String desc,
final String signature,
final Object value) {
super(Opcodes.ASM6);
if (cw.firstField == null) {
cw.firstField = this;
@@ -171,8 +143,7 @@ final class FieldWriter extends FieldVisitor {
// ------------------------------------------------------------------------
@Override
public AnnotationVisitor visitAnnotation(final String desc,
final boolean visible) {
public AnnotationVisitor visitAnnotation(final String desc, final boolean visible) {
ByteVector bv = new ByteVector();
// write type, and reserve space for values count
bv.putShort(cw.newUTF8(desc)).putShort(0);
@@ -188,15 +159,14 @@ final class FieldWriter extends FieldVisitor {
}
@Override
public AnnotationVisitor visitTypeAnnotation(final int typeRef,
final TypePath typePath, final String desc, final boolean visible) {
public AnnotationVisitor visitTypeAnnotation(
final int typeRef, final TypePath typePath, final String desc, final boolean visible) {
ByteVector bv = new ByteVector();
// write target_type and target_info
AnnotationWriter.putTarget(typeRef, typePath, bv);
// write type, and reserve space for values count
bv.putShort(cw.newUTF8(desc)).putShort(0);
AnnotationWriter aw = new AnnotationWriter(cw, true, bv, bv,
bv.length - 2);
AnnotationWriter aw = new AnnotationWriter(cw, true, bv, bv, bv.length - 2);
if (visible) {
aw.next = tanns;
tanns = aw;
@@ -234,8 +204,7 @@ final class FieldWriter extends FieldVisitor {
size += 8;
}
if ((access & Opcodes.ACC_SYNTHETIC) != 0) {
if ((cw.version & 0xFFFF) < Opcodes.V1_5
|| (access & ClassWriter.ACC_SYNTHETIC_ATTRIBUTE) != 0) {
if ((cw.version & 0xFFFF) < Opcodes.V1_5 || (access & ClassWriter.ACC_SYNTHETIC_ATTRIBUTE) != 0) {
cw.newUTF8("Synthetic");
size += 6;
}
@@ -273,12 +242,12 @@ final class FieldWriter extends FieldVisitor {
/**
* Puts the content of this field into the given byte vector.
*
* @param out
* where the content of this field must be put.
* @param out where the content of this field must be put.
*/
void put(final ByteVector out) {
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);
out.putShort(access & ~mask).putShort(name).putShort(desc);
int attributeCount = 0;
@@ -286,8 +255,7 @@ final class FieldWriter extends FieldVisitor {
++attributeCount;
}
if ((access & Opcodes.ACC_SYNTHETIC) != 0) {
if ((cw.version & 0xFFFF) < Opcodes.V1_5
|| (access & ClassWriter.ACC_SYNTHETIC_ATTRIBUTE) != 0) {
if ((cw.version & 0xFFFF) < Opcodes.V1_5 || (access & ClassWriter.ACC_SYNTHETIC_ATTRIBUTE) != 0) {
++attributeCount;
}
}
@@ -318,8 +286,7 @@ final class FieldWriter extends FieldVisitor {
out.putInt(2).putShort(value);
}
if ((access & Opcodes.ACC_SYNTHETIC) != 0) {
if ((cw.version & 0xFFFF) < Opcodes.V1_5
|| (access & ClassWriter.ACC_SYNTHETIC_ATTRIBUTE) != 0) {
if ((cw.version & 0xFFFF) < Opcodes.V1_5 || (access & ClassWriter.ACC_SYNTHETIC_ATTRIBUTE) != 0) {
out.putShort(cw.newUTF8("Synthetic")).putInt(0);
}
}

View File

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

View File

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

View File

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

View File

@@ -59,94 +59,61 @@
package org.redkale.asm;
/**
* A constant pool item. Constant pool items can be created with the 'newXXX'
* methods in the {@link ClassWriter} class.
* A constant pool item. Constant pool items can be created with the 'newXXX' methods in the {@link ClassWriter} class.
*
* @author Eric Bruneton
*/
final class Item {
/**
* Index of this item in the constant pool.
*/
/** Index of this item in the constant pool. */
int index;
/**
* Type of this constant pool item. A single class is used to represent all
* constant pool item types, in order to minimize the bytecode size of this
* 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#STR}, {@link ClassWriter#CLASS},
* {@link ClassWriter#NAME_TYPE}, {@link ClassWriter#FIELD},
* {@link ClassWriter#METH}, {@link ClassWriter#IMETH},
* {@link ClassWriter#MODULE}, {@link ClassWriter#PACKAGE},
* Type of this constant pool item. A single class is used to represent all constant pool item types, in order to
* minimize the bytecode size of this 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#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}.
*
* MethodHandle constant 9 variations are stored using a range of 9 values
* from {@link ClassWriter#HANDLE_BASE} + 1 to
* {@link ClassWriter#HANDLE_BASE} + 9.
* <p>MethodHandle constant 9 variations are stored using a range of 9 values from {@link ClassWriter#HANDLE_BASE} +
* 1 to {@link ClassWriter#HANDLE_BASE} + 9.
*
* Special Item types are used for Items that are stored in the ClassWriter
* {@link ClassWriter#typeTable}, instead of the constant pool, in order to
* avoid clashes with normal constant pool items in the ClassWriter constant
* pool's hash table. These special item types are
* {@link ClassWriter#TYPE_NORMAL}, {@link ClassWriter#TYPE_UNINIT} and
* {@link ClassWriter#TYPE_MERGED}.
* <p>Special Item types are used for Items that are stored in the ClassWriter {@link ClassWriter#typeTable},
* instead of the constant pool, in order to avoid clashes with normal constant pool items in the ClassWriter
* constant pool's hash table. These special item types are {@link ClassWriter#TYPE_NORMAL},
* {@link ClassWriter#TYPE_UNINIT} and {@link ClassWriter#TYPE_MERGED}.
*/
int type;
/**
* Value of this item, for an integer item.
*/
/** Value of this item, for an integer item. */
int intVal;
/**
* Value of this item, for a long item.
*/
/** Value of this item, for a long item. */
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;
/**
* 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;
/**
* 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;
/**
* The hash code value of this constant pool item.
*/
/** The hash code value of this constant pool item. */
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;
/**
* Constructs an uninitialized {@link Item}.
*/
Item() {
}
/** Constructs an uninitialized {@link Item}. */
Item() {}
/**
* Constructs an uninitialized {@link Item} for constant pool element at
* given position.
* Constructs an uninitialized {@link Item} for constant pool element at given position.
*
* @param index
* index of the item to be constructed.
* @param index index of the item to be constructed.
*/
Item(final int index) {
this.index = index;
@@ -155,10 +122,8 @@ final class Item {
/**
* Constructs a copy of the given item.
*
* @param index
* index of the item to be constructed.
* @param i
* the item that must be copied into the item to be constructed.
* @param index index of 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) {
this.index = index;
@@ -174,8 +139,7 @@ final class Item {
/**
* Sets this item to an integer item.
*
* @param intVal
* the value of this item.
* @param intVal the value of this item.
*/
void set(final int intVal) {
this.type = ClassWriter.INT;
@@ -186,8 +150,7 @@ final class Item {
/**
* Sets this item to a long item.
*
* @param longVal
* the value of this item.
* @param longVal the value of this item.
*/
void set(final long longVal) {
this.type = ClassWriter.LONG;
@@ -198,8 +161,7 @@ final class Item {
/**
* Sets this item to a float item.
*
* @param floatVal
* the value of this item.
* @param floatVal the value of this item.
*/
void set(final float floatVal) {
this.type = ClassWriter.FLOAT;
@@ -210,8 +172,7 @@ final class Item {
/**
* Sets this item to a double item.
*
* @param doubleVal
* the value of this item.
* @param doubleVal the value of this item.
*/
void set(final double doubleVal) {
this.type = ClassWriter.DOUBLE;
@@ -222,18 +183,13 @@ final class Item {
/**
* Sets this item to an item that do not hold a primitive value.
*
* @param type
* the type of this item.
* @param strVal1
* first 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.
* @param type the type of this item.
* @param strVal1 first 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")
void set(final int type, final String strVal1, final String strVal2,
final String strVal3) {
void set(final int type, final String strVal1, final String strVal2, final String strVal3) {
this.type = type;
this.strVal1 = strVal1;
this.strVal2 = strVal2;
@@ -250,8 +206,7 @@ final class Item {
hashCode = 0x7FFFFFFF & (type + strVal1.hashCode());
return;
case ClassWriter.NAME_TYPE: {
hashCode = 0x7FFFFFFF & (type + strVal1.hashCode()
* strVal2.hashCode());
hashCode = 0x7FFFFFFF & (type + strVal1.hashCode() * strVal2.hashCode());
return;
}
// ClassWriter.FIELD:
@@ -259,39 +214,31 @@ final class Item {
// ClassWriter.IMETH:
// ClassWriter.HANDLE_BASE + 1..9
default:
hashCode = 0x7FFFFFFF & (type + strVal1.hashCode()
* strVal2.hashCode() * strVal3.hashCode());
hashCode = 0x7FFFFFFF & (type + strVal1.hashCode() * strVal2.hashCode() * strVal3.hashCode());
}
}
/**
* Sets the item to an InvokeDynamic item.
*
* @param name
* invokedynamic's name.
* @param desc
* invokedynamic's desc.
* @param bsmIndex
* zero based index into the class attribute BootrapMethods.
* @param name invokedynamic's name.
* @param desc invokedynamic's desc.
* @param bsmIndex zero based index into the class attribute BootrapMethods.
*/
void set(String name, String desc, int bsmIndex) {
this.type = ClassWriter.INDY;
this.longVal = bsmIndex;
this.strVal1 = name;
this.strVal2 = desc;
this.hashCode = 0x7FFFFFFF & (ClassWriter.INDY + bsmIndex
* strVal1.hashCode() * strVal2.hashCode());
this.hashCode = 0x7FFFFFFF & (ClassWriter.INDY + bsmIndex * strVal1.hashCode() * strVal2.hashCode());
}
/**
* Sets the item to a BootstrapMethod item.
*
* @param position
* 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 the hashcode of all
* bootstrap arguments.
* @param position 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
* the hashcode of all bootstrap arguments.
*/
void set(int position, int hashCode) {
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
* that the two items have the same {@link #type}</i>.
* Indicates if the given item is equal to this one. <i>This method assumes that the two items have the same
* {@link #type}</i>.
*
* @param i
* the item to be compared to this one. Both items must have the
* same {@link #type}.
* @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.
* @param i the item to be compared to this one. Both items must have the same {@link #type}.
* @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) {
switch (type) {
@@ -331,17 +276,14 @@ final class Item {
case ClassWriter.NAME_TYPE:
return i.strVal1.equals(strVal1) && i.strVal2.equals(strVal2);
case ClassWriter.INDY: {
return i.longVal == longVal && i.strVal1.equals(strVal1)
&& i.strVal2.equals(strVal2);
return i.longVal == longVal && i.strVal1.equals(strVal1) && i.strVal2.equals(strVal2);
}
// case ClassWriter.FIELD:
// case ClassWriter.METH:
// case ClassWriter.IMETH:
// case ClassWriter.HANDLE_BASE + 1..9
default:
return i.strVal1.equals(strVal1) && i.strVal2.equals(strVal2)
&& i.strVal3.equals(strVal3);
return i.strVal1.equals(strVal1) && i.strVal2.equals(strVal2) && i.strVal3.equals(strVal3);
}
}
}

View File

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

View File

@@ -9,8 +9,8 @@ import java.util.*;
/**
* MethodVisitor 的调试类
* <p>
* 详情见: https://redkale.org
*
* <p>详情见: https://redkale.org
*
* @author zhangjx
*/
@@ -70,10 +70,7 @@ public class MethodDebugVisitor extends MethodVisitor {
}
}
/**
*
* @param visitor MethodVisitor
*/
/** @param visitor MethodVisitor */
public MethodDebugVisitor(MethodVisitor visitor) {
super(Opcodes.ASM6, visitor);
this.visitor = visitor;
@@ -105,7 +102,8 @@ public class MethodDebugVisitor extends MethodVisitor {
public AnnotationVisitor visitTypeAnnotation(int typeRef, TypePath typePath, String desc, boolean visible) {
AnnotationVisitor av = visitor.visitTypeAnnotation(typeRef, typePath, desc, visible);
if (debug) {
System.out.println("mv.visitTypeAnnotation(" + typeRef + ", " + typePath + ", \"" + desc + "\", " + visible + ");");
System.out.println(
"mv.visitTypeAnnotation(" + typeRef + ", " + typePath + ", \"" + desc + "\", " + visible + ");");
}
return av;
}
@@ -139,7 +137,8 @@ public class MethodDebugVisitor extends MethodVisitor {
} else if (type == 4) {
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) {
visitor.visitMethodInsn(opcode, owner, name, desc, itf);
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) {
visitor.visitLocalVariable(name, desc, signature, start, end, index);
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) {
visitor.visitFieldInsn(opcode, owner, name, desc);
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");
}
}
}

View File

@@ -59,49 +59,42 @@
package org.redkale.asm;
/**
* A visitor to visit a Java method. The methods of this class must be called in
* the following order: ( &#60;tt&#62;visitParameter&#60;/tt&#62; )* [
* &#60;tt&#62;visitAnnotationDefault&#60;/tt&#62; ] ( &#60;tt&#62;visitAnnotation&#60;/tt&#62; |
* &#60;tt&#62;visitParameterAnnotation&#60;/tt&#62; &#60;tt&#62;visitTypeAnnotation&#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;visit<i>X</i>Insn&#60;/tt&#62; | &#60;tt&#62;visitLabel&#60;/tt&#62; |
* &#60;tt&#62;visitInsnAnnotation&#60;/tt&#62; | &#60;tt&#62;visitTryCatchBlock&#60;/tt&#62; |
* &#60;tt&#62;visitTryCatchAnnotation&#60;/tt&#62; | &#60;tt&#62;visitLocalVariable&#60;/tt&#62; |
* &#60;tt&#62;visitLocalVariableAnnotation&#60;/tt&#62; | &#60;tt&#62;visitLineNumber&#60;/tt&#62; )*
* &#60;tt&#62;visitMaxs&#60;/tt&#62; ] &#60;tt&#62;visitEnd&#60;/tt&#62;. 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 called in
* 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;visitTryCatchBlock&#60;/tt&#62; must be called <i>before</i> the
* labels passed as arguments have been visited,
* &#60;tt&#62;visitTryCatchBlockAnnotation&#60;/tt&#62; must be called <i>after</i> the
* corresponding try catch block has been visited, and the
* &#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.
* A visitor to visit a Java method. The methods of this class must be called in the following order: (
* &#60;tt&#62;visitParameter&#60;/tt&#62; )* [ &#60;tt&#62;visitAnnotationDefault&#60;/tt&#62; ] (
* &#60;tt&#62;visitAnnotation&#60;/tt&#62; | &#60;tt&#62;visitParameterAnnotation&#60;/tt&#62;
* &#60;tt&#62;visitTypeAnnotation&#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;visit<i>X</i>Insn&#60;/tt&#62;
* | &#60;tt&#62;visitLabel&#60;/tt&#62; | &#60;tt&#62;visitInsnAnnotation&#60;/tt&#62; |
* &#60;tt&#62;visitTryCatchBlock&#60;/tt&#62; | &#60;tt&#62;visitTryCatchAnnotation&#60;/tt&#62; |
* &#60;tt&#62;visitLocalVariable&#60;/tt&#62; | &#60;tt&#62;visitLocalVariableAnnotation&#60;/tt&#62; |
* &#60;tt&#62;visitLineNumber&#60;/tt&#62; )* &#60;tt&#62;visitMaxs&#60;/tt&#62; ] &#60;tt&#62;visitEnd&#60;/tt&#62;.
* 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
* called in 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;visitTryCatchBlock&#60;/tt&#62; must be called <i>before</i> the labels passed as arguments have been
* visited, &#60;tt&#62;visitTryCatchBlockAnnotation&#60;/tt&#62; must be called <i>after</i> the corresponding try
* catch block has been visited, and the &#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
*/
public abstract class MethodVisitor {
/**
* The ASM API version implemented by this visitor. The value of this field
* must be one of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
* The ASM API version implemented by this visitor. The value of this field must be one of {@link Opcodes#ASM4},
* {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
*/
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;
/**
* Constructs a new {@link MethodVisitor}.
*
* @param api
* the ASM API version implemented by this visitor. Must be one
* of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
* @param api the ASM API version implemented by this visitor. Must be one of {@link Opcodes#ASM4},
* {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
*/
public MethodVisitor(final int api) {
this(api, null);
@@ -110,12 +103,9 @@ public abstract class MethodVisitor {
/**
* Constructs a new {@link MethodVisitor}.
*
* @param api
* the ASM API version implemented by this visitor. Must be one
* 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 api the ASM API version implemented by this visitor. Must be one 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.
*/
public MethodVisitor(final int api, final MethodVisitor mv) {
this.api = api;
@@ -129,12 +119,10 @@ public abstract class MethodVisitor {
/**
* Visits a parameter of this method.
*
* @param name
* parameter name or null if none is provided.
* @param access
* the parameter's access flags, only &#60;tt&#62;ACC_FINAL&#60;/tt&#62;,
* &#60;tt&#62;ACC_SYNTHETIC&#60;/tt&#62; or/and &#60;tt&#62;ACC_MANDATED&#60;/tt&#62; are
* allowed (see {@link Opcodes}).
* @param name parameter name or null if none is provided.
* @param access the parameter's access flags, only &#60;tt&#62;ACC_FINAL&#60;/tt&#62;,
* &#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) {
if (mv != null) {
@@ -145,12 +133,10 @@ public abstract class MethodVisitor {
/**
* Visits the default value of this annotation interface method.
*
* @return a visitor to the visit the actual default value of this
* annotation interface method, or &#60;tt&#62;null&#60;/tt&#62; if this visitor is
* 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 must be called on this
* annotation visitor, followed by visitEnd.
* @return a visitor to the visit the actual default value of this annotation interface method, or
* &#60;tt&#62;null&#60;/tt&#62; if this visitor is 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
* must be called on this annotation visitor, followed by visitEnd.
*/
public AnnotationVisitor visitAnnotationDefault() {
if (mv != null) {
@@ -162,12 +148,10 @@ public abstract class MethodVisitor {
/**
* Visits an annotation of this method.
*
* @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.
* @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 visitAnnotation(String desc, boolean visible) {
if (mv != null) {
@@ -179,30 +163,20 @@ public abstract class MethodVisitor {
/**
* Visits an annotation on a type in the method signature.
*
* @param typeRef
* a reference to the annotated type. The sort of this type
* reference must be {@link TypeReference#METHOD_TYPE_PARAMETER
* METHOD_TYPE_PARAMETER},
* {@link TypeReference#METHOD_TYPE_PARAMETER_BOUND
* METHOD_TYPE_PARAMETER_BOUND},
* {@link TypeReference#METHOD_RETURN METHOD_RETURN},
* {@link TypeReference#METHOD_RECEIVER METHOD_RECEIVER},
* {@link TypeReference#METHOD_FORMAL_PARAMETER
* METHOD_FORMAL_PARAMETER} or {@link TypeReference#THROWS
* THROWS}. See {@link TypeReference}.
* @param typePath
* the path to the annotated type argument, wildcard bound, array
* element type, or static inner type within 'typeRef'. May be
* &#60;tt&#62;null&#60;/tt&#62; if the annotation targets 'typeRef' as a whole.
* @param desc
* the class descriptor of the annotation class.
* @param visible
* &#60;tt&#62;true&#60;/tt&#62; if the annotation is visible at runtime.
* @return a visitor to visit the annotation values, or &#60;tt&#62;null&#60;/tt&#62; if
* this visitor is not interested in visiting this annotation.
* @param typeRef a reference to the annotated type. The sort of this type reference must be
* {@link TypeReference#METHOD_TYPE_PARAMETER METHOD_TYPE_PARAMETER},
* {@link TypeReference#METHOD_TYPE_PARAMETER_BOUND METHOD_TYPE_PARAMETER_BOUND},
* {@link TypeReference#METHOD_RETURN METHOD_RETURN}, {@link TypeReference#METHOD_RECEIVER METHOD_RECEIVER},
* {@link TypeReference#METHOD_FORMAL_PARAMETER METHOD_FORMAL_PARAMETER} or {@link TypeReference#THROWS THROWS}.
* See {@link TypeReference}.
* @param typePath the path to the annotated type argument, wildcard bound, array element type, or static inner type
* within 'typeRef'. May be &#60;tt&#62;null&#60;/tt&#62; if the annotation targets 'typeRef' as a whole.
* @param desc the class descriptor of the annotation class.
* @param visible &#60;tt&#62;true&#60;/tt&#62; if the annotation is visible at runtime.
* @return a visitor to visit the annotation values, or &#60;tt&#62;null&#60;/tt&#62; if this visitor is not
* interested in visiting this annotation.
*/
public AnnotationVisitor visitTypeAnnotation(int typeRef,
TypePath typePath, String desc, boolean visible) {
public AnnotationVisitor visitTypeAnnotation(int typeRef, TypePath typePath, String desc, boolean visible) {
if (mv != null) {
return mv.visitTypeAnnotation(typeRef, typePath, desc, visible);
}
@@ -212,17 +186,13 @@ public abstract class MethodVisitor {
/**
* Visits an annotation of a parameter this method.
*
* @param parameter
* the parameter index.
* @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.
* @param parameter the parameter index.
* @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 visitParameterAnnotation(int parameter,
String desc, boolean visible) {
public AnnotationVisitor visitParameterAnnotation(int parameter, String desc, boolean visible) {
if (mv != null) {
return mv.visitParameterAnnotation(parameter, desc, visible);
}
@@ -232,8 +202,7 @@ public abstract class MethodVisitor {
/**
* Visits a non standard attribute of this method.
*
* @param attr
* an attribute.
* @param attr an attribute.
*/
public void visitAttribute(Attribute attr) {
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() {
if (mv != null) {
mv.visitCode();
@@ -251,82 +218,57 @@ public abstract class MethodVisitor {
}
/**
* Visits the current state of the local variables and operand stack
* elements. This method must(*) be called <i>just before</i> any
* instruction <b>i</b> that follows an unconditional branch instruction
* such as GOTO or THROW, that is the target of a jump instruction, or that
* 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>
* Visits the current state of the local variables and operand stack elements. This method must(*) be called <i>just
* before</i> any instruction <b>i</b> that follows an unconditional branch instruction such as GOTO or THROW, that
* is the target of a jump instruction, or that 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>
* (*) this is mandatory only for classes whose version is greater than or
* equal to {@link Opcodes#V1_6 V1_6}. <br>
* (*) this is mandatory only for classes whose version is greater than or equal to {@link Opcodes#V1_6 V1_6}. <br>
* <br>
* The frames of a method must be given either in expanded form, or in
* compressed form (all frames must use the same format, i.e. you must not
* 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).
* The frames of a method must be given either in expanded form, or in compressed form (all frames must use the same
* format, i.e. you must not mix expanded and compressed frames within a single method):
*
* @param type
* the type of this stack map frame. Must be
* {@link Opcodes#F_NEW} for expanded frames, or
* {@link Opcodes#F_FULL}, {@link Opcodes#F_APPEND},
* {@link Opcodes#F_CHOP}, {@link Opcodes#F_SAME} or
* {@link Opcodes#F_APPEND}, {@link Opcodes#F_SAME1} for
* compressed frames.
* @param nLocal
* the number of local variables in the visited frame.
* @param local
* the local variable types in this frame. This array must not be
* modified. Primitive types are represented by
* {@link Opcodes#TOP}, {@link Opcodes#INTEGER},
* {@link Opcodes#FLOAT}, {@link Opcodes#LONG},
* {@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).
* <ul>
* <li>In expanded form, all frames must have the F_NEW type.
* <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>{@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>{@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>{@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>{@link Opcodes#F_FULL} representing complete frame data.
* </ul>
* </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 the type of this stack map frame. Must be {@link Opcodes#F_NEW} for expanded frames, or
* {@link Opcodes#F_FULL}, {@link Opcodes#F_APPEND}, {@link Opcodes#F_CHOP}, {@link Opcodes#F_SAME} or
* {@link Opcodes#F_APPEND}, {@link Opcodes#F_SAME1} for compressed frames.
* @param nLocal the number of local variables in the visited frame.
* @param local the local variable types in this frame. This array must not be modified. Primitive types are
* represented by {@link Opcodes#TOP}, {@link Opcodes#INTEGER}, {@link Opcodes#FLOAT}, {@link Opcodes#LONG},
* {@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,
Object[] stack) {
public void visitFrame(int type, int nLocal, Object[] local, int nStack, Object[] stack) {
if (mv != null) {
mv.visitFrame(type, nLocal, local, nStack, stack);
}
@@ -339,22 +281,15 @@ public abstract class MethodVisitor {
/**
* Visits a zero operand instruction.
*
* @param opcode
* the opcode of the instruction to be visited. This opcode is
* either NOP, ACONST_NULL, ICONST_M1, ICONST_0, ICONST_1,
* ICONST_2, ICONST_3, ICONST_4, ICONST_5, LCONST_0, LCONST_1,
* FCONST_0, FCONST_1, FCONST_2, DCONST_0, DCONST_1, IALOAD,
* LALOAD, FALOAD, DALOAD, AALOAD, BALOAD, CALOAD, SALOAD,
* IASTORE, LASTORE, FASTORE, DASTORE, AASTORE, BASTORE, CASTORE,
* SASTORE, POP, POP2, DUP, DUP_X1, DUP_X2, DUP2, DUP2_X1,
* DUP2_X2, SWAP, IADD, LADD, FADD, DADD, ISUB, LSUB, FSUB, DSUB,
* 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.
* @param opcode the opcode of the instruction to be visited. This opcode is either NOP, ACONST_NULL, ICONST_M1,
* ICONST_0, ICONST_1, ICONST_2, ICONST_3, ICONST_4, ICONST_5, LCONST_0, LCONST_1, FCONST_0, FCONST_1, FCONST_2,
* DCONST_0, DCONST_1, IALOAD, LALOAD, FALOAD, DALOAD, AALOAD, BALOAD, CALOAD, SALOAD, IASTORE, LASTORE,
* FASTORE, DASTORE, AASTORE, BASTORE, CASTORE, SASTORE, POP, POP2, DUP, DUP_X1, DUP_X2, DUP2, DUP2_X1, DUP2_X2,
* SWAP, IADD, LADD, FADD, DADD, ISUB, LSUB, FSUB, DSUB, 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) {
if (mv != null) {
@@ -365,19 +300,12 @@ public abstract class MethodVisitor {
/**
* Visits an instruction with a single int operand.
*
* @param opcode
* the opcode of the instruction to be visited. This opcode is
* either BIPUSH, SIPUSH or NEWARRAY.
* @param operand
* the operand of the instruction to be visited.<br>
* When opcode is BIPUSH, operand value should be between
* 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},
* @param opcode the opcode of the instruction to be visited. This opcode is either BIPUSH, SIPUSH or NEWARRAY.
* @param operand the operand of the instruction to be visited.<br>
* When opcode is BIPUSH, operand value should be between 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}.
*/
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
* instruction that loads or stores the value of a local variable.
* Visits a local variable instruction. A local variable instruction is an instruction that loads or stores the
* value of a local variable.
*
* @param opcode
* the opcode of the local variable instruction to be visited.
* This opcode is either ILOAD, LLOAD, FLOAD, DLOAD, ALOAD,
* 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.
* @param opcode the opcode of the local variable instruction to be visited. This opcode is either ILOAD, LLOAD,
* FLOAD, DLOAD, ALOAD, 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) {
if (mv != null) {
@@ -405,16 +329,13 @@ public abstract class MethodVisitor {
}
/**
* Visits a type instruction. A type instruction is an instruction that
* takes the internal name of a class as parameter.
* Visits a type instruction. A type instruction is an instruction that takes the internal name of a class as
* parameter.
*
* @param opcode
* the opcode of the type instruction to be visited. This opcode
* 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 array class (see
* {@link Type#getInternalName() getInternalName}).
* @param opcode the opcode of the type instruction to be visited. This opcode 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
* array class (see {@link Type#getInternalName() getInternalName}).
*/
public void visitTypeInsn(int opcode, String type) {
if (mv != null) {
@@ -423,47 +344,32 @@ public abstract class MethodVisitor {
}
/**
* Visits a field instruction. A field instruction is an instruction that
* loads or stores the value of a field of an object.
* Visits a field instruction. A field instruction is an instruction that loads or stores the value of a field of an
* object.
*
* @param opcode
* the opcode of the type instruction to be visited. This opcode
* is either GETSTATIC, PUTSTATIC, GETFIELD or PUTFIELD.
* @param owner
* the internal name of the field's owner class (see
* {@link Type#getInternalName() getInternalName}).
* @param name
* the field's name.
* @param desc
* the field's descriptor (see {@link Type Type}).
* @param opcode the opcode of the type instruction to be visited. This opcode is either GETSTATIC, PUTSTATIC,
* GETFIELD or PUTFIELD.
* @param owner the internal name of the field's owner class (see {@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,
String desc) {
public void visitFieldInsn(int opcode, String owner, String name, String desc) {
if (mv != null) {
mv.visitFieldInsn(opcode, owner, name, desc);
}
}
/**
* Visits a method instruction. A method instruction is an instruction that
* invokes a method.
* Visits a method instruction. A method instruction is an instruction that invokes a method.
*
* @param opcode
* the opcode of the type instruction to be visited. This opcode
* is either INVOKEVIRTUAL, INVOKESPECIAL, INVOKESTATIC or
* INVOKEINTERFACE.
* @param owner
* the internal name of the method's owner class (see
* {@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.
* @param opcode the opcode of the type instruction to be visited. This opcode is either INVOKEVIRTUAL,
* INVOKESPECIAL, INVOKESTATIC or INVOKEINTERFACE.
* @param owner the internal name of the method's owner class (see {@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,
String desc, boolean itf) {
public void visitMethodInsn(int opcode, String owner, String name, String desc, boolean itf) {
if (mv != null) {
mv.visitMethodInsn(opcode, owner, name, desc, itf);
}
@@ -472,39 +378,27 @@ public abstract class MethodVisitor {
/**
* Visits an invokedynamic instruction.
*
* @param name
* the method's name.
* @param desc
* the method's descriptor (see {@link Type Type}).
* @param bsm
* the bootstrap method.
* @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.
* @param name the method's name.
* @param desc the method's descriptor (see {@link Type Type}).
* @param bsm the bootstrap method.
* @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,
Object... bsmArgs) {
public void visitInvokeDynamicInsn(String name, String desc, Handle bsm, Object... bsmArgs) {
if (mv != null) {
mv.visitInvokeDynamicInsn(name, desc, bsm, bsmArgs);
}
}
/**
* Visits a jump instruction. A jump instruction is an instruction that may
* jump to another instruction.
* Visits a jump instruction. A jump instruction is an instruction that may jump to another instruction.
*
* @param opcode
* the opcode of the type instruction to be visited. This opcode
* is either IFEQ, IFNE, IFLT, IFGE, IFGT, IFLE, IF_ICMPEQ,
* IF_ICMPNE, IF_ICMPLT, IF_ICMPGE, IF_ICMPGT, IF_ICMPLE,
* IF_ACMPEQ, IF_ACMPNE, GOTO, JSR, IFNULL or IFNONNULL.
* @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.
* @param opcode the opcode of the type instruction to be visited. This opcode is either IFEQ, IFNE, IFLT, IFGE,
* IFGT, IFLE, IF_ICMPEQ, IF_ICMPNE, IF_ICMPLT, IF_ICMPGE, IF_ICMPGT, IF_ICMPLE, IF_ACMPEQ, IF_ACMPNE, GOTO,
* JSR, IFNULL or IFNONNULL.
* @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) {
if (mv != null) {
@@ -513,11 +407,9 @@ public abstract class MethodVisitor {
}
/**
* Visits a label. A label designates the instruction that will be visited
* just after it.
* Visits a label. A label designates the instruction that will be visited just after it.
*
* @param label
* a {@link Label Label} object.
* @param label a {@link Label Label} object.
*/
public void visitLabel(Label label) {
if (mv != null) {
@@ -530,10 +422,9 @@ public abstract class MethodVisitor {
// -------------------------------------------------------------------------
/**
* Visits a LDC instruction. Note that new constant types may be added in
* future versions of the Java Virtual Machine. To easily detect new
* constant types, implementations of this method should check for
* unexpected constant types, like this:
* Visits a LDC instruction. Note that new constant types may be added in future versions of the Java Virtual
* Machine. To easily detect new constant types, implementations of this method should check for unexpected constant
* types, like this:
*
* <pre>
* if (cst instanceof Integer) {
@@ -564,14 +455,10 @@ public abstract class MethodVisitor {
* }
* </pre>
*
* @param cst
* the constant to be loaded on the stack. This parameter must be
* a non null {@link Integer}, a {@link Float}, a {@link Long}, a
* {@link Double}, a {@link String}, a {@link Type} of OBJECT or
* 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.
* @param cst the constant to be loaded on the stack. This parameter must be a non null {@link Integer}, a
* {@link Float}, a {@link Long}, a {@link Double}, a {@link String}, a {@link Type} of OBJECT or 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) {
if (mv != null) {
@@ -582,10 +469,8 @@ public abstract class MethodVisitor {
/**
* Visits an IINC instruction.
*
* @param var
* index of the local variable to be incremented.
* @param increment
* amount to increment the local variable by.
* @param var index of the local variable to be incremented.
* @param increment amount to increment the local variable by.
*/
public void visitIincInsn(int var, int increment) {
if (mv != null) {
@@ -596,18 +481,13 @@ public abstract class MethodVisitor {
/**
* Visits a TABLESWITCH instruction.
*
* @param min
* the minimum key value.
* @param max
* the maximum key value.
* @param dflt
* 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.
* @param min the minimum key value.
* @param max the maximum key value.
* @param dflt 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,
Label... labels) {
public void visitTableSwitchInsn(int min, int max, Label dflt, Label... labels) {
if (mv != null) {
mv.visitTableSwitchInsn(min, max, dflt, labels);
}
@@ -616,13 +496,10 @@ public abstract class MethodVisitor {
/**
* Visits a LOOKUPSWITCH instruction.
*
* @param dflt
* beginning of the default handler block.
* @param keys
* the values of the keys.
* @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.
* @param dflt beginning of the default handler block.
* @param keys the values of the keys.
* @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) {
if (mv != null) {
@@ -633,10 +510,8 @@ public abstract class MethodVisitor {
/**
* Visits a MULTIANEWARRAY instruction.
*
* @param desc
* an array type descriptor (see {@link Type Type}).
* @param dims
* number of dimensions of the array to allocate.
* @param desc an array type descriptor (see {@link Type Type}).
* @param dims number of dimensions of the array to allocate.
*/
public void visitMultiANewArrayInsn(String desc, int dims) {
if (mv != null) {
@@ -645,38 +520,25 @@ public abstract class MethodVisitor {
}
/**
* Visits an annotation on an instruction. This method must be called just
* <i>after</i> the annotated instruction. It can be called several times
* for the same instruction.
* Visits an annotation on an instruction. This method must be called just <i>after</i> the annotated instruction.
* It can be called several times for the same instruction.
*
* @param typeRef
* a reference to the annotated type. The sort of this type
* reference must be {@link TypeReference#INSTANCEOF INSTANCEOF},
* {@link TypeReference#NEW NEW},
* {@link TypeReference#CONSTRUCTOR_REFERENCE
* CONSTRUCTOR_REFERENCE}, {@link TypeReference#METHOD_REFERENCE
* METHOD_REFERENCE}, {@link TypeReference#CAST CAST},
* {@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
* @param typeRef a reference to the annotated type. The sort of this type reference must be
* {@link TypeReference#INSTANCEOF INSTANCEOF}, {@link TypeReference#NEW NEW},
* {@link TypeReference#CONSTRUCTOR_REFERENCE CONSTRUCTOR_REFERENCE}, {@link TypeReference#METHOD_REFERENCE
* METHOD_REFERENCE}, {@link TypeReference#CAST CAST}, {@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}.
* @param typePath
* the path to the annotated type argument, wildcard bound, array
* element type, or static inner type within 'typeRef'. May be
* &#60;tt&#62;null&#60;/tt&#62; if the annotation targets 'typeRef' as a whole.
* @param desc
* the class descriptor of the annotation class.
* @param visible
* &#60;tt&#62;true&#60;/tt&#62; if the annotation is visible at runtime.
* @return a visitor to visit the annotation values, or &#60;tt&#62;null&#60;/tt&#62; if
* this visitor is not interested in visiting this annotation.
* @param typePath the path to the annotated type argument, wildcard bound, array element type, or static inner type
* within 'typeRef'. May be &#60;tt&#62;null&#60;/tt&#62; if the annotation targets 'typeRef' as a whole.
* @param desc the class descriptor of the annotation class.
* @param visible &#60;tt&#62;true&#60;/tt&#62; if the annotation is visible at runtime.
* @return a visitor to visit the annotation values, or &#60;tt&#62;null&#60;/tt&#62; if this visitor is not
* interested in visiting this annotation.
*/
public AnnotationVisitor visitInsnAnnotation(int typeRef,
TypePath typePath, String desc, boolean visible) {
public AnnotationVisitor visitInsnAnnotation(int typeRef, TypePath typePath, String desc, boolean visible) {
if (mv != null) {
return mv.visitInsnAnnotation(typeRef, typePath, desc, visible);
}
@@ -690,50 +552,35 @@ public abstract class MethodVisitor {
/**
* Visits a try catch block.
*
* @param start
* beginning of the exception handler's scope (inclusive).
* @param end
* end of the exception handler's scope (exclusive).
* @param handler
* beginning of the exception handler's code.
* @param type
* 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).
* @param start beginning of the exception handler's scope (inclusive).
* @param end end of the exception handler's scope (exclusive).
* @param handler beginning of the exception handler's code.
* @param type 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,
String type) {
public void visitTryCatchBlock(Label start, Label end, Label handler, String type) {
if (mv != null) {
mv.visitTryCatchBlock(start, end, handler, type);
}
}
/**
* Visits an annotation on an exception handler type. This method must be
* called <i>after</i> the {@link #visitTryCatchBlock} for the annotated
* exception handler. It can be called several times for the same exception
* handler.
* Visits an annotation on an exception handler type. This method must be called <i>after</i> the
* {@link #visitTryCatchBlock} for the annotated exception handler. It can be called several times for the same
* exception handler.
*
* @param typeRef
* a reference to the annotated type. The sort of this type
* reference must be {@link TypeReference#EXCEPTION_PARAMETER
* EXCEPTION_PARAMETER}. See {@link TypeReference}.
* @param typePath
* the path to the annotated type argument, wildcard bound, array
* element type, or static inner type within 'typeRef'. May be
* &#60;tt&#62;null&#60;/tt&#62; if the annotation targets 'typeRef' as a whole.
* @param desc
* the class descriptor of the annotation class.
* @param visible
* &#60;tt&#62;true&#60;/tt&#62; if the annotation is visible at runtime.
* @return a visitor to visit the annotation values, or &#60;tt&#62;null&#60;/tt&#62; if
* this visitor is not interested in visiting this annotation.
* @param typeRef a reference to the annotated type. The sort of this type reference must be
* {@link TypeReference#EXCEPTION_PARAMETER EXCEPTION_PARAMETER}. See {@link TypeReference}.
* @param typePath the path to the annotated type argument, wildcard bound, array element type, or static inner type
* within 'typeRef'. May be &#60;tt&#62;null&#60;/tt&#62; if the annotation targets 'typeRef' as a whole.
* @param desc the class descriptor of the annotation class.
* @param visible &#60;tt&#62;true&#60;/tt&#62; if the annotation is visible at runtime.
* @return a visitor to visit the annotation values, or &#60;tt&#62;null&#60;/tt&#62; if this visitor is not
* interested in visiting this annotation.
*/
public AnnotationVisitor visitTryCatchAnnotation(int typeRef,
TypePath typePath, String desc, boolean visible) {
public AnnotationVisitor visitTryCatchAnnotation(int typeRef, TypePath typePath, String desc, boolean visible) {
if (mv != null) {
return mv.visitTryCatchAnnotation(typeRef, typePath, desc, visible);
}
@@ -743,28 +590,17 @@ public abstract class MethodVisitor {
/**
* Visits a local variable declaration.
*
* @param name
* the name of a local variable.
* @param desc
* the type descriptor of this local variable.
* @param signature
* the type signature of this local variable. May be
* &#60;tt&#62;null&#60;/tt&#62; if the local variable type does not use generic
* types.
* @param start
* 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).
* @param name the name of a local variable.
* @param desc the type descriptor of this local variable.
* @param signature the type signature of this local variable. May be &#60;tt&#62;null&#60;/tt&#62; if the local
* variable type does not use generic types.
* @param start 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,
Label start, Label end, int index) {
public void visitLocalVariable(String name, String desc, String signature, Label start, Label end, int index) {
if (mv != null) {
mv.visitLocalVariable(name, desc, signature, start, end, index);
}
@@ -773,38 +609,25 @@ public abstract class MethodVisitor {
/**
* Visits an annotation on a local variable type.
*
* @param typeRef
* a reference to the annotated type. The sort of this type
* reference must be {@link TypeReference#LOCAL_VARIABLE
* LOCAL_VARIABLE} or {@link TypeReference#RESOURCE_VARIABLE
* @param typeRef a reference to the annotated type. The sort of this type reference must be
* {@link TypeReference#LOCAL_VARIABLE LOCAL_VARIABLE} or {@link TypeReference#RESOURCE_VARIABLE
* RESOURCE_VARIABLE}. See {@link TypeReference}.
* @param typePath
* the path to the annotated type argument, wildcard bound, array
* element type, or static inner type within 'typeRef'. May be
* &#60;tt&#62;null&#60;/tt&#62; if the annotation targets 'typeRef' as a whole.
* @param start
* the fist instructions corresponding to the continuous ranges
* that make the scope of this local variable (inclusive).
* @param end
* the last instructions corresponding to the continuous ranges
* that make the scope of this local variable (exclusive). This
* array must have the same size as the 'start' array.
* @param index
* the local variable's index in each range. This array must have
* the same size as the 'start' array.
* @param desc
* the class descriptor of the annotation class.
* @param visible
* &#60;tt&#62;true&#60;/tt&#62; if the annotation is visible at runtime.
* @return a visitor to visit the annotation values, or &#60;tt&#62;null&#60;/tt&#62; if
* this visitor is not interested in visiting this annotation.
* @param typePath the path to the annotated type argument, wildcard bound, array element type, or static inner type
* within 'typeRef'. May be &#60;tt&#62;null&#60;/tt&#62; if the annotation targets 'typeRef' as a whole.
* @param start the fist instructions corresponding to the continuous ranges that make the scope of this local
* variable (inclusive).
* @param end the last instructions corresponding to the continuous ranges that make the scope of this local
* variable (exclusive). This array must have the same size as the 'start' array.
* @param index the local variable's index in each range. This array must have the same size as the 'start' array.
* @param desc the class descriptor of the annotation class.
* @param visible &#60;tt&#62;true&#60;/tt&#62; if the annotation is visible at runtime.
* @return a visitor to visit the annotation values, or &#60;tt&#62;null&#60;/tt&#62; if this visitor is not
* interested in visiting this annotation.
*/
public AnnotationVisitor visitLocalVariableAnnotation(int typeRef,
TypePath typePath, Label[] start, Label[] end, int[] index,
String desc, boolean visible) {
public AnnotationVisitor visitLocalVariableAnnotation(
int typeRef, TypePath typePath, Label[] start, Label[] end, int[] index, String desc, boolean visible) {
if (mv != null) {
return mv.visitLocalVariableAnnotation(typeRef, typePath, start,
end, index, desc, visible);
return mv.visitLocalVariableAnnotation(typeRef, typePath, start, end, index, desc, visible);
}
return null;
}
@@ -812,14 +635,10 @@ public abstract class MethodVisitor {
/**
* Visits a line number declaration.
*
* @param line
* a line number. This number refers to the source file from
* which the class was compiled.
* @param start
* 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).
* @param line a line number. This number refers to the source file from which the class was compiled.
* @param start 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) {
if (mv != null) {
@@ -828,13 +647,10 @@ public abstract class MethodVisitor {
}
/**
* Visits the maximum stack size and the maximum number of local variables
* of the method.
* Visits the maximum stack size and the maximum number of local variables of the method.
*
* @param maxStack
* maximum stack size of the method.
* @param maxLocals
* maximum number of local variables for the method.
* @param maxStack maximum stack size of the method.
* @param maxLocals maximum number of local variables for the method.
*/
public void visitMaxs(int maxStack, int maxLocals) {
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
* called, is used to inform the visitor that all the annotations and
* attributes of the method have been visited.
* Visits the end of the method. This method, which is the last one to be called, is used to inform the visitor that
* all the annotations and attributes of the method have been visited.
*/
public void visitEnd() {
if (mv != null) {

File diff suppressed because it is too large Load Diff

View File

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

View File

@@ -59,119 +59,87 @@
package org.redkale.asm;
/**
* @author Remi Forax
*/
/** @author Remi Forax */
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;
/**
* size in byte of the Module attribute.
*/
/** size in byte of the Module attribute. */
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;
/**
* Size in bytes of the attributes associated with the current module
*/
/** Size in bytes of the attributes associated with the current module */
int attributesSize;
/**
* module name index in the constant pool
*/
/** module name index in the constant pool */
private final int name;
/**
* module access flags
*/
/** module access flags */
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;
/**
* module main class index in the constant pool or 0
*/
/** module main class index in the constant pool or 0 */
private int mainClass;
/**
* number of packages
*/
/** number of packages */
private int packageCount;
/**
* The packages in bytecode form. This byte vector only contains
* the items themselves, the number of items is store in packageCount
* The packages in bytecode form. This byte vector only contains the items themselves, the number of items is store
* in packageCount
*/
private ByteVector packages;
/**
* number of requires items
*/
/** number of requires items */
private int requireCount;
/**
* The requires items in bytecode form. This byte vector only contains
* the items themselves, the number of items is store in requireCount
* The requires items in bytecode form. This byte vector only contains the items themselves, the number of items is
* store in requireCount
*/
private ByteVector requires;
/**
* number of exports items
*/
/** number of exports items */
private int exportCount;
/**
* The exports items in bytecode form. This byte vector only contains
* the items themselves, the number of items is store in exportCount
* The exports items in bytecode form. This byte vector only contains the items themselves, the number of items is
* store in exportCount
*/
private ByteVector exports;
/**
* number of opens items
*/
/** number of opens items */
private int openCount;
/**
* The opens items in bytecode form. This byte vector only contains
* the items themselves, the number of items is store in openCount
* The opens items in bytecode form. This byte vector only contains the items themselves, the number of items is
* store in openCount
*/
private ByteVector opens;
/**
* number of uses items
*/
/** number of uses items */
private int useCount;
/**
* The uses items in bytecode form. This byte vector only contains
* the items themselves, the number of items is store in useCount
* The uses items in bytecode form. This byte vector only contains the items themselves, the number of items is
* store in useCount
*/
private ByteVector uses;
/**
* number of provides items
*/
/** number of provides items */
private int provideCount;
/**
* The uses provides in bytecode form. This byte vector only contains
* the items themselves, the number of items is store in provideCount
* The uses provides in bytecode form. This byte vector only contains the items themselves, the number of items is
* store in provideCount
*/
private ByteVector provides;
ModuleWriter(final ClassWriter cw, final int name,
final int access, final int version) {
ModuleWriter(final ClassWriter cw, final int name, final int access, final int version) {
super(Opcodes.ASM6);
this.cw = cw;
this.size = 16; // name + access + version + 5 counts
@@ -209,9 +177,7 @@ final class ModuleWriter extends ModuleVisitor {
if (requires == null) {
requires = new ByteVector();
}
requires.putShort(cw.newModule(module))
.putShort(access)
.putShort(version == null? 0: cw.newUTF8(version));
requires.putShort(cw.newModule(module)).putShort(access).putShort(version == null ? 0 : cw.newUTF8(version));
requireCount++;
size += 6;
}

View File

@@ -59,13 +59,10 @@
package org.redkale.asm;
/**
* Defines the JVM opcodes, access flags and array type codes. This interface
* does not define all the JVM opcodes because some opcodes are automatically
* 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 interface. Likewise for LDC,
* automatically replaced by LDC_W or LDC2_W when necessary, WIDE, GOTO_W and
* JSR_W.
* Defines the JVM opcodes, access flags and array type codes. This interface does not define all the JVM opcodes
* because some opcodes are automatically 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
* interface. Likewise for LDC, automatically replaced by LDC_W or LDC2_W when necessary, WIDE, GOTO_W and JSR_W.
*
* @author Eric Bruneton
* @author Eugene Kuleshov
@@ -117,7 +114,6 @@ public interface Opcodes {
int ACC_MANDATED = 0x8000; // parameter, module, module *
int ACC_MODULE = 0x8000; // class
// ASM specific pseudo access flags
int ACC_DEPRECATED = 0x20000; // class, field, method
@@ -147,39 +143,30 @@ public interface Opcodes {
// 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;
/**
* Represents a compressed frame with complete frame data.
*/
/** Represents a compressed frame with complete frame data. */
int F_FULL = 0;
/**
* Represents a compressed frame where locals are the same as the locals in
* the previous frame, except that additional 1-3 locals are defined, and
* with an empty stack.
* Represents a compressed frame where locals are the same as the locals in the previous frame, except that
* additional 1-3 locals are defined, and with an empty stack.
*/
int F_APPEND = 1;
/**
* Represents a compressed frame where locals are the same as the locals in
* the previous frame, except that the last 1-3 locals are absent and with
* an empty stack.
* Represents a compressed frame where locals are the same as the locals in the previous frame, except that the last
* 1-3 locals are absent and with an empty stack.
*/
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;
/**
* Represents a compressed frame with exactly the same locals as the
* previous frame and with a single value on the stack.
* Represents a compressed frame with exactly the same locals as the previous frame and with a single value on the
* stack.
*/
int F_SAME1 = 4;
@@ -187,13 +174,26 @@ public interface Opcodes {
// these values are compared by reference and not by value
// The constructor of Integer was deprecated in 9
// but we are stuck with it by backward compatibility
@SuppressWarnings("deprecation") Integer TOP = new Integer(0);
@SuppressWarnings("deprecation") Integer INTEGER = new Integer(1);
@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);
@SuppressWarnings("deprecation")
Integer TOP = new Integer(0);
@SuppressWarnings("deprecation")
Integer INTEGER = new Integer(1);
@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)

View File

@@ -62,154 +62,94 @@ import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
/**
* A Java field or method type. This class can be used to make it easier to
* manipulate type and method descriptors.
* A Java field or method type. This class can be used to make it easier to manipulate type and method descriptors.
*
* @author Eric Bruneton
* @author Chris Nokleberg
*/
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;
/**
* 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;
/**
* 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;
/**
* 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;
/**
* 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;
/**
* 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;
/**
* 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;
/**
* 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;
/**
* 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;
/**
* 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;
/**
* 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;
/**
* The sort of method types. See {@link #getSort getSort}.
*/
/** The sort of method types. See {@link #getSort getSort}. */
public static final int METHOD = 11;
/**
* 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);
/** 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);
/**
* 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);
/** 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);
/**
* 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);
/** 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);
/**
* 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);
/** 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);
/**
* 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);
/** 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);
/**
* 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);
/** 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);
/**
* 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);
/** 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);
/**
* 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);
/** 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);
/**
* 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);
/** 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);
// ------------------------------------------------------------------------
// Fields
// ------------------------------------------------------------------------
/**
* The sort of this Java type.
*/
/** The sort of this Java type. */
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;
/**
* The offset of the internal name of this Java type in {@link #buf buf} or,
* for primitive types, the size, descriptor and getOpcode offsets for this
* type (byte 0 contains the size, byte 1 the descriptor, byte 2 the offset
* for IALOAD or IASTORE, byte 3 the offset for all other instructions).
* The offset of the internal name of this Java type in {@link #buf buf} or, for primitive types, the size,
* descriptor and getOpcode offsets for this type (byte 0 contains the size, byte 1 the descriptor, byte 2 the
* offset for IALOAD or IASTORE, byte 3 the offset for all other instructions).
*/
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;
// ------------------------------------------------------------------------
@@ -219,14 +159,10 @@ public class Type {
/**
* Constructs a reference type.
*
* @param sort
* the sort of the reference type to be constructed.
* @param buf
* a buffer containing the descriptor of the previous type.
* @param off
* the offset of this descriptor in the previous buffer.
* @param len
* the length of this descriptor.
* @param sort the sort of the reference type to be constructed.
* @param buf a buffer containing the descriptor of the previous type.
* @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) {
this.sort = sort;
@@ -238,8 +174,7 @@ public class Type {
/**
* Returns the Java type corresponding to the given type descriptor.
*
* @param typeDescriptor
* a field or method type descriptor.
* @param typeDescriptor a field or method type descriptor.
* @return the Java type corresponding to the given type descriptor.
*/
public static Type getType(final String typeDescriptor) {
@@ -249,8 +184,7 @@ public class Type {
/**
* Returns the Java type corresponding to the given internal name.
*
* @param internalName
* an internal name.
* @param internalName an internal name.
* @return the Java type corresponding to the given internal name.
*/
public static Type getObjectType(final String internalName) {
@@ -259,11 +193,10 @@ public class Type {
}
/**
* Returns the Java type corresponding to the given method descriptor.
* Equivalent to <code>Type.getType(methodDescriptor)</code>.
* Returns the Java type corresponding to the given method descriptor. Equivalent to <code>
* Type.getType(methodDescriptor)</code>.
*
* @param methodDescriptor
* a method descriptor.
* @param methodDescriptor a method descriptor.
* @return the Java type corresponding to the given method descriptor.
*/
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
* return types.
* Returns the Java method type corresponding to the given argument and return types.
*
* @param returnType
* the return type of the method.
* @param argumentTypes
* the argument types of the method.
* @return the Java type corresponding to the given argument and return
* types.
* @param returnType the return type of the method.
* @param argumentTypes 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,
final Type... argumentTypes) {
public static Type getMethodType(final Type returnType, final Type... argumentTypes) {
return getType(getMethodDescriptor(returnType, argumentTypes));
}
/**
* Returns the Java type corresponding to the given class.
*
* @param c
* a class.
* @param c a class.
* @return the Java type corresponding to the given class.
*/
public static Type getType(final Class<?> c) {
@@ -322,8 +249,7 @@ public class Type {
/**
* Returns the Java method type corresponding to the given constructor.
*
* @param c
* a {@link Constructor Constructor} object.
* @param c a {@link Constructor Constructor} object.
* @return the Java method type corresponding to the given constructor.
*/
public static Type getType(final Constructor<?> c) {
@@ -333,8 +259,7 @@ public class Type {
/**
* Returns the Java method type corresponding to the given method.
*
* @param m
* a {@link Method Method} object.
* @param m a {@link Method Method} object.
* @return the Java method type corresponding to the given method.
*/
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
* method descriptor.
* Returns the Java types corresponding to the argument types of the given method descriptor.
*
* @param methodDescriptor
* a method descriptor.
* @return the Java types corresponding to the argument types of the given
* method descriptor.
* @param methodDescriptor a method descriptor.
* @return the Java types corresponding to the argument types of the given method descriptor.
*/
public static Type[] getArgumentTypes(final String methodDescriptor) {
char[] buf = methodDescriptor.toCharArray();
@@ -379,13 +301,10 @@ public class Type {
}
/**
* Returns the Java types corresponding to the argument types of the given
* method.
* Returns the Java types corresponding to the argument types of the given method.
*
* @param method
* a method.
* @return the Java types corresponding to the argument types of the given
* method.
* @param method a method.
* @return the Java types corresponding to the argument types of the given method.
*/
public static Type[] getArgumentTypes(final Method method) {
Class<?>[] classes = method.getParameterTypes();
@@ -397,13 +316,10 @@ public class Type {
}
/**
* Returns the Java type corresponding to the return type of the given
* method descriptor.
* Returns the Java type corresponding to the return type of the given method descriptor.
*
* @param methodDescriptor
* a method descriptor.
* @return the Java type corresponding to the return type of the given
* method descriptor.
* @param methodDescriptor a method descriptor.
* @return the Java type corresponding to the return type of the given method descriptor.
*/
public static Type getReturnType(final String methodDescriptor) {
char[] buf = methodDescriptor.toCharArray();
@@ -421,13 +337,10 @@ public class Type {
}
/**
* Returns the Java type corresponding to the return type of the given
* method.
* Returns the Java type corresponding to the return type of the given method.
*
* @param method
* a method.
* @return the Java type corresponding to the return type of the given
* method.
* @param method a method.
* @return the Java type corresponding to the return type of the given method.
*/
public static Type getReturnType(final Method method) {
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.
*
* @param desc
* 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 of its return
* value, retSize, packed into a single int i =
* &#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;).
* @param desc 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
* of its return value, retSize, packed into a single int i = &#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) {
int n = 1;
@@ -451,8 +362,7 @@ public class Type {
char car = desc.charAt(c++);
if (car == ')') {
car = desc.charAt(c);
return n << 2
| (car == 'V' ? 0 : (car == 'D' || car == 'J' ? 2 : 1));
return n << 2 | (car == 'V' ? 0 : (car == 'D' || car == 'J' ? 2 : 1));
} else if (car == 'L') {
while (desc.charAt(c++) != ';') {
// do nothing
@@ -474,14 +384,11 @@ public class Type {
}
/**
* Returns the Java type corresponding to the given type descriptor. For
* method descriptors, buf is supposed to contain nothing more than the
* descriptor itself.
* Returns the Java type corresponding to the given type descriptor. For method descriptors, buf is supposed to
* contain nothing more than the descriptor itself.
*
* @param buf
* a buffer containing a type descriptor.
* @param off
* the offset of this descriptor in the previous buffer.
* @param buf a buffer containing a type descriptor.
* @param off the offset of this descriptor in the previous buffer.
* @return the Java type corresponding to the given type descriptor.
*/
private static Type getType(final char[] buf, final int off) {
@@ -536,19 +443,16 @@ public class Type {
/**
* Returns the sort of this Java type.
*
* @return {@link #VOID VOID}, {@link #BOOLEAN BOOLEAN}, {@link #CHAR CHAR},
* {@link #BYTE BYTE}, {@link #SHORT SHORT}, {@link #INT INT},
* {@link #FLOAT FLOAT}, {@link #LONG LONG}, {@link #DOUBLE DOUBLE},
* {@link #ARRAY ARRAY}, {@link #OBJECT OBJECT} or {@link #METHOD
* METHOD}.
* @return {@link #VOID VOID}, {@link #BOOLEAN BOOLEAN}, {@link #CHAR CHAR}, {@link #BYTE BYTE}, {@link #SHORT
* SHORT}, {@link #INT INT}, {@link #FLOAT FLOAT}, {@link #LONG LONG}, {@link #DOUBLE DOUBLE}, {@link #ARRAY
* ARRAY}, {@link #OBJECT OBJECT} or {@link #METHOD METHOD}.
*/
public int getSort() {
return sort;
}
/**
* Returns the number of dimensions of this array type. This method should
* only be used for an array type.
* Returns the number of dimensions of this array type. This method should only be used for an 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
* only be used for an array type.
* Returns the type of the elements of this array type. This method should only be used for an 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
* method must not be used on method types.
* Returns the binary name of the class corresponding to this type. This method must not be used on method types.
*
* @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
* array type. The internal name of a class is its fully qualified name (as
* returned by Class.getName(), where '.' are replaced by '/'. This method
* should only be used for an object or array type.
* Returns the internal name of the class corresponding to this object or array type. The internal name of a class
* is its fully qualified name (as returned by Class.getName(), where '.' are replaced by '/'. This method should
* only be used for an object or array 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
* only be used for method types.
* Returns the argument types of methods of this type. This method should only be used for method types.
*
* @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
* be used for method types.
* Returns the return type of methods of this type. This method should only be used for method types.
*
* @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
* this type. This method should only be used for method types.
* Returns the size of the arguments and of the return value of methods of this type. This method should only be
* used for method types.
*
* @return the size of the arguments (plus one for the implicit this
* argument), argSize, and the size of the return value, retSize,
* packed into a single
* int i = &#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;).
* @return the size of the arguments (plus one for the implicit this argument), argSize, and the size of the return
* value, retSize, packed into a single int i = &#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 int getArgumentsAndReturnSizes() {
return getArgumentsAndReturnSizes(getDescriptor());
@@ -672,18 +569,13 @@ public class Type {
}
/**
* Returns the descriptor corresponding to the given argument and return
* types.
* Returns the descriptor corresponding to the given argument and return types.
*
* @param returnType
* the return type of the method.
* @param argumentTypes
* the argument types of the method.
* @return the descriptor corresponding to the given argument and return
* types.
* @param returnType the return type of the method.
* @param argumentTypes the argument types of the method.
* @return the descriptor corresponding to the given argument and return types.
*/
public static String getMethodDescriptor(final Type returnType,
final Type... argumentTypes) {
public static String getMethodDescriptor(final Type returnType, final Type... argumentTypes) {
StringBuilder buf = new StringBuilder();
buf.append('(');
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
* string buffer.
* Appends the descriptor corresponding to this Java type to the given string buffer.
*
* @param buf
* the string buffer to which the descriptor must be appended.
* @param buf the string buffer to which the descriptor must be appended.
*/
private void getDescriptor(final StringBuilder buf) {
if (this.buf == null) {
@@ -721,12 +611,10 @@ public class Type {
// ------------------------------------------------------------------------
/**
* Returns the internal name of the given class. The internal name of a
* class is its fully qualified name, as returned by Class.getName(), where
* '.' are replaced by '/'.
* Returns the internal name of the given class. The internal name of a class is its fully qualified name, as
* returned by Class.getName(), where '.' are replaced by '/'.
*
* @param c
* an object or array class.
* @param c an object or array class.
* @return the internal name of the given class.
*/
public static String getInternalName(final Class<?> c) {
@@ -736,8 +624,7 @@ public class Type {
/**
* Returns the descriptor corresponding to the given Java type.
*
* @param c
* an object class, a primitive class or an array class.
* @param c an object class, a primitive class or an array class.
* @return the descriptor corresponding to the given class.
*/
public static String getDescriptor(final Class<?> c) {
@@ -749,8 +636,7 @@ public class Type {
/**
* Returns the descriptor corresponding to the given constructor.
*
* @param c
* a {@link Constructor Constructor} object.
* @param c a {@link Constructor Constructor} object.
* @return the descriptor of the given constructor.
*/
public static String getConstructorDescriptor(final Constructor<?> c) {
@@ -766,8 +652,7 @@ public class Type {
/**
* Returns the descriptor corresponding to the given method.
*
* @param m
* a {@link Method Method} object.
* @param m a {@link Method Method} object.
* @return the descriptor of the given method.
*/
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.
*
* @param buf
* the string buffer to which the descriptor must be appended.
* @param c
* the class whose descriptor must be computed.
* @param buf the string buffer to which the descriptor must be appended.
* @param c the class whose descriptor must be computed.
*/
private static void getDescriptor(final StringBuilder buf, final Class<?> 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
* method types.
* Returns the size of values of this type. This method must not be used for method types.
*
* @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.
@@ -850,16 +732,13 @@ public class Type {
}
/**
* Returns a JVM instruction opcode adapted to this Java type. This method
* must not be used for method types.
* Returns a JVM instruction opcode adapted to this Java type. This method must not be used for method types.
*
* @param opcode
* a JVM instruction opcode. This opcode must be one of ILOAD,
* ISTORE, IALOAD, IASTORE, IADD, ISUB, IMUL, IDIV, IREM, INEG,
* ISHL, ISHR, IUSHR, IAND, IOR, IXOR and IRETURN.
* @return an opcode that is similar to the given opcode, but adapted to
* 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.
* @param opcode a JVM instruction opcode. This opcode must be one of ILOAD, ISTORE, IALOAD, IASTORE, IADD, ISUB,
* IMUL, IDIV, IREM, INEG, ISHL, ISHR, IUSHR, IAND, IOR, IXOR and IRETURN.
* @return an opcode that is similar to the given opcode, but adapted to 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) {
if (opcode == Opcodes.IALOAD || opcode == Opcodes.IASTORE) {
@@ -880,8 +759,7 @@ public class Type {
/**
* Tests if the given object is equal to this type.
*
* @param o
* the object to be compared to this type.
* @param o 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.
*/
@Override

View File

@@ -60,55 +60,35 @@
package org.redkale.asm;
/**
* The path to a type argument, wildcard bound, array element type, or static
* inner type within an enclosing type.
* The path to a type argument, wildcard bound, array element type, or static inner type within an enclosing type.
*
* @author Eric Bruneton
*/
public class TypePath {
/**
* A type path step that steps into the element type of an array type. See
* {@link #getStep getStep}.
*/
public final static int ARRAY_ELEMENT = 0;
/** A type path step that steps into the element type of an array type. See {@link #getStep getStep}. */
public static final int ARRAY_ELEMENT = 0;
/**
* A type path step that steps into the nested type of a class type. See
* {@link #getStep getStep}.
*/
public final static int INNER_TYPE = 1;
/** A type path step that steps into the nested type of a class type. See {@link #getStep getStep}. */
public static final int INNER_TYPE = 1;
/**
* A type path step that steps into the bound of a wildcard type. See
* {@link #getStep getStep}.
*/
public final static int WILDCARD_BOUND = 2;
/** A type path step that steps into the bound of a wildcard type. See {@link #getStep getStep}. */
public static final int WILDCARD_BOUND = 2;
/**
* A type path step that steps into a type argument of a generic type. See
* {@link #getStep getStep}.
*/
public final static int TYPE_ARGUMENT = 3;
/** A type path step that steps into a type argument of a generic type. See {@link #getStep getStep}. */
public static final 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;
/**
* 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;
/**
* Creates a new type path.
*
* @param b
* the byte array containing the type path in Java class file
* format.
* @param offset
* the offset of the first byte of the type path in 'b'.
* @param b the byte array containing the type path in Java class file format.
* @param offset the offset of the first byte of the type path in 'b'.
*/
TypePath(byte[] b, int offset) {
this.b = b;
@@ -127,37 +107,29 @@ public class TypePath {
/**
* Returns the value of the given step of this path.
*
* @param index
* an index between 0 and {@link #getLength()}, exclusive.
* @return {@link #ARRAY_ELEMENT ARRAY_ELEMENT}, {@link #INNER_TYPE
* INNER_TYPE}, {@link #WILDCARD_BOUND WILDCARD_BOUND}, or
* {@link #TYPE_ARGUMENT TYPE_ARGUMENT}.
* @param index an index between 0 and {@link #getLength()}, exclusive.
* @return {@link #ARRAY_ELEMENT ARRAY_ELEMENT}, {@link #INNER_TYPE INNER_TYPE}, {@link #WILDCARD_BOUND
* WILDCARD_BOUND}, or {@link #TYPE_ARGUMENT TYPE_ARGUMENT}.
*/
public int getStep(int index) {
return b[offset + 2 * index + 1];
}
/**
* Returns the index of the type argument that the given step is stepping
* into. This method should only be used for steps whose value is
* {@link #TYPE_ARGUMENT TYPE_ARGUMENT}.
* Returns the index of the type argument that the given step is stepping into. This method should only be used for
* steps whose value is {@link #TYPE_ARGUMENT TYPE_ARGUMENT}.
*
* @param index
* an index between 0 and {@link #getLength()}, exclusive.
* @return the index of the type argument that the given step is stepping
* into.
* @param index an index between 0 and {@link #getLength()}, exclusive.
* @return the index of the type argument that the given step is stepping into.
*/
public int getStepArgument(int index) {
return b[offset + 2 * index + 2];
}
/**
* Converts a type path in string form, in the format used by
* {@link #toString()}, into a TypePath object.
* Converts a type path in string form, in the format used by {@link #toString()}, into a TypePath object.
*
* @param typePath
* a type path in string form, in the format used by
* {@link #toString()}. May be null or empty.
* @param typePath 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.
*/
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
* ARRAY_ELEMENT} steps are represented with '[', {@link #INNER_TYPE
* INNER_TYPE} steps with '.', {@link #WILDCARD_BOUND WILDCARD_BOUND} steps
* with '*' and {@link #TYPE_ARGUMENT TYPE_ARGUMENT} steps with their type
* argument index in decimal form followed by ';'.
* Returns a string representation of this type path. {@link #ARRAY_ELEMENT ARRAY_ELEMENT} steps are represented
* with '[', {@link #INNER_TYPE INNER_TYPE} steps with '.', {@link #WILDCARD_BOUND WILDCARD_BOUND} steps with '*'
* and {@link #TYPE_ARGUMENT TYPE_ARGUMENT} steps with their type argument index in decimal form followed by ';'.
*/
@Override
public String toString() {

View File

@@ -60,160 +60,136 @@
package org.redkale.asm;
/**
* A reference to a type appearing in a class, field or method declaration, or
* on an instruction. Such a reference designates the part of the class where
* 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).
* A reference to a type appearing in a class, field or method declaration, or on an instruction. Such a reference
* designates the part of the class where 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).
*
* @author Eric Bruneton
*/
public class TypeReference {
/**
* The sort of type references that target a type parameter of a generic
* class. See {@link #getSort getSort}.
*/
public final static int CLASS_TYPE_PARAMETER = 0x00;
/** The sort of type references that target a type parameter of a generic class. See {@link #getSort getSort}. */
public static final int CLASS_TYPE_PARAMETER = 0x00;
/** The sort of type references that target a type parameter of a generic method. See {@link #getSort getSort}. */
public static final int METHOD_TYPE_PARAMETER = 0x01;
/**
* The sort of type references that target a type parameter of a generic
* 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
* 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 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}.
*/
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.
* See {@link #getSort getSort}.
* The sort of type references that target the type of a local variable in a method. 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
* a method. See {@link #getSort getSort}.
* The sort of type references that target the type of a resource variable in a method. See {@link #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
* in the throws clause of a method. See {@link #getSort getSort}.
* The sort of type references that target the type of the exception of a 'catch' clause in a method. See
* {@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
* method. See {@link #getSort getSort}.
* The sort of type references that target the type declared in an 'instanceof' instruction. See {@link #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
* in a method. See {@link #getSort getSort}.
* The sort of type references that target the type of the object created by a 'new' instruction. See
* {@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
* 'catch' clause in a method. See {@link #getSort getSort}.
* The sort of type references that target the receiver type of a constructor reference. See {@link #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
* 'instanceof' instruction. See {@link #getSort getSort}.
* The sort of type references that target the receiver type of a method reference. 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
* a 'new' instruction. See {@link #getSort getSort}.
* The sort of type references that target the type declared in an explicit or implicit cast instruction. See
* {@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
* constructor reference. See {@link #getSort getSort}.
* The sort of type references that target a type parameter of a generic constructor in a constructor call. See
* {@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
* reference. See {@link #getSort getSort}.
* 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_REFERENCE = 0x46;
public static final int METHOD_INVOCATION_TYPE_ARGUMENT = 0x49;
/**
* The sort of type references that target the type declared in an explicit
* or implicit cast instruction. See {@link #getSort getSort}.
* 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 CAST = 0x47;
public static final int CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT = 0x4A;
/**
* The sort of type references that target a type parameter of a generic
* constructor in a constructor call. See {@link #getSort getSort}.
* 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 CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT = 0x48;
public static final int METHOD_REFERENCE_TYPE_ARGUMENT = 0x4B;
/**
* 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.
*/
/** The type reference value in Java class file format. */
private int value;
/**
* Creates a new TypeReference.
*
* @param typeRef
* the int encoded value of the type reference, as received in a
* visit method related to type annotations, like
* visitTypeAnnotation.
* @param typeRef the int encoded value of the type reference, as received in a visit method related to type
* annotations, like visitTypeAnnotation.
*/
public TypeReference(int typeRef) {
this.value = typeRef;
@@ -222,13 +198,9 @@ public class TypeReference {
/**
* Returns a type reference of the given sort.
*
* @param sort
* {@link #FIELD FIELD}, {@link #METHOD_RETURN METHOD_RETURN},
* {@link #METHOD_RECEIVER METHOD_RECEIVER},
* {@link #LOCAL_VARIABLE LOCAL_VARIABLE},
* {@link #RESOURCE_VARIABLE RESOURCE_VARIABLE},
* {@link #INSTANCEOF INSTANCEOF}, {@link #NEW NEW},
* {@link #CONSTRUCTOR_REFERENCE CONSTRUCTOR_REFERENCE}, or
* @param sort {@link #FIELD FIELD}, {@link #METHOD_RETURN METHOD_RETURN}, {@link #METHOD_RECEIVER METHOD_RECEIVER},
* {@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}.
* @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.
*
* @param sort
* {@link #CLASS_TYPE_PARAMETER CLASS_TYPE_PARAMETER} or
* {@link #METHOD_TYPE_PARAMETER METHOD_TYPE_PARAMETER}.
* @param paramIndex
* the type parameter index.
* @param sort {@link #CLASS_TYPE_PARAMETER CLASS_TYPE_PARAMETER} or {@link #METHOD_TYPE_PARAMETER
* METHOD_TYPE_PARAMETER}.
* @param paramIndex the type parameter index.
* @return a reference to the given generic class or method type parameter.
*/
public static TypeReference newTypeParameterReference(int sort,
int paramIndex) {
public static TypeReference newTypeParameterReference(int sort, int paramIndex) {
return new TypeReference((sort << 24) | (paramIndex << 16));
}
/**
* Returns a reference to a type parameter bound of a generic class or
* method.
* Returns a reference to a type parameter bound of a generic class or method.
*
* @param sort
* {@link #CLASS_TYPE_PARAMETER CLASS_TYPE_PARAMETER} or
* {@link #METHOD_TYPE_PARAMETER METHOD_TYPE_PARAMETER}.
* @param paramIndex
* the type parameter index.
* @param boundIndex
* the type bound index within the above type parameters.
* @return a reference to the given generic class or method type parameter
* bound.
* @param sort {@link #CLASS_TYPE_PARAMETER CLASS_TYPE_PARAMETER} or {@link #METHOD_TYPE_PARAMETER
* METHOD_TYPE_PARAMETER}.
* @param paramIndex the type parameter index.
* @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,
int paramIndex, int boundIndex) {
return new TypeReference((sort << 24) | (paramIndex << 16)
| (boundIndex << 8));
public static TypeReference newTypeParameterBoundReference(int sort, int paramIndex, int boundIndex) {
return new TypeReference((sort << 24) | (paramIndex << 16) | (boundIndex << 8));
}
/**
* Returns a reference to the super class or to an interface of the
* 'implements' clause of a class.
* Returns a reference to the super class or to an interface of the 'implements' clause of a class.
*
* @param itfIndex
* the index of an interface in the 'implements' clause of a
* class, or -1 to reference the super class of the class.
* @param itfIndex the index of an interface in the 'implements' clause of a class, or -1 to reference the super
* class of the class.
* @return a reference to the given super type of a class.
*/
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.
*
* @param paramIndex
* the formal parameter index.
*
* @param paramIndex the formal parameter index.
* @return a reference to the type of the given method formal parameter.
*/
public static TypeReference newFormalParameterReference(int paramIndex) {
return new TypeReference((METHOD_FORMAL_PARAMETER << 24)
| (paramIndex << 16));
return new TypeReference((METHOD_FORMAL_PARAMETER << 24) | (paramIndex << 16));
}
/**
* Returns a reference to the type of an exception, in a 'throws' clause of
* a method.
*
* @param exceptionIndex
* the index of an exception in a 'throws' clause of a method.
* Returns a reference to the type 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.
*/
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'
* clause of a method.
*
* @param tryCatchBlockIndex
* the index of a try catch block (using the order in which they
* are visited with visitTryCatchBlock).
* Returns a reference to the type of the exception declared in a 'catch' clause of a method.
*
* @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.
*/
public static TypeReference newTryCatchReference(int tryCatchBlockIndex) {
return new TypeReference((EXCEPTION_PARAMETER << 24)
| (tryCatchBlockIndex << 8));
return new TypeReference((EXCEPTION_PARAMETER << 24) | (tryCatchBlockIndex << 8));
}
/**
* Returns a reference to the type of a type argument in a constructor or
* method call or reference.
* Returns a reference to the type of a type argument in a constructor or method call or reference.
*
* @param sort
* {@link #CAST CAST},
* {@link #CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT
* CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT},
* {@link #METHOD_INVOCATION_TYPE_ARGUMENT
* METHOD_INVOCATION_TYPE_ARGUMENT},
* {@link #CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT
* CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT}, or
* {@link #METHOD_REFERENCE_TYPE_ARGUMENT
* @param sort {@link #CAST CAST}, {@link #CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT
* CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT}, {@link #METHOD_INVOCATION_TYPE_ARGUMENT
* METHOD_INVOCATION_TYPE_ARGUMENT}, {@link #CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT
* CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT}, or {@link #METHOD_REFERENCE_TYPE_ARGUMENT
* METHOD_REFERENCE_TYPE_ARGUMENT}.
* @param argIndex
* the type argument index.
*
* @param argIndex the type argument index.
* @return a reference to the type of the given type argument.
*/
public static TypeReference newTypeArgumentReference(int sort, int argIndex) {
@@ -352,27 +294,17 @@ public class TypeReference {
/**
* Returns the sort of this type reference.
*
* @return {@link #CLASS_TYPE_PARAMETER CLASS_TYPE_PARAMETER},
* {@link #METHOD_TYPE_PARAMETER METHOD_TYPE_PARAMETER},
* {@link #CLASS_EXTENDS CLASS_EXTENDS},
* {@link #CLASS_TYPE_PARAMETER_BOUND CLASS_TYPE_PARAMETER_BOUND},
* {@link #METHOD_TYPE_PARAMETER_BOUND METHOD_TYPE_PARAMETER_BOUND},
* {@link #FIELD FIELD}, {@link #METHOD_RETURN METHOD_RETURN},
* {@link #METHOD_RECEIVER METHOD_RECEIVER},
* {@link #METHOD_FORMAL_PARAMETER METHOD_FORMAL_PARAMETER},
* {@link #THROWS THROWS}, {@link #LOCAL_VARIABLE LOCAL_VARIABLE},
* {@link #RESOURCE_VARIABLE RESOURCE_VARIABLE},
* {@link #EXCEPTION_PARAMETER EXCEPTION_PARAMETER},
* {@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
* @return {@link #CLASS_TYPE_PARAMETER CLASS_TYPE_PARAMETER}, {@link #METHOD_TYPE_PARAMETER METHOD_TYPE_PARAMETER},
* {@link #CLASS_EXTENDS CLASS_EXTENDS}, {@link #CLASS_TYPE_PARAMETER_BOUND CLASS_TYPE_PARAMETER_BOUND},
* {@link #METHOD_TYPE_PARAMETER_BOUND METHOD_TYPE_PARAMETER_BOUND}, {@link #FIELD FIELD}, {@link #METHOD_RETURN
* METHOD_RETURN}, {@link #METHOD_RECEIVER METHOD_RECEIVER}, {@link #METHOD_FORMAL_PARAMETER
* METHOD_FORMAL_PARAMETER}, {@link #THROWS THROWS}, {@link #LOCAL_VARIABLE LOCAL_VARIABLE},
* {@link #RESOURCE_VARIABLE RESOURCE_VARIABLE}, {@link #EXCEPTION_PARAMETER EXCEPTION_PARAMETER},
* {@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}.
*/
public int getSort() {
@@ -380,11 +312,9 @@ public class TypeReference {
}
/**
* Returns the index of the type parameter referenced by this type
* reference. This method must only be used for type references whose sort
* is {@link #CLASS_TYPE_PARAMETER CLASS_TYPE_PARAMETER},
* {@link #METHOD_TYPE_PARAMETER METHOD_TYPE_PARAMETER},
* {@link #CLASS_TYPE_PARAMETER_BOUND CLASS_TYPE_PARAMETER_BOUND} or
* Returns the index of the type parameter referenced by this type reference. This method must only be used for type
* references whose sort is {@link #CLASS_TYPE_PARAMETER CLASS_TYPE_PARAMETER}, {@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}.
*
* @return a type parameter index.
@@ -394,11 +324,10 @@ public class TypeReference {
}
/**
* Returns the index of the type parameter bound, within the type parameter
* {@link #getTypeParameterIndex}, referenced by this type reference. This
* 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 METHOD_TYPE_PARAMETER_BOUND}.
* Returns the index of the type parameter bound, within the type parameter {@link #getTypeParameterIndex},
* referenced by this type reference. This 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
* METHOD_TYPE_PARAMETER_BOUND}.
*
* @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
* this type reference. This method must only be used for type references
* whose sort is {@link #CLASS_EXTENDS CLASS_EXTENDS}.
* Returns the index of the "super type" of a class that is referenced by this type reference. This method must only
* be used for type references whose sort is {@link #CLASS_EXTENDS CLASS_EXTENDS}.
*
* @return the index of an interface in the 'implements' clause of a class,
* or -1 if this type reference references the type of the super
* class.
* @return the index of an interface in the 'implements' clause of a class, or -1 if this type reference references
* the type of the super class.
*/
public int getSuperTypeIndex() {
return (short) ((value & 0x00FFFF00) >> 8);
}
/**
* Returns the index of the formal parameter whose type is referenced by
* this type reference. This method must only be used for type references
* whose sort is {@link #METHOD_FORMAL_PARAMETER METHOD_FORMAL_PARAMETER}.
* Returns the index of the formal parameter whose type is referenced by this type reference. This method must only
* be used for type references whose sort is {@link #METHOD_FORMAL_PARAMETER METHOD_FORMAL_PARAMETER}.
*
* @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,
* whose type is referenced by this type reference. This method must only be
* used for type references whose sort is {@link #THROWS THROWS}.
* Returns the index of the exception, in a 'throws' clause of a method, whose type is referenced by this type
* reference. This method must only be used for type references whose sort is {@link #THROWS THROWS}.
*
* @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
* are visited with visitTryCatchBlock), whose 'catch' type is referenced by
* this type reference. This method must only be used for type references
* whose sort is {@link #EXCEPTION_PARAMETER EXCEPTION_PARAMETER} .
* Returns the index of the try catch block (using the order in which they are visited with visitTryCatchBlock),
* whose 'catch' type is referenced by this type reference. This method must only be used for type references whose
* sort is {@link #EXCEPTION_PARAMETER EXCEPTION_PARAMETER} .
*
* @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.
* This method must only be used for type references whose sort is
* {@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
* Returns the index of the type argument referenced by this type reference. This method must only be used for type
* references whose sort is {@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}.
*
* @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
* visit methods related to type annotations, like visitTypeAnnotation.
* Returns the int encoded value of this type reference, suitable for use in visit methods related to type
* annotations, like visitTypeAnnotation.
*
* @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;

View File

@@ -27,24 +27,20 @@ import org.redkale.util.*;
* 继承 HttpBaseServlet 是为了获取 HttpMapping 信息 <br>
* https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md
*
* <p>
* 详情见: https://redkale.org
* <p>详情见: https://redkale.org
*
* @author zhangjx
*/
public final class ApiDocCommand {
private static final java.lang.reflect.Type TYPE_RETRESULT_OBJECT = new TypeToken<RetResult<Object>>() {
}.getType();
private static final java.lang.reflect.Type TYPE_RETRESULT_OBJECT = new TypeToken<RetResult<Object>>() {}.getType();
private static final java.lang.reflect.Type TYPE_RETRESULT_STRING = new TypeToken<RetResult<String>>() {
}.getType();
private static final java.lang.reflect.Type TYPE_RETRESULT_STRING = new TypeToken<RetResult<String>>() {}.getType();
private static final java.lang.reflect.Type TYPE_RETRESULT_INTEGER = new TypeToken<RetResult<Integer>>() {
}.getType();
private static final java.lang.reflect.Type TYPE_RETRESULT_INTEGER =
new TypeToken<RetResult<Integer>>() {}.getType();
private static final java.lang.reflect.Type TYPE_RETRESULT_LONG = new TypeToken<RetResult<Long>>() {
}.getType();
private static final java.lang.reflect.Type TYPE_RETRESULT_LONG = new TypeToken<RetResult<Long>>() {}.getType();
private final Application app; // Application全局对象
@@ -88,10 +84,13 @@ public final class ApiDocCommand {
serverList.add(map);
HttpServer server = node.getServer();
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<>();
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()) {
plainContentType = "application/json";
}
@@ -115,7 +114,12 @@ public final class ApiDocCommand {
node.logger.log(Level.INFO, servlet + " be skipped because @WebServlet.name is empty");
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<>();
String prefix = (String) prefixField.get(servlet);
String[] urlregs = ws.value();
@@ -181,7 +185,8 @@ public final class ApiDocCommand {
// if (rtype.getName().startsWith("java.")) continue;
// if (rtype.getName().startsWith("javax.")) continue;
// 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;
// do {
// if (loop == null || loop.isInterface()) break;
@@ -190,7 +195,9 @@ public final class ApiDocCommand {
// if (Modifier.isStatic(field.getModifiers())) continue;
//
// Map<String, Object> fieldmap = new LinkedHashMap<>();
// fieldmap.put("type", field.getType().isArray() ? (field.getType().getComponentType().getName() + "[]") : field.getGenericType().getTypeName());
// fieldmap.put("type", field.getType().isArray() ?
// (field.getType().getComponentType().getName() + "[]") :
// field.getGenericType().getTypeName());
//
// Comment comment = field.getAnnotation(Comment.class);
// Column col = field.getAnnotation(Column.class);
@@ -202,10 +209,14 @@ public final class ApiDocCommand {
// } else if (fc != null) {
// fieldmap.put("comment", fc.comment());
// }
// fieldmap.put("primary", !filter && (field.getAnnotation(Id.class) != null));
// fieldmap.put("updatable", (filter || col == null || col.updatable()));
// if (servlet.getClass().getAnnotation(Rest.RestDyn.class) != null) {
// if (field.getAnnotation(RestAddress.class) != null) continue;
// fieldmap.put("primary", !filter &&
// (field.getAnnotation(Id.class) != null));
// fieldmap.put("updatable", (filter || col == null ||
// col.updatable()));
// if (servlet.getClass().getAnnotation(Rest.RestDyn.class)
// != null) {
// if (field.getAnnotation(RestAddress.class) != null)
// continue;
// }
//
// typeMap.put(field.getName(), fieldmap);
@@ -235,26 +246,40 @@ public final class ApiDocCommand {
f.setAccessible(true);
paramGenericType = (Type) f.get(servlet);
}
simpleSchemaType(null, node.getLogger(), swaggerComponentsMap,
param.type(), paramGenericType, paramSchemaMap, true);
simpleSchemaType(
null,
node.getLogger(),
swaggerComponentsMap,
param.type(),
paramGenericType,
paramSchemaMap,
true);
if (param.style() == HttpParam.HttpParameterStyle.BODY) {
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 {
final Map<String, Object> swaggerParamMap = new LinkedHashMap<>();
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("required", param.required());
if (param.deprecated()) {
swaggerParamMap.put("deprecated", param.deprecated());
}
// https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#parameterStyle
swaggerParamMap.put("style", param.style() == HttpParam.HttpParameterStyle.HEADER
|| param.name().indexOf('#') == 0 ? "simple" : "form");
swaggerParamMap.put(
"style",
param.style() == HttpParam.HttpParameterStyle.HEADER
|| param.name().indexOf('#') == 0
? "simple"
: "form");
swaggerParamMap.put("explode", true);
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) {
swaggerParamMap.put("example", example);
} else if (!param.example().isEmpty()) {
@@ -295,12 +320,18 @@ public final class ApiDocCommand {
}
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());
Column col = field.getAnnotation(Column.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) {
fieldmap.put("comment", comment.value());
} else if (comment2 != null) {
@@ -308,8 +339,12 @@ public final class ApiDocCommand {
} else if (col != null) {
fieldmap.put("comment", col.comment());
}
fieldmap.put("primary", !filter && (field.getAnnotation(Id.class) != null
|| field.getAnnotation(javax.persistence.Id.class) != null));
fieldmap.put(
"primary",
!filter
&& (field.getAnnotation(Id.class) != null
|| field.getAnnotation(javax.persistence.Id.class)
!= null));
fieldmap.put("updatable", (filter || col == null || col.updatable()));
if (servlet.getClass().getAnnotation(Rest.RestDyn.class) != null) {
@@ -334,9 +369,18 @@ public final class ApiDocCommand {
swaggerOperatMap.put("deprecated", true);
}
Map<String, Object> respSchemaMap = new LinkedHashMap<>();
JsonFactory returnFactory = Rest.createJsonFactory(0,
method.getAnnotationsByType(RestConvert.class), method.getAnnotationsByType(RestConvertCoder.class));
simpleSchemaType(returnFactory, node.getLogger(), swaggerComponentsMap, action.result(), resultType, respSchemaMap, true);
JsonFactory returnFactory = Rest.createJsonFactory(
0,
method.getAnnotationsByType(RestConvert.class),
method.getAnnotationsByType(RestConvertCoder.class));
simpleSchemaType(
returnFactory,
node.getLogger(),
swaggerComponentsMap,
action.result(),
resultType,
respSchemaMap,
true);
Map<String, Object> respMap = new LinkedHashMap<>();
respMap.put("schema", respSchemaMap);
@@ -352,16 +396,35 @@ public final class ApiDocCommand {
if (action.rpcOnly()) {
actiondesc = "[Only for RPC API] " + actiondesc;
}
swaggerOperatMap.put("responses", Utility.ofMap("200",
Utility.ofMap("description", actiondesc, "content", Utility.ofMap("application/json", respMap))));
swaggerOperatMap.put(
"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) {
m = hasBodyParam || TYPE_RETRESULT_STRING.equals(resultType) || 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";
m = hasBodyParam
|| TYPE_RETRESULT_STRING.equals(resultType)
|| 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);
mappingsList.sort((o1, o2) -> ((String) o1.get("url")).compareTo((String) o2.get("url")));
@@ -417,13 +480,22 @@ public final class ApiDocCommand {
return "apidoc success";
}
private static void simpleSchemaType(JsonFactory factory, Logger logger,
Map<String, Map<String, Object>> componentsMap, Class type, Type genericType, Map<String, Object> schemaMap, boolean recursive) {
private static void simpleSchemaType(
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) {
schemaMap.put("type", "integer");
schemaMap.put("format", "int32");
} else if (type == long.class || type == Long.class
|| type == AtomicLong.class || type == LongAdder.class || type == BigInteger.class) {
} else if (type == long.class
|| type == Long.class
|| type == AtomicLong.class
|| type == LongAdder.class
|| type == BigInteger.class) {
schemaMap.put("type", "integer");
schemaMap.put("format", "int64");
} else if (type == float.class || type == Float.class) {
@@ -442,13 +514,28 @@ public final class ApiDocCommand {
schemaMap.put("type", "array");
Map<String, Object> sbumap = new LinkedHashMap<>();
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) {
Type subpt = ((ParameterizedType) genericType).getActualTypeArguments()[0];
if (subpt instanceof Class) {
simpleSchemaType(factory, logger, componentsMap, (Class) subpt, subpt, sbumap, false);
} else if (subpt instanceof ParameterizedType && ((ParameterizedType) subpt).getOwnerType() instanceof Class) {
simpleSchemaType(factory, logger, componentsMap, (Class) ((ParameterizedType) subpt).getOwnerType(), subpt, sbumap, false);
} else if (subpt instanceof ParameterizedType
&& ((ParameterizedType) subpt).getOwnerType() instanceof Class) {
simpleSchemaType(
factory,
logger,
componentsMap,
(Class) ((ParameterizedType) subpt).getOwnerType(),
subpt,
sbumap,
false);
} else {
sbumap.put("type", "object");
}
@@ -468,8 +555,12 @@ public final class ApiDocCommand {
}
}
private static String simpleComponentType(JsonFactory factory, Logger logger,
Map<String, Map<String, Object>> componentsMap, Class type, Type genericType) {
private static String simpleComponentType(
JsonFactory factory,
Logger logger,
Map<String, Map<String, Object>> componentsMap,
Class type,
Type genericType) {
try {
Set<Type> types = new HashSet<>();
Encodeable encodeable = JsonFactory.root().loadEncoder(genericType);
@@ -489,9 +580,14 @@ public final class ApiDocCommand {
if (encodeable instanceof ObjectEncoder) {
for (EnMember member : ((ObjectEncoder) encodeable).getMembers()) {
Map<String, Object> schemaMap = new LinkedHashMap<>();
simpleSchemaType(factory, logger, componentsMap,
simpleSchemaType(
factory,
logger,
componentsMap,
TypeToken.typeToClassOrElse(member.getEncoder().getType(), Object.class),
member.getEncoder().getType(), schemaMap, true);
member.getEncoder().getType(),
schemaMap,
true);
String desc = "";
if (member.getField() != null) {
Column col = member.getField().getAnnotation(Column.class);
@@ -502,9 +598,14 @@ public final class ApiDocCommand {
}
}
if (desc.isEmpty() && member.getField().getAnnotation(Comment.class) != null) {
desc = member.getField().getAnnotation(Comment.class).value();
} else if (desc.isEmpty() && member.getField().getAnnotation(org.redkale.util.Comment.class) != null) {
desc = member.getField().getAnnotation(org.redkale.util.Comment.class).value();
desc = member.getField()
.getAnnotation(Comment.class)
.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) {
Column col = member.getMethod().getAnnotation(Column.class);
@@ -515,9 +616,14 @@ public final class ApiDocCommand {
}
}
if (desc.isEmpty() && member.getMethod().getAnnotation(Comment.class) != null) {
desc = member.getMethod().getAnnotation(Comment.class).value();
} else if (desc.isEmpty() && member.getMethod().getAnnotation(org.redkale.util.Comment.class) != null) {
desc = member.getMethod().getAnnotation(org.redkale.util.Comment.class).value();
desc = member.getMethod()
.getAnnotation(Comment.class)
.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()) {
@@ -537,8 +643,14 @@ public final class ApiDocCommand {
}
}
private static String componentKey(JsonFactory factory, Logger logger, Set<Type> types,
Map<String, Map<String, Object>> componentsMap, EnMember field, Encodeable encodeable, boolean first) {
private static String componentKey(
JsonFactory factory,
Logger logger,
Set<Type> types,
Map<String, Map<String, Object>> componentsMap,
EnMember field,
Encodeable encodeable,
boolean first) {
if (encodeable instanceof ObjectEncoder) {
if (types.contains(encodeable.getType())) {
return "";
@@ -547,9 +659,9 @@ public final class ApiDocCommand {
StringBuilder sb = new StringBuilder();
sb.append(((ObjectEncoder) encodeable).getTypeClass().getSimpleName());
for (EnMember member : ((ObjectEncoder) encodeable).getMembers()) {
if (member.getEncoder() instanceof ArrayEncoder
|| member.getEncoder() instanceof CollectionEncoder) {
String subsb = componentKey(factory, logger, types, componentsMap, member, member.getEncoder(), false);
if (member.getEncoder() instanceof ArrayEncoder || member.getEncoder() instanceof CollectionEncoder) {
String subsb =
componentKey(factory, logger, types, componentsMap, member, member.getEncoder(), false);
if (subsb == null) {
return null;
}
@@ -558,7 +670,9 @@ public final class ApiDocCommand {
continue;
}
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) {
continue;
}
@@ -569,7 +683,8 @@ public final class ApiDocCommand {
sb.append("_");
}
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();
if (real == null) {
continue;
@@ -579,18 +694,33 @@ public final class ApiDocCommand {
}
types.add(member.getEncoder().getType());
if (member.getEncoder() instanceof SimpledCoder) {
simpleSchemaType(factory, logger, componentsMap, ((SimpledCoder) member.getEncoder()).getType(),
((SimpledCoder) member.getEncoder()).getType(), new LinkedHashMap<>(), true);
simpleSchemaType(
factory,
logger,
componentsMap,
((SimpledCoder) member.getEncoder()).getType(),
((SimpledCoder) member.getEncoder()).getType(),
new LinkedHashMap<>(),
true);
} else {
simpleSchemaType(factory, logger, componentsMap, ((ObjectEncoder) member.getEncoder()).getTypeClass(),
((ObjectEncoder) member.getEncoder()).getType(), new LinkedHashMap<>(), true);
simpleSchemaType(
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();
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) {
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) {
return null;
}
@@ -610,7 +740,8 @@ public final class ApiDocCommand {
return sb.toString();
} else if (encodeable instanceof ArrayEncoder || encodeable instanceof CollectionEncoder) {
final boolean array = (encodeable instanceof ArrayEncoder);
Encodeable subEncodeable = array ? ((ArrayEncoder) encodeable).getComponentEncoder()
Encodeable subEncodeable = array
? ((ArrayEncoder) encodeable).getComponentEncoder()
: ((CollectionEncoder) encodeable).getComponentEncoder();
if (subEncodeable instanceof SimpledCoder && field != null) {
return "";
@@ -625,8 +756,10 @@ public final class ApiDocCommand {
return sb + (array ? "_Array" : "_Collection");
} else if (encodeable instanceof SimpledCoder) {
Class stype = ((SimpledCoder) encodeable).getType();
if (stype.isPrimitive() || stype == Boolean.class
|| Number.class.isAssignableFrom(stype) || CharSequence.class.isAssignableFrom(stype)) {
if (stype.isPrimitive()
|| stype == Boolean.class
|| Number.class.isAssignableFrom(stype)
|| CharSequence.class.isAssignableFrom(stype)) {
return stype.getSimpleName();
}
return "";
@@ -681,8 +814,13 @@ public final class ApiDocCommand {
try {
ParameterizedType pt = (ParameterizedType) genericType;
Type valType = pt.getActualTypeArguments()[0];
return formatExample(factory, example, valType instanceof ParameterizedType
? (Class) ((ParameterizedType) valType).getRawType() : ((Class) valType), valType);
return formatExample(
factory,
example,
valType instanceof ParameterizedType
? (Class) ((ParameterizedType) valType).getRawType()
: ((Class) valType),
valType);
} catch (Throwable t) {
// do nothing
}
@@ -692,10 +830,15 @@ public final class ApiDocCommand {
try {
ParameterizedType pt = (ParameterizedType) genericType;
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);
return new StringWrapper(jsonFactory.getConvert()
.convertTo(jsonFactory.getConvert().convertFrom(genericType, "{'rows':[" + val + "," + val + "]}")));
return new StringWrapper(jsonFactory
.getConvert()
.convertTo(jsonFactory
.getConvert()
.convertFrom(genericType, "{'rows':[" + val + "," + val + "]}")));
} catch (Throwable t) {
// do nothing
}
@@ -703,7 +846,8 @@ public final class ApiDocCommand {
} else if (type.isArray()) {
try {
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 + "]")));
} catch (Throwable t) {
// do nothing
@@ -713,9 +857,12 @@ public final class ApiDocCommand {
try {
ParameterizedType pt = (ParameterizedType) genericType;
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);
return new StringWrapper(jsonFactory.getConvert()
return new StringWrapper(jsonFactory
.getConvert()
.convertTo(jsonFactory.getConvert().convertFrom(genericType, "[" + val + "," + val + "]")));
} catch (Throwable t) {
// do nothing
@@ -726,9 +873,12 @@ public final class ApiDocCommand {
try {
ParameterizedType pt = (ParameterizedType) genericType;
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);
return new StringWrapper(jsonFactory.getConvert()
return new StringWrapper(jsonFactory
.getConvert()
.convertTo(jsonFactory.getConvert().convertFrom(genericType, "{'result':" + val + "}")));
} catch (Throwable t) {
// do nothing
@@ -765,5 +915,4 @@ public final class ApiDocCommand {
}
private static final JsonFactory exampleFactory = JsonFactory.create().withFeatures(0);
}

View File

@@ -3,6 +3,10 @@
*/
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.File;
import java.io.FileInputStream;
@@ -20,13 +24,10 @@ import java.util.List;
import java.util.Properties;
import java.util.Set;
import java.util.logging.SimpleFormatter;
import static org.redkale.boot.Application.*;
import org.redkale.source.DataSources;
import org.redkale.util.AnyValue;
import org.redkale.util.AnyValueWriter;
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.Utility;
@@ -113,9 +114,7 @@ class AppConfig {
this.initSourceProperties();
}
/**
* 初始化classLoader、serverClassLoader
*/
/** 初始化classLoader、serverClassLoader */
private void initClassLoader() {
ClassLoader currClassLoader = Thread.currentThread().getContextClassLoader();
if (currClassLoader instanceof RedkaleClassLoader) {
@@ -124,9 +123,11 @@ class AppConfig {
Set<String> cacheClasses = null;
if (!singletonMode && !compileMode) {
try {
InputStream in = Application.class.getResourceAsStream(RedkaleClassLoader.RESOURCE_CACHE_CLASSES_PATH);
InputStream in =
Application.class.getResourceAsStream(RedkaleClassLoader.RESOURCE_CACHE_CLASSES_PATH);
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<>();
reader.lines().forEach(list::add);
Collections.sort(list);
@@ -153,16 +154,16 @@ class AppConfig {
}
}
/**
* 初始化home、confDir、localAddress等信息
*/
/** 初始化home、confDir、localAddress等信息 */
private void initAppHome() {
final File root = new File(System.getProperty(RESNAME_APP_HOME, ""));
final String rootPath = getCanonicalPath(root);
this.home = new File(rootPath);
String confDir = System.getProperty(RESNAME_APP_CONF_DIR, "conf");
if (confDir.contains("://") || confDir.startsWith("file:")
|| confDir.startsWith("resource:") || confDir.contains("!")) { //graalvm native-image startwith resource:META-INF
if (confDir.contains("://")
|| confDir.startsWith("file:")
|| confDir.startsWith("resource:")
|| confDir.contains("!")) { // graalvm native-image startwith resource:META-INF
this.confDir = URI.create(confDir);
if (confDir.startsWith("file:")) {
this.confFile = getCanonicalFile(new File(this.confDir.getPath()));
@@ -175,14 +176,13 @@ class AppConfig {
this.confDir = confFile.toURI();
}
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();
this.localAddress = new InetSocketAddress(addr, config.getIntValue("port"));
}
/**
* 读取本地参数配置
*/
/** 读取本地参数配置 */
private void initLocalProperties() {
// 环境变量的优先级最高
System.getProperties().forEach((k, v) -> {
@@ -207,11 +207,13 @@ class AppConfig {
}
}
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()) {
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) {
continue;
}
@@ -240,9 +242,7 @@ class AppConfig {
}
}
/**
* 读取本地DataSource、CacheSource配置
*/
/** 读取本地DataSource、CacheSource配置 */
private void initSourceProperties() {
if ("file".equals(this.confDir.getScheme())) {
File sourceFile = new File(new File(confDir), "source.properties");
@@ -272,7 +272,8 @@ class AppConfig {
}
} else { // 从url或jar文件中resources读取
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();
Properties props = new Properties();
props.load(in);
@@ -284,9 +285,7 @@ class AppConfig {
}
}
/**
* 读取本地日志配置
*/
/** 读取本地日志配置 */
private void initLogProperties() {
URI logConfURI;
File logConfFile = null;
@@ -317,9 +316,14 @@ class AppConfig {
putReflectionPublicConstructors(SimpleFormatter.class, SimpleFormatter.class.getName());
putReflectionPublicConstructors(LoggingSearchHandler.class, LoggingSearchHandler.class.getName());
putReflectionPublicConstructors(LoggingFileHandler.class, LoggingFileHandler.class.getName());
putReflectionPublicConstructors(LoggingFileHandler.LoggingFormater.class, LoggingFileHandler.LoggingFormater.class.getName());
putReflectionPublicConstructors(LoggingFileHandler.LoggingConsoleHandler.class, LoggingFileHandler.LoggingConsoleHandler.class.getName());
putReflectionPublicConstructors(LoggingFileHandler.LoggingSncpFileHandler.class, LoggingFileHandler.LoggingSncpFileHandler.class.getName());
putReflectionPublicConstructors(
LoggingFileHandler.LoggingFormater.class, LoggingFileHandler.LoggingFormater.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
*/
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);
if (sysConfFile != null) {
String text;
@@ -344,8 +350,10 @@ class AppConfig {
throw new IOException("Read application conf file (" + sysConfFile + ") error ");
}
}
return text.trim().startsWith("<") ? AnyValue.loadFromXml(text, (k, v) -> v.replace("${" + RESNAME_APP_HOME + "}", home))
.getAnyValue("application") : AnyValue.loadFromProperties(text).getAnyValue("redkale");
return text.trim().startsWith("<")
? 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");
URI appConfFile;
@@ -374,7 +382,10 @@ class AppConfig {
} catch (IOException e) { // 没有application.xml就尝试读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;
}
}
@@ -395,7 +406,10 @@ class AppConfig {
} catch (IOException e) { // 没有application.xml就尝试读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;
}
}
@@ -404,7 +418,8 @@ class AppConfig {
String text = Utility.readThenClose(appConfFile.toURL().openStream());
AnyValue conf;
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 {
conf = AnyValue.loadFromProperties(text).getAnyValue("redkale");
}
@@ -419,7 +434,6 @@ class AppConfig {
* 检查name是否含特殊字符
*
* @param name
*
* @return
*/
private static String checkName(String name) {
@@ -443,7 +457,6 @@ class AppConfig {
* 检查node是否含特殊字符
*
* @param name
*
* @return
*/
private static String checkNodeid(String nodeid) {
@@ -478,5 +491,4 @@ class AppConfig {
return file;
}
}
}

View File

@@ -50,8 +50,8 @@ import org.redkale.util.*;
import org.redkale.watch.WatchServlet;
/**
*
* 进程启动类,全局对象。 <br>
*
* <pre>
* 程序启动执行步骤:
* 1、读取application.xml
@@ -59,26 +59,20 @@ import org.redkale.watch.WatchServlet;
* 3、优先加载所有SNCP协议的服务再加载其他协议服务 最后加载WATCH协议的服务
* 4、最后进行Service、Servlet与其他资源之间的依赖注入
* </pre>
* <p>
* 详情见: https://redkale.org
*
* <p>详情见: https://redkale.org
*
* @author zhangjx
*/
public final class Application {
/**
* 当前进程启动的时间, 类型: long
*/
/** 当前进程启动的时间, 类型: long */
public static final String RESNAME_APP_TIME = "APP_TIME";
/**
* 当前进程服务的名称, 类型String
*/
/** 当前进程服务的名称, 类型String */
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";
/**
@@ -87,14 +81,10 @@ public final class Application {
*/
public static final String RESNAME_APP_CONF_DIR = "APP_CONF_DIR";
/**
* 当前进程节点的nodeid 类型String
*/
/** 当前进程节点的nodeid 类型String */
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";
/**
@@ -108,28 +98,19 @@ public final class Application {
* 使用RESNAME_APP_CLIENT_IOGROUP代替
*
* @since 2.3.0
*
*/
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";
/**
* 当前Service所属的SNCP Server所属的组 类型: String<br>
*/
/** 当前Service所属的SNCP Server所属的组 类型: String<br> */
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;
/**
* 当前Server的ResourceFactory
*/
/** 当前Server的ResourceFactory */
public static final String RESNAME_SERVER_RESFACTORY = "SERVER_RESFACTORY";
public static final String SYSNAME_APP_NAME = "redkale.application.name";
@@ -146,8 +127,7 @@ public final class Application {
RESNAME_APP_TIME,
RESNAME_APP_HOME,
RESNAME_APP_ADDR,
RESNAME_APP_CONF_DIR
));
RESNAME_APP_CONF_DIR));
// UDP协议的ByteBuffer Capacity
private static final int UDP_CAPACITY = 1024;
@@ -242,8 +222,7 @@ public final class Application {
* 3、日志配置初始化 <br>
* 4、本地和远程配置文件读取 <br>
* 5、ClusterAgent和MessageAgent实例化 <br>
* 6、Work线程池初始化
* 7、原生sql解析器初始化 <br>
* 6、Work线程池初始化 7、原生sql解析器初始化 <br>
*
* @param singletonMode 是否测试模式
* @param compileMode 是否编译模式
@@ -273,7 +252,8 @@ public final class Application {
this.resourceFactory.register(RESNAME_APP_NODEID, String.class, 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);
@@ -286,7 +266,8 @@ public final class Application {
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, 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, File.class, appConfig.confFile);
@@ -316,9 +297,12 @@ public final class Application {
this.resourceFactory.register(BsonFactory.root().getConvert());
this.resourceFactory.register(JsonFactory.root().getConvert());
this.resourceFactory.register(ProtobufFactory.root().getConvert());
this.resourceFactory.register("bsonconvert", Convert.class, BsonFactory.root().getConvert());
this.resourceFactory.register("jsonconvert", Convert.class, JsonFactory.root().getConvert());
this.resourceFactory.register("protobufconvert", Convert.class, ProtobufFactory.root().getConvert());
this.resourceFactory.register(
"bsonconvert", Convert.class, BsonFactory.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
@@ -332,26 +316,41 @@ public final class Application {
loggingModule.reconfigLogging(true, appConfig.locaLogProperties);
// 打印基础信息日志
logger.log(Level.INFO, colorMessage(logger, 36, 1,
"-------------------------------- Redkale " + Redkale.getDotedVersion() + " --------------------------------"));
logger.log(
Level.INFO,
colorMessage(
logger,
36,
1,
"-------------------------------- Redkale " + Redkale.getDotedVersion()
+ " --------------------------------"));
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"
+ "APP_JAVA = " + System.getProperty("java.runtime.name",
+ "APP_JAVA = "
+ System.getProperty(
"java.runtime.name",
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"
+ RESNAME_APP_NAME + " = " + this.name + "\r\n"
+ RESNAME_APP_NODEID + " = " + this.nodeid + "\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_CONF_DIR + " = " + confDirStr.substring(confDirStr.indexOf('!') + 1));
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);
Server.loadLib(classLoader, logger, lib.isEmpty() ? confDirStr : (lib + ";" + confDirStr));
}
@@ -381,7 +380,13 @@ public final class Application {
this.resourceFactory.register(new ResourceTypeLoader() {
@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 {
field.set(srcObj, application);
return application;
@@ -404,9 +409,16 @@ public final class Application {
this.resourceFactory.register(new ResourceTypeLoader() {
@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 {
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);
field.set(srcObj, rs);
return rs;
@@ -429,7 +441,13 @@ public final class Application {
this.resourceFactory.register(new ResourceTypeLoader() {
@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 {
NodeServer server = null;
for (NodeServer ns : application.getNodeServers()) {
@@ -462,7 +480,13 @@ public final class Application {
this.resourceFactory.register(new ResourceTypeLoader() {
@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 {
NodeServer server = null;
for (NodeServer ns : application.getNodeServers()) {
@@ -495,7 +519,13 @@ public final class Application {
this.resourceFactory.register(new ResourceTypeLoader() {
@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 {
NodeServer server = null;
for (NodeServer ns : application.getNodeServers()) {
@@ -530,7 +560,13 @@ public final class Application {
resourceFactory.register(new ResourceTypeLoader() {
@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 {
java.net.http.HttpClient.Builder builder = java.net.http.HttpClient.newBuilder();
if (resourceName.endsWith(".1.1")) {
@@ -558,7 +594,13 @@ public final class Application {
resourceFactory.register(new ResourceTypeLoader() {
@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 {
WebClient httpClient = WebClient.create(workExecutor, clientAsyncGroup);
field.set(srcObj, httpClient);
@@ -580,12 +622,19 @@ public final class Application {
resourceFactory.register(new ResourceTypeLoader() {
@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 {
ClusterAgent clusterAgent = resourceFactory.find("", ClusterAgent.class);
MessageAgent messageAgent = resourceFactory.find(resourceName, MessageAgent.class);
if (messageAgent != null) {
if (clusterAgent == null || !Objects.equals(clusterAgent.getName(), resourceName)
if (clusterAgent == null
|| !Objects.equals(clusterAgent.getName(), resourceName)
|| messageAgent.isRpcFirst()) {
HttpRpcClient rpcClient = messageAgent.getHttpRpcClient();
field.set(srcObj, rpcClient);
@@ -638,9 +687,7 @@ public final class Application {
}
}
/**
* 设置WorkExecutor
*/
/** 设置WorkExecutor */
private void initWorkExecutor() {
int bufferCapacity = 32 * 1024;
int bufferPoolSize = Utility.cpus() * 8;
@@ -669,7 +716,9 @@ public final class Application {
clientWorkExecutor = WorkThread.createWorkExecutor(clientThreads, "Redkale-DefaultClient-WorkThread-%s");
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();
if (executorLog.length() > 0) {
@@ -719,7 +768,8 @@ public final class Application {
}
RedkaleClassLoader.putReflectionDeclaredConstructors(clazz, clazz.getName());
@SuppressWarnings("unchecked")
ApplicationListener listener = (ApplicationListener) clazz.getDeclaredConstructor().newInstance();
ApplicationListener listener =
(ApplicationListener) clazz.getDeclaredConstructor().newInstance();
resourceFactory.inject(listener);
listener.init(config);
this.listeners.add(listener);
@@ -728,7 +778,8 @@ public final class Application {
}
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 也能正常着色
boolean supported = true;
Logger l = logger;
@@ -781,7 +832,8 @@ public final class Application {
while (loop) {
ByteArrayOutputStream out = new ByteArrayOutputStream();
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];
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();
logger.info(application.getClass().getSimpleName() + " shutdowning");
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;
logger.info(application.getClass().getSimpleName() + " shutdown in " + e + " ms");
channel.close();
@@ -821,7 +877,8 @@ public final class Application {
if (o instanceof CharSequence) {
sb.append(o).append("\r\n");
} 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个字节为数据内容的长度
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();
int count = (bytes.length + 4) / UDP_CAPACITY + ((bytes.length + 4) % UDP_CAPACITY > 0 ? 1 : 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();
buffer.clear();
SocketAddress src = null;
@@ -963,27 +1022,21 @@ public final class Application {
return list.size() == 1 ? list.get(0) : AsmMethodBoost.create(remote, list);
}
/**
* 进入Application.init方法时被调用
*/
/** 进入Application.init方法时被调用 */
private void onAppPreInit() {
for (ModuleEngine item : moduleEngines) {
item.onAppPreInit();
}
}
/**
* 结束Application.init方法前被调用
*/
/** 结束Application.init方法前被调用 */
private void onAppPostInit() {
for (ModuleEngine item : moduleEngines) {
item.onAppPostInit();
}
}
/**
* 进入Application.start方法被调用
*/
/** 进入Application.start方法被调用 */
private void onAppPreStart() {
for (ApplicationListener listener : this.listeners) {
listener.onPreStart(this);
@@ -993,9 +1046,7 @@ public final class Application {
}
}
/**
* 结束Application.start方法前被调用
*/
/** 结束Application.start方法前被调用 */
private void onAppPostStart() {
for (ApplicationListener listener : this.listeners) {
listener.onPostStart(this);
@@ -1029,63 +1080,49 @@ public final class Application {
}
}
/**
* 服务全部启动前被调用
*/
/** 服务全部启动前被调用 */
private void onServersPreStart() {
for (ModuleEngine item : moduleEngines) {
item.onServersPreStart();
}
}
/**
* 服务全部启动后被调用
*/
/** 服务全部启动后被调用 */
private void onServersPostStart() {
for (ModuleEngine item : moduleEngines) {
item.onServersPostStart();
}
}
/**
* 执行Service.init方法前被调用
*/
/** 执行Service.init方法前被调用 */
void onServicePreInit(Service service) {
for (ModuleEngine item : moduleEngines) {
item.onServicePreInit(service);
}
}
/**
* 执行Service.init方法后被调用
*/
/** 执行Service.init方法后被调用 */
void onServicePostInit(Service service) {
for (ModuleEngine item : moduleEngines) {
item.onServicePostInit(service);
}
}
/**
* 执行Service.destroy方法前被调用
*/
/** 执行Service.destroy方法前被调用 */
void onServicePreDestroy(Service service) {
for (ModuleEngine item : moduleEngines) {
item.onServicePreDestroy(service);
}
}
/**
* 执行Service.destroy方法后被调用
*/
/** 执行Service.destroy方法后被调用 */
void onServicePostDestroy(Service service) {
for (ModuleEngine item : moduleEngines) {
item.onServicePostDestroy(service);
}
}
/**
* 服务全部停掉前被调用
*/
/** 服务全部停掉前被调用 */
private void onServersPreStop() {
for (ApplicationListener listener : listeners) {
listener.onServersPreStop(this);
@@ -1095,9 +1132,7 @@ public final class Application {
}
}
/**
* 服务全部停掉后被调用
*/
/** 服务全部停掉后被调用 */
private void onServersPostStop() {
for (ApplicationListener listener : listeners) {
listener.onServersPostStop(this);
@@ -1107,9 +1142,7 @@ public final class Application {
}
}
/**
* 进入Application.shutdown方法被调用
*/
/** 进入Application.shutdown方法被调用 */
private void onAppPreShutdown() {
for (ApplicationListener listener : this.listeners) {
try {
@@ -1123,9 +1156,7 @@ public final class Application {
}
}
/**
* 结束Application.shutdown方法前被调用
*/
/** 结束Application.shutdown方法前被调用 */
private void onAppPostShutdown() {
for (ModuleEngine item : moduleEngines) {
item.onAppPostShutdown();
@@ -1187,8 +1218,13 @@ public final class Application {
long intms = System.currentTimeMillis() - startTime;
String ms = String.valueOf(intms);
int repeat = ms.length() > 7 ? 0 : (7 - ms.length()) / 2;
logger.info(colorMessage(logger, 36, 1, "-".repeat(repeat) + "------------------------ Redkale started in "
+ ms + " ms " + (ms.length() / 2 == 0 ? " " : "") + "-".repeat(repeat) + "------------------------") + "\r\n");
logger.info(colorMessage(
logger,
36,
1,
"-".repeat(repeat) + "------------------------ Redkale started in " + ms + " ms "
+ (ms.length() / 2 == 0 ? " " : "") + "-".repeat(repeat) + "------------------------")
+ "\r\n");
LoggingBaseHandler.traceEnable = true;
if (!singletonMode && !compileMode) {
@@ -1202,11 +1238,11 @@ public final class Application {
* @param <T> 泛型
* @param serviceClass 指定的service类
* @param extServiceClasses 需要排除的service类
*
* @return Service对象
* @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);
}
@@ -1217,11 +1253,11 @@ public final class Application {
* @param name Service的资源名
* @param serviceClass 指定的service类
* @param extServiceClasses 需要排除的service类
*
* @return Service对象
* @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) {
throw new IllegalArgumentException("serviceClass is null");
}
@@ -1359,8 +1395,13 @@ public final class Application {
long intms = System.currentTimeMillis() - f;
String ms = String.valueOf(intms);
int repeat = ms.length() > 7 ? 0 : (7 - ms.length()) / 2;
logger.info(colorMessage(logger, 36, 1, "-".repeat(repeat) + "------------------------ Redkale shutdown in "
+ ms + " ms " + (ms.length() / 2 == 0 ? " " : "") + "-".repeat(repeat) + "------------------------") + "\r\n" + "\r\n");
logger.info(colorMessage(
logger,
36,
1,
"-".repeat(repeat) + "------------------------ Redkale shutdown in " + ms + " ms "
+ (ms.length() / 2 == 0 ? " " : "") + "-".repeat(repeat) + "------------------------")
+ "\r\n" + "\r\n");
LoggingBaseHandler.traceEnable = true;
}
@@ -1390,8 +1431,10 @@ public final class Application {
for (final AnyValue serconf : serverConfs) {
Thread thread = new Thread() {
{
setName("Redkale-" + serconf.getValue("protocol", "Server").toUpperCase().replaceFirst("\\..+", "")
+ ":" + serconf.getIntValue("port") + "-Thread");
setName("Redkale-"
+ serconf.getValue("protocol", "Server")
.toUpperCase()
.replaceFirst("\\..+", "") + ":" + serconf.getIntValue("port") + "-Thread");
this.setDaemon(true);
}
@@ -1400,7 +1443,9 @@ public final class Application {
try {
// Thread ctd = Thread.currentThread();
// 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;
if ("SNCP".equals(protocol)) {
server = NodeSncpServer.createNodeServer(Application.this, serconf);
@@ -1420,7 +1465,8 @@ public final class Application {
nodeLock.lock();
try {
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);
final Set<FilterEntry<NodeServer>> entrys = profilter.getFilterEntrys();
for (FilterEntry<NodeServer> entry : entrys) {
@@ -1433,7 +1479,8 @@ public final class Application {
final Class<? extends NodeServer> old = nodeClasses.get(p);
if (old != null && old != type) {
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);
}
@@ -1448,7 +1495,10 @@ public final class Application {
}
}
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);
System.exit(1);
}
@@ -1457,7 +1507,9 @@ public final class Application {
if (!singletonMode && !compileMode) {
server.start();
} else if (compileMode) {
server.getServer().getDispatcherServlet().init(server.getServer().getContext(), serconf);
server.getServer()
.getDispatcherServlet()
.init(server.getServer().getContext(), serconf);
}
servers.add(server);
serverCdl.countDown();
@@ -1600,5 +1652,4 @@ public final class Application {
public boolean isSingletonMode() {
return singletonMode;
}
}

View File

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

View File

@@ -22,8 +22,8 @@ import org.redkale.util.*;
/**
* class过滤器 符合条件的class会保留下来存入FilterEntry。
* <p>
* 详情见: https://redkale.org
*
* <p>详情见: https://redkale.org
*
* @author zhangjx
* @param <T> 泛型
@@ -67,11 +67,20 @@ public final class ClassFilter<T> {
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);
}
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.superClass = superClass;
this.excludeSuperClasses = excludeSuperClasses;
@@ -83,7 +92,13 @@ public final class ClassFilter<T> {
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);
filter.setIncludePatterns(includeRegxs == null ? null : includeRegxs.split(";"));
filter.setExcludePatterns(excludeRegxs == null ? null : excludeRegxs.split(";"));
@@ -228,18 +243,27 @@ public final class ClassFilter<T> {
}
AutoLoad auto = (AutoLoad) clazz.getAnnotation(AutoLoad.class);
org.redkale.util.AutoLoad auto2 = (org.redkale.util.AutoLoad) clazz.getAnnotation(org.redkale.util.AutoLoad.class);
if ((expectPredicate != null && expectPredicate.test(clazzName)) || (autoScan && auto != null && !auto.value())
org.redkale.util.AutoLoad auto2 =
(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)的
expectEntrys.add(new FilterEntry(clazz, autoScan, true, property));
} else {
entrys.add(new FilterEntry(clazz, autoScan, false, property));
}
} catch (Throwable cfe) {
if (logger.isLoggable(Level.FINEST) && !clazzName.startsWith("sun.") && !clazzName.startsWith("javax.")
&& !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 (logger.isLoggable(Level.FINEST)
&& !clazzName.startsWith("sun.")
&& !clazzName.startsWith("javax.")
&& !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) {
String msg = ((NoClassDefFoundError) cfe).getMessage();
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)
// || ((NoClassDefFoundError) cfe).getMessage().startsWith("java.lang.NoClassDefFoundError: java"))) {
logger.log(Level.FINEST, ClassFilter.class.getSimpleName()
+ " filter error for class: " + clazzName + (url == null ? "" : (" in " + url)), cfe);
logger.log(
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是否有效
*
* @param className String
*
* @return boolean
*/
public boolean accept(String className) {
@@ -270,7 +296,6 @@ public final class ClassFilter<T> {
*
* @param property AnyValue
* @param className String
*
* @return boolean
*/
public boolean accept(AnyValue property, String className) {
@@ -329,7 +354,6 @@ public final class ClassFilter<T> {
* @param property AnyValue
* @param clazz Class
* @param autoscan boolean
*
* @return boolean
*/
@SuppressWarnings("unchecked")
@@ -458,7 +482,6 @@ public final class ClassFilter<T> {
public void setPrivilegeExcludes(Set<String> privilegeExcludes) {
this.privilegeExcludes = privilegeExcludes == null || privilegeExcludes.isEmpty() ? null : privilegeExcludes;
}
/**
@@ -489,7 +512,8 @@ public final class ClassFilter<T> {
this.property = property;
this.autoload = autoload;
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", "");
}
@@ -505,7 +529,8 @@ public final class ClassFilter<T> {
@Override
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
@@ -555,12 +580,9 @@ public final class ClassFilter<T> {
public boolean isExpect() {
return expect;
}
}
/**
* class加载类
*/
/** class加载类 */
public static class Loader {
protected static final Logger logger = Logger.getLogger(Loader.class.getName());
@@ -581,10 +603,10 @@ public final class ClassFilter<T> {
* @param excludeFile 不需要扫描的文件夹, 可以为null
* @param loader RedkaleClassloader 不可为null
* @param filters 过滤器
*
* @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> urlJares = new ArrayList<>(2);
final URI exurl = excludeFile != null ? excludeFile.toURI() : null;
@@ -697,7 +719,10 @@ public final class ClassFilter<T> {
String rootPath = root.getPath();
loadClassFiles(excludeFile, root, 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.")) {
continue;
}

View File

@@ -8,8 +8,8 @@ import org.redkale.util.Traces;
/**
* Handler基类
* <p>
* 详情见: https://redkale.org
*
* <p>详情见: https://redkale.org
*
* @author zhangjx
* @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";
// 有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
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提前初始化
/**
* 默认的日志时间格式化类
* 与SimpleFormatter的区别在于level不使用本地化
*
*/
/** 默认的日志时间格式化类 与SimpleFormatter的区别在于level不使用本地化 */
public static class LoggingFormater extends Formatter {
@Override
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";
}
String source;
@@ -67,7 +67,8 @@ public abstract class LoggingBaseHandler extends Handler {
Object[] params = log.getParameters();
if (params != null) {
if (params.length == 1) {
return String.format(FORMATTER_FORMAT2,
return String.format(
FORMATTER_FORMAT2,
log.getInstant().toEpochMilli(),
source,
log.getLoggerName(),
@@ -76,7 +77,8 @@ public abstract class LoggingBaseHandler extends Handler {
throwable,
params[0]);
} else if (params.length == 2) {
return String.format(FORMATTER_FORMAT3,
return String.format(
FORMATTER_FORMAT3,
log.getInstant().toEpochMilli(),
source,
log.getLoggerName(),
@@ -87,7 +89,8 @@ public abstract class LoggingBaseHandler extends Handler {
params[1]);
}
}
return String.format(FORMATTER_FORMAT,
return String.format(
FORMATTER_FORMAT,
log.getInstant().toEpochMilli(),
source,
log.getLoggerName(),
@@ -118,7 +121,8 @@ public abstract class LoggingBaseHandler extends Handler {
try {
ByteArrayOutputStream out = new ByteArrayOutputStream();
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(".level = FINEST");
ps.println("jdk.level = INFO");
@@ -134,5 +138,4 @@ public abstract class LoggingBaseHandler extends Handler {
// do nothing
}
}
}

View File

@@ -5,9 +5,10 @@
*/
package org.redkale.boot;
import static java.nio.file.StandardCopyOption.*;
import java.io.*;
import java.nio.file.Files;
import static java.nio.file.StandardCopyOption.*;
import java.util.Calendar;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.atomic.*;
@@ -17,17 +18,15 @@ import org.redkale.util.*;
/**
* 自定义的日志输出类
* <p>
* 详情见: https://redkale.org
*
* <p>详情见: https://redkale.org
*
* @author zhangjx
*/
@SuppressWarnings("unchecked")
public class LoggingFileHandler extends LoggingBaseHandler {
/**
* SNCP的日志输出Handler
*/
/** SNCP的日志输出Handler */
public static class LoggingSncpFileHandler extends LoggingFileHandler {
@Override
@@ -150,10 +149,18 @@ public class LoggingFileHandler extends LoggingBaseHandler {
for (int i = Math.min(count - 2, logIndex.get() - 1); i > 0; i--) {
File greater = new File(logFile.getPath() + "." + i);
if (greater.exists()) {
Files.move(greater.toPath(), new File(logFile.getPath() + "." + (i + 1)).toPath(), REPLACE_EXISTING, ATOMIC_MOVE);
Files.move(
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 {
if (logFile.exists() && logFile.length() < 1) {
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--) {
File greater = new File(logUnusualFile.getPath() + "." + i);
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 {
if (logUnusualFile.exists() && logUnusualFile.length() < 1) {
Files.delete(logUnusualFile.toPath());
@@ -181,14 +196,20 @@ public class LoggingFileHandler extends LoggingBaseHandler {
}
if (logStream == null) {
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();
logLength.set(logFile.length());
logStream = new FileOutputStream(logFile, append);
}
if (unusual != null && logUnusualStream == null) {
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();
logUnusualLength.set(logUnusualFile.length());
logUnusualStream = new FileOutputStream(logUnusualFile, append);
@@ -210,7 +231,6 @@ public class LoggingFileHandler extends LoggingBaseHandler {
}
}
}
}
}.start();
}
@@ -257,7 +277,10 @@ public class LoggingFileHandler extends LoggingBaseHandler {
boolean g = limitstr.indexOf('G') > 0;
boolean m = limitstr.indexOf('M') > 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) {
ls *= 1024 * 1024 * 1024;
} 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;
/**
*
* 日志模块组件
*
* <p>
* 详情见: https://redkale.org
* <p>详情见: https://redkale.org
*
* @author zhangjx
*
* @since 2.8.0
*/
class LoggingModule extends BootModule {
@@ -80,8 +77,10 @@ class LoggingModule extends BootModule {
allProps.entrySet().forEach(x -> {
String key = x.getKey().toString();
if (key.startsWith("java.util.logging.") || key.contains(".level") || key.equals("handlers")) {
String val = envs.getPropertyValue(x.getValue().toString()
.replace("%m", "%tY%tm").replace("%d", "%tY%tm%td") //兼容旧时间格式
String val = envs.getPropertyValue(x.getValue()
.toString()
.replace("%m", "%tY%tm")
.replace("%d", "%tY%tm%td") // 兼容旧时间格式
.replace(searchRawHandler, searchReadHandler));
onlyLogProps.put(key.replace(searchRawHandler, searchReadHandler), val);
}
@@ -90,32 +89,42 @@ class LoggingModule extends BootModule {
if (application.isCompileMode()) {
onlyLogProps.setProperty("java.util.logging.FileHandler.formatter", SimpleFormatter.class.getName());
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 {
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 (application.isCompileMode()) {
onlyLogProps.setProperty("java.util.logging.ConsoleHandler.formatter", SimpleFormatter.class.getName());
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 {
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
final String handlers = onlyLogProps.getProperty("handlers");
if (handlers != null && handlers.contains("java.util.logging.ConsoleHandler")) {
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();
String prefix = consoleHandlerClass + ".";
onlyLogProps.entrySet().forEach(x -> {
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 -> {
@@ -130,7 +139,10 @@ class LoggingModule extends BootModule {
final String handlers = onlyLogProps.getProperty("handlers");
if (handlers != null && handlers.contains("java.util.logging.FileHandler")) {
// singletonrun模式下不输出文件日志
prop.setProperty("handlers", handlers.replace("java.util.logging.FileHandler",
prop.setProperty(
"handlers",
handlers.replace(
"java.util.logging.FileHandler",
application.isSingletonMode() || application.isCompileMode() ? "" : fileHandlerClass));
}
if (!prop.isEmpty()) {
@@ -143,7 +155,9 @@ class LoggingModule extends BootModule {
prop.entrySet().forEach(x -> onlyLogProps.put(x.getKey(), x.getValue()));
}
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()) {

View File

@@ -2,6 +2,9 @@
*/
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.util.*;
import java.util.concurrent.LinkedBlockingQueue;
@@ -9,8 +12,6 @@ import java.util.concurrent.atomic.AtomicInteger;
import java.util.logging.*;
import java.util.logging.Formatter;
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.json.JsonConvert;
import org.redkale.persistence.*;
@@ -20,8 +21,8 @@ import org.redkale.util.*;
/**
* 基于SearchSource的日志输出类
* <p>
* 详情见: https://redkale.org
*
* <p>详情见: https://redkale.org
*
* @author zhangjx
* @since 2.7.0
@@ -96,7 +97,6 @@ public class LoggingSearchHandler extends LoggingBaseHandler {
logList.clear();
}
}
}
}.start();
}
@@ -239,7 +239,9 @@ public class LoggingSearchHandler extends LoggingBaseHandler {
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);
logqueue.offer(new SearchLogRecord(rawTag, log));
}
@@ -299,8 +301,7 @@ public class LoggingSearchHandler extends LoggingBaseHandler {
@ConvertDisabled
String rawTag;
public SearchLogRecord() {
}
public SearchLogRecord() {}
protected SearchLogRecord(String tag, LogRecord log) {
this.rawLog = log;
@@ -347,7 +348,6 @@ public class LoggingSearchHandler extends LoggingBaseHandler {
public String[] getTables(String table, FilterNode node) {
throw new UnsupportedOperationException("Not supported yet.");
}
}
}
}

View File

@@ -15,14 +15,11 @@ import org.redkale.util.AnyValue;
import org.redkale.util.Environment;
/**
*
* 各组件的引擎类, 由Application管理
*
* <p>
* 详情见: https://redkale.org
* <p>详情见: https://redkale.org
*
* @author zhangjx
*
* @since 2.8.0
*/
public abstract class ModuleEngine {
@@ -48,7 +45,6 @@ public abstract class ModuleEngine {
* @param key 配置项名称
* @param val1 配置项原值
* @param val2 配置项新值
*
* @return MergeEnum
*/
public AnyValue.MergeEnum mergeAppConfigStrategy(String path, String key, AnyValue val1, AnyValue val2) {
@@ -60,40 +56,28 @@ public abstract class ModuleEngine {
*
* @param remote 是否远程模式
* @param serviceClass 类
*
* @return 方法动态扩展器
*/
public AsmMethodBoost createAsmMethodBoost(boolean remote, Class serviceClass) {
return null;
}
/**
* 进入Application.init方法时被调用
* 此时状态:
* 1、远程配置项未获取
* 2、WorkExecutor未初始化
*/
/** 进入Application.init方法时被调用 此时状态: 1、远程配置项未获取 2、WorkExecutor未初始化 */
public void onAppPreInit() {
// do nothing
}
/**
* 结束Application.init方法前被调用
*/
/** 结束Application.init方法前被调用 */
public void onAppPostInit() {
// do nothing
}
/**
* 进入Application.start方法被调用
*/
/** 进入Application.start方法被调用 */
public void onAppPreStart() {
// do nothing
}
/**
* 结束Application.start方法前被调用
*/
/** 结束Application.start方法前被调用 */
public void onAppPostStart() {
// do nothing
}
@@ -117,32 +101,22 @@ public abstract class ModuleEngine {
// do nothing
}
/**
* Application 在运行Compile前调用
*
*/
/** Application 在运行Compile前调用 */
public void onPreCompile() {
// do nothing
}
/**
* Application 在运行Compile后调用
*
*/
/** Application 在运行Compile后调用 */
public void onPostCompile() {
// do nothing
}
/**
* 服务全部启动前被调用
*/
/** 服务全部启动前被调用 */
public void onServersPreStart() {
// do nothing
}
/**
* 服务全部启动后被调用
*/
/** 服务全部启动后被调用 */
public void onServersPostStart() {
// do nothing
}
@@ -183,30 +157,22 @@ public abstract class ModuleEngine {
// do nothing
}
/**
* 服务全部停掉前被调用
*/
/** 服务全部停掉前被调用 */
public void onServersPreStop() {
// do nothing
}
/**
* 服务全部停掉后被调用
*/
/** 服务全部停掉后被调用 */
public void onServersPostStop() {
// do nothing
}
/**
* 进入Application.shutdown方法被调用
*/
/** 进入Application.shutdown方法被调用 */
public void onAppPreShutdown() {
// do nothing
}
/**
* 结束Application.shutdown方法前被调用
*/
/** 结束Application.shutdown方法前被调用 */
public void onAppPostShutdown() {
// do nothing
}

View File

@@ -5,6 +5,8 @@
*/
package org.redkale.boot;
import static org.redkale.boot.Application.RESNAME_SNCP_ADDRESS;
import java.lang.annotation.Annotation;
import java.lang.reflect.*;
import java.net.*;
@@ -15,7 +17,6 @@ import java.util.logging.Level;
import java.util.stream.Stream;
import org.redkale.annotation.*;
import org.redkale.asm.AsmMethodBoost;
import static org.redkale.boot.Application.RESNAME_SNCP_ADDRESS;
import org.redkale.boot.ClassFilter.FilterEntry;
import org.redkale.cluster.spi.ClusterAgent;
import org.redkale.inject.ResourceFactory;
@@ -31,8 +32,7 @@ import org.redkale.watch.*;
/**
* HTTP Server节点的配置Server
*
* <p>
* 详情见: https://redkale.org
* <p>详情见: https://redkale.org
*
* @author zhangjx
*/
@@ -49,11 +49,13 @@ public class NodeHttpServer extends NodeServer {
super(application, createServer(application, serconf));
this.httpServer = (HttpServer) server;
this.rest = serconf != null && serconf.getAnyValue("rest") != null;
}
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() {
@@ -68,24 +70,40 @@ public class NodeHttpServer extends NodeServer {
@Override
@SuppressWarnings("unchecked")
protected ClassFilter<Service> createServiceClassFilter() {
return createClassFilter(this.sncpGroup, null, Service.class, new Class[]{org.redkale.watch.WatchService.class}, Annotation.class, "services", "service");
return createClassFilter(
this.sncpGroup,
null,
Service.class,
new Class[] {org.redkale.watch.WatchService.class},
Annotation.class,
"services",
"service");
}
@Override
@SuppressWarnings("unchecked")
protected ClassFilter<Filter> createFilterClassFilter() {
return createClassFilter(null, null, HttpFilter.class, new Class[]{WatchFilter.class}, null, "filters", "filter");
return createClassFilter(
null, null, HttpFilter.class, new Class[] {WatchFilter.class}, null, "filters", "filter");
}
@Override
@SuppressWarnings("unchecked")
protected ClassFilter<Servlet> createServletClassFilter() {
return createClassFilter(null, WebServlet.class, HttpServlet.class, new Class[]{WatchServlet.class}, null, "servlets", "servlet");
return createClassFilter(
null,
WebServlet.class,
HttpServlet.class,
new Class[] {WatchServlet.class},
null,
"servlets",
"servlet");
}
@Override
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();
if (filters == null) {
filters = new ArrayList<>();
@@ -130,7 +148,13 @@ public class NodeHttpServer extends NodeServer {
resourceFactory.register(new ResourceTypeLoader() {
@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 {
if (!(srcObj instanceof WebSocketServlet)) {
return null;
@@ -149,17 +173,28 @@ public class NodeHttpServer extends NodeServer {
}
Service nodeService = 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();
try {
if (nodeService == null) {
nodeService = (Service) rf.find(resourceName, WebSocketNode.class);
}
if (sncpResFactory != null && resourceFactory.find(RESNAME_SNCP_ADDRESS, String.class) == null) {
resourceFactory.register(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 (sncpResFactory != null
&& resourceFactory.find(RESNAME_SNCP_ADDRESS, String.class) == null) {
resourceFactory.register(
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) {
MessageAgent messageAgent = null;
@@ -171,9 +206,19 @@ public class NodeHttpServer extends NodeServer {
} catch (Exception ex) {
logger.log(Level.WARNING, "WebSocketServlet getMessageAgent error", ex);
}
AsmMethodBoost methodBoost = application.createAsmMethodBoost(false, WebSocketNodeService.class);
nodeService = Sncp.createLocalService(serverClassLoader, resourceName, WebSocketNodeService.class, methodBoost,
application.getResourceFactory(), application.getSncpRpcGroups(), sncpClient, messageAgent, (String) null, (AnyValue) null);
AsmMethodBoost methodBoost =
application.createAsmMethodBoost(false, WebSocketNodeService.class);
nodeService = Sncp.createLocalService(
serverClassLoader,
resourceName,
WebSocketNodeService.class,
methodBoost,
application.getResourceFactory(),
application.getSncpRpcGroups(),
sncpClient,
messageAgent,
(String) null,
(AnyValue) null);
regFactory.register(resourceName, WebSocketNode.class, nodeService);
}
resourceFactory.inject(resourceName, nodeService, self);
@@ -226,7 +271,8 @@ public class NodeHttpServer extends NodeServer {
protected void loadHttpServlet(final ClassFilter<? extends Servlet> servletFilter) throws Exception {
RedkaleClassLoader.putReflectionPublicClasses(HttpServlet.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 StringBuilder sb = logger.isLoggable(Level.INFO) ? new StringBuilder() : null;
String prefix0 = servletsConf == null ? "" : servletsConf.getValue("path", "");
@@ -238,14 +284,19 @@ public class NodeHttpServer extends NodeServer {
}
final String prefix = prefix0;
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 ws2 = WebSocketServlet.class.isAssignableFrom(o2.getType());
if (ws1 == ws2) {
Priority p1 = o1.getType().getAnnotation(Priority.class);
Priority p2 = o2.getType().getAnnotation(Priority.class);
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;
});
@@ -284,8 +335,10 @@ public class NodeHttpServer extends NodeServer {
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[]>> webss = sb == null ? null : new CopyOnWriteArrayList<>();
final CopyOnWriteArrayList<AbstractMap.SimpleEntry<String, String[]>> rests =
sb == null ? null : new CopyOnWriteArrayList<>();
final CopyOnWriteArrayList<AbstractMap.SimpleEntry<String, String[]>> webss =
sb == null ? null : new CopyOnWriteArrayList<>();
if (rest && serverConf != null) {
final List<Object> restedObjects = new ArrayList<>();
final ReentrantLock restedLock = new ReentrantLock();
@@ -356,7 +409,8 @@ public class NodeHttpServer extends NodeServer {
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) {
if (as.getKey().length() > max) {
max = as.getKey().length();
@@ -367,9 +421,14 @@ public class NodeHttpServer extends NodeServer {
for (int i = 0; i < max - as.getKey().length(); i++) {
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) {
logger.log(Level.INFO, sb.toString().trim());
@@ -377,11 +436,15 @@ public class NodeHttpServer extends NodeServer {
}
@SuppressWarnings("unchecked")
protected void loadRestServlet(final ClassFilter<? extends WebSocket> webSocketFilter,
final AnyValue restConf, final List<Object> restedObjects,
final ReentrantLock restedLock, final StringBuilder sb,
protected void loadRestServlet(
final ClassFilter<? extends WebSocket> webSocketFilter,
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[]>> webss) throws Exception {
final CopyOnWriteArrayList<AbstractMap.SimpleEntry<String, String[]>> webss)
throws Exception {
if (!rest) {
return;
}
@@ -401,7 +464,8 @@ public class NodeHttpServer extends NodeServer {
if (mqname != null) {
agent0 = application.getResourceFactory().find(mqname, MessageAgent.class);
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;
@@ -414,7 +478,8 @@ public class NodeHttpServer extends NodeServer {
String userTypeStr = restConf.getValue("usertype");
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> excludeValues = new HashSet<>();
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());
Stream<Service> stream = super.servletServices.stream();
if (!application.isCompileMode()) {
@@ -457,7 +528,8 @@ public class NodeHttpServer extends NodeServer {
} finally {
restedLock.unlock();
}
HttpServlet servlet = httpServer.addRestServlet(serverClassLoader, service, userType, baseServletType, prefix);
HttpServlet servlet =
httpServer.addRestServlet(serverClassLoader, service, userType, baseServletType, prefix);
if (servlet == 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 (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++) {
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 {
scdl.countDown();
@@ -495,7 +570,13 @@ public class NodeHttpServer extends NodeServer {
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());
for (FilterEntry<? extends WebSocket> en : list) {
@@ -529,7 +610,8 @@ public class NodeHttpServer extends NodeServer {
continue;
}
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) {
continue; // 没有RestOnMessage方法的HttpServlet调用Rest.createRestWebSocketServlet就会返回null
}
@@ -543,7 +625,8 @@ public class NodeHttpServer extends NodeServer {
logger.finest(stype.getName() + " create a RestWebSocketServlet");
}
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++) {
mappings[i] = prefix2 + mappings[i];
}

View File

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

View File

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

View File

@@ -5,6 +5,8 @@
*/
package org.redkale.boot;
import static org.redkale.boot.Application.*;
import java.io.*;
import java.lang.annotation.Annotation;
import java.lang.reflect.*;
@@ -19,7 +21,6 @@ import org.redkale.annotation.*;
import org.redkale.annotation.AutoLoad;
import org.redkale.annotation.Command;
import org.redkale.asm.AsmMethodBoost;
import static org.redkale.boot.Application.*;
import org.redkale.boot.ClassFilter.FilterEntry;
import org.redkale.cluster.spi.ClusterAgent;
import org.redkale.inject.ResourceFactory;
@@ -38,8 +39,7 @@ import org.redkale.util.*;
/**
* Server节点的初始化配置类
*
*
* 详情见: https://redkale.org
* <p>详情见: https://redkale.org
*
* @author zhangjx
*/
@@ -116,7 +116,8 @@ public abstract class NodeServer {
this.server = server;
this.resourceFactory = server.getResourceFactory();
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();
} else {
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) {
try {
RedkaleClassLoader.putReflectionDeclaredConstructors(clazz, clazz.getName(), Application.class, AnyValue.class);
return clazz.getDeclaredConstructor(Application.class, AnyValue.class).newInstance(application, serconf);
RedkaleClassLoader.putReflectionDeclaredConstructors(
clazz, clazz.getName(), Application.class, AnyValue.class);
return clazz.getDeclaredConstructor(Application.class, AnyValue.class)
.newInstance(application, serconf);
} catch (Exception e) {
throw new RedkaleException(e);
}
@@ -138,7 +141,9 @@ public abstract class NodeServer {
public void init(AnyValue config) throws Exception {
this.serverConf = config == null ? AnyValue.create() : config;
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()) {
host = application.localAddress.getAddress().getHostAddress();
}
@@ -146,7 +151,8 @@ public abstract class NodeServer {
this.sncpGroup = application.getSncpRpcGroups().getGroup(this.sncpAddress);
// 单向SNCP服务不需要对等group
// 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
@@ -154,7 +160,10 @@ public abstract class NodeServer {
this.resourceFactory.register(RESNAME_SNCP_ADDRESS, 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, 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) {
this.resourceFactory.register(RESNAME_SNCP_GROUP, this.sncpGroup);
@@ -178,10 +187,19 @@ public abstract class NodeServer {
// 必须要进行初始化, 构建Service时需要使用Context中的ExecutorService
server.init(this.serverConf);
if (this.sncpAddress != null) { // 初始化SncpClient
this.sncpAsyncGroup = new AsyncIOGroup("Redkale-SncpClient-IOThread-%s", application.getWorkExecutor(),
server.getBufferCapacity(), server.getBufferPoolSize()).skipClose(true);
this.sncpClient = new SncpClient(server.getName(), this.sncpAsyncGroup, application.getNodeid(),
this.sncpAddress, new ClientAddress(this.sncpAddress), server.getNetprotocol(), Utility.cpus(), 1000);
this.sncpAsyncGroup = new AsyncIOGroup(
"Redkale-SncpClient-IOThread-%s",
application.getWorkExecutor(), server.getBufferCapacity(), server.getBufferPoolSize())
.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注册依赖注入时的监听回调事件。
@@ -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;
@@ -252,7 +269,13 @@ public abstract class NodeServer {
// --------------------- 注册 Local AutoLoad(false) Service ---------------------
resourceFactory.register(new ResourceTypeLoader() {
@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);
}
@@ -266,7 +289,13 @@ public abstract class NodeServer {
final ResourceFactory appResFactory = application.getResourceFactory();
resourceFactory.register(new ResourceTypeLoader() {
@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 {
if ((srcObj instanceof Service) && Sncp.isRemote((Service) srcObj)) {
return null; // 远程模式不得注入
@@ -277,10 +306,21 @@ public abstract class NodeServer {
if (groups.isEmpty() && isSNCP() && NodeServer.this.sncpGroup != null) {
groups.add(NodeServer.this.sncpGroup);
}
AsmMethodBoost methodBoost = application.createAsmMethodBoost(false, WebSocketNodeService.class);
nodeService = Sncp.createLocalService(serverClassLoader, resourceName, WebSocketNodeService.class, methodBoost,
application.getResourceFactory(), application.getSncpRpcGroups(), sncpClient, null, (String) null, (AnyValue) null);
(isSNCP() ? appResFactory : resourceFactory).register(resourceName, WebSocketNode.class, nodeService);
AsmMethodBoost methodBoost =
application.createAsmMethodBoost(false, WebSocketNodeService.class);
nodeService = Sncp.createLocalService(
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);
}
resourceFactory.inject(resourceName, nodeService, self);
@@ -314,7 +354,13 @@ public abstract class NodeServer {
}
// 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 ResourceFactory appResFactory = application.getResourceFactory();
Class<Service> serviceImplClass = Service.class;
@@ -346,12 +392,30 @@ public abstract class NodeServer {
} else if (Utility.isAbstractOrInterface(serviceImplClass)) { // 没有具体实现类
AsmMethodBoost methodBoost = application.createAsmMethodBoost(true, serviceImplClass);
MessageAgent mqAgent = appResFactory.find("", MessageAgent.class);
service = Sncp.createRemoteService(serverClassLoader, resourceName, serviceImplClass,
methodBoost, appResFactory, application.getSncpRpcGroups(), this.sncpClient, mqAgent, null, null);
service = Sncp.createRemoteService(
serverClassLoader,
resourceName,
serviceImplClass,
methodBoost,
appResFactory,
application.getSncpRpcGroups(),
this.sncpClient,
mqAgent,
null,
null);
} else {
AsmMethodBoost methodBoost = application.createAsmMethodBoost(false, serviceImplClass);
service = Sncp.createLocalService(serverClassLoader, resourceName, serviceImplClass,
methodBoost, appResFactory, application.getSncpRpcGroups(), sncpClient, null, null, null);
service = Sncp.createLocalService(
serverClassLoader,
resourceName,
serviceImplClass,
methodBoost,
appResFactory,
application.getSncpRpcGroups(),
sncpClient,
null,
null,
null);
}
appResFactory.register(resourceName, serviceImplClass, service);
@@ -360,11 +424,14 @@ public abstract class NodeServer {
if (!application.isCompileMode() && !Sncp.isRemote(service)) {
service.init(null);
}
logger.info("Load Service(" + (Sncp.isRemote(service) ? "Remote" : "@Local")
+ " @AutoLoad service = " + serviceImplClass.getSimpleName() + ", resourceName = '" + resourceName + "')");
logger.info("Load Service(" + (Sncp.isRemote(service) ? "Remote" : "@Local") + " @AutoLoad service = "
+ serviceImplClass.getSimpleName() + ", resourceName = '" + resourceName + "')");
return service;
} 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;
}
}
@@ -385,8 +452,14 @@ public abstract class NodeServer {
private final boolean localMode;
public ExpectServiceLoader(Class type, Class<? extends Service> serviceImplClass, AtomicInteger serviceCount,
SncpRpcGroups rpcGroups, FilterEntry<? extends Service> entry, String group, boolean localMode) {
public ExpectServiceLoader(
Class type,
Class<? extends Service> serviceImplClass,
AtomicInteger serviceCount,
SncpRpcGroups rpcGroups,
FilterEntry<? extends Service> entry,
String group,
boolean localMode) {
this.type = type;
this.serviceImplClass = serviceImplClass;
this.serviceCount = serviceCount;
@@ -397,16 +470,27 @@ public abstract class NodeServer {
}
@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 {
final ResourceFactory appResourceFactory = application.getResourceFactory();
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(javax.annotation.Priority.class) == null)) { //class没有可用的方法且没有标记启动优先级的 通常为BaseService
if (!serviceImplClass.getName().startsWith("org.redkale.") && !serviceImplClass.getSimpleName().contains("Base")) {
logger.log(Level.FINE, serviceImplClass + " cannot load because not found less one public non-final method");
&& serviceImplClass.getAnnotation(javax.annotation.Priority.class)
== null)) { // class没有可用的方法且没有标记启动优先级的 通常为BaseService
if (!serviceImplClass.getName().startsWith("org.redkale.")
&& !serviceImplClass.getSimpleName().contains("Base")) {
logger.log(
Level.FINE,
serviceImplClass + " cannot load because not found less one public non-final method");
}
return null;
}
@@ -421,19 +505,37 @@ public abstract class NodeServer {
service = serviceImplClass.getDeclaredConstructor().newInstance();
} else if (srcObj instanceof WebSocketServlet || localMode) { // 本地模式
AsmMethodBoost methodBoost = application.createAsmMethodBoost(false, serviceImplClass);
service = Sncp.createLocalService(serverClassLoader, resourceName, serviceImplClass,
methodBoost, appResourceFactory, rpcGroups, sncpClient, mqAgent, group, entry.getProperty());
service = Sncp.createLocalService(
serverClassLoader,
resourceName,
serviceImplClass,
methodBoost,
appResourceFactory,
rpcGroups,
sncpClient,
mqAgent,
group,
entry.getProperty());
} else {
AsmMethodBoost methodBoost = application.createAsmMethodBoost(true, serviceImplClass);
service = Sncp.createRemoteService(serverClassLoader, resourceName, serviceImplClass,
methodBoost, appResourceFactory, rpcGroups, sncpClient, mqAgent, group, entry.getProperty());
service = Sncp.createRemoteService(
serverClassLoader,
resourceName,
serviceImplClass,
methodBoost,
appResourceFactory,
rpcGroups,
sncpClient,
mqAgent,
group,
entry.getProperty());
}
final Class restype = Sncp.getResourceType(service);
if (rf.find(resourceName, restype) == null) {
regFactory.register(resourceName, restype, service);
} else if (isSNCP() && !entry.isAutoload()) {
throw new RedkaleException(restype.getSimpleName()
+ "(class:" + serviceImplClass.getName() + ", name:" + resourceName + ", group:" + group + ") is repeat.");
throw new RedkaleException(restype.getSimpleName() + "(class:" + serviceImplClass.getName()
+ ", name:" + resourceName + ", group:" + group + ") is repeat.");
}
if (Sncp.isRemote(service)) {
remoteServices.add(service);
@@ -460,7 +562,6 @@ public abstract class NodeServer {
public Type resourceType() {
return type;
}
}
@SuppressWarnings("unchecked")
@@ -493,7 +594,8 @@ public abstract class NodeServer {
}
}
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())) {
throw new RedkaleException("Not found group(" + entry.getGroup() + ")");
@@ -516,21 +618,22 @@ public abstract class NodeServer {
if (entry.isExpect()) {
Class t = ResourceFactory.getResourceType(entry.getType());
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 {
ExpectServiceLoader resourceLoader = new ExpectServiceLoader(serviceImplClass,
serviceImplClass, serviceCount, rpcGroups, entry, group, localMode);
ExpectServiceLoader resourceLoader = new ExpectServiceLoader(
serviceImplClass, serviceImplClass, serviceCount, rpcGroups, entry, group, localMode);
resourceLoader.load(resourceFactory, null, null, entry.getName(), null, false);
}
}
long et = System.currentTimeMillis();
if (serviceCdl != null) {
serviceCdl.countDown();
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;
// ---------------- inject ----------------
@@ -545,7 +648,9 @@ public abstract class NodeServer {
if (sb != null) {
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()) {
@@ -569,7 +674,9 @@ public abstract class NodeServer {
if (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) {
rs = Sncp.getResourceName(o1).compareTo(Sncp.getResourceName(o2));
}
@@ -586,7 +693,11 @@ public abstract class NodeServer {
localServices.stream().forEach(y -> {
String serstr = Sncp.toSimpleString(y, maxNameLength, maxTypeLength);
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 {
@@ -598,8 +709,14 @@ public abstract class NodeServer {
long e = System.currentTimeMillis() - s;
if (slist != null) {
String serstr = Sncp.toSimpleString(y, maxNameLength, maxTypeLength);
slist.add(new StringBuilder().append(serstr).append(" load and init in ")
.append(e < 10 ? " " : (e < 100 ? " " : "")).append(e).append(" ms").append(LINE_SEPARATOR).toString());
slist.add(new StringBuilder()
.append(serstr)
.append(" load and init in ")
.append(e < 10 ? " " : (e < 100 ? " " : ""))
.append(e)
.append(" ms")
.append(LINE_SEPARATOR)
.toString());
}
});
localServices.stream().forEach(y -> {
@@ -609,21 +726,35 @@ public abstract class NodeServer {
long e = System.currentTimeMillis() - s;
if (rs && slist != null) {
String serstr = Sncp.toSimpleString(y, maxNameLength, maxTypeLength);
slist.add(new StringBuilder().append(serstr).append(" component-start in ")
.append(e < 10 ? " " : (e < 100 ? " " : "")).append(e).append(" ms").append(LINE_SEPARATOR).toString());
slist.add(new StringBuilder()
.append(serstr)
.append(" component-start in ")
.append(e < 10 ? " " : (e < 100 ? " " : ""))
.append(e)
.append(" ms")
.append(LINE_SEPARATOR)
.toString());
}
}
});
}
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) {
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) {
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) {
logger.log(Level.INFO, sb.toString());
@@ -633,11 +764,13 @@ public abstract class NodeServer {
private void calcMaxLength(Service y) { // 计算toString中的长度
String n = Sncp.getResourceName(y);
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) {
if (Modifier.isAbstract(serviceImplClass.getModifiers()) || Modifier.isInterface(serviceImplClass.getModifiers())) {
if (Modifier.isAbstract(serviceImplClass.getModifiers())
|| Modifier.isInterface(serviceImplClass.getModifiers())) {
return false;
}
return true;
@@ -659,7 +792,8 @@ public abstract class NodeServer {
}
// 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);
if (!application.isCompileMode() && cluster != null) {
NodeProtocol pros = getClass().getAnnotation(NodeProtocol.class);
@@ -675,17 +809,17 @@ public abstract class NodeServer {
}
// loadServlet执行之后调用
protected void postLoadServlets() {
}
protected void postLoadServlets() {}
// 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);
if (!application.isCompileMode() && cluster != null) { // 服务注销
NodeProtocol pros = getClass().getAnnotation(NodeProtocol.class);
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);
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执行之后调用
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();
@@ -710,12 +843,24 @@ public abstract class NodeServer {
}
protected ClassFilter<Service> createServiceClassFilter() {
return createClassFilter(this.sncpGroup, null, Service.class,
(!isSNCP() && application.watching) ? null : new Class[]{org.redkale.watch.WatchService.class}, Annotation.class, "services", "service");
return createClassFilter(
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,
Class inter, Class[] excludeSuperClasses, Class<? extends Annotation> ref2, String properties, String property) {
protected ClassFilter createClassFilter(
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);
if (properties == null) {
cf.setRefused(true);
@@ -870,7 +1015,11 @@ public abstract class NodeServer {
application.onServicePostDestroy(y);
long e = System.currentTimeMillis() - s;
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) {
@@ -942,7 +1091,13 @@ public abstract class NodeServer {
}
long e = System.currentTimeMillis() - s;
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) {
@@ -970,5 +1125,4 @@ public abstract class NodeServer {
public String getThreadName() {
return this.threadName;
}
}

View File

@@ -18,8 +18,7 @@ import org.redkale.util.*;
/**
* SNCP Server节点的配置Server
*
* <p>
* 详情见: https://redkale.org
* <p>详情见: https://redkale.org
*
* @author zhangjx
*/
@@ -38,7 +37,11 @@ public class NodeSncpServer extends NodeServer {
}
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
@@ -61,11 +64,14 @@ public class NodeSncpServer extends NodeServer {
int maxNameLength = 0;
for (SncpServlet en : servlets) {
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) {
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) {
@@ -83,7 +89,11 @@ public class NodeSncpServer extends NodeServer {
for (int i = 0; i < len; i++) {
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++) {
sb.append(' ');
}
@@ -108,7 +118,8 @@ public class NodeSncpServer extends NodeServer {
}
@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;
List<FilterEntry<? extends Filter>> list = new ArrayList(classFilter.getFilterEntrys());
for (FilterEntry<? extends Filter> entry : list) {
@@ -144,7 +155,8 @@ public class NodeSncpServer extends NodeServer {
dynServletMap.put(x, servlet);
String mq = Sncp.getResourceMQ(x);
if (mq != null) {
MessageAgent agent = application.getResourceFactory().find(mq, MessageAgent.class);
MessageAgent agent =
application.getResourceFactory().find(mq, MessageAgent.class);
agent.putService(this, x, servlet);
}
});
@@ -154,12 +166,18 @@ public class NodeSncpServer extends NodeServer {
@Override
@SuppressWarnings("unchecked")
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
protected ClassFilter<Servlet> createServletClassFilter() {
return null;
}
}

View File

@@ -13,10 +13,7 @@ import org.redkale.service.Service;
import org.redkale.util.AnyValue;
import org.redkale.watch.*;
/**
*
* @author zhangjx
*/
/** @author zhangjx */
@NodeProtocol("WATCH")
public class NodeWatchServer extends NodeHttpServer {
@@ -27,7 +24,8 @@ public class NodeWatchServer extends NodeHttpServer {
@Override
@SuppressWarnings("unchecked")
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

View File

@@ -34,12 +34,17 @@ public class PrepareCompiler {
application.init();
application.onPreCompile();
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<?> 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<?> 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);
application.loadClassByFilters(entityFilter, beanFilter, filterFilter);

View File

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

View File

@@ -5,25 +5,18 @@
*/
package org.redkale.boot.watch;
import org.redkale.service.AbstractService;
import org.redkale.annotation.Comment;
import org.redkale.service.AbstractService;
import org.redkale.watch.WatchService;
/**
*
* @author zhangjx
*/
/** @author zhangjx */
public abstract class AbstractWatchService extends AbstractService implements WatchService {
/**
* 缺少参数
*/
/** 缺少参数 */
@Comment("缺少参数")
public static final int RET_WATCH_PARAMS_ILLEGAL = 1600_0001;
/**
* 执行异常
*/
/** 执行异常 */
@Comment("执行异常")
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.service.RetResult;
/**
*
* @author zhangjx
*/
/** @author zhangjx */
@RestService(name = "filter", catalog = "watch", repair = false)
public class FilterWatchService extends AbstractWatchService {
@@ -35,9 +32,11 @@ public class FilterWatchService extends AbstractWatchService {
protected Application application;
@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 = "type", comment = "Filter类名") final String filterType) throws IOException {
@RestParam(name = "type", comment = "Filter类名") final String filterType)
throws IOException {
if (filterType == null) {
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.service.RetResult;
/**
*
* @author zhangjx
*/
/** @author zhangjx */
@RestService(name = "server", catalog = "watch", repair = false)
public class ServerWatchService extends AbstractWatchService {
@@ -34,7 +31,9 @@ public class ServerWatchService extends AbstractWatchService {
@RestMapping(name = "info", comment = "单个Server信息查询")
public RetResult info(@RestParam(name = "#port:") final int port) {
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) {
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的监听地址和端口")
public RetResult changeAddress(@RestParam(name = "#port:") final int oldport,
@RestParam(name = "#newhost:") final String newhost, @RestParam(name = "#newport:") final int newport) {
public RetResult changeAddress(
@RestParam(name = "#port:") final int oldport,
@RestParam(name = "#newhost:") final String newhost,
@RestParam(name = "#newport:") final int newport) {
if (oldport < 1) {
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`");
}
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) {
return new RetResult(RET_SERVER_NOT_EXISTS, "Server(port=" + oldport + ") not found");
}
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 {
server.changeAddress(application, newAddr);
} catch (IOException e) {
@@ -96,7 +100,9 @@ public class ServerWatchService extends AbstractWatchService {
rs.put("backlog", server.getBacklog());
rs.put("bufferCapacity", server.getBufferCapacity());
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("maxconns", server.getMaxConns());
rs.put("serverStartTime", server.getServerStartTime());

View File

@@ -15,7 +15,6 @@ import org.redkale.net.http.*;
import org.redkale.service.RetResult;
/**
* <p>
* 详情见: https://redkale.org
*
* @author zhangjx
@@ -31,7 +30,8 @@ public class ServiceWatchService extends AbstractWatchService {
@RestConvert(type = void.class)
@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 = "field", comment = "字段名") String field,
@RestParam(name = "value", comment = "字段值") String value) {
@@ -80,7 +80,8 @@ public class ServiceWatchService extends AbstractWatchService {
@RestConvert(type = void.class)
@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 = "field", comment = "字段名") String field) {
if (name == null) {
@@ -127,7 +128,8 @@ public class ServiceWatchService extends AbstractWatchService {
@RestConvert(type = void.class)
@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 = "method", comment = "Service的方法名") String method,
@RestParam(name = "params", comment = "方法的参数值") List<String> params,
@@ -188,7 +190,10 @@ public class ServiceWatchService extends AbstractWatchService {
}
} while ((clazz = clazz.getSuperclass()) != Object.class);
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);
if (paramcount < 1) {
@@ -209,41 +214,47 @@ public class ServiceWatchService extends AbstractWatchService {
Object dest = null;
for (NodeServer ns : application.getNodeServers()) {
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()) {
continue;
}
dest = list.get(0);
}
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;
}
@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) {
// 待开发
return RetResult.success();
}
@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) {
// 待开发
return RetResult.success();
}
@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) {
// 待开发
return RetResult.success();
}
@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) {
// 待开发
return RetResult.success();

View File

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

View File

@@ -11,18 +11,14 @@ import org.redkale.util.ThrowSupplier;
/**
* 缓存管理器
*
* <p>
* 详情见: https://redkale.org
* <p>详情见: https://redkale.org
*
* @author zhangjx
*
* @since 2.8.0
*/
public interface CacheManager {
/**
* 默认的hash
*/
/** 默认的hash */
public static final String DEFAULT_HASH = "cache-hash";
// -------------------------------------- 本地缓存 --------------------------------------
@@ -33,7 +29,6 @@ public interface CacheManager {
* @param hash 缓存hash
* @param key 缓存键
* @param type 数据类型
*
* @return 数据值
*/
public <T> T localGet(final String hash, final String key, final Type type);
@@ -44,7 +39,6 @@ public interface CacheManager {
* @param <T> 泛型
* @param key 缓存键
* @param type 数据类型
*
* @return 数据值
*/
default <T> T localGet(final String key, final Type type) {
@@ -56,7 +50,6 @@ public interface CacheManager {
*
* @param hash 缓存hash
* @param key 缓存键
*
* @return 数据值
*/
default String localGetString(final String hash, final String key) {
@@ -67,7 +60,6 @@ public interface CacheManager {
* 本地获取字符串缓存数据, 过期返回null
*
* @param key 缓存键
*
* @return 数据值
*/
default String localGetString(final String key) {
@@ -84,10 +76,15 @@ public interface CacheManager {
* @param nullable 是否缓存null值
* @param expire 过期时长Duration.ZERO为永不过期
* @param supplier 数据函数
*
* @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
@@ -98,10 +95,10 @@ public interface CacheManager {
* @param nullable 是否缓存null值
* @param expire 过期时长Duration.ZERO为永不过期
* @param supplier 数据函数
*
* @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);
}
@@ -115,10 +112,15 @@ public interface CacheManager {
* @param nullable 是否缓存null值
* @param expire 过期时长Duration.ZERO为永不过期
* @param supplier 数据函数
*
* @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
@@ -129,10 +131,10 @@ public interface CacheManager {
* @param nullable 是否缓存null值
* @param expire 过期时长Duration.ZERO为永不过期
* @param supplier 数据函数
*
* @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);
}
@@ -189,7 +191,6 @@ public interface CacheManager {
*
* @param hash 缓存hash
* @param key 缓存键
*
* @return 删除数量
*/
public long localDel(String hash, String key);
@@ -198,7 +199,6 @@ public interface CacheManager {
* 本地删除缓存数据
*
* @param key 缓存键
*
* @return 删除数量
*/
default long localDel(String key) {
@@ -213,7 +213,6 @@ public interface CacheManager {
* @param hash 缓存hash
* @param key 缓存键
* @param type 数据类型
*
* @return 数据值
*/
public <T> T remoteGet(final String hash, final String key, final Type type);
@@ -224,7 +223,6 @@ public interface CacheManager {
* @param <T> 泛型
* @param key 缓存键
* @param type 数据类型
*
* @return 数据值
*/
default <T> T remoteGet(final String key, final Type type) {
@@ -236,7 +234,6 @@ public interface CacheManager {
*
* @param hash 缓存hash
* @param key 缓存键
*
* @return 数据值
*/
default String remoteGetString(final String hash, final String key) {
@@ -247,7 +244,6 @@ public interface CacheManager {
* 远程获取字符串缓存数据, 过期返回null
*
* @param key 缓存键
*
* @return 数据值
*/
default String remoteGetString(final String key) {
@@ -261,7 +257,6 @@ public interface CacheManager {
* @param hash 缓存hash
* @param key 缓存键
* @param type 数据类型
*
* @return 数据值
*/
public <T> CompletableFuture<T> remoteGetAsync(final String hash, final String key, final Type type);
@@ -272,7 +267,6 @@ public interface CacheManager {
* @param <T> 泛型
* @param key 缓存键
* @param type 数据类型
*
* @return 数据值
*/
default <T> CompletableFuture<T> remoteGetAsync(final String key, final Type type) {
@@ -284,7 +278,6 @@ public interface CacheManager {
*
* @param hash 缓存hash
* @param key 缓存键
*
* @return 数据值
*/
default CompletableFuture<String> remoteGetStringAsync(final String hash, final String key) {
@@ -295,7 +288,6 @@ public interface CacheManager {
* 远程异步获取字符串缓存数据, 过期返回null
*
* @param key 缓存键
*
* @return 数据值
*/
default CompletableFuture<String> remoteGetStringAsync(final String key) {
@@ -312,11 +304,15 @@ public interface CacheManager {
* @param nullable 是否缓存null值
* @param expire 过期时长Duration.ZERO为永不过期
* @param supplier 数据函数
*
* @return 数据值
*/
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);
/**
* 远程获取缓存数据, 过期返回null
@@ -327,11 +323,10 @@ public interface CacheManager {
* @param nullable 是否缓存null值
* @param expire 过期时长Duration.ZERO为永不过期
* @param supplier 数据函数
*
* @return 数据值
*/
default <T> T remoteGetSet(final String key, final Type type, boolean nullable,
Duration expire, ThrowSupplier<T> supplier) {
default <T> T remoteGetSet(
final String key, final Type type, boolean nullable, Duration expire, ThrowSupplier<T> supplier) {
return remoteGetSet(DEFAULT_HASH, key, type, nullable, expire, supplier);
}
@@ -345,11 +340,15 @@ public interface CacheManager {
* @param nullable 是否缓存null值
* @param expire 过期时长Duration.ZERO为永不过期
* @param supplier 数据函数
*
* @return 数据值
*/
public <T> CompletableFuture<T> remoteGetSetAsync(String hash, String key, Type type, boolean nullable,
Duration expire, ThrowSupplier<CompletableFuture<T>> supplier);
public <T> CompletableFuture<T> remoteGetSetAsync(
String hash,
String key,
Type type,
boolean nullable,
Duration expire,
ThrowSupplier<CompletableFuture<T>> supplier);
/**
* 远程异步获取缓存数据, 过期返回null
@@ -360,11 +359,10 @@ public interface CacheManager {
* @param nullable 是否缓存null值
* @param expire 过期时长Duration.ZERO为永不过期
* @param supplier 数据函数
*
* @return 数据值
*/
default <T> CompletableFuture<T> remoteGetSetAsync(String key, Type type, boolean nullable,
Duration expire, ThrowSupplier<CompletableFuture<T>> supplier) {
default <T> CompletableFuture<T> remoteGetSetAsync(
String key, Type type, boolean nullable, Duration expire, ThrowSupplier<CompletableFuture<T>> supplier) {
return remoteGetSetAsync(DEFAULT_HASH, key, type, nullable, expire, supplier);
}
@@ -425,7 +423,6 @@ public interface CacheManager {
* @param type 数据类型
* @param value 数据值
* @param expire 过期时长Duration.ZERO为永不过期
*
* @return void
*/
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 value 数据值
* @param expire 过期时长Duration.ZERO为永不过期
*
* @return void
*/
default <T> CompletableFuture<Void> remoteSetAsync(String key, Type type, T value, Duration expire) {
@@ -452,10 +448,10 @@ public interface CacheManager {
* @param key 缓存键
* @param value 数据值
* @param expire 过期时长Duration.ZERO为永不过期
*
* @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);
}
@@ -465,7 +461,6 @@ public interface CacheManager {
* @param key 缓存键
* @param value 数据值
* @param expire 过期时长Duration.ZERO为永不过期
*
* @return void
*/
default CompletableFuture<Void> remoteSetStringAsync(final String key, final String value, Duration expire) {
@@ -477,7 +472,6 @@ public interface CacheManager {
*
* @param hash 缓存hash
* @param key 缓存键
*
* @return 删除数量
*/
public long remoteDel(String hash, String key);
@@ -486,7 +480,6 @@ public interface CacheManager {
* 远程删除缓存数据
*
* @param key 缓存键
*
* @return 删除数量
*/
default long remoteDel(String key) {
@@ -498,7 +491,6 @@ public interface CacheManager {
*
* @param hash 缓存hash
* @param key 缓存键
*
* @return 删除数量
*/
public CompletableFuture<Long> remoteDelAsync(String hash, String key);
@@ -507,7 +499,6 @@ public interface CacheManager {
* 远程异步删除缓存数据
*
* @param key 缓存键
*
* @return 删除数量
*/
default CompletableFuture<Long> remoteDelAsync(String key) {
@@ -522,7 +513,6 @@ public interface CacheManager {
* @param hash 缓存hash
* @param key 缓存键
* @param type 数据类型
*
* @return 数据值
*/
public <T> T bothGet(final String hash, final String key, final Type type);
@@ -533,7 +523,6 @@ public interface CacheManager {
* @param <T> 泛型
* @param key 缓存键
* @param type 数据类型
*
* @return 数据值
*/
default <T> T bothGet(final String key, final Type type) {
@@ -545,7 +534,6 @@ public interface CacheManager {
*
* @param hash 缓存hash
* @param key 缓存键
*
* @return 数据值
*/
default String bothGetString(final String hash, final String key) {
@@ -556,7 +544,6 @@ public interface CacheManager {
* 本地或远程获取字符串缓存数据, 过期返回null
*
* @param key 缓存键
*
* @return 数据值
*/
default String bothGetString(final String key) {
@@ -570,7 +557,6 @@ public interface CacheManager {
* @param hash 缓存hash
* @param key 缓存键
* @param type 数据类型
*
* @return 数据值
*/
public <T> CompletableFuture<T> bothGetAsync(final String hash, final String key, final Type type);
@@ -581,7 +567,6 @@ public interface CacheManager {
* @param <T> 泛型
* @param key 缓存键
* @param type 数据类型
*
* @return 数据值
*/
default <T> CompletableFuture<T> bothGetAsync(final String key, final Type type) {
@@ -593,7 +578,6 @@ public interface CacheManager {
*
* @param hash 缓存hash
* @param key 缓存键
*
* @return 数据值
*/
default CompletableFuture<String> bothGetStringAsync(final String hash, final String key) {
@@ -604,7 +588,6 @@ public interface CacheManager {
* 本地或远程异步获取字符串缓存数据, 过期返回null
*
* @param key 缓存键
*
* @return 数据值
*/
default CompletableFuture<String> bothGetStringAsync(final String key) {
@@ -622,11 +605,16 @@ public interface CacheManager {
* @param localExpire 本地过期时长Duration.ZERO为永不过期为null表示不本地缓存
* @param remoteExpire 远程过期时长Duration.ZERO为永不过期为null表示不远程缓存
* @param supplier 数据函数
*
* @return 数据值
*/
public <T> T bothGetSet(String hash, String key, Type type, boolean nullable,
Duration localExpire, Duration remoteExpire, ThrowSupplier<T> supplier);
public <T> T bothGetSet(
String hash,
String key,
Type type,
boolean nullable,
Duration localExpire,
Duration remoteExpire,
ThrowSupplier<T> supplier);
/**
* 本地或远程获取缓存数据, 过期返回null
@@ -638,11 +626,15 @@ public interface CacheManager {
* @param localExpire 本地过期时长Duration.ZERO为永不过期为null表示不本地缓存
* @param remoteExpire 远程过期时长Duration.ZERO为永不过期为null表示不远程缓存
* @param supplier 数据函数
*
* @return 数据值
*/
default <T> T bothGetSet(String key, Type type, boolean nullable,
Duration localExpire, Duration remoteExpire, ThrowSupplier<T> supplier) {
default <T> T bothGetSet(
String key,
Type type,
boolean nullable,
Duration localExpire,
Duration remoteExpire,
ThrowSupplier<T> supplier) {
return bothGetSet(DEFAULT_HASH, key, type, nullable, localExpire, remoteExpire, supplier);
}
@@ -657,11 +649,16 @@ public interface CacheManager {
* @param localExpire 本地过期时长Duration.ZERO为永不过期为null表示不本地缓存
* @param remoteExpire 远程过期时长Duration.ZERO为永不过期为null表示不远程缓存
* @param supplier 数据函数
*
* @return 数据值
*/
public <T> CompletableFuture<T> bothGetSetAsync(String hash, String key, Type type, boolean nullable,
Duration localExpire, Duration remoteExpire, ThrowSupplier<CompletableFuture<T>> supplier);
public <T> CompletableFuture<T> bothGetSetAsync(
String hash,
String key,
Type type,
boolean nullable,
Duration localExpire,
Duration remoteExpire,
ThrowSupplier<CompletableFuture<T>> supplier);
/**
* 本地或远程异步获取缓存数据, 过期返回null
@@ -673,11 +670,15 @@ public interface CacheManager {
* @param localExpire 本地过期时长Duration.ZERO为永不过期为null表示不本地缓存
* @param remoteExpire 远程过期时长Duration.ZERO为永不过期为null表示不远程缓存
* @param supplier 数据函数
*
* @return 数据值
*/
default <T> CompletableFuture<T> bothGetSetAsync(String key, Type type, boolean nullable,
Duration localExpire, Duration remoteExpire, ThrowSupplier<CompletableFuture<T>> supplier) {
default <T> CompletableFuture<T> bothGetSetAsync(
String key,
Type type,
boolean nullable,
Duration localExpire,
Duration remoteExpire,
ThrowSupplier<CompletableFuture<T>> supplier) {
return bothGetSetAsync(DEFAULT_HASH, key, type, nullable, localExpire, remoteExpire, supplier);
}
@@ -692,7 +693,13 @@ public interface CacheManager {
* @param localExpire 本地过期时长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 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);
}
@@ -717,7 +725,8 @@ public interface CacheManager {
* @param localExpire 本地过期时长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);
}
@@ -743,10 +752,10 @@ public interface CacheManager {
* @param value 数据值
* @param localExpire 本地过期时长Duration.ZERO为永不过期为null表示不本地缓存
* @param remoteExpire 远程过期时长Duration.ZERO为永不过期为null表示不远程缓存
*
* @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 localExpire 本地过期时长Duration.ZERO为永不过期为null表示不本地缓存
* @param remoteExpire 远程过期时长Duration.ZERO为永不过期为null表示不远程缓存
*
* @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);
}
@@ -772,10 +781,10 @@ public interface CacheManager {
* @param value 数据值
* @param localExpire 本地过期时长Duration.ZERO为永不过期为null表示不本地缓存
* @param remoteExpire 远程过期时长Duration.ZERO为永不过期为null表示不远程缓存
*
* @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);
}
@@ -786,10 +795,10 @@ public interface CacheManager {
* @param value 数据值
* @param localExpire 本地过期时长Duration.ZERO为永不过期为null表示不本地缓存
* @param remoteExpire 远程过期时长Duration.ZERO为永不过期为null表示不远程缓存
*
* @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);
}
@@ -798,7 +807,6 @@ public interface CacheManager {
*
* @param hash 缓存hash
* @param key 缓存键
*
* @return 删除数量
*/
public long bothDel(String hash, String key);
@@ -807,7 +815,6 @@ public interface CacheManager {
* 本地和远程删除缓存数据
*
* @param key 缓存键
*
* @return 删除数量
*/
default long bothDel(String key) {
@@ -819,7 +826,6 @@ public interface CacheManager {
*
* @param hash 缓存hash
* @param key 缓存键
*
* @return 删除数量
*/
public CompletableFuture<Long> bothDelAsync(String hash, String key);
@@ -828,11 +834,9 @@ public interface CacheManager {
* 本地和远程异步删除缓存数据
*
* @param key 缓存键
*
* @return 删除数量
*/
default CompletableFuture<Long> bothDelAsync(String key) {
return bothDelAsync(DEFAULT_HASH, key);
}
}

View File

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

View File

@@ -8,6 +8,7 @@ import java.lang.reflect.Type;
import java.time.Duration;
import java.util.Objects;
import java.util.concurrent.CompletableFuture;
import org.redkale.annotation.ClassDepends;
import org.redkale.annotation.Nullable;
import org.redkale.annotation.Resource;
import org.redkale.cache.CacheManager;
@@ -16,17 +17,13 @@ import org.redkale.util.Environment;
import org.redkale.util.MultiHashKey;
import org.redkale.util.ThrowSupplier;
import org.redkale.util.TypeToken;
import org.redkale.annotation.ClassDepends;
/**
*
* 缓存的方法对象
*
* <p>
* 详情见: https://redkale.org
* <p>详情见: https://redkale.org
*
* @author zhangjx
*
* @since 2.8.0
*/
@ClassDepends
@@ -78,8 +75,14 @@ public class CacheAction {
// 远程缓存过期时长Duration.ZERO为永不过期为null表示不远程缓存
private Duration remoteExpire;
CacheAction(CacheEntry cached, Type returnType, Class serviceClass, Class[] paramTypes,
String[] paramNames, String methodName, String fieldName) {
CacheAction(
CacheEntry cached,
Type returnType,
Class serviceClass,
Class[] paramTypes,
String[] paramNames,
String methodName,
String fieldName) {
this.cached = cached;
this.nullable = cached.isNullable();
this.serviceClass = Objects.requireNonNull(serviceClass);
@@ -92,8 +95,7 @@ public class CacheAction {
}
void init() {
this.hash = cached.getHash().trim().isEmpty()
|| CacheManager.DEFAULT_HASH.equals(cached.getHash())
this.hash = cached.getHash().trim().isEmpty() || CacheManager.DEFAULT_HASH.equals(cached.getHash())
? CacheManager.DEFAULT_HASH
: environment.getPropertyValue(cached.getHash());
String key = environment.getPropertyValue(cached.getKey());
@@ -106,9 +108,11 @@ public class CacheAction {
public <T> T get(ThrowSupplier<T> supplier, Object... args) {
if (async) {
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 {
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
+ "}";
}
}

View File

@@ -3,6 +3,8 @@
*/
package org.redkale.cache.spi;
import static org.redkale.asm.Opcodes.*;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
@@ -21,7 +23,6 @@ import org.redkale.asm.Handle;
import org.redkale.asm.Label;
import org.redkale.asm.MethodVisitor;
import org.redkale.asm.Opcodes;
import static org.redkale.asm.Opcodes.*;
import org.redkale.asm.Type;
import org.redkale.cache.Cached;
import org.redkale.inject.ResourceFactory;
@@ -31,14 +32,10 @@ import org.redkale.util.RedkaleException;
import org.redkale.util.ThrowSupplier;
import org.redkale.util.TypeToken;
/**
*
* @author zhangjx
*/
/** @author zhangjx */
public class CacheAsmMethodBoost extends AsmMethodBoost {
private static final java.lang.reflect.Type FUTURE_VOID = new TypeToken<CompletableFuture<Void>>() {
}.getType();
private static final java.lang.reflect.Type FUTURE_VOID = new TypeToken<CompletableFuture<Void>>() {}.getType();
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
public String doMethod(ClassLoader classLoader, ClassWriter cw,
String newDynName, String fieldPrefix, List filterAnns, Method method, final String newMethodName) {
public String doMethod(
ClassLoader classLoader,
ClassWriter cw,
String newDynName,
String fieldPrefix,
List filterAnns,
Method method,
final String newMethodName) {
Map<String, CacheAction> actions = this.actionMap;
if (actions == null) {
actions = new LinkedHashMap<>();
@@ -72,10 +75,12 @@ public class CacheAsmMethodBoost extends AsmMethodBoost {
return newMethodName;
}
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())) {
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())) {
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);
List<Integer> insns = visitVarInsnParamTypes(mv, method, 0);
String dynDesc = methodBean.getDesc();
dynDesc = "(L" + newDynName + ";" + dynDesc.substring(1, dynDesc.lastIndexOf(')') + 1) + Type.getDescriptor(ThrowSupplier.class);
mv.visitInvokeDynamicInsn("get", dynDesc, Asms.createLambdaMetaHandle(),
new Object[]{
dynDesc = "(L" + newDynName + ";" + dynDesc.substring(1, dynDesc.lastIndexOf(')') + 1)
+ Type.getDescriptor(ThrowSupplier.class);
mv.visitInvokeDynamicInsn("get", dynDesc, Asms.createLambdaMetaHandle(), new Object[] {
org.redkale.asm.Type.getType("()Ljava/lang/Object;"),
new Handle(Opcodes.H_INVOKESPECIAL, newDynName, "lambda$" + actionIndex, methodBean.getDesc(), false),
org.redkale.asm.Type.getType("()" + Type.getDescriptor(method.getReturnType()))
@@ -132,15 +137,24 @@ public class CacheAsmMethodBoost extends AsmMethodBoost {
mv.visitVarInsn(ILOAD, insn);
}
Class bigclaz = TypeToken.primitiveToWrapper(pt);
mv.visitMethodInsn(INVOKESTATIC, bigclaz.getName().replace('.', '/'), "valueOf",
"(" + Type.getDescriptor((Class) pt) + ")" + Type.getDescriptor(bigclaz), false);
mv.visitMethodInsn(
INVOKESTATIC,
bigclaz.getName().replace('.', '/'),
"valueOf",
"(" + Type.getDescriptor((Class) pt) + ")" + Type.getDescriptor(bigclaz),
false);
} else {
mv.visitVarInsn(ALOAD, insn);
}
mv.visitInsn(AASTORE);
}
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.visitInsn(ARETURN);
Label l2 = new Label();
@@ -151,13 +165,21 @@ public class CacheAsmMethodBoost extends AsmMethodBoost {
mv.visitMaxs(20, 20);
mv.visitEnd();
CacheAction action = new CacheAction(new CacheEntry(cached), method.getGenericReturnType(), serviceType,
method.getParameterTypes(), methodBean.fieldNameArray(), method.getName(), dynFieldName);
CacheAction action = new CacheAction(
new CacheEntry(cached),
method.getGenericReturnType(),
serviceType,
method.getParameterTypes(),
methodBean.fieldNameArray(),
method.getName(),
dynFieldName);
actions.put(dynFieldName, action);
}
{ // ThrowSupplier
final MethodVisitor mv = cw.visitMethod(ACC_PRIVATE + ACC_SYNTHETIC,
"lambda$" + actionIndex, methodBean.getDesc(), null, new String[]{"java/lang/Throwable"});
final MethodVisitor mv = cw.visitMethod(
ACC_PRIVATE + ACC_SYNTHETIC, "lambda$" + actionIndex, methodBean.getDesc(), null, new String[] {
"java/lang/Throwable"
});
// mv.setDebug(true);
Label l0 = new Label();
mv.visitLabel(l0);
@@ -172,11 +194,16 @@ public class CacheAsmMethodBoost extends AsmMethodBoost {
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();
}
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;
}
@@ -192,8 +219,14 @@ public class CacheAsmMethodBoost extends AsmMethodBoost {
if (cached != null) {
String dynFieldName = cached.dynField();
AsmMethodBean methodBean = AsmMethodBean.get(methodBeans, method);
CacheAction action = new CacheAction(new CacheEntry(cached), method.getGenericReturnType(), serviceType,
method.getParameterTypes(), methodBean.fieldNameArray(), method.getName(), dynFieldName);
CacheAction action = new CacheAction(
new CacheEntry(cached),
method.getGenericReturnType(),
serviceType,
method.getParameterTypes(),
methodBean.fieldNameArray(),
method.getName(),
dynFieldName);
actionMap.put(dynFieldName, action);
}
}
@@ -212,5 +245,4 @@ public class CacheAsmMethodBoost extends AsmMethodBoost {
});
// do nothing
}
}

View File

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

View File

@@ -7,15 +7,11 @@ import org.redkale.cache.CacheManager;
import org.redkale.util.InstanceProvider;
/**
*
* 自定义的CacheManager加载器, 如果标记&#64;Priority加载器的优先级需要大于1000 1000以下预留给官方加载器
*
* <p>
* 详情见: https://redkale.org
* <p>详情见: https://redkale.org
*
* @author zhangjx
* @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;
}
}
}
@Override
@@ -132,7 +131,6 @@ public class CacheManagerService implements CacheManager, Service {
* @param hash 缓存hash
* @param key 缓存键
* @param type 数据类型
*
* @return 数据值
*/
@Override
@@ -151,11 +149,16 @@ public class CacheManagerService implements CacheManager, Service {
* @param nullable 是否缓存null值
* @param expire 过期时长Duration.ZERO为永不过期
* @param supplier 数据函数
*
* @return 数据值
*/
@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);
}
@@ -169,12 +172,18 @@ public class CacheManagerService implements CacheManager, Service {
* @param nullable 是否缓存null值
* @param expire 过期时长Duration.ZERO为永不过期
* @param supplier 数据函数
*
* @return 数据值
*/
@Override
public <T> CompletableFuture<T> localGetSetAsync(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);
public <T> CompletableFuture<T> localGetSetAsync(
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 key 缓存键
*
* @return 删除数量
*/
@Override
@@ -214,7 +222,6 @@ public class CacheManagerService implements CacheManager, Service {
* @param hash 缓存hash
* @param key 缓存键
* @param type 数据类型
*
* @return 数据值
*/
@Override
@@ -230,7 +237,6 @@ public class CacheManagerService implements CacheManager, Service {
* @param hash 缓存hash
* @param key 缓存键
* @param type 数据类型
*
* @return 数据值
*/
@Override
@@ -250,11 +256,16 @@ public class CacheManagerService implements CacheManager, Service {
* @param nullable 是否缓存null值
* @param expire 过期时长Duration.ZERO为永不过期
* @param supplier 数据函数
*
* @return 数据值
*/
@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);
}
@@ -268,12 +279,18 @@ public class CacheManagerService implements CacheManager, Service {
* @param nullable 是否缓存null值
* @param expire 过期时长Duration.ZERO为永不过期
* @param supplier 数据函数
*
* @return 数据值
*/
@Override
public <T> CompletableFuture<T> remoteGetSetAsync(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);
public <T> CompletableFuture<T> remoteGetSetAsync(
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 key 缓存键
*
* @return 删除数量
*/
@Override
@@ -325,7 +341,6 @@ public class CacheManagerService implements CacheManager, Service {
*
* @param hash 缓存hash
* @param key 缓存键
*
* @return 删除数量
*/
@Override
@@ -342,7 +357,6 @@ public class CacheManagerService implements CacheManager, Service {
* @param hash 缓存hash
* @param key 缓存键
* @param type 数据类型
*
* @return 数据值
*/
@Override
@@ -357,7 +371,6 @@ public class CacheManagerService implements CacheManager, Service {
* @param hash 缓存hash
* @param key 缓存键
* @param type 数据类型
*
* @return 数据值
*/
@Override
@@ -372,17 +385,21 @@ public class CacheManagerService implements CacheManager, Service {
* @param hash 缓存hash
* @param key 缓存键
* @param type 数据类型
*
* @param nullable 是否缓存null值
* @param localExpire 本地过期时长Duration.ZERO为永不过期为null表示不本地缓存
* @param remoteExpire 远程过期时长Duration.ZERO为永不过期为null表示不远程缓存
* @param supplier 数据函数
*
* @return 数据值
*/
@Override
public <T> T bothGetSet(final String hash, final String key, final Type type, boolean nullable,
Duration localExpire, Duration remoteExpire, ThrowSupplier<T> supplier) {
public <T> T bothGetSet(
final String hash,
final String key,
final Type type,
boolean nullable,
Duration localExpire,
Duration remoteExpire,
ThrowSupplier<T> supplier) {
if (!enabled) {
try {
return supplier.get();
@@ -400,12 +417,20 @@ public class CacheManagerService implements CacheManager, Service {
Objects.requireNonNull(remoteExpire);
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);
if (remoteSource != null) {
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 remoteExpire 远程过期时长Duration.ZERO为永不过期为null表示不远程缓存
* @param supplier 数据函数
*
* @return 数据值
*/
@Override
public <T> CompletableFuture<T> bothGetSetAsync(String hash, String key, Type type, boolean nullable,
Duration localExpire, Duration remoteExpire, ThrowSupplier<CompletableFuture<T>> supplier) {
public <T> CompletableFuture<T> bothGetSetAsync(
String hash,
String key,
Type type,
boolean nullable,
Duration localExpire,
Duration remoteExpire,
ThrowSupplier<CompletableFuture<T>> supplier) {
if (!enabled) {
try {
return supplier.get();
@@ -440,14 +470,22 @@ public class CacheManagerService implements CacheManager, Service {
Objects.requireNonNull(remoteExpire);
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);
if (remoteSource != null) {
return remoteSetCacheAsync(i, remoteExpire, t, v);
} else {
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表示不远程缓存
*/
@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();
if (localExpire != null) {
setCache(localSource, hash, key, type, value, localExpire);
@@ -482,11 +526,11 @@ public class CacheManagerService implements CacheManager, Service {
* @param value 数据值
* @param localExpire 本地过期时长Duration.ZERO为永不过期为null表示不本地缓存
* @param remoteExpire 远程过期时长Duration.ZERO为永不过期为null表示不远程缓存
*
* @return void
*/
@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();
if (localExpire != null) {
setCache(localSource, hash, key, type, value, localExpire);
@@ -503,7 +547,6 @@ public class CacheManagerService implements CacheManager, Service {
*
* @param hash 缓存hash
* @param key 缓存键
*
* @return 删除数量
*/
@Override
@@ -523,7 +566,6 @@ public class CacheManagerService implements CacheManager, Service {
*
* @param hash 缓存hash
* @param key 缓存键
*
* @return 删除数量
*/
@Override
@@ -551,11 +593,17 @@ public class CacheManagerService implements CacheManager, Service {
* @param nullable 是否缓存null值
* @param expire 过期时长Duration.ZERO为永不过期
* @param supplier 数据函数
*
* @return 数据值
*/
protected <T> T getSet(GetterFunc<CacheValue<T>> getter, SetterSyncFunc setter,
String hash, String key, Type type, boolean nullable, Duration expire, ThrowSupplier<T> supplier) {
protected <T> T getSet(
GetterFunc<CacheValue<T>> getter,
SetterSyncFunc setter,
String hash,
String key,
Type type,
boolean nullable,
Duration expire,
ThrowSupplier<T> supplier) {
checkEnable();
Objects.requireNonNull(expire);
Objects.requireNonNull(supplier);
@@ -603,11 +651,17 @@ public class CacheManagerService implements CacheManager, Service {
* @param nullable 是否缓存null值
* @param expire 过期时长Duration.ZERO为永不过期
* @param supplier 数据函数
*
* @return 数据值
*/
protected <T> CompletableFuture<T> getSetAsync(GetterFunc<CompletableFuture<CacheValue<T>>> getter, SetterAsyncFunc setter,
String hash, String key, Type type, boolean nullable, Duration expire, ThrowSupplier<CompletableFuture<T>> supplier) {
protected <T> CompletableFuture<T> getSetAsync(
GetterFunc<CompletableFuture<CacheValue<T>>> getter,
SetterAsyncFunc setter,
String hash,
String key,
Type type,
boolean nullable,
Duration expire,
ThrowSupplier<CompletableFuture<T>> supplier) {
checkEnable();
Objects.requireNonNull(supplier);
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);
}
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);
}
@@ -657,7 +713,8 @@ public class CacheManagerService implements CacheManager, Service {
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();
Objects.requireNonNull(expire);
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();
Objects.requireNonNull(expire);
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));
}
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));
}
@@ -698,10 +757,10 @@ public class CacheManagerService implements CacheManager, Service {
* @param hash 缓存hash
* @param key 缓存键
* @param type 数据类型
*
* @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));
}
@@ -724,7 +783,6 @@ public class CacheManagerService implements CacheManager, Service {
* @param <T> 泛型
* @param id 缓存键
* @param cacheType 数据类型
*
* @return 数据值
*/
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 key 缓存键
*
* @return key
*/
protected String idFor(String hash, String key) {
@@ -764,7 +821,6 @@ public class CacheManagerService implements CacheManager, Service {
* @param <T> 泛型
* @param nullable 是否缓存null值
* @param value 缓存值
*
* @return CacheValue函数
*/
protected <T> CacheValue<T> toCacheValue(boolean nullable, T value) {
@@ -780,7 +836,6 @@ public class CacheManagerService implements CacheManager, Service {
* @param <T> 泛型
* @param nullable 是否缓存null值
* @param supplier 数据函数
*
* @return CacheValue函数
*/
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 value 数据值
*
* @return CacheValue泛型
*/
protected Type loadCacheType(Type type, final Object value) {
@@ -803,11 +857,11 @@ public class CacheManagerService implements CacheManager, Service {
* 创建数据类型创建对应CacheValue泛型
*
* @param type 数据类型
*
* @return CacheValue泛型
*/
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();
@@ -890,6 +944,5 @@ public class CacheManagerService implements CacheManager, Service {
lock.unlock();
}
}
}
}

View File

@@ -16,10 +16,7 @@ import org.redkale.util.AnyValue;
import org.redkale.util.InstanceProvider;
import org.redkale.util.RedkaleClassLoader;
/**
*
* @author zhangjx
*/
/** @author zhangjx */
public class CacheModuleEngine extends ModuleEngine {
// 全局缓存管理器
@@ -38,7 +35,6 @@ public class CacheModuleEngine extends ModuleEngine {
* @param key 配置项名称
* @param val1 配置项原值
* @param val2 配置项新值
*
* @return MergeEnum
*/
@Override
@@ -54,7 +50,6 @@ public class CacheModuleEngine extends ModuleEngine {
*
* @param remote 是否远程模式
* @param serviceClass 类
*
* @return 方法动态扩展器
*/
@Override
@@ -62,9 +57,7 @@ public class CacheModuleEngine extends ModuleEngine {
return new CacheAsmMethodBoost(remote, serviceClass);
}
/**
* 结束Application.init方法前被调用
*/
/** 结束Application.init方法前被调用 */
@Override
public void onAppPostInit() {
// 设置缓存管理器
@@ -79,9 +72,7 @@ public class CacheModuleEngine extends ModuleEngine {
this.resourceFactory.register("", CacheManager.class, this.cacheManager);
}
/**
* 进入Application.shutdown方法被调用
*/
/** 进入Application.shutdown方法被调用 */
@Override
public void onAppPreShutdown() {
if (!application.isCompileMode() && this.cacheManager instanceof Service) {
@@ -90,13 +81,15 @@ public class CacheModuleEngine extends ModuleEngine {
}
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);
List<CacheManagerProvider> providers = new ArrayList<>();
while (it.hasNext()) {
CacheManagerProvider provider = it.next();
if (provider != null && provider.acceptsConf(conf)) {
RedkaleClassLoader.putReflectionPublicConstructors(provider.getClass(), provider.getClass().getName());
RedkaleClassLoader.putReflectionPublicConstructors(
provider.getClass(), provider.getClass().getName());
providers.add(provider);
}
}

View File

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

View File

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

View File

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

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