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>
@@ -166,6 +168,21 @@
</execution>
</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

@@ -20,13 +20,10 @@ 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")
@@ -19,21 +17,21 @@ import java.lang.annotation.*;
@Retention(RetentionPolicy.RUNTIME)
public @interface Resource {
// /**
// * AuthenticationType
// */
// @Deprecated
// public enum AuthenticationType {
// /**
// * @deprecated
// */
// CONTAINER,
// /**
// * @deprecated
// */
// APPLICATION
// }
//
// /**
// * AuthenticationType
// */
// @Deprecated
// public enum AuthenticationType {
// /**
// * @deprecated
// */
// CONTAINER,
// /**
// * @deprecated
// */
// APPLICATION
// }
//
/**
* 资源名称
*
@@ -47,39 +45,39 @@ public @interface Resource {
* @return Class
*/
public Class<?> type() default Object.class;
//
// /**
// *
// * @return AuthenticationType
// */
// @Deprecated
// public AuthenticationType authenticationType() default AuthenticationType.CONTAINER;
//
// /**
// *
// * @return boolean
// */
// @Deprecated
// public boolean shareable() default true;
//
// /**
// *
// * @return String
// */
// @Deprecated
// public String description() default "";
//
// /**
// *
// * @return String
// */
// @Deprecated
// public String mappedName() default "";
//
// /**
// *
// * @return String
// */
// @Deprecated
// public String lookup() default "";
//
// /**
// *
// * @return AuthenticationType
// */
// @Deprecated
// public AuthenticationType authenticationType() default AuthenticationType.CONTAINER;
//
// /**
// *
// * @return boolean
// */
// @Deprecated
// public boolean shareable() default true;
//
// /**
// *
// * @return String
// */
// @Deprecated
// public String description() default "";
//
// /**
// *
// * @return String
// */
// @Deprecated
// public String mappedName() default "";
//
// /**
// *
// * @return String
// */
// @Deprecated
// public String lookup() default "";
}

View File

@@ -1,38 +1,32 @@
/** *****************************************************************************
* Copyright (c) 2008 - 2013 Oracle Corporation. All rights reserved.
/**
* ***************************************************************************** Copyright (c) 2008 - 2013 Oracle
* Corporation. All rights reserved.
*
* This program and the accompanying materials are made available under the
* 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,23 +43,21 @@ 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")
@Deprecated(since = "2.8.0")
@Target({METHOD, FIELD})
@Retention(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,32 +118,28 @@ 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>
* 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>
* if type==byte[] and length &#60;= 16777215 then sqltype is MEDIUMBLOB <br>
* if type==byte[] and length &#62; 16777215 then sqltype is LONGBLOB <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>
* if type==byte[] and length &#60;= 16777215 then sqltype is MEDIUMBLOB <br>
* if type==byte[] and length &#62; 16777215 then sqltype is LONGBLOB <br>
*
* @return int
*/
int length() default 255;
/**
* (Optional) The precision for a decimal (exact numeric)
* column. (Applies only if a decimal column is used.)
* Value must be set by developer if used when generating
* the DDL for the column.
* (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")
@@ -36,15 +32,14 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME;
@Retention(RUNTIME)
public @interface Entity {
/**
* (Optional) The entity name. Defaults to the unqualified
* name of the entity class. This name is used to refer to the
* entity in queries. The name must not be a reserved literal
* in the Java Persistence query language.
/**
* (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 "";
*/
String name() default "";
/**
* (Optional) The comment of the entity.
*

View File

@@ -1,39 +1,32 @@
/*******************************************************************************
* Copyright (c) 2008 - 2013 Oracle Corporation. All rights reserved.
/**
* ***************************************************************************** Copyright (c) 2008 - 2013 Oracle
* Corporation. All rights reserved.
*
* This program and the accompanying materials are made available under the
* 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
@@ -88,9 +81,8 @@ public @interface Table {
/**
* comment
*
*
* @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,17 +1,14 @@
/**
* <p>
* see: https://redkale.org
*
* @author zhangjx
*
*/
module org.redkale {
requires java.base;
requires java.logging;
requires java.logging;
requires java.net.http;
requires java.sql;
requires jdk.unsupported; //sun.misc.Unsafe
requires jdk.unsupported; // sun.misc.Unsafe
exports org.redkale.annotation;
exports org.redkale.boot;
@@ -44,7 +41,7 @@ module org.redkale {
exports org.redkale.source.spi;
exports org.redkale.util;
exports org.redkale.watch;
uses org.redkale.props.spi.PropertiesAgentProvider;
uses org.redkale.cache.spi.CacheManagerProvider;
uses org.redkale.cluster.spi.ClusterAgentProvider;
@@ -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
*
* <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

@@ -6,22 +6,20 @@ package org.redkale.annotation;
import java.lang.annotation.*;
/**
* 非阻塞模式标记, 标记在Service类和方法、Filter类、HttpServlet类上 <br>
* 一般情况下,没有显注此注解的方法视为阻塞时, 以下两种情况除外: <br>
* 非阻塞模式标记, 标记在Service类和方法、Filter类、HttpServlet类上 <br>
* 一般情况下,没有显注此注解的方法视为阻塞时, 以下两种情况除外: <br>
* 1、返回类型是CompletionStage <br>
* 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})
@Retention(RetentionPolicy.RUNTIME)
public @interface NonBlocking { //不可使用@Inherited防止被继承, 见HttpServlet.preExecute/authenticate/execute
public @interface NonBlocking { // 不可使用@Inherited防止被继承, 见HttpServlet.preExecute/authenticate/execute
boolean value() default true;
}

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

@@ -8,12 +8,11 @@ package org.redkale.annotation;
import java.lang.annotation.*;
/**
* &#64;Resource(name = "@") 表示资源name采用所属对象的name <br>
* &#64;Resource(name = "#name") 表示资源对象自身的name <br>
* &#64;Resource(name = "#type") 表示资源对象自身的类型 <br>
* &#64;Resource(name = "@") 表示资源name采用所属对象的name <br>
* &#64;Resource(name = "#name") 表示资源对象自身的name <br>
* &#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>
* 资源名称 <br>
*
* <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,49 +316,45 @@ 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) {
case 0x00: // CLASS_TYPE_PARAMETER
case 0x01: // METHOD_TYPE_PARAMETER
case 0x16: // METHOD_FORMAL_PARAMETER
out.putShort(typeRef >>> 16);
break;
case 0x13: // FIELD
case 0x14: // METHOD_RETURN
case 0x15: // METHOD_RECEIVER
out.putByte(typeRef >>> 24);
break;
case 0x47: // CAST
case 0x48: // CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT
case 0x49: // METHOD_INVOCATION_TYPE_ARGUMENT
case 0x4A: // CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT
case 0x4B: // METHOD_REFERENCE_TYPE_ARGUMENT
out.putInt(typeRef);
break;
// case 0x10: // CLASS_EXTENDS
// case 0x11: // CLASS_TYPE_PARAMETER_BOUND
// case 0x12: // METHOD_TYPE_PARAMETER_BOUND
// case 0x17: // THROWS
// case 0x42: // EXCEPTION_PARAMETER
// case 0x43: // INSTANCEOF
// case 0x44: // NEW
// case 0x45: // CONSTRUCTOR_REFERENCE
// case 0x46: // METHOD_REFERENCE
default:
out.put12(typeRef >>> 24, (typeRef & 0xFFFF00) >> 8);
break;
case 0x00: // CLASS_TYPE_PARAMETER
case 0x01: // METHOD_TYPE_PARAMETER
case 0x16: // METHOD_FORMAL_PARAMETER
out.putShort(typeRef >>> 16);
break;
case 0x13: // FIELD
case 0x14: // METHOD_RETURN
case 0x15: // METHOD_RECEIVER
out.putByte(typeRef >>> 24);
break;
case 0x47: // CAST
case 0x48: // CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT
case 0x49: // METHOD_INVOCATION_TYPE_ARGUMENT
case 0x4A: // CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT
case 0x4B: // METHOD_REFERENCE_TYPE_ARGUMENT
out.putInt(typeRef);
break;
// case 0x10: // CLASS_EXTENDS
// case 0x11: // CLASS_TYPE_PARAMETER_BOUND
// case 0x12: // METHOD_TYPE_PARAMETER_BOUND
// case 0x17: // THROWS
// case 0x42: // EXCEPTION_PARAMETER
// case 0x43: // INSTANCEOF
// case 0x44: // NEW
// case 0x45: // CONSTRUCTOR_REFERENCE
// case 0x46: // METHOD_REFERENCE
default:
out.put12(typeRef >>> 24, (typeRef & 0xFFFF00) >> 8);
break;
}
if (typePath == null) {
out.putByte(0);

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,16 +60,14 @@ public abstract class AsmMethodBoost<T> {
}
/**
*
* 返回一个类所有方法的字节信息, key为: method.getName+':'+Type.getMethodDescriptor(method)
*
* @param clazz Class
*
* @return Map
*/
public static Map<String, AsmMethodBean> getMethodBeans(Class clazz) {
Map<String, AsmMethodBean> rs = MethodParamClassVisitor.getMethodParamNames(new HashMap<>(), clazz);
//返回的List中参数列表可能会比方法参数量多因为方法内的临时变量也会存入list中 所以需要list的元素集合比方法的参数多
// 返回的List中参数列表可能会比方法参数量多因为方法内的临时变量也会存入list中 所以需要list的元素集合比方法的参数多
rs.values().forEach(AsmMethodBean::removeEmptyNames);
return rs;
}
@@ -82,7 +80,6 @@ public abstract class AsmMethodBoost<T> {
* 获取需屏蔽的方法上的注解
*
* @param method 方法
*
* @return 需要屏蔽的注解
*/
public abstract List<Class<? extends Annotation>> filterMethodAnnotations(Method method);
@@ -90,34 +87,39 @@ public abstract class AsmMethodBoost<T> {
/**
* 对方法进行动态加强处理
*
* @param classLoader ClassLoader
* @param cw 动态字节码Writer
* @param newDynName 动态新类名
* @param fieldPrefix 动态字段的前缀
* @param filterAnns 需要过滤的注解
* @param method 操作的方法
* @param classLoader ClassLoader
* @param cw 动态字节码Writer
* @param newDynName 动态新类名
* @param fieldPrefix 动态字段的前缀
* @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 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) {}
/**
* 实例对象进行操作,通常用于给动态的字段赋值
*
* @param resourceFactory ResourceFactory
* @param service 实例对象
* @param service 实例对象
*/
public abstract void doInstance(ResourceFactory resourceFactory, T service);
@@ -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,28 +169,30 @@ public abstract class AsmMethodBoost<T> {
}
}
protected void visitRawAnnotation(Method method, String newMethodName, MethodVisitor mv, Class selfAnnType, List filterAnns) {
protected void visitRawAnnotation(
Method method, String newMethodName, MethodVisitor mv, Class selfAnnType, List filterAnns) {
if (newMethodName == null) {
//给方法加上原有的Annotation
// 给方法加上原有的Annotation
final Annotation[] anns = method.getAnnotations();
for (Annotation ann : anns) {
if (ann.annotationType() != selfAnnType
&& (filterAnns == null || !filterAnns.contains(ann.annotationType()))) {
&& (filterAnns == null || !filterAnns.contains(ann.annotationType()))) {
Asms.visitAnnotation(mv.visitAnnotation(Type.getDescriptor(ann.annotationType()), true), ann);
}
}
//给参数加上原有的Annotation
// 给参数加上原有的Annotation
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);
}
}
}
}
protected List<Integer> visitVarInsnParamTypes(MethodVisitor mv, Method method, int insn) {
//传参数
// 传参数
Class[] paramTypes = method.getParameterTypes();
List<Integer> insns = new ArrayList<>();
for (Class pt : paramTypes) {
@@ -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,12 +369,13 @@ 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;
}
int size = paramList.size();
//index并不会按顺序执行
// index并不会按顺序执行
if (varIndex > size) {
for (int i = size; i < varIndex; i++) {
paramList.add(new AsmMethodParam(" ", varDesc, varSignature));
@@ -360,7 +387,7 @@ public abstract class AsmMethodBoost<T> {
};
}
//返回的List中参数列表可能会比方法参数量多因为方法内的临时变量也会存入list中 所以需要list的元素集合比方法的参数多
// 返回的List中参数列表可能会比方法参数量多因为方法内的临时变量也会存入list中 所以需要list的元素集合比方法的参数多
static Map<String, AsmMethodBean> getMethodParamNames(Map<String, AsmMethodBean> map, Class clazz) {
String n = clazz.getName();
InputStream in = clazz.getResourceAsStream(n.substring(n.lastIndexOf('.') + 1) + ".class");
@@ -368,11 +395,12 @@ public abstract class AsmMethodBoost<T> {
return map;
}
try {
new ClassReader(Utility.readBytesThenClose(in)).accept(new MethodParamClassVisitor(Opcodes.ASM6, clazz, map), 0);
} catch (Exception e) { //无需理会
new ClassReader(Utility.readBytesThenClose(in))
.accept(new MethodParamClassVisitor(Opcodes.ASM6, clazz, map), 0);
} catch (Exception e) { // 无需理会
}
Class superClass = clazz.getSuperclass();
if (superClass == null || superClass == Object.class) { //接口的getSuperclass为null
if (superClass == null || superClass == Object.class) { // 接口的getSuperclass为null
return map;
}
return getMethodParamNames(map, superClass);

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
* 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 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 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
* attributes are not code attributes.
* @param out
* where the attributes must be written.
* @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 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.
//see also changes in ClassReader.accept.
/**
*
*/
// 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");
}
@@ -307,7 +262,7 @@ public class Attribute {
int size = cr.readShort(off);
a.classes = new String[size];
off += 2;
for (int i = 0; i < size ; i++) {
for (int i = 0; i < size; i++) {
a.classes[i] = cr.readClass(off, buf);
off += 2;
}
@@ -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) {
@@ -303,8 +272,8 @@ public class ByteVector {
}
int start = length - i - 2;
if (start >= 0) {
data[start] = (byte) (byteLength >>> 8);
data[start + 1] = (byte) byteLength;
data[start] = (byte) (byteLength >>> 8);
data[start + 1] = (byte) byteLength;
}
if (length + byteLength - i > data.length) {
enlarge(byteLength - i);
@@ -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
* &#60;tt&#62;null&#60;/tt&#62;.
* @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;
@@ -215,7 +185,7 @@ final class FieldWriter extends FieldVisitor {
@Override
public void visitEnd() {
//do nothing
// do nothing
}
// ------------------------------------------------------------------------
@@ -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);
}
}

File diff suppressed because it is too large Load Diff

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,18 +163,16 @@ 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
public int hashCode() {
return tag + (itf? 64: 0) + owner.hashCode() * name.hashCode() * desc.hashCode();
return tag + (itf ? 64 : 0) + owner.hashCode() * name.hashCode() * desc.hashCode();
}
/**
* Returns the textual representation of this handle. The textual
* representation is:
* Returns the textual representation of this handle. The textual representation is:
*
* <pre>
* for a reference to a class:
@@ -217,6 +185,6 @@ public final class Handle {
*/
@Override
public String toString() {
return owner + '.' + name + desc + " (" + tag + (itf? " itf": "") + ')';
return owner + '.' + name + desc + " (" + tag + (itf ? " itf" : "") + ')';
}
}

View File

@@ -65,48 +65,36 @@ package org.redkale.asm;
*/
class Handler {
/**
* 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,76 +183,62 @@ 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;
this.strVal3 = strVal3;
switch (type) {
case ClassWriter.CLASS:
this.intVal = 0; // intVal of a class must be zero, see visitInnerClass
case ClassWriter.UTF8:
case ClassWriter.STR:
case ClassWriter.MTYPE:
case ClassWriter.MODULE:
case ClassWriter.PACKAGE:
case ClassWriter.TYPE_NORMAL:
hashCode = 0x7FFFFFFF & (type + strVal1.hashCode());
return;
case ClassWriter.NAME_TYPE: {
hashCode = 0x7FFFFFFF & (type + strVal1.hashCode()
* strVal2.hashCode());
return;
}
// ClassWriter.FIELD:
// ClassWriter.METH:
// ClassWriter.IMETH:
// ClassWriter.HANDLE_BASE + 1..9
default:
hashCode = 0x7FFFFFFF & (type + strVal1.hashCode()
* strVal2.hashCode() * strVal3.hashCode());
case ClassWriter.CLASS:
this.intVal = 0; // intVal of a class must be zero, see visitInnerClass
case ClassWriter.UTF8:
case ClassWriter.STR:
case ClassWriter.MTYPE:
case ClassWriter.MODULE:
case ClassWriter.PACKAGE:
case ClassWriter.TYPE_NORMAL:
hashCode = 0x7FFFFFFF & (type + strVal1.hashCode());
return;
case ClassWriter.NAME_TYPE: {
hashCode = 0x7FFFFFFF & (type + strVal1.hashCode() * strVal2.hashCode());
return;
}
// ClassWriter.FIELD:
// ClassWriter.METH:
// ClassWriter.IMETH:
// ClassWriter.HANDLE_BASE + 1..9
default:
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,48 +247,43 @@ 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) {
case ClassWriter.UTF8:
case ClassWriter.STR:
case ClassWriter.CLASS:
case ClassWriter.MODULE:
case ClassWriter.PACKAGE:
case ClassWriter.MTYPE:
case ClassWriter.TYPE_NORMAL:
return i.strVal1.equals(strVal1);
case ClassWriter.TYPE_MERGED:
case ClassWriter.LONG:
case ClassWriter.DOUBLE:
return i.longVal == longVal;
case ClassWriter.INT:
case ClassWriter.FLOAT:
return i.intVal == intVal;
case ClassWriter.TYPE_UNINIT:
return i.intVal == intVal && i.strVal1.equals(strVal1);
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);
}
// 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);
case ClassWriter.UTF8:
case ClassWriter.STR:
case ClassWriter.CLASS:
case ClassWriter.MODULE:
case ClassWriter.PACKAGE:
case ClassWriter.MTYPE:
case ClassWriter.TYPE_NORMAL:
return i.strVal1.equals(strVal1);
case ClassWriter.TYPE_MERGED:
case ClassWriter.LONG:
case ClassWriter.DOUBLE:
return i.longVal == longVal;
case ClassWriter.INT:
case ClassWriter.FLOAT:
return i.intVal == intVal;
case ClassWriter.TYPE_UNINIT:
return i.intVal == intVal && i.strVal1.equals(strVal1);
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);
}
// 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);
}
}
}

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,11 +237,9 @@ public class Label {
// Constructor
// ------------------------------------------------------------------------
/**
* Constructs a new label.
*/
/** Constructs a new label. */
public Label() {
//do nothing
// do nothing
}
// ------------------------------------------------------------------------
@@ -295,44 +247,33 @@ public class Label {
// ------------------------------------------------------------------------
/**
* Returns the offset corresponding to this label. This offset is computed
* 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
* &#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.
* @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.
*/
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
*/
@@ -36,7 +36,7 @@ public class MethodDebugVisitor extends MethodVisitor {
private final Map<Label, Integer> labels = new LinkedHashMap<>();
private static final String[] opcodes = new String[200]; //0 -18
private static final String[] opcodes = new String[200]; // 0 -18
static {
try {
@@ -66,14 +66,11 @@ public class MethodDebugVisitor extends MethodVisitor {
opcodes[(int) (Integer) field.get(null)] = name;
}
} catch (Exception ex) {
throw new RuntimeException(ex); //不可能会发生
throw new RuntimeException(ex); // 不可能会发生
}
}
/**
*
* @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,11 +137,12 @@ 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) + ");");
}
}
public void visitJumpInsn(int opcode, Label var) { //调用此方法的 ClassWriter 必须由 COMPUTE_FRAMES 构建
public void visitJumpInsn(int opcode, Label var) { // 调用此方法的 ClassWriter 必须由 COMPUTE_FRAMES 构建
visitor.visitJumpInsn(opcode, var);
if (debug) {
Integer index = labels.get(var);
@@ -179,7 +178,8 @@ public class MethodDebugVisitor extends MethodVisitor {
public void visitMethodInsn(int opcode, String owner, String name, String desc, boolean itf) {
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,20 +300,13 @@ 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},
* {@link Opcodes#T_INT} or {@link Opcodes#T_LONG}.
* @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) {
if (mv != null) {
@@ -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
* 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 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.
*/
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
* 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 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.
*/
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
* {@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 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;.
*/
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
* {@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 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;.
*/
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,122 +59,90 @@
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
this.size = 16; // name + access + version + 5 counts
this.name = name;
this.access = access;
this.version = version;
@@ -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;
}
@@ -227,7 +193,7 @@ final class ModuleWriter extends ModuleVisitor {
size += 6;
} else {
exports.putShort(modules.length);
for(String module: modules) {
for (String module : modules) {
exports.putShort(cw.newModule(module));
}
size += 6 + 2 * modules.length;
@@ -246,7 +212,7 @@ final class ModuleWriter extends ModuleVisitor {
size += 6;
} else {
opens.putShort(modules.length);
for(String module: modules) {
for (String module : modules) {
opens.putShort(cw.newModule(module));
}
size += 6 + 2 * modules.length;
@@ -271,7 +237,7 @@ final class ModuleWriter extends ModuleVisitor {
}
provides.putShort(cw.newClass(service));
provides.putShort(providers.length);
for(String provider: providers) {
for (String provider : providers) {
provides.putShort(cw.newClass(provider));
}
provideCount++;
@@ -289,9 +255,9 @@ final class ModuleWriter extends ModuleVisitor {
}
if (packages != null) {
out.putShort(cw.newUTF8("ModulePackages"))
.putInt(2 + 2 * packageCount)
.putShort(packageCount)
.putByteArray(packages.data, 0, packages.length);
.putInt(2 + 2 * packageCount)
.putShort(packageCount)
.putByteArray(packages.data, 0, packages.length);
}
}

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) {
@@ -311,7 +238,7 @@ public class Type {
return DOUBLE_TYPE;
} else if (c == Float.TYPE) {
return FLOAT_TYPE;
} else /* if (c == Long.TYPE) */{
} else /* if (c == Long.TYPE) */ {
return LONG_TYPE;
}
} else {
@@ -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();
@@ -360,7 +282,7 @@ public class Type {
break;
} else if (car == 'L') {
while (buf[off++] != ';') {
//do nothing
// do nothing
}
++size;
} else if (car != '[') {
@@ -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();
@@ -414,20 +330,17 @@ public class Type {
return getType(buf, off);
} else if (car == 'L') {
while (buf[off++] != ';') {
//do nothing
// do nothing
}
}
}
}
/**
* 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,11 +362,10 @@ 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
// do nothing
}
n += 1;
} else if (car == '[') {
@@ -474,58 +384,55 @@ 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) {
int len;
switch (buf[off]) {
case 'V':
return VOID_TYPE;
case 'Z':
return BOOLEAN_TYPE;
case 'C':
return CHAR_TYPE;
case 'B':
return BYTE_TYPE;
case 'S':
return SHORT_TYPE;
case 'I':
return INT_TYPE;
case 'F':
return FLOAT_TYPE;
case 'J':
return LONG_TYPE;
case 'D':
return DOUBLE_TYPE;
case '[':
len = 1;
while (buf[off + len] == '[') {
++len;
}
if (buf[off + len] == 'L') {
++len;
case 'V':
return VOID_TYPE;
case 'Z':
return BOOLEAN_TYPE;
case 'C':
return CHAR_TYPE;
case 'B':
return BYTE_TYPE;
case 'S':
return SHORT_TYPE;
case 'I':
return INT_TYPE;
case 'F':
return FLOAT_TYPE;
case 'J':
return LONG_TYPE;
case 'D':
return DOUBLE_TYPE;
case '[':
len = 1;
while (buf[off + len] == '[') {
++len;
}
if (buf[off + len] == 'L') {
++len;
while (buf[off + len] != ';') {
++len;
}
}
return new Type(ARRAY, buf, off, len + 1);
case 'L':
len = 1;
while (buf[off + len] != ';') {
++len;
}
}
return new Type(ARRAY, buf, off, len + 1);
case 'L':
len = 1;
while (buf[off + len] != ';') {
++len;
}
return new Type(OBJECT, buf, off + 1, len - 1);
// case '(':
default:
return new Type(METHOD, buf, off, buf.length - off);
return new Type(OBJECT, buf, off + 1, len - 1);
// case '(':
default:
return new Type(METHOD, buf, off, buf.length - off);
}
}
@@ -536,19 +443,16 @@ public class Type {
/**
* Returns the sort of this Java type.
*
* @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,49 +474,47 @@ 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.
*/
public String getClassName() {
switch (sort) {
case VOID:
return "void";
case BOOLEAN:
return "boolean";
case CHAR:
return "char";
case BYTE:
return "byte";
case SHORT:
return "short";
case INT:
return "int";
case FLOAT:
return "float";
case LONG:
return "long";
case DOUBLE:
return "double";
case ARRAY:
StringBuilder sb = new StringBuilder(getElementType().getClassName());
for (int i = getDimensions(); i > 0; --i) {
sb.append("[]");
}
return sb.toString();
case OBJECT:
return new String(buf, off, len).replace('/', '.');
default:
return null;
case VOID:
return "void";
case BOOLEAN:
return "boolean";
case CHAR:
return "char";
case BYTE:
return "byte";
case SHORT:
return "short";
case INT:
return "int";
case FLOAT:
return "float";
case LONG:
return "long";
case DOUBLE:
return "double";
case ARRAY:
StringBuilder sb = new StringBuilder(getElementType().getClassName());
for (int i = getDimensions(); i > 0; --i) {
sb.append("[]");
}
return sb.toString();
case OBJECT:
return new String(buf, off, len).replace('/', '.');
default:
return null;
}
}
/**
* 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;
@@ -811,7 +694,7 @@ public class Type {
car = 'D';
} else if (d == Float.TYPE) {
car = 'F';
} else /* if (d == Long.TYPE) */{
} else /* if (d == Long.TYPE) */ {
car = 'J';
}
buf.append(car);
@@ -838,11 +721,10 @@ public class Type {
// ------------------------------------------------------------------------
/**
* Returns the size of values of this type. This method must not be used for
* 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.
* &#60;tt&#62;double&#60;/tt&#62;, 0 for &#60;tt&#62;void&#60;/tt&#62; and 1 otherwise.
*/
public int getSize() {
// the size is in byte 0 of 'off' for primitive types (buf == null)
@@ -850,16 +732,13 @@ public class Type {
}
/**
* Returns a JVM instruction opcode adapted to this Java type. This method
* 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) {
@@ -167,7 +139,7 @@ public class TypePath {
int n = typePath.length();
ByteVector out = new ByteVector(n);
out.putByte(0);
for (int i = 0; i < n;) {
for (int i = 0; i < n; ) {
char c = typePath.charAt(i++);
if (c == '[') {
out.put11(ARRAY_ELEMENT, 0);
@@ -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() {
@@ -204,20 +174,20 @@ public class TypePath {
StringBuilder result = new StringBuilder(length * 2);
for (int i = 0; i < length; ++i) {
switch (getStep(i)) {
case ARRAY_ELEMENT:
result.append('[');
break;
case INNER_TYPE:
result.append('.');
break;
case WILDCARD_BOUND:
result.append('*');
break;
case TYPE_ARGUMENT:
result.append(getStepArgument(i)).append(';');
break;
default:
result.append('_');
case ARRAY_ELEMENT:
result.append('[');
break;
case INNER_TYPE:
result.append('.');
break;
case WILDCARD_BOUND:
result.append('*');
break;
case TYPE_ARGUMENT:
result.append(getStepArgument(i)).append(';');
break;
default:
result.append('_');
}
}
return result.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,14 +198,10 @@ 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
* {@link #METHOD_REFERENCE METHOD_REFERENCE}.
* @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.
*/
public static TypeReference newTypeReference(int sort) {
@@ -239,45 +211,33 @@ public class TypeReference {
/**
* Returns a reference to a type parameter of a generic class or method.
*
* @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.
*
* @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.
* 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
* METHOD_REFERENCE_TYPE_ARGUMENT}.
* @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,39 +294,27 @@ 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
* 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() {
return value >>> 24;
}
/**
* 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

@@ -23,37 +23,33 @@ import org.redkale.source.*;
import org.redkale.util.*;
/**
* API接口文档生成类作用生成Application实例中所有HttpServer的可用HttpServlet的API接口方法 <br>
* API接口文档生成类作用生成Application实例中所有HttpServer的可用HttpServlet的API接口方法 <br>
* 继承 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全局对象
private final Application app; // Application全局对象
public ApiDocCommand(Application app) {
this.app = app;
}
public String command(String cmd, String[] params) throws Exception {
//是否跳过RPC接口
// 是否跳过RPC接口
boolean skipRPC = true;
String apiHost = "http://localhost";
@@ -75,7 +71,7 @@ public final class ApiDocCommand {
Field prefixField = HttpServlet.class.getDeclaredField("_prefix");
prefixField.setAccessible(true);
Map<String, Map<String, Map<String, Object>>> typesMap = new LinkedHashMap<>();
//https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md
// https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md
Map<String, Object> swaggerPathsMap = new LinkedHashMap<>();
List<Map> swaggerServers = new ArrayList<>();
List<Map> swaggerTags = new ArrayList<>();
@@ -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();
@@ -147,16 +151,16 @@ public final class ApiDocCommand {
continue;
}
if (!action.inherited() && selfClz != clz) {
continue; //忽略不被继承的方法
continue; // 忽略不被继承的方法
}
if (actionUrls.contains(action.url())) {
continue;
}
if (HttpScope.class.isAssignableFrom(action.result())) {
continue; //忽略模板引擎的方法
continue; // 忽略模板引擎的方法
}
if (action.rpcOnly() && skipRPC) {
continue; //不生成RPC接口
continue; // 不生成RPC接口
}
final List<Map<String, Object>> swaggerParamsList = new ArrayList<>();
@@ -175,44 +179,51 @@ public final class ApiDocCommand {
f.setAccessible(true);
resultType = (Type) f.get(servlet);
}
// for (final Class rtype : action.results()) {
// results.add(rtype.getName());
// if (typesMap.containsKey(rtype.getName())) continue;
// 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<>();
// Class loop = rtype;
// do {
// if (loop == null || loop.isInterface()) break;
// for (Field field : loop.getDeclaredFields()) {
// if (Modifier.isFinal(field.getModifiers())) continue;
// if (Modifier.isStatic(field.getModifiers())) continue;
//
// Map<String, Object> fieldmap = new LinkedHashMap<>();
// fieldmap.put("type", field.getType().isArray() ? (field.getType().getComponentType().getName() + "[]") : field.getGenericType().getTypeName());
//
// Comment comment = field.getAnnotation(Comment.class);
// Column col = field.getAnnotation(Column.class);
// FilterColumn fc = field.getAnnotation(FilterColumn.class);
// if (comment != null) {
// fieldmap.put("comment", comment.value());
// } else if (col != null) {
// fieldmap.put("comment", col.comment());
// } 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;
// }
//
// typeMap.put(field.getName(), fieldmap);
// }
// } while ((loop = loop.getSuperclass()) != Object.class);
// typesMap.put(rtype.getName(), typeMap);
// }
// for (final Class rtype : action.results()) {
// results.add(rtype.getName());
// if (typesMap.containsKey(rtype.getName())) continue;
// 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<>();
// Class loop = rtype;
// do {
// if (loop == null || loop.isInterface()) break;
// for (Field field : loop.getDeclaredFields()) {
// if (Modifier.isFinal(field.getModifiers())) continue;
// if (Modifier.isStatic(field.getModifiers())) continue;
//
// Map<String, Object> fieldmap = new LinkedHashMap<>();
// fieldmap.put("type", field.getType().isArray() ?
// (field.getType().getComponentType().getName() + "[]") :
// field.getGenericType().getTypeName());
//
// Comment comment = field.getAnnotation(Comment.class);
// Column col = field.getAnnotation(Column.class);
// FilterColumn fc = field.getAnnotation(FilterColumn.class);
// if (comment != null) {
// fieldmap.put("comment", comment.value());
// } else if (col != null) {
// fieldmap.put("comment", col.comment());
// } 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;
// }
//
// typeMap.put(field.getName(), fieldmap);
// }
// } while ((loop = loop.getSuperclass()) != Object.class);
// typesMap.put(rtype.getName(), typeMap);
// }
mappingMap.put("results", results);
boolean hasBodyParam = false;
Map<String, Object> swaggerRequestBody = new LinkedHashMap<>();
@@ -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");
// 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("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) {
@@ -328,15 +363,24 @@ public final class ApiDocCommand {
mappingsList.add(mappingMap);
final Map<String, Object> swaggerOperatMap = new LinkedHashMap<>();
swaggerOperatMap.put("tags", new String[]{tag});
swaggerOperatMap.put("tags", new String[] {tag});
swaggerOperatMap.put("operationId", action.name());
if (method.getAnnotation(Deprecated.class) != null) {
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")));
@@ -376,7 +439,7 @@ public final class ApiDocCommand {
return urlregs1.length > 0 ? (urlregs2.length > 0 ? urlregs1[0].compareTo(urlregs2[0]) : 1) : -1;
});
}
{ // https://github.com/OAI/OpenAPI-Specification
{ // https://github.com/OAI/OpenAPI-Specification
Map<String, Object> swaggerResultMap = new LinkedHashMap<>();
swaggerResultMap.put("openapi", "3.0.0");
Map<String, Object> infomap = new LinkedHashMap<>();
@@ -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);
@@ -481,7 +572,7 @@ public final class ApiDocCommand {
return ct;
}
Map<String, Object> cmap = new LinkedHashMap<>();
componentsMap.put(ct, cmap); //必须在调用simpleSchemaType之前put不然嵌套情况下死循环
componentsMap.put(ct, cmap); // 必须在调用simpleSchemaType之前put不然嵌套情况下死循环
cmap.put("type", "object");
List<String> requireds = new ArrayList<>();
@@ -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,
TypeToken.typeToClassOrElse(member.getEncoder().getType(), Object.class),
member.getEncoder().getType(), schemaMap, true);
simpleSchemaType(
factory,
logger,
componentsMap,
TypeToken.typeToClassOrElse(member.getEncoder().getType(), Object.class),
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,8 +740,9 @@ 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()
: ((CollectionEncoder) 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 "";
@@ -657,21 +790,21 @@ public final class ApiDocCommand {
} else if (type.isPrimitive()) {
return 0;
} else if (type == boolean[].class || type == Boolean[].class) {
return new boolean[]{true, false};
return new boolean[] {true, false};
} else if (type == byte[].class || type == Byte[].class) {
return new byte[]{0, 0};
return new byte[] {0, 0};
} else if (type == char[].class || type == Character[].class) {
return new char[]{'a', 'b'};
return new char[] {'a', 'b'};
} else if (type == short[].class || type == Short[].class) {
return new short[]{0, 0};
return new short[] {0, 0};
} else if (type == int[].class || type == Integer[].class) {
return new int[]{0, 0};
return new int[] {0, 0};
} else if (type == long[].class || type == Long[].class) {
return new long[]{0, 0};
return new long[] {0, 0};
} else if (type == float[].class || type == Float[].class) {
return new float[]{0, 0};
return new float[] {0, 0};
} else if (type == double[].class || type == Double[].class) {
return new double[]{0, 0};
return new double[] {0, 0};
} else if (Number.class.isAssignableFrom(type)) {
return 0;
} else if (CharSequence.class.isAssignableFrom(type)) {
@@ -681,44 +814,58 @@ 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
// do nothing
}
}
} else if (Sheet.class.isAssignableFrom(type)) { //要在Collection前面
} else if (Sheet.class.isAssignableFrom(type)) { // 要在Collection前面
if (genericType instanceof ParameterizedType) {
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
// do nothing
}
}
} else if (type.isArray()) {
try {
Object val = formatExample(factory, example, type.getComponentType(), type.getComponentType());
return new StringWrapper(jsonFactory.getConvert()
.convertTo(jsonFactory.getConvert().convertFrom(genericType, "[" + val + "," + val + "]")));
return new StringWrapper(jsonFactory
.getConvert()
.convertTo(jsonFactory.getConvert().convertFrom(genericType, "[" + val + "," + val + "]")));
} catch (Throwable t) {
//do nothing
// do nothing
}
} else if (Collection.class.isAssignableFrom(type)) {
if (genericType instanceof ParameterizedType) {
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, "[" + val + "," + val + "]")));
return new StringWrapper(jsonFactory
.getConvert()
.convertTo(jsonFactory.getConvert().convertFrom(genericType, "[" + val + "," + val + "]")));
} catch (Throwable t) {
//do nothing
// do nothing
}
}
} else if (type == RetResult.class) {
@@ -726,12 +873,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, "{'result':" + val + "}")));
return new StringWrapper(jsonFactory
.getConvert()
.convertTo(jsonFactory.getConvert().convertFrom(genericType, "{'result':" + val + "}")));
} catch (Throwable t) {
//do nothing
// do nothing
}
}
} else if (type != void.class) {
@@ -758,12 +908,11 @@ public final class ApiDocCommand {
Creator creator = Creator.create(type);
return new StringWrapper(jsonFactory.getConvert().convertTo(creator.create()));
} catch (Throwable t) {
//do nothing
// do nothing
}
}
return example;
}
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;
@@ -43,46 +44,46 @@ class AppConfig {
*/
static final String PARAM_APP_CONF_FILE = "APP_CONF_FILE";
//是否用于main方法运行
// 是否用于main方法运行
final boolean singletonMode;
//是否用于编译模式运行
// 是否用于编译模式运行
final boolean compileMode;
//application.xml原始配置信息
// application.xml原始配置信息
AnyValue config;
//是否从/META-INF中读取配置
// 是否从/META-INF中读取配置
boolean configFromCache;
//本进程节点ID
// 本进程节点ID
String nodeid;
//本进程节点ID
// 本进程节点ID
String name;
//本地IP地址
// 本地IP地址
InetSocketAddress localAddress;
//进程根目录
// 进程根目录
File home;
//配置文件目录
// 配置文件目录
File confFile;
//配置文件目录
// 配置文件目录
URI confDir;
//根ClassLoader
// 根ClassLoader
RedkaleClassLoader classLoader;
//Server根ClassLoader
// Server根ClassLoader
RedkaleClassLoader serverClassLoader;
//本地文件日志配置项
// 本地文件日志配置项
final Properties locaLogProperties = new Properties();
//本地文件除logging配置之外的所有的配置项, 包含system.property.、mimetype.property.开头的
// 本地文件除logging配置之外的所有的配置项, 包含system.property.、mimetype.property.开头的
final Properties localEnvProperties = new Properties();
public AppConfig(boolean singletonMode, boolean compileMode) {
@@ -101,21 +102,19 @@ class AppConfig {
this.name = checkName(config.getValue("name", ""));
this.nodeid = checkNodeid(config.getValue("nodeid", String.valueOf(Math.abs(System.nanoTime()))));
this.configFromCache = "true".equals(config.getValue("[config-from-cache]"));
//初始化classLoader、serverClassLoader
// 初始化classLoader、serverClassLoader
this.initClassLoader();
//初始化home、confDir、localAddress等信息
// 初始化home、confDir、localAddress等信息
this.initAppHome();
//读取本地参数配置
// 读取本地参数配置
this.initLocalProperties();
//读取本地日志配置
// 读取本地日志配置
this.initLogProperties();
//读取本地数据库配置
// 读取本地数据库配置
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);
@@ -136,7 +137,7 @@ class AppConfig {
in.close();
}
} catch (Exception e) {
//do nothing
// do nothing
}
}
if (cacheClasses == null) {
@@ -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,16 +176,15 @@ class AppConfig {
this.confDir = confFile.toURI();
}
String localaddr = config.getValue("address", "").trim();
InetAddress addr = localaddr.isEmpty() ? Utility.localInetAddress()
: new InetSocketAddress(localaddr, config.getIntValue("port")).getAddress();
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) -> {
if (k.toString().startsWith("redkale.")) {
localEnvProperties.put(k, v);
@@ -198,7 +198,7 @@ class AppConfig {
propsConf = resources.getAnyValue("properties");
}
}
if (propsConf != null) { //设置配置文件中的系统变量
if (propsConf != null) { // 设置配置文件中的系统变量
for (AnyValue prop : propsConf.getAnyValues("property")) {
String key = prop.getValue("name", "");
String value = prop.getValue("value");
@@ -206,12 +206,14 @@ class AppConfig {
localEnvProperties.put(key, value);
}
}
if (propsConf.getValue("load") != null) { //加载本地配置项文件
for (String dfload : propsConf.getValue("load").replace(',', ';').split(";")) {
if (propsConf.getValue("load") != null) { // 加载本地配置项文件
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;
}
@@ -229,20 +231,18 @@ class AppConfig {
}
}
}
//设置Convert默认配置项
// 设置Convert默认配置项
if (System.getProperty("redkale.convert.pool.size") == null
&& localEnvProperties.getProperty("system.property.redkale.convert.pool.size") == null) {
&& localEnvProperties.getProperty("system.property.redkale.convert.pool.size") == null) {
localEnvProperties.put("system.property.redkale.convert.pool.size", "128");
}
if (System.getProperty("redkale.convert.writer.buffer.defsize") == null
&& localEnvProperties.getProperty("system.property.redkale.convert.writer.buffer.defsize") == null) {
&& localEnvProperties.getProperty("system.property.redkale.convert.writer.buffer.defsize") == null) {
localEnvProperties.put("system.property.redkale.convert.writer.buffer.defsize", "4096");
}
}
/**
* 读取本地DataSource、CacheSource配置
*/
/** 读取本地DataSource、CacheSource配置 */
private void initSourceProperties() {
if ("file".equals(this.confDir.getScheme())) {
File sourceFile = new File(new File(confDir), "source.properties");
@@ -257,7 +257,7 @@ class AppConfig {
}
this.localEnvProperties.putAll(props);
} else {
//兼容 persistence.xml 【已废弃】
// 兼容 persistence.xml 【已废弃】
File persist = new File(new File(confDir), "persistence.xml");
if (persist.isFile() && persist.canRead()) {
System.err.println("persistence.xml is deprecated, replaced by source.properties");
@@ -270,23 +270,22 @@ class AppConfig {
}
}
}
} else { //从url或jar文件中resources读取
} else { // 从url或jar文件中resources读取
try {
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);
in.close();
this.localEnvProperties.putAll(props);
} catch (Exception e) {
//没有文件 跳过
// 没有文件 跳过
}
}
}
/**
* 读取本地日志配置
*/
/** 读取本地日志配置 */
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,20 +350,22 @@ 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;
boolean fromCache = false;
if (confDir.contains("://")) { //jar内部资源
if (confDir.contains("://")) { // jar内部资源
appConfFile = URI.create(confDir + (confDir.endsWith("/") ? "" : "/") + "application.xml");
try {
appConfFile.toURL().openStream().close();
} catch (IOException e) { //没有application.xml就尝试读application.properties
} catch (IOException e) { // 没有application.xml就尝试读application.properties
appConfFile = URI.create(confDir + (confDir.endsWith("/") ? "" : "/") + "application.properties");
}
} else if (confDir.charAt(0) == '/' || confDir.indexOf(':') > 0) { //绝对路径
} else if (confDir.charAt(0) == '/' || confDir.indexOf(':') > 0) { // 绝对路径
File f = new File(confDir, "application.xml");
if (f.isFile() && f.canRead()) {
appConfFile = f.toURI();
@@ -368,17 +376,20 @@ class AppConfig {
appConfFile = f.toURI();
confDir = f.getParentFile().getCanonicalPath();
} else {
appConfFile = RedkaleClassLoader.getConfResourceAsURI(null, "application.xml"); //不能传confDir
appConfFile = RedkaleClassLoader.getConfResourceAsURI(null, "application.xml"); // 不能传confDir
try {
appConfFile.toURL().openStream().close();
} catch (IOException e) { //没有application.xml就尝试读application.properties
} 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;
}
}
} else { //相对路径
} else { // 相对路径
File f = new File(new File(home, confDir), "application.xml");
if (f.isFile() && f.canRead()) {
appConfFile = f.toURI();
@@ -389,13 +400,16 @@ class AppConfig {
appConfFile = f.toURI();
confDir = f.getParentFile().getCanonicalPath();
} else {
appConfFile = RedkaleClassLoader.getConfResourceAsURI(null, "application.xml"); //不能传confDir
appConfFile = RedkaleClassLoader.getConfResourceAsURI(null, "application.xml"); // 不能传confDir
try {
appConfFile.toURL().openStream().close();
} catch (IOException e) { //没有application.xml就尝试读application.properties
} 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) {
@@ -428,11 +442,11 @@ class AppConfig {
}
for (char ch : name.toCharArray()) {
if (!((ch >= '0' && ch <= '9')
|| (ch >= 'a' && ch <= 'z')
|| (ch >= 'A' && ch <= 'Z')
|| ch == '_'
|| ch == '.'
|| ch == '-')) { //不能含特殊字符
|| (ch >= 'a' && ch <= 'z')
|| (ch >= 'A' && ch <= 'Z')
|| ch == '_'
|| ch == '.'
|| ch == '-')) { // 不能含特殊字符
throw new RedkaleException("name only 0-9 a-z A-Z _ - .");
}
}
@@ -443,7 +457,6 @@ class AppConfig {
* 检查node是否含特殊字符
*
* @param name
*
* @return
*/
private static String checkNodeid(String nodeid) {
@@ -452,11 +465,11 @@ class AppConfig {
}
for (char ch : nodeid.toCharArray()) {
if (!((ch >= '0' && ch <= '9')
|| (ch >= 'a' && ch <= 'z')
|| (ch >= 'A' && ch <= 'Z')
|| ch == '_'
|| ch == '.'
|| ch == '-')) { //不能含特殊字符
|| (ch >= 'a' && ch <= 'z')
|| (ch >= 'A' && ch <= 'Z')
|| ch == '_'
|| ch == '.'
|| ch == '-')) { // 不能含特殊字符
throw new RedkaleException("nodeid only 0-9 a-z A-Z _ - .");
}
}
@@ -478,5 +491,4 @@ class AppConfig {
return file;
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -11,8 +11,7 @@ import org.redkale.util.AnyValue;
* Application启动和关闭时的监听事件 <br>
* 只能通过application.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;
@@ -46,7 +43,7 @@ public abstract class BootModule {
protected void onEnvironmentChanged(String namespace, List<ResourceEvent> events) {
if (namespace != null && namespace.contains("logging")) {
//日志配置单独处理
// 日志配置单独处理
application.loggingModule.onEnvironmentUpdated(events);
} else {
application.onEnvironmentChanged(namespace, events);

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> 泛型
@@ -31,35 +31,35 @@ import org.redkale.util.*;
@SuppressWarnings("unchecked")
public final class ClassFilter<T> {
private static final Logger logger = Logger.getLogger(ClassFilter.class.getName()); //日志对象
private static final Logger logger = Logger.getLogger(ClassFilter.class.getName()); // 日志对象
private final Set<FilterEntry<T>> entrys = new HashSet<>(); //符合条件的结果
private final Set<FilterEntry<T>> entrys = new HashSet<>(); // 符合条件的结果
private final Set<FilterEntry<T>> expectEntrys = new HashSet<>(); //准备符合条件的结果
private final Set<FilterEntry<T>> expectEntrys = new HashSet<>(); // 准备符合条件的结果
private Predicate<String> expectPredicate;
private boolean refused; //是否拒绝所有数据,设置true则其他规则失效,都是拒绝.
private boolean refused; // 是否拒绝所有数据,设置true则其他规则失效,都是拒绝.
private Class superClass; //符合的父类型。不为空时扫描结果的class必须是superClass的子类
private Class superClass; // 符合的父类型。不为空时扫描结果的class必须是superClass的子类
private Class[] excludeSuperClasses; //不符合的父类型。
private Class[] excludeSuperClasses; // 不符合的父类型。
private Class<? extends Annotation> annotationClass;//符合的注解。不为空时扫描结果的class必须包含该注解
private Class<? extends Annotation> annotationClass; // 符合的注解。不为空时扫描结果的class必须包含该注解
private Pattern[] includePatterns; //符合的className正则表达式
private Pattern[] includePatterns; // 符合的className正则表达式
private Pattern[] excludePatterns;//拒绝的className正则表达式
private Pattern[] excludePatterns; // 拒绝的className正则表达式
private Set<String> privilegeIncludes; //特批符合条件的className
private Set<String> privilegeIncludes; // 特批符合条件的className
private Set<String> privilegeExcludes;//特批拒绝条件的className
private Set<String> privilegeExcludes; // 特批拒绝条件的className
private List<ClassFilter> ors; //或关系的其他ClassFilter
private List<ClassFilter> ors; // 或关系的其他ClassFilter
private List<ClassFilter> ands;//与关系的其他ClassFilter
private List<ClassFilter> ands; // 与关系的其他ClassFilter
private AnyValue conf; //基本配置信息, 当符合条件时将conf的属性赋值到FilterEntry中去。
private AnyValue conf; // 基本配置信息, 当符合条件时将conf的属性赋值到FilterEntry中去。
private final ClassLoader classLoader;
@@ -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(";"));
@@ -159,9 +174,9 @@ public final class ClassFilter<T> {
/**
* 自动扫描地过滤指定的class
*
* @param property AnyValue
* @param property AnyValue
* @param clazzName String
* @param url URL
* @param url URL
*/
@SuppressWarnings("unchecked")
public final void filter(AnyValue property, String clazzName, URI url) {
@@ -171,9 +186,9 @@ public final class ClassFilter<T> {
/**
* 过滤指定的class
*
* @param property application.xml中对应class节点下的property属性项
* @param property application.xml中对应class节点下的property属性项
* @param clazzName class名称
* @param autoscan 为true表示自动扫描的 false表示显著调用filter AutoLoad的注解将被忽略
* @param autoscan 为true表示自动扫描的 false表示显著调用filter AutoLoad的注解将被忽略
*/
public final void filter(AnyValue property, String clazzName, boolean autoscan) {
filter(property, clazzName, autoscan, null);
@@ -182,10 +197,10 @@ public final class ClassFilter<T> {
/**
* 过滤指定的class
*
* @param property application.xml中对应class节点下的property属性项
* @param property application.xml中对应class节点下的property属性项
* @param clazzName class名称
* @param autoScan 为true表示自动扫描的 false表示显著调用filter AutoLoad的注解将被忽略
* @param url URL
* @param autoScan 为true表示自动扫描的 false表示显著调用filter AutoLoad的注解将被忽略
* @param url URL
*/
public final void filter(AnyValue property, String clazzName, boolean autoScan, URI url) {
boolean r = accept0(property, clazzName);
@@ -228,28 +243,40 @@ 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())
|| (autoScan && auto2 != null && !auto2.value())) { //自动扫描且被标记为@AutoLoad(false)的
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/")) {
return;
}
}
//&& (!(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);
// && (!(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);
}
}
}
@@ -258,7 +285,6 @@ public final class ClassFilter<T> {
* 判断class是否有效
*
* @param className String
*
* @return boolean
*/
public boolean accept(String className) {
@@ -268,9 +294,8 @@ public final class ClassFilter<T> {
/**
* 判断class是否有效
*
* @param property AnyValue
* @param property AnyValue
* @param className String
*
* @return boolean
*/
public boolean accept(AnyValue property, String className) {
@@ -327,9 +352,8 @@ public final class ClassFilter<T> {
* 判断class是否有效
*
* @param property AnyValue
* @param clazz Class
* @param clazz Class
* @param autoscan boolean
*
* @return boolean
*/
@SuppressWarnings("unchecked")
@@ -374,7 +398,7 @@ public final class ClassFilter<T> {
return ps;
}
//将简化版正则转成标准的正则表达式
// 将简化版正则转成标准的正则表达式
// *.platf.* 转成 ^.*\.platf\..*$
// .platf. 转成 ^.*\.platf\..*$
private static String format(String regx) {
@@ -385,7 +409,7 @@ public final class ClassFilter<T> {
if (regx.startsWith("*") || regx.startsWith(".")) {
str = "^.*" + str.substring(1);
}
return str.replace(new String(new char[]{8}), "\\.");
return str.replace(new String(new char[] {8}), "\\.");
}
public void setSuperClass(Class superClass) {
@@ -458,7 +482,6 @@ public final class ClassFilter<T> {
public void setPrivilegeExcludes(Set<String> privilegeExcludes) {
this.privilegeExcludes = privilegeExcludes == null || privilegeExcludes.isEmpty() ? null : privilegeExcludes;
}
/**
@@ -468,7 +491,7 @@ public final class ClassFilter<T> {
*/
public static final class FilterEntry<T> implements Comparable<FilterEntry<T>> {
private final String group; //优先级高于remote属性
private final String group; // 优先级高于remote属性
private final String name;
@@ -489,11 +512,12 @@ 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", "");
}
@Override //@Priority值越大优先级越高, 需要排前面
@Override // @Priority值越大优先级越高, 需要排前面
public int compareTo(FilterEntry o) {
if (!(o instanceof FilterEntry)) {
return 1;
@@ -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());
@@ -568,7 +590,7 @@ public final class ClassFilter<T> {
protected static final ConcurrentMap<URI, Set<String>> cache = new ConcurrentHashMap<>();
private Loader() {
//do nothng
// do nothng
}
public static void close() {
@@ -579,12 +601,12 @@ public final class ClassFilter<T> {
* 加载当前线程的classpath扫描所有class进行过滤
*
* @param excludeFile 不需要扫描的文件夹, 可以为null
* @param loader RedkaleClassloader 不可为null
* @param filters 过滤器
*
* @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;
@@ -614,9 +636,9 @@ public final class ClassFilter<T> {
if (className.startsWith("javax.") || className.startsWith("com.sun.")) {
continue;
}
//常见的jar跳过
// 常见的jar跳过
if (className.startsWith("org.redkaledyn.")) {
break; //redkale动态生成的类
break; // redkale动态生成的类
}
if (className.startsWith("org.junit.")) {
break;
@@ -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;
}
@@ -731,7 +756,7 @@ public final class ClassFilter<T> {
}
}
}
//if (debug) logger.log(Level.INFO, "Scan classes: \r\n{0}", debugstr);
// if (debug) logger.log(Level.INFO, "Scan classes: \r\n{0}", debugstr);
}
private static void loadClassFiles(File exclude, File root, List<File> files) {

View File

@@ -8,36 +8,36 @@ import org.redkale.util.Traces;
/**
* Handler基类
* <p>
* 详情见: https://redkale.org
*
* <p>详情见: https://redkale.org
*
* @author zhangjx
* @since 2.7.0
*/
public abstract class LoggingBaseHandler extends Handler {
//public static final String FORMATTER_FORMAT = "%1$tY-%1$tm-%1$td %1$tH:%1$tM:%1$tS.%tL %4$s %2$s%n%5$s%6$s%n";
//无threadName、TID
// public static final String FORMATTER_FORMAT = "%1$tY-%1$tm-%1$td %1$tH:%1$tM:%1$tS.%tL %4$s %2$s%n%5$s%6$s%n";
// 无threadName、TID
public static final String FORMATTER_FORMAT = "[%1$tY-%1$tm-%1$td %1$tH:%1$tM:%1$tS.%tL] %4$s %2$s\r\n%5$s%6$s\r\n";
//有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";
// 有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";
//有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";
// 有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";
static boolean traceEnable = false; //防止设置system.property前调用Traces类导致enable提前初始化
static boolean traceEnable = false; // 防止设置system.property前调用Traces类导致enable提前初始化
/**
* 默认的日志时间格式化类
* 与SimpleFormatter的区别在于level不使用本地化
*
*/
/** 默认的日志时间格式化类 与SimpleFormatter的区别在于level不使用本地化 */
public static class LoggingFormater extends Formatter {
@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,33 +67,36 @@ public abstract class LoggingBaseHandler extends Handler {
Object[] params = log.getParameters();
if (params != null) {
if (params.length == 1) {
return String.format(FORMATTER_FORMAT2,
log.getInstant().toEpochMilli(),
source,
log.getLoggerName(),
log.getLevel().getName(),
message,
throwable,
params[0]);
return String.format(
FORMATTER_FORMAT2,
log.getInstant().toEpochMilli(),
source,
log.getLoggerName(),
log.getLevel().getName(),
message,
throwable,
params[0]);
} else if (params.length == 2) {
return String.format(FORMATTER_FORMAT3,
log.getInstant().toEpochMilli(),
source,
log.getLoggerName(),
log.getLevel().getName(),
message,
throwable,
params[0],
params[1]);
return String.format(
FORMATTER_FORMAT3,
log.getInstant().toEpochMilli(),
source,
log.getLoggerName(),
log.getLevel().getName(),
message,
throwable,
params[0],
params[1]);
}
}
return String.format(FORMATTER_FORMAT,
log.getInstant().toEpochMilli(),
source,
log.getLoggerName(),
log.getLevel().getName(),
message,
throwable);
return String.format(
FORMATTER_FORMAT,
log.getInstant().toEpochMilli(),
source,
log.getLoggerName(),
log.getLevel().getName(),
message,
throwable);
}
}
@@ -108,9 +111,9 @@ public abstract class LoggingBaseHandler extends Handler {
}
}
if (traceid == null) {
log.setParameters(new String[]{Thread.currentThread().getName()});
log.setParameters(new String[] {Thread.currentThread().getName()});
} else {
log.setParameters(new String[]{Thread.currentThread().getName(), traceid});
log.setParameters(new String[] {Thread.currentThread().getName(), traceid});
}
}
@@ -118,7 +121,8 @@ public abstract class LoggingBaseHandler extends Handler {
try {
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");
@@ -131,8 +135,7 @@ public abstract class LoggingBaseHandler extends Handler {
ps.println(handlerName + ".formatter = " + LoggingFormater.class.getName());
LogManager.getLogManager().readConfiguration(new ByteArrayInputStream(out.toByteArray()));
} catch (Exception e) {
//do nothing
// 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
@@ -57,7 +56,7 @@ public class LoggingFileHandler extends LoggingBaseHandler {
this.denyRegx = Pattern.compile(denyregxstr);
}
} catch (Exception e) {
//do nothing
// do nothing
}
}
@@ -75,19 +74,19 @@ public class LoggingFileHandler extends LoggingBaseHandler {
protected String pattern;
protected String patternDateFormat; //需要时间格式化
protected String patternDateFormat; // 需要时间格式化
protected String unusual; //不为null表示将 WARNING、SEVERE 级别的日志写入单独的文件中
protected String unusual; // 不为null表示将 WARNING、SEVERE 级别的日志写入单独的文件中
protected String unusualDateFormat; //需要时间格式化
protected String unusualDateFormat; // 需要时间格式化
private int limit; //文件大小限制
private int limit; // 文件大小限制
private final AtomicInteger logIndex = new AtomicInteger();
private final AtomicInteger logUnusualIndex = new AtomicInteger();
private int count = 1; //文件限制
private int count = 1; // 文件限制
private long tomorrow;
@@ -150,10 +149,18 @@ public class LoggingFileHandler extends LoggingBaseHandler {
for (int i = Math.min(count - 2, logIndex.get() - 1); i > 0; i--) {
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,19 +196,25 @@ 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);
}
//----------------------写日志-------------------------
// ----------------------写日志-------------------------
String message = getFormatter().format(log);
String encoding = getEncoding();
byte[] bytes = encoding == null ? message.getBytes() : message.getBytes(encoding);
@@ -210,7 +231,6 @@ public class LoggingFileHandler extends LoggingBaseHandler {
}
}
}
}
}.start();
}
@@ -233,9 +253,9 @@ public class LoggingFileHandler extends LoggingBaseHandler {
this.pattern = getPrefix() + this.pattern;
}
}
if (this.pattern != null && this.pattern.contains("%")) { //需要时间格式化
if (this.pattern != null && this.pattern.contains("%")) { // 需要时间格式化
this.patternDateFormat = this.pattern;
Times.formatTime(this.patternDateFormat, -1, System.currentTimeMillis()); //测试时间格式是否正确
Times.formatTime(this.patternDateFormat, -1, System.currentTimeMillis()); // 测试时间格式是否正确
}
String unusualstr = manager.getProperty(cname + ".unusual");
if (unusualstr != null) {
@@ -246,9 +266,9 @@ public class LoggingFileHandler extends LoggingBaseHandler {
this.unusual = getPrefix() + unusualstr;
}
}
if (this.unusual != null && this.unusual.contains("%")) { //需要时间格式化
if (this.unusual != null && this.unusual.contains("%")) { // 需要时间格式化
this.unusualDateFormat = this.unusual;
Times.formatTime(this.unusualDateFormat, -1, System.currentTimeMillis()); //测试时间格式是否正确
Times.formatTime(this.unusualDateFormat, -1, System.currentTimeMillis()); // 测试时间格式是否正确
}
String limitstr = manager.getProperty(cname + ".limit");
try {
@@ -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) {
@@ -268,7 +291,7 @@ public class LoggingFileHandler extends LoggingBaseHandler {
this.limit = ls;
}
} catch (Exception e) {
//do nothing
// do nothing
}
String countstr = manager.getProperty(cname + ".count");
try {
@@ -276,7 +299,7 @@ public class LoggingFileHandler extends LoggingBaseHandler {
this.count = Math.max(1, Math.abs(Integer.decode(countstr)));
}
} catch (Exception e) {
//do nothing
// do nothing
}
String appendstr = manager.getProperty(cname + ".append");
try {
@@ -284,7 +307,7 @@ public class LoggingFileHandler extends LoggingBaseHandler {
this.append = "true".equalsIgnoreCase(appendstr) || "1".equals(appendstr);
}
} catch (Exception e) {
//do nothing
// do nothing
}
String levelstr = manager.getProperty(cname + ".level");
try {
@@ -293,7 +316,7 @@ public class LoggingFileHandler extends LoggingBaseHandler {
setLevel(l != null ? l : Level.ALL);
}
} catch (Exception e) {
//do nothing
// do nothing
}
String filterstr = manager.getProperty(cname + ".filter");
try {
@@ -303,7 +326,7 @@ public class LoggingFileHandler extends LoggingBaseHandler {
setFilter((Filter) clz.getDeclaredConstructor().newInstance());
}
} catch (Exception e) {
//do nothing
// do nothing
}
String formatterstr = manager.getProperty(cname + ".formatter");
try {
@@ -313,7 +336,7 @@ public class LoggingFileHandler extends LoggingBaseHandler {
setFormatter((Formatter) clz.getDeclaredConstructor().newInstance());
}
} catch (Exception e) {
//do nothing
// do nothing
}
if (getFormatter() == null) {
setFormatter(new SimpleFormatter());
@@ -325,7 +348,7 @@ public class LoggingFileHandler extends LoggingBaseHandler {
setEncoding(encodingstr);
}
} catch (Exception e) {
//do nothing
// do nothing
}
String denyregxstr = manager.getProperty(cname + ".denyregx");
@@ -334,7 +357,7 @@ public class LoggingFileHandler extends LoggingBaseHandler {
denyRegx = Pattern.compile(denyregxstr);
}
} catch (Exception e) {
//do nothing
// do nothing
}
}
@@ -377,5 +400,4 @@ public class LoggingFileHandler extends LoggingBaseHandler {
}
}
}
}

View File

@@ -22,19 +22,16 @@ import org.redkale.net.sncp.SncpClient;
import org.redkale.util.Environment;
/**
*
* 日志模块组件
*
* <p>
* 详情见: https://redkale.org
* <p>详情见: https://redkale.org
*
* @author zhangjx
*
* @since 2.8.0
*/
class LoggingModule extends BootModule {
//日志配置资源
// 日志配置资源
private final Properties loggingProperties = new Properties();
LoggingModule(Application application) {
@@ -69,7 +66,7 @@ class LoggingModule extends BootModule {
/**
* 设置日志策略
*
* @param first 是否首次设置
* @param first 是否首次设置
* @param allProps 配置项全量
*/
public void reconfigLogging(boolean first, Properties allProps) {
@@ -80,9 +77,11 @@ 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") //兼容旧时间格式
.replace(searchRawHandler, searchReadHandler));
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
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 -> {
@@ -124,14 +133,17 @@ class LoggingModule extends BootModule {
}
}
String fileHandlerPattern = onlyLogProps.getProperty("java.util.logging.FileHandler.pattern");
if (fileHandlerPattern != null && fileHandlerPattern.contains("%")) { //带日期格式
if (fileHandlerPattern != null && fileHandlerPattern.contains("%")) { // 带日期格式
final String fileHandlerClass = LoggingFileHandler.class.getName();
Properties prop = new Properties();
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",
application.isSingletonMode() || application.isCompileMode() ? "" : fileHandlerClass));
// singletonrun模式下不输出文件日志
prop.setProperty(
"handlers",
handlers.replace(
"java.util.logging.FileHandler",
application.isSingletonMode() || application.isCompileMode() ? "" : fileHandlerClass));
}
if (!prop.isEmpty()) {
String prefix = fileHandlerClass + ".";
@@ -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()) {
@@ -172,7 +186,7 @@ class LoggingModule extends BootModule {
}
}
}
} catch (IOException e) { //不会发生
} catch (IOException e) { // 不会发生
}
}
}

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
@@ -34,9 +35,9 @@ public class LoggingSearchHandler extends LoggingBaseHandler {
protected final AtomicInteger retryCount = new AtomicInteger(3);
protected String tag = DEFAULT_TABLE_NAME; //用于表前缀, 默认是
protected String tag = DEFAULT_TABLE_NAME; // 用于表前缀, 默认是
protected String tagDateFormat; //需要时间格式化
protected String tagDateFormat; // 需要时间格式化
protected String pattern;
@@ -46,7 +47,7 @@ public class LoggingSearchHandler extends LoggingBaseHandler {
protected SearchSource source;
//在LogManager.getLogManager().readConfiguration执行完后通过反射注入Application
// 在LogManager.getLogManager().readConfiguration执行完后通过反射注入Application
protected Application application;
public LoggingSearchHandler() {
@@ -56,7 +57,7 @@ public class LoggingSearchHandler extends LoggingBaseHandler {
private void open() {
final String name = "Redkale-Logging-" + getClass().getSimpleName().replace("Logging", "") + "-Thread";
final int batchSize = 100; //批量最多100条
final int batchSize = 100; // 批量最多100条
final List<SearchLogRecord> logList = new ArrayList<>();
final Formatter formatter = new LoggingBaseHandler.LoggingFormater();
final PrintStream outStream = System.out;
@@ -72,8 +73,8 @@ public class LoggingSearchHandler extends LoggingBaseHandler {
try {
SearchLogRecord log = logqueue.take();
while (source == null && retryCount.get() > 0) initSource();
//----------------------写日志-------------------------
if (source == null) { //source加载失败
// ----------------------写日志-------------------------
if (source == null) { // source加载失败
outStream.print(formatter.format(log.rawLog));
} else {
logList.add(log);
@@ -96,7 +97,6 @@ public class LoggingSearchHandler extends LoggingBaseHandler {
logList.clear();
}
}
}
}.start();
}
@@ -106,7 +106,7 @@ public class LoggingSearchHandler extends LoggingBaseHandler {
return;
}
try {
Utility.sleep(3000); //如果SearchSource自身在打印日志需要停顿一点时间让SearchSource初始化完成
Utility.sleep(3000); // 如果SearchSource自身在打印日志需要停顿一点时间让SearchSource初始化完成
if (application == null) {
Utility.sleep(3000);
}
@@ -127,7 +127,7 @@ public class LoggingSearchHandler extends LoggingBaseHandler {
}
}
private static boolean checkTagName(String name) { //只能是字母、数字、短横、点、%、$和下划线
private static boolean checkTagName(String name) { // 只能是字母、数字、短横、点、%、$和下划线
if (name.isEmpty()) {
return false;
}
@@ -164,7 +164,7 @@ public class LoggingSearchHandler extends LoggingBaseHandler {
this.tag = tagStr.replace("${" + RESNAME_APP_NAME + "}", System.getProperty(SYSNAME_APP_NAME, ""));
if (this.tag.contains("%")) {
this.tagDateFormat = this.tag;
Times.formatTime(this.tagDateFormat, -1, System.currentTimeMillis()); //测试时间格式是否正确
Times.formatTime(this.tagDateFormat, -1, System.currentTimeMillis()); // 测试时间格式是否正确
}
}
@@ -175,7 +175,7 @@ public class LoggingSearchHandler extends LoggingBaseHandler {
setLevel(l != null ? l : Level.ALL);
}
} catch (Exception e) {
//do nothing
// do nothing
}
String filterStr = manager.getProperty(cname + ".filter");
try {
@@ -185,7 +185,7 @@ public class LoggingSearchHandler extends LoggingBaseHandler {
setFilter((Filter) clz.getDeclaredConstructor().newInstance());
}
} catch (Exception e) {
//do nothing
// do nothing
}
String formatterStr = manager.getProperty(cname + ".formatter");
try {
@@ -195,7 +195,7 @@ public class LoggingSearchHandler extends LoggingBaseHandler {
setFormatter((Formatter) clz.getDeclaredConstructor().newInstance());
}
} catch (Exception e) {
//do nothing
// do nothing
}
if (getFormatter() == null) {
setFormatter(new SimpleFormatter());
@@ -207,7 +207,7 @@ public class LoggingSearchHandler extends LoggingBaseHandler {
setEncoding(encodingStr);
}
} catch (Exception e) {
//do nothing
// do nothing
}
String denyRegxStr = manager.getProperty(cname + ".denyregx");
@@ -216,7 +216,7 @@ public class LoggingSearchHandler extends LoggingBaseHandler {
denyRegx = Pattern.compile(denyRegxStr);
}
} catch (Exception e) {
//do nothing
// do nothing
}
}
@@ -239,19 +239,21 @@ 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));
}
@Override
public void flush() {
//do nothing
// do nothing
}
@Override
public void close() throws SecurityException {
//do nothing
// do nothing
}
@Entity
@@ -288,8 +290,8 @@ public class LoggingSearchHandler extends LoggingBaseHandler {
public String methodName;
@ConvertColumn(index = 8)
@SearchColumn(text = true, options = "offsets") //, analyzer = "ik_max_word"
public String message; //log.message +"\r\n"+ log.thrown
@SearchColumn(text = true, options = "offsets") // , analyzer = "ik_max_word"
public String message; // log.message +"\r\n"+ log.thrown
@Transient
@ConvertDisabled
@@ -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 {
@@ -45,10 +42,9 @@ public abstract class ModuleEngine {
* 判断模块的配置项合并策略, 返回null表示模块不识别此配置项
*
* @param path 配置项路径
* @param key 配置项名称
* @param key 配置项名称
* @param val1 配置项原值
* @param val2 配置项新值
*
* @return MergeEnum
*/
public AnyValue.MergeEnum mergeAppConfigStrategy(String path, String key, AnyValue val1, AnyValue val2) {
@@ -58,44 +54,32 @@ public abstract class ModuleEngine {
/**
* 动态扩展类的方法
*
* @param remote 是否远程模式
* @param remote 是否远程模式
* @param serviceClass 类
*
* @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
// do nothing
}
/**
* 结束Application.init方法前被调用
*/
/** 结束Application.init方法前被调用 */
public void onAppPostInit() {
//do nothing
// do nothing
}
/**
* 进入Application.start方法被调用
*/
/** 进入Application.start方法被调用 */
public void onAppPreStart() {
//do nothing
// do nothing
}
/**
* 结束Application.start方法前被调用
*/
/** 结束Application.start方法前被调用 */
public void onAppPostStart() {
//do nothing
// do nothing
}
/**
@@ -104,47 +88,37 @@ public abstract class ModuleEngine {
* @param allProps 配置项全量
*/
public void onEnvironmentLoaded(Properties allProps) {
//do nothing
// do nothing
}
/**
* 配置项变更时被调用
*
* @param namespace 命名空间
* @param events 变更项
* @param events 变更项
*/
public void onEnvironmentChanged(String namespace, List<ResourceEvent> events) {
//do nothing
// do nothing
}
/**
* Application 在运行Compile前调用
*
*/
/** Application 在运行Compile前调用 */
public void onPreCompile() {
//do nothing
// do nothing
}
/**
* Application 在运行Compile后调用
*
*/
/** Application 在运行Compile后调用 */
public void onPostCompile() {
//do nothing
// do nothing
}
/**
* 服务全部启动前被调用
*/
/** 服务全部启动前被调用 */
public void onServersPreStart() {
//do nothing
// do nothing
}
/**
* 服务全部启动后被调用
*/
/** 服务全部启动后被调用 */
public void onServersPostStart() {
//do nothing
// do nothing
}
/**
@@ -153,7 +127,7 @@ public abstract class ModuleEngine {
* @param service Service
*/
public void onServicePreInit(Service service) {
//do nothing
// do nothing
}
/**
@@ -162,7 +136,7 @@ public abstract class ModuleEngine {
* @param service Service
*/
public void onServicePostInit(Service service) {
//do nothing
// do nothing
}
/**
@@ -171,7 +145,7 @@ public abstract class ModuleEngine {
* @param service Service
*/
public void onServicePreDestroy(Service service) {
//do nothing
// do nothing
}
/**
@@ -180,34 +154,26 @@ public abstract class ModuleEngine {
* @param service Service
*/
public void onServicePostDestroy(Service service) {
//do nothing
// do nothing
}
/**
* 服务全部停掉前被调用
*/
/** 服务全部停掉前被调用 */
public void onServersPreStop() {
//do nothing
// do nothing
}
/**
* 服务全部停掉后被调用
*/
/** 服务全部停掉后被调用 */
public void onServersPostStop() {
//do nothing
// do nothing
}
/**
* 进入Application.shutdown方法被调用
*/
/** 进入Application.shutdown方法被调用 */
public void onAppPreShutdown() {
//do nothing
// do nothing
}
/**
* 结束Application.shutdown方法前被调用
*/
/** 结束Application.shutdown方法前被调用 */
public void onAppPostShutdown() {
//do nothing
// 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,15 +32,14 @@ import org.redkale.watch.*;
/**
* HTTP Server节点的配置Server
*
* <p>
* 详情见: https://redkale.org
* <p>详情见: https://redkale.org
*
* @author zhangjx
*/
@NodeProtocol("HTTP")
public class NodeHttpServer extends NodeServer {
protected final boolean rest; //是否加载REST服务 为true加载rest节点信息并将所有可REST化的Service生成RestServlet
protected final boolean rest; // 是否加载REST服务 为true加载rest节点信息并将所有可REST化的Service生成RestServlet
protected final HttpServer httpServer;
@@ -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<>();
@@ -98,7 +116,7 @@ public class NodeHttpServer extends NodeServer {
protected void loadOthers(List<ClassFilter> otherFilters) throws Exception {
List<ClassFilter> filters = otherFilters;
if (filters != null) {
filters.remove(this.webSocketFilter); //webSocketFilter会在loadHttpFilter中处理先剔除
filters.remove(this.webSocketFilter); // webSocketFilter会在loadHttpFilter中处理先剔除
}
super.loadOthers(filters);
}
@@ -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);
@@ -205,7 +250,7 @@ public class NodeHttpServer extends NodeServer {
if (Modifier.isAbstract(clazz.getModifiers())) {
continue;
}
if (entry.isExpect()) { //跳过不自动加载的Filter
if (entry.isExpect()) { // 跳过不自动加载的Filter
continue;
}
RedkaleClassLoader.putReflectionDeclaredConstructors(clazz, clazz.getName());
@@ -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,17 +284,22 @@ 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
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 ws1 ? -1 : 1;
});
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 ws1 ? -1 : 1;
});
final long starts = System.currentTimeMillis();
final List<AbstractMap.SimpleEntry<String, String[]>> ss = sb == null ? null : new ArrayList<>();
for (FilterEntry<? extends Servlet> entry : list) {
@@ -257,9 +308,9 @@ public class NodeHttpServer extends NodeServer {
continue;
}
if (clazz.getAnnotation(Rest.RestDyn.class) != null) {
continue; //动态生成的跳过
continue; // 动态生成的跳过
}
if (entry.isExpect()) { //跳过不自动加载的Servlet
if (entry.isExpect()) { // 跳过不自动加载的Servlet
continue;
}
WebServlet ws = clazz.getAnnotation(WebServlet.class);
@@ -284,8 +335,10 @@ public class NodeHttpServer extends NodeServer {
ss.add(new AbstractMap.SimpleEntry<>("HttpServlet (type=" + clazz.getName() + ")", mappings));
}
}
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,16 +436,20 @@ 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,
final CopyOnWriteArrayList<AbstractMap.SimpleEntry<String, String[]>> rests,
final CopyOnWriteArrayList<AbstractMap.SimpleEntry<String, String[]>> webss) throws Exception {
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 {
if (!rest) {
return;
}
if (restConf == null) {
return; //不存在REST服务
return; // 不存在REST服务
}
String prefix0 = restConf.getValue("path", "");
if (!prefix0.isEmpty() && prefix0.charAt(prefix0.length() - 1) == '/') {
@@ -401,20 +464,22 @@ 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;
if (messageAgent != null) {
prefix0 = ""; //开启MQ时,prefix字段失效
prefix0 = ""; // 开启MQ时,prefix字段失效
}
final String prefix = prefix0;
final boolean autoload = restConf.getBoolValue("autoload", true);
{ //加载RestService
{ // 加载RestService
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,11 +490,17 @@ public class NodeHttpServer extends NodeServer {
}
}
final ClassFilter restFilter = ClassFilter.create(serverClassLoader, null, application.isCompileMode() ? "" : restConf.getValue("includes", ""), application.isCompileMode() ? "" : restConf.getValue("excludes", ""), includeValues, excludeValues);
final ClassFilter restFilter = ClassFilter.create(
serverClassLoader,
null,
application.isCompileMode() ? "" : restConf.getValue("includes", ""),
application.isCompileMode() ? "" : restConf.getValue("excludes", ""),
includeValues,
excludeValues);
final CountDownLatch scdl = new CountDownLatch(super.servletServices.size());
Stream<Service> stream = super.servletServices.stream();
if (!application.isCompileMode()) {
stream = stream.parallel(); //不能并行否则在maven plugin运行环境下ClassLoader不对
stream = stream.parallel(); // 不能并行否则在maven plugin运行环境下ClassLoader不对
}
stream.forEach((service) -> {
try {
@@ -453,13 +524,14 @@ public class NodeHttpServer extends NodeServer {
logger.log(Level.WARNING, stype.getName() + " repeat create rest servlet, so ignore");
return;
}
restedObjects.add(service); //避免重复创建Rest对象
restedObjects.add(service); // 避免重复创建Rest对象
} 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
return; // 没有HttpMapping方法的HttpServlet调用Rest.createRestServlet就会返回null
}
String prefix2 = prefix;
WebServlet ws = servlet.getClass().getAnnotation(WebServlet.class);
@@ -471,13 +543,16 @@ public class NodeHttpServer extends NodeServer {
if (messageAgent != null) {
messageAgent.putService(this, service, servlet);
}
//if (finest) logger.finest("Create RestServlet(resource.name='" + name + "') = " + servlet);
// if (finest) logger.finest("Create RestServlet(resource.name='" + name + "') = " + servlet);
if (rests != null) {
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();
@@ -485,7 +560,7 @@ public class NodeHttpServer extends NodeServer {
});
scdl.await();
}
if (webSocketFilter != null) { //加载RestWebSocket
if (webSocketFilter != null) { // 加载RestWebSocket
final Set<String> includeValues = new HashSet<>();
final Set<String> excludeValues = new HashSet<>();
for (AnyValue item : restConf.getAnyValues("websocket")) {
@@ -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) {
@@ -528,10 +609,11 @@ public class NodeHttpServer extends NodeServer {
logger.log(Level.WARNING, stype.getName() + " repeat create rest websocket, so ignore");
continue;
}
restedObjects.add(stype); //避免重复创建Rest对象
WebSocketServlet servlet = httpServer.addRestWebSocketServlet(serverClassLoader, stype, messageAgent, prefix, en.getProperty());
restedObjects.add(stype); // 避免重复创建Rest对象
WebSocketServlet servlet = httpServer.addRestWebSocketServlet(
serverClassLoader, stype, messageAgent, prefix, en.getProperty());
if (servlet == null) {
continue; //没有RestOnMessage方法的HttpServlet调用Rest.createRestWebSocketServlet就会返回null
continue; // 没有RestOnMessage方法的HttpServlet调用Rest.createRestWebSocketServlet就会返回null
}
String prefix2 = prefix;
WebServlet ws = servlet.getClass().getAnnotation(WebServlet.class);
@@ -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];
}
@@ -556,7 +639,7 @@ public class NodeHttpServer extends NodeServer {
}
}
@Override //loadServlet执行之后调用
@Override // loadServlet执行之后调用
protected void postLoadServlets() {
final ClusterAgent cluster = application.getResourceFactory().find("", ClusterAgent.class);
if (!application.isCompileMode() && cluster != null) {

View File

@@ -8,21 +8,20 @@ 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
*/
public void preStart(NodeServer server) {
//do nothing
// do nothing
}
/**
@@ -32,7 +31,6 @@ public class NodeInterceptor {
* @param server NodeServer
*/
public void preShutdown(NodeServer server) {
//do nothing
// do nothing
}
}

View File

@@ -10,8 +10,7 @@ import java.lang.annotation.*;
/**
* 根据application.xml中的server节点中的protocol值来适配Server的加载逻辑, 只能注解在NodeServer子类上
*
* <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,70 +39,69 @@ import org.redkale.util.*;
/**
* Server节点的初始化配置类
*
*
* 详情见: https://redkale.org
* <p>详情见: https://redkale.org
*
* @author zhangjx
*/
@SuppressWarnings("unchecked")
public abstract class NodeServer {
//INFO日志的换行符
// INFO日志的换行符
public static final String LINE_SEPARATOR = "\r\n";
//日志输出对象
// 日志输出对象
protected final Logger logger;
//进程主类
// 进程主类
protected final Application application;
//依赖注入工厂类
// 依赖注入工厂类
protected final ResourceFactory resourceFactory;
//当前Server对象
// 当前Server对象
protected final Server server;
//ClassLoader
// ClassLoader
protected RedkaleClassLoader serverClassLoader;
protected final Thread serverThread;
//server节点的配置
// server节点的配置
protected AnyValue serverConf;
protected final String threadName;
//加载server节点后的拦截器
// 加载server节点后的拦截器
protected NodeInterceptor interceptor;
//本地模式的Service对象集合
// 本地模式的Service对象集合
protected final Set<Service> localServices = new LinkedHashSet<>();
//远程模式的Service对象集合
// 远程模式的Service对象集合
protected final Set<Service> remoteServices = new LinkedHashSet<>();
//需要转换成Servlet的Service对象集合, Component的Service不在其内
// 需要转换成Servlet的Service对象集合, Component的Service不在其内
protected final Set<Service> servletServices = new LinkedHashSet<>();
//存在SncpServlet、RestServlet
// 存在SncpServlet、RestServlet
protected final Map<Service, Servlet> dynServletMap = new LinkedHashMap<>();
//MessageAgent对象集合
// MessageAgent对象集合
protected final Map<String, MessageAgent> messageAgents = new HashMap<>();
//需要远程模式Service的MessageAgent对象集合
// 需要远程模式Service的MessageAgent对象集合
protected final Map<String, MessageAgent> sncpRemoteAgents = new HashMap<>();
//当前Server的SNCP协议的组
// 当前Server的SNCP协议的组
protected String sncpGroup = null;
//当前Server的SNCP服务Client
// 当前Server的SNCP服务Client
protected SncpClient sncpClient;
//SncpClient的AsyncGroup
// SncpClient的AsyncGroup
private AsyncIOGroup sncpAsyncGroup;
//SNCP服务的地址 非SNCP为null
// SNCP服务的地址 非SNCP为null
private InetSocketAddress sncpAddress;
private volatile int maxTypeLength = 0;
@@ -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,29 +141,35 @@ 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();
}
this.sncpAddress = new InetSocketAddress(host, this.serverConf.getIntValue("port"));
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");
//}
// 单向SNCP服务不需要对等group
// if (this.sncpGroup == null) {
// throw new RedkaleException("Server (" + String.valueOf(config).replaceAll("\\s+", " ") + ") not found
// <group> info");
// }
}
//单点服务不会有 sncpAddress、sncpGroup
// 单点服务不会有 sncpAddress、sncpGroup
if (this.sncpAddress != null) {
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);
}
{
//设置root文件夹
// 设置root文件夹
String webroot = this.serverConf.getValue("root", "root");
File myroot = new File(webroot);
if (!webroot.contains(":") && !webroot.startsWith("/")) {
@@ -171,20 +180,29 @@ public abstract class NodeServer {
resourceFactory.register(Server.RESNAME_SERVER_ROOT, File.class, myroot.getCanonicalFile());
resourceFactory.register(Server.RESNAME_SERVER_ROOT, Path.class, myroot.toPath());
//加入指定的classpath
// 加入指定的classpath
Server.loadLib(serverClassLoader, logger, this.serverConf.getValue("lib", ""));
this.serverThread.setContextClassLoader(this.serverClassLoader);
}
//必须要进行初始化, 构建Service时需要使用Context中的ExecutorService
// 必须要进行初始化, 构建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);
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);
}
registerResTypeLoader(); //给DataSource、CacheSource注册依赖注入时的监听回调事件。
registerResTypeLoader(); // 给DataSource、CacheSource注册依赖注入时的监听回调事件。
String interceptorClass = this.serverConf.getValue("interceptor", "");
if (!interceptorClass.isEmpty()) {
Class clazz = serverClassLoader.loadClass(interceptorClass);
@@ -193,7 +211,7 @@ public abstract class NodeServer {
}
ClassFilter<Service> serviceFilter = createServiceClassFilter();
if (application.isSingletonMode()) { //singleton模式下只加载指定的Service
if (application.isSingletonMode()) { // singleton模式下只加载指定的Service
final String ssc = System.getProperty("redkale.singleton.serviceclass");
final String extssc = System.getProperty("redkale.singleton.extserviceclasses");
if (ssc != null) {
@@ -229,9 +247,9 @@ public abstract class NodeServer {
application.loadClassByFilters(filters.toArray(new ClassFilter[filters.size()]));
long e = System.currentTimeMillis() - s;
logger.info(this.getClass().getSimpleName() + " load filter class in " + e + " ms");
loadService(serviceFilter); //必须在servlet之前
loadService(serviceFilter); // 必须在servlet之前
loadOthers(otherFilters);
if (!application.isSingletonMode()) { //非singleton模式下才加载Filter、Servlet
if (!application.isSingletonMode()) { // 非singleton模式下才加载Filter、Servlet
loadFilter(filterFilter);
loadServlet(servletFilter);
postLoadServlets();
@@ -241,18 +259,23 @@ public abstract class NodeServer {
}
}
protected void loadOthers(List<ClassFilter> otherFilters) throws Exception {
}
protected void loadOthers(List<ClassFilter> otherFilters) throws Exception {}
protected abstract void loadFilter(ClassFilter<? extends Filter> filterFilter) throws Exception;
protected abstract void loadServlet(ClassFilter<? extends Servlet> servletFilter) throws Exception;
private void registerResTypeLoader() {
//--------------------- 注册 Local AutoLoad(false) Service ---------------------
// --------------------- 注册 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);
}
@@ -261,15 +284,21 @@ public abstract class NodeServer {
return Service.class;
}
});
//----------------------------- 注册 WebSocketNode -----------------------------
// ----------------------------- 注册 WebSocketNode -----------------------------
final NodeServer self = this;
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; //远程模式不得注入
return null; // 远程模式不得注入
}
Service nodeService = rf.find(resourceName, WebSocketNode.class);
if (nodeService == 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);
@@ -288,7 +328,7 @@ public abstract class NodeServer {
if (Sncp.isRemote(nodeService)) {
remoteServices.add(nodeService);
} else {
rf.inject(resourceName, nodeService); //动态加载的Service也存在按需加载的注入资源
rf.inject(resourceName, nodeService); // 动态加载的Service也存在按需加载的注入资源
localServices.add(nodeService);
if (!Sncp.isComponent(nodeService)) {
servletServices.add(nodeService);
@@ -313,8 +353,14 @@ public abstract class NodeServer {
});
}
//Service.class的ResourceTypeLoader
private Object loadResourceService(ResourceFactory rf, String srcResourceName, Object srcObj, String resourceName, Field field, Object attachment) {
// Service.class的ResourceTypeLoader
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;
@@ -324,7 +370,7 @@ public abstract class NodeServer {
return null;
}
if ((srcObj instanceof Service) && Sncp.isRemote((Service) srcObj)) {
return null; //远程模式不得注入 AutoLoad Service
return null; // 远程模式不得注入 AutoLoad Service
}
boolean auto = true;
AutoLoad al = serviceImplClass.getAnnotation(AutoLoad.class);
@@ -339,19 +385,37 @@ public abstract class NodeServer {
return null;
}
//ResourceFactory resfactory = (isSNCP() ? appResFactory : resourceFactory);
// ResourceFactory resfactory = (isSNCP() ? appResFactory : resourceFactory);
Service service;
if (Modifier.isFinal(serviceImplClass.getModifiers()) || Sncp.isComponent(serviceImplClass)) {
service = (Service) serviceImplClass.getConstructor().newInstance();
} else if (Utility.isAbstractOrInterface(serviceImplClass)) { //没有具体实现类
} 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,43 +470,72 @@ 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()
&& (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");
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");
}
return null;
}
RedkaleClassLoader.putReflectionPublicMethods(serviceImplClass.getName());
MessageAgent mqAgent = getMessageAgent(entry.getProperty());
Service service;
if (Sncp.isComponent(serviceImplClass)) { //Component
if (Sncp.isComponent(serviceImplClass)) { // Component
RedkaleClassLoader.putReflectionPublicConstructors(serviceImplClass, serviceImplClass.getName());
if (!acceptsComponent(serviceImplClass)) {
return null;
}
service = serviceImplClass.getDeclaredConstructor().newInstance();
} else if (srcObj instanceof WebSocketServlet || localMode) { //本地模式
} 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);
@@ -442,7 +544,7 @@ public abstract class NodeServer {
}
} else {
if (field != null) {
rf.inject(resourceName, service); //动态加载的Service也存在按需加载的注入资源
rf.inject(resourceName, service); // 动态加载的Service也存在按需加载的注入资源
}
localServices.add(service);
if (!Sncp.isComponent(service)) {
@@ -460,7 +562,6 @@ public abstract class NodeServer {
public Type resourceType() {
return type;
}
}
@SuppressWarnings("unchecked")
@@ -470,20 +571,20 @@ public abstract class NodeServer {
final Set<FilterEntry<? extends Service>> entrys = (Set) serviceFilter.getAllFilterEntrys();
final SncpRpcGroups rpcGroups = application.getSncpRpcGroups();
final AtomicInteger serviceCount = new AtomicInteger();
for (FilterEntry<? extends Service> entry : entrys) { //service实现类
for (FilterEntry<? extends Service> entry : entrys) { // service实现类
final Class<? extends Service> serviceImplClass = entry.getType();
if (Modifier.isFinal(serviceImplClass.getModifiers())) {
continue; //修饰final的类跳过
continue; // 修饰final的类跳过
}
if (!Modifier.isPublic(serviceImplClass.getModifiers())) {
continue;
}
if (Sncp.isSncpDyn(serviceImplClass)) {
continue; //动态生成的跳过
continue; // 动态生成的跳过
}
if (entry.isExpect()) {
if (Modifier.isAbstract(serviceImplClass.getModifiers())) {
continue; //修饰abstract的类跳过
continue; // 修饰abstract的类跳过
}
if (DataSource.class.isAssignableFrom(serviceImplClass)) {
continue;
@@ -493,13 +594,14 @@ 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() + ")");
}
Service oldOther = resourceFactory.find(entry.getName(), serviceImplClass);
if (oldOther != null) { //Server加载Service时需要判断是否已在其他协议服务中加载
if (oldOther != null) { // Server加载Service时需要判断是否已在其他协议服务中加载
if (!Sncp.isRemote(oldOther)) {
if (!Sncp.isComponent(oldOther)) {
servletServices.add(oldOther);
@@ -509,43 +611,46 @@ public abstract class NodeServer {
}
boolean isLocalGroup0 = rpcGroups.isLocalGroup(this.sncpGroup, this.sncpAddress, entry);
final String group = isLocalGroup0 ? null : entry.getGroup();
final boolean localMode = serviceImplClass.getAnnotation(Local.class) != null || isLocalGroup0;//本地模式
final boolean localMode = serviceImplClass.getAnnotation(Local.class) != null || isLocalGroup0; // 本地模式
if ((localMode || Sncp.isComponent(serviceImplClass)) && Utility.isAbstractOrInterface(serviceImplClass)) {
continue; //本地模式或Component不能实例化接口和抽象类的Service类
continue; // 本地模式或Component不能实例化接口和抽象类的Service类
}
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 ----------------
// ---------------- inject ----------------
new ArrayList<>(localServices).forEach(y -> {
resourceFactory.inject(Sncp.getResourceName(y), y, NodeServer.this);
});
//远程模式不可inject 里面存在@Resource.required=true依赖
// new ArrayList<>(remoteServices).forEach(y -> {
// resourceFactory.inject(Sncp.getResourceName(y), y, NodeServer.this);
// calcMaxLength(y);
// });
// 远程模式不可inject 里面存在@Resource.required=true依赖
// new ArrayList<>(remoteServices).forEach(y -> {
// resourceFactory.inject(Sncp.getResourceName(y), y, NodeServer.this);
// calcMaxLength(y);
// });
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()) {
@@ -554,7 +659,7 @@ public abstract class NodeServer {
// mqAgent.startSncpRespConsumer();
});
}
//----------------- init -----------------
// ----------------- init -----------------
List<Service> swlist = new ArrayList<>(localServices);
swlist.forEach(y -> calcMaxLength(y));
swlist.sort((o1, o2) -> {
@@ -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));
}
@@ -577,7 +684,7 @@ public abstract class NodeServer {
});
localServices.clear();
localServices.addAll(swlist);
//this.loadPersistData();
// this.loadPersistData();
long preinits = System.currentTimeMillis();
preInitServices(localServices, remoteServices, servletServices);
long preinite = System.currentTimeMillis() - preinits;
@@ -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,35 +726,51 @@ 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());
}
}
private void calcMaxLength(Service y) { //计算toString中的长度
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;
@@ -658,8 +791,9 @@ public abstract class NodeServer {
return agent;
}
//Service.init执行之前调用
protected void preInitServices(Set<Service> localServices, Set<Service> remoteServices, Set<Service> servletServices) {
// Service.init执行之前调用
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);
@@ -674,32 +808,31 @@ public abstract class NodeServer {
}
}
//loadServlet执行之后调用
protected void postLoadServlets() {
// loadServlet执行之后调用
protected void postLoadServlets() {}
}
//Service.destroy执行之前调用
protected void preDestroyServices(Set<Service> localServices, Set<Service> remoteServices, Set<Service> servletServices) {
// Service.destroy执行之前调用
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) { //服务注销
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);
}
}
if (!application.isCompileMode() && !this.messageAgents.isEmpty()) { //MQ
if (!application.isCompileMode() && !this.messageAgents.isEmpty()) { // MQ
}
}
protected void afterClusterDeregisterOnPreDestroyServices(ClusterAgent cluster, String protocol) {
}
protected void afterClusterDeregisterOnPreDestroyServices(ClusterAgent cluster, String protocol) {}
//Server.start执行之后调用
protected void postStartServer(Set<Service> localServices, Set<Service> remoteServices, Set<Service> servletServices) {
}
// Server.start执行之后调用
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);
@@ -753,17 +898,17 @@ public abstract class NodeServer {
ClassFilter filter = new ClassFilter(this.serverClassLoader, ref, inter, excludeSuperClasses, prop);
for (AnyValue av : list.getAnyValues(property)) { // <service>、<filter>、<servlet> 节点
final AnyValue[] items = av.getAnyValues("property");
if (items.length > 0) { //存在 <property>节点
if (items.length > 0) { // 存在 <property>节点
AnyValueWriter dav = AnyValueWriter.create();
final AnyValue.Entry<String>[] strings = av.getStringEntrys();
if (strings != null) { //将<service>、<filter>、<servlet>节点的属性值传给dav
if (strings != null) { // 将<service>、<filter>、<servlet>节点的属性值传给dav
for (AnyValue.Entry<String> en : strings) {
dav.addValue(en.name, en.getValue());
}
}
final AnyValue.Entry<AnyValue>[] anys = av.getAnyEntrys();
if (anys != null) {
for (AnyValue.Entry<AnyValue> en : anys) { //将<service>、<filter>、<servlet>节点的非property属性节点传给dav
for (AnyValue.Entry<AnyValue> en : anys) { // 将<service>、<filter>、<servlet>节点的非property属性节点传给dav
if (!"property".equals(en.name)) {
dav.addValue(en.name, en.getValue());
}
@@ -785,7 +930,7 @@ public abstract class NodeServer {
String excludes = list.getValue("excludes", "");
filter.setIncludePatterns(includes.split(";"));
filter.setExcludePatterns(excludes.split(";"));
} else if (ref2 == null || ref2 == Annotation.class) { //service如果是autoload=false则不需要加载
} else if (ref2 == null || ref2 == Annotation.class) { // service如果是autoload=false则不需要加载
filter.setRefused(true);
} else if (ref2 != Annotation.class) {
filter.setAnnotationClass(ref2);
@@ -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) {
@@ -895,7 +1044,7 @@ public abstract class NodeServer {
localServices.forEach(y -> {
Set<Method> methods = new HashSet<>();
Class loop = y.getClass();
//do { public方法不用递归
// do { public方法不用递归
for (Method m : loop.getMethods()) {
Command c = m.getAnnotation(Command.class);
org.redkale.util.Command c2 = m.getAnnotation(org.redkale.util.Command.class);
@@ -923,7 +1072,7 @@ public abstract class NodeServer {
}
methods.add(m);
}
//} while ((loop = loop.getSuperclass()) != Object.class);
// } while ((loop = loop.getSuperclass()) != Object.class);
if (methods.isEmpty()) {
return;
}
@@ -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
@@ -49,9 +52,9 @@ public class NodeSncpServer extends NodeServer {
@Override
public void init(AnyValue config) throws Exception {
super.init(config);
//-------------------------------------------------------------------
// -------------------------------------------------------------------
if (sncpServer == null) {
return; //调试时server才可能为null
return; // 调试时server才可能为null
}
final StringBuilder sb = logger.isLoggable(Level.FINE) ? new StringBuilder() : null;
List<SncpServlet> servlets = sncpServer.getSncpServlets();
@@ -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) {
@@ -116,7 +127,7 @@ public class NodeSncpServer extends NodeServer {
if (Utility.isAbstractOrInterface(clazz)) {
continue;
}
if (entry.isExpect()) { //跳过不自动加载的Filter
if (entry.isExpect()) { // 跳过不自动加载的Filter
continue;
}
RedkaleClassLoader.putReflectionDeclaredConstructors(clazz, clazz.getName());
@@ -138,28 +149,35 @@ public class NodeSncpServer extends NodeServer {
RedkaleClassLoader.putReflectionPublicClasses(SncpServlet.class.getName());
if (!application.isSingletonMode()) {
this.servletServices.stream()
.filter(x -> x.getClass().getAnnotation(Local.class) == null) //Local模式的Service不生成SncpServlet
.forEach(x -> {
SncpServlet servlet = sncpServer.addSncpServlet(x);
dynServletMap.put(x, servlet);
String mq = Sncp.getResourceMQ(x);
if (mq != null) {
MessageAgent agent = application.getResourceFactory().find(mq, MessageAgent.class);
agent.putService(this, x, servlet);
}
});
.filter(x -> x.getClass().getAnnotation(Local.class) == null) // Local模式的Service不生成SncpServlet
.forEach(x -> {
SncpServlet servlet = sncpServer.addSncpServlet(x);
dynServletMap.put(x, servlet);
String mq = Sncp.getResourceMQ(x);
if (mq != null) {
MessageAgent agent =
application.getResourceFactory().find(mq, MessageAgent.class);
agent.putService(this, x, servlet);
}
});
}
}
@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
@@ -44,7 +42,7 @@ public class NodeWatchServer extends NodeHttpServer {
@Override
protected List<ClassFilter> createOtherClassFilters() {
return null; //不调用 super.createOtherClassFilters()
return null; // 不调用 super.createOtherClassFilters()
}
@Override

View File

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

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,
@RestParam(name = "server", comment = "Server节点名") final String serverName,
@RestParam(name = "type", comment = "Filter类") final String filterType) throws IOException {
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 {
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,10 +30,11 @@ 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,
@RestParam(name = "type", comment = "Service的") String type,
@RestParam(name = "field", comment = "字段") String field,
@RestParam(name = "value", comment = "字段") String value) {
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) {
if (name == null) {
name = "";
}
@@ -80,9 +80,10 @@ 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,
@RestParam(name = "type", comment = "Service的") String type,
@RestParam(name = "field", comment = "字段") String field) {
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) {
name = "";
}
@@ -127,11 +128,12 @@ 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,
@RestParam(name = "type", comment = "Service的") String type,
@RestParam(name = "method", comment = "Service的方法") String method,
@RestParam(name = "params", comment = "方法的参数值") List<String> params,
@RestParam(name = "paramtypes", comment = "方法的参数数据类型") List<String> paramtypes) {
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,
@RestParam(name = "paramtypes", comment = "方法的参数数据类型") List<String> paramtypes) {
if (name == null) {
name = "";
}
@@ -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,43 +214,49 @@ 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,
@RestUploadFile(maxLength = 10 * 1024 * 1024, fileNameRegx = "\\.jar$") byte[] jar) {
//待开发
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,
@RestParam(name = "type", comment = "Service的") String type) {
//待开发
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,
@RestParam(name = "type", comment = "Service的") String type) {
//待开发
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,
@RestParam(name = "type", comment = "Service的") String type) {
//待开发
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,29 +11,24 @@ 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";
//-------------------------------------- 本地缓存 --------------------------------------
// -------------------------------------- 本地缓存 --------------------------------------
/**
* 本地获取缓存数据, 过期返回null
*
* @param <T> 泛型
* @param <T> 泛型
* @param hash 缓存hash
* @param key 缓存键
* @param key 缓存键
* @param type 数据类型
*
* @return 数据值
*/
public <T> T localGet(final String hash, final String key, final Type type);
@@ -41,10 +36,9 @@ public interface CacheManager {
/**
* 本地获取缓存数据, 过期返回null
*
* @param <T> 泛型
* @param key 缓存键
* @param <T> 泛型
* @param key 缓存键
* @param type 数据类型
*
* @return 数据值
*/
default <T> T localGet(final String key, final Type type) {
@@ -55,8 +49,7 @@ public interface CacheManager {
* 本地获取字符串缓存数据, 过期返回null
*
* @param hash 缓存hash
* @param key 缓存键
*
* @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) {
@@ -77,73 +69,83 @@ public interface CacheManager {
/**
* 本地获取缓存数据, 过期返回null
*
* @param <T> 泛型
* @param hash 缓存hash
* @param key 缓存键
* @param type 数据类型
* @param <T> 泛型
* @param hash 缓存hash
* @param key 缓存键
* @param type 数据类型
* @param nullable 是否缓存null值
* @param expire 过期时长Duration.ZERO为永不过期
* @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
*
* @param <T> 泛型
* @param key 缓存键
* @param type 数据类型
* @param <T> 泛型
* @param key 缓存键
* @param type 数据类型
* @param nullable 是否缓存null值
* @param expire 过期时长Duration.ZERO为永不过期
* @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);
}
/**
* 本地异步获取缓存数据, 过期返回null
*
* @param <T> 泛型
* @param hash 缓存hash
* @param key 缓存键
* @param type 数据类型
* @param <T> 泛型
* @param hash 缓存hash
* @param key 缓存键
* @param type 数据类型
* @param nullable 是否缓存null值
* @param expire 过期时长Duration.ZERO为永不过期
* @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
*
* @param <T> 泛型
* @param key 缓存键
* @param type 数据类型
* @param <T> 泛型
* @param key 缓存键
* @param type 数据类型
* @param nullable 是否缓存null值
* @param expire 过期时长Duration.ZERO为永不过期
* @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);
}
/**
* 本地缓存数据
*
* @param <T> 泛型
* @param hash 缓存hash
* @param key 缓存键
* @param type 数据类型
* @param value 数据值
* @param <T> 泛型
* @param hash 缓存hash
* @param key 缓存键
* @param type 数据类型
* @param value 数据值
* @param expire 过期时长Duration.ZERO为永不过期
*/
public <T> void localSet(String hash, String key, Type type, T value, Duration expire);
@@ -151,10 +153,10 @@ public interface CacheManager {
/**
* 本地缓存数据
*
* @param <T> 泛型
* @param key 缓存键
* @param type 数据类型
* @param value 数据值
* @param <T> 泛型
* @param key 缓存键
* @param type 数据类型
* @param value 数据值
* @param expire 过期时长Duration.ZERO为永不过期
*/
default <T> void localSet(String key, Type type, T value, Duration expire) {
@@ -164,9 +166,9 @@ public interface CacheManager {
/**
* 本地缓存字符串数据
*
* @param hash 缓存hash
* @param key 缓存键
* @param value 数据值
* @param hash 缓存hash
* @param key 缓存键
* @param value 数据值
* @param expire 过期时长Duration.ZERO为永不过期
*/
default void localSetString(final String hash, final String key, final String value, Duration expire) {
@@ -176,8 +178,8 @@ public interface CacheManager {
/**
* 本地缓存字符串数据
*
* @param key 缓存键
* @param value 数据值
* @param key 缓存键
* @param value 数据值
* @param expire 过期时长Duration.ZERO为永不过期
*/
default void localSetString(final String key, final String value, Duration expire) {
@@ -188,8 +190,7 @@ public interface CacheManager {
* 本地删除缓存数据
*
* @param hash 缓存hash
* @param key 缓存键
*
* @param key 缓存键
* @return 删除数量
*/
public long localDel(String hash, String key);
@@ -198,22 +199,20 @@ public interface CacheManager {
* 本地删除缓存数据
*
* @param key 缓存键
*
* @return 删除数量
*/
default long localDel(String key) {
return localDel(DEFAULT_HASH, key);
}
//-------------------------------------- 远程缓存 --------------------------------------
// -------------------------------------- 远程缓存 --------------------------------------
/**
* 远程获取缓存数据, 过期返回null
*
* @param <T> 泛型
* @param <T> 泛型
* @param hash 缓存hash
* @param key 缓存键
* @param key 缓存键
* @param type 数据类型
*
* @return 数据值
*/
public <T> T remoteGet(final String hash, final String key, final Type type);
@@ -221,10 +220,9 @@ public interface CacheManager {
/**
* 远程获取缓存数据, 过期返回null
*
* @param <T> 泛型
* @param key 缓存键
* @param <T> 泛型
* @param key 缓存键
* @param type 数据类型
*
* @return 数据值
*/
default <T> T remoteGet(final String key, final Type type) {
@@ -235,8 +233,7 @@ public interface CacheManager {
* 远程获取字符串缓存数据, 过期返回null
*
* @param hash 缓存hash
* @param key 缓存键
*
* @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) {
@@ -257,11 +253,10 @@ public interface CacheManager {
/**
* 远程异步获取缓存数据, 过期返回null
*
* @param <T> 泛型
* @param <T> 泛型
* @param hash 缓存hash
* @param key 缓存键
* @param key 缓存键
* @param type 数据类型
*
* @return 数据值
*/
public <T> CompletableFuture<T> remoteGetAsync(final String hash, final String key, final Type type);
@@ -269,10 +264,9 @@ public interface CacheManager {
/**
* 远程异步获取缓存数据, 过期返回null
*
* @param <T> 泛型
* @param key 缓存键
* @param <T> 泛型
* @param key 缓存键
* @param type 数据类型
*
* @return 数据值
*/
default <T> CompletableFuture<T> remoteGetAsync(final String key, final Type type) {
@@ -283,8 +277,7 @@ public interface CacheManager {
* 远程异步获取字符串缓存数据, 过期返回null
*
* @param hash 缓存hash
* @param key 缓存键
*
* @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) {
@@ -305,77 +297,83 @@ public interface CacheManager {
/**
* 远程获取缓存数据, 过期返回null
*
* @param <T> 泛型
* @param hash 缓存hash
* @param key 缓存键
* @param type 数据类型
* @param <T> 泛型
* @param hash 缓存hash
* @param key 缓存键
* @param type 数据类型
* @param nullable 是否缓存null值
* @param expire 过期时长Duration.ZERO为永不过期
* @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
*
* @param <T> 泛型
* @param key 缓存键
* @param type 数据类型
* @param <T> 泛型
* @param key 缓存键
* @param type 数据类型
* @param nullable 是否缓存null值
* @param expire 过期时长Duration.ZERO为永不过期
* @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);
}
/**
* 远程异步获取缓存数据, 过期返回null
*
* @param <T> 泛型
* @param hash 缓存hash
* @param key 缓存键
* @param type 数据类型
* @param <T> 泛型
* @param hash 缓存hash
* @param key 缓存键
* @param type 数据类型
* @param nullable 是否缓存null值
* @param expire 过期时长Duration.ZERO为永不过期
* @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
*
* @param <T> 泛型
* @param key 缓存键
* @param type 数据类型
* @param <T> 泛型
* @param key 缓存键
* @param type 数据类型
* @param nullable 是否缓存null值
* @param expire 过期时长Duration.ZERO为永不过期
* @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);
}
/**
* 远程缓存数据
*
* @param <T> 泛型
* @param hash 缓存hash
* @param key 缓存键
* @param type 数据类型
* @param value 数据值
* @param <T> 泛型
* @param hash 缓存hash
* @param key 缓存键
* @param type 数据类型
* @param value 数据值
* @param expire 过期时长Duration.ZERO为永不过期
*/
public <T> void remoteSet(final String hash, final String key, final Type type, final T value, Duration expire);
@@ -383,10 +381,10 @@ public interface CacheManager {
/**
* 远程缓存数据
*
* @param <T> 泛型
* @param key 缓存键
* @param type 数据类型
* @param value 数据值
* @param <T> 泛型
* @param key 缓存键
* @param type 数据类型
* @param value 数据值
* @param expire 过期时长Duration.ZERO为永不过期
*/
default <T> void remoteSet(final String key, final Type type, final T value, Duration expire) {
@@ -396,9 +394,9 @@ public interface CacheManager {
/**
* 远程缓存字符串数据
*
* @param hash 缓存hash
* @param key 缓存键
* @param value 数据值
* @param hash 缓存hash
* @param key 缓存键
* @param value 数据值
* @param expire 过期时长Duration.ZERO为永不过期
*/
default void remoteSetString(final String hash, final String key, final String value, Duration expire) {
@@ -408,8 +406,8 @@ public interface CacheManager {
/**
* 远程缓存字符串数据
*
* @param key 缓存键
* @param value 数据值
* @param key 缓存键
* @param value 数据值
* @param expire 过期时长Duration.ZERO为永不过期
*/
default void remoteSetString(final String key, final String value, Duration expire) {
@@ -419,13 +417,12 @@ public interface CacheManager {
/**
* 远程异步缓存数据
*
* @param <T> 泛型
* @param hash 缓存hash
* @param key 缓存键
* @param type 数据类型
* @param value 数据值
* @param <T> 泛型
* @param hash 缓存hash
* @param key 缓存键
* @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);
@@ -433,12 +430,11 @@ public interface CacheManager {
/**
* 远程异步缓存数据
*
* @param <T> 泛型
* @param key 缓存键
* @param type 数据类型
* @param value 数据值
* @param <T> 泛型
* @param key 缓存键
* @param type 数据类型
* @param value 数据值
* @param expire 过期时长Duration.ZERO为永不过期
*
* @return void
*/
default <T> CompletableFuture<Void> remoteSetAsync(String key, Type type, T value, Duration expire) {
@@ -448,24 +444,23 @@ public interface CacheManager {
/**
* 远程异步缓存字符串数据
*
* @param hash 缓存hash
* @param key 缓存键
* @param value 数据值
* @param hash 缓存hash
* @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);
}
/**
* 远程异步缓存字符串数据
*
* @param key 缓存键
* @param value 数据值
* @param key 缓存键
* @param value 数据值
* @param expire 过期时长Duration.ZERO为永不过期
*
* @return void
*/
default CompletableFuture<Void> remoteSetStringAsync(final String key, final String value, Duration expire) {
@@ -476,8 +471,7 @@ public interface CacheManager {
* 远程删除缓存数据
*
* @param hash 缓存hash
* @param key 缓存键
*
* @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) {
@@ -497,8 +490,7 @@ public interface CacheManager {
* 远程异步删除缓存数据
*
* @param hash 缓存hash
* @param key 缓存键
*
* @param key 缓存键
* @return 删除数量
*/
public CompletableFuture<Long> remoteDelAsync(String hash, String key);
@@ -507,22 +499,20 @@ public interface CacheManager {
* 远程异步删除缓存数据
*
* @param key 缓存键
*
* @return 删除数量
*/
default CompletableFuture<Long> remoteDelAsync(String key) {
return remoteDelAsync(DEFAULT_HASH, key);
}
//-------------------------------------- both缓存 --------------------------------------
// -------------------------------------- both缓存 --------------------------------------
/**
* 本地或远程获取缓存数据, 过期返回null
*
* @param <T> 泛型
* @param <T> 泛型
* @param hash 缓存hash
* @param key 缓存键
* @param key 缓存键
* @param type 数据类型
*
* @return 数据值
*/
public <T> T bothGet(final String hash, final String key, final Type type);
@@ -530,10 +520,9 @@ public interface CacheManager {
/**
* 本地或远程获取缓存数据, 过期返回null
*
* @param <T> 泛型
* @param key 缓存键
* @param <T> 泛型
* @param key 缓存键
* @param type 数据类型
*
* @return 数据值
*/
default <T> T bothGet(final String key, final Type type) {
@@ -544,8 +533,7 @@ public interface CacheManager {
* 本地或远程获取字符串缓存数据, 过期返回null
*
* @param hash 缓存hash
* @param key 缓存键
*
* @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) {
@@ -566,11 +553,10 @@ public interface CacheManager {
/**
* 本地或远程异步获取缓存数据, 过期返回null
*
* @param <T> 泛型
* @param <T> 泛型
* @param hash 缓存hash
* @param key 缓存键
* @param key 缓存键
* @param type 数据类型
*
* @return 数据值
*/
public <T> CompletableFuture<T> bothGetAsync(final String hash, final String key, final Type type);
@@ -578,10 +564,9 @@ public interface CacheManager {
/**
* 本地或远程异步获取缓存数据, 过期返回null
*
* @param <T> 泛型
* @param key 缓存键
* @param <T> 泛型
* @param key 缓存键
* @param type 数据类型
*
* @return 数据值
*/
default <T> CompletableFuture<T> bothGetAsync(final String key, final Type type) {
@@ -592,8 +577,7 @@ public interface CacheManager {
* 本地或远程异步获取字符串缓存数据, 过期返回null
*
* @param hash 缓存hash
* @param key 缓存键
*
* @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) {
@@ -614,119 +597,145 @@ public interface CacheManager {
/**
* 本地或远程获取缓存数据, 过期返回null
*
* @param <T> 泛型
* @param hash 缓存hash
* @param key 缓存键
* @param type 数据类型
* @param nullable 是否缓存null值
* @param localExpire 本地过期时长Duration.ZERO为永不过期为null表示不本地缓存
* @param <T> 泛型
* @param hash 缓存hash
* @param key 缓存键
* @param type 数据类型
* @param nullable 是否缓存null值
* @param localExpire 本地过期时长Duration.ZERO为永不过期为null表示不本地缓存
* @param remoteExpire 远程过期时长Duration.ZERO为永不过期为null表示不远程缓存
* @param supplier 数据函数
*
* @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
*
* @param <T> 泛型
* @param key 缓存键
* @param type 数据类型
* @param nullable 是否缓存null值
* @param localExpire 本地过期时长Duration.ZERO为永不过期为null表示不本地缓存
* @param <T> 泛型
* @param key 缓存键
* @param type 数据类型
* @param nullable 是否缓存null值
* @param localExpire 本地过期时长Duration.ZERO为永不过期为null表示不本地缓存
* @param remoteExpire 远程过期时长Duration.ZERO为永不过期为null表示不远程缓存
* @param supplier 数据函数
*
* @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);
}
/**
* 本地或远程异步获取缓存数据, 过期返回null
*
* @param <T> 泛型
* @param hash 缓存hash
* @param key 缓存键
* @param type 数据类型
* @param nullable 是否缓存null值
* @param localExpire 本地过期时长Duration.ZERO为永不过期为null表示不本地缓存
* @param <T> 泛型
* @param hash 缓存hash
* @param key 缓存键
* @param type 数据类型
* @param nullable 是否缓存null值
* @param localExpire 本地过期时长Duration.ZERO为永不过期为null表示不本地缓存
* @param remoteExpire 远程过期时长Duration.ZERO为永不过期为null表示不远程缓存
* @param supplier 数据函数
*
* @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
*
* @param <T> 泛型
* @param key 缓存键
* @param type 数据类型
* @param nullable 是否缓存null值
* @param localExpire 本地过期时长Duration.ZERO为永不过期为null表示不本地缓存
* @param <T> 泛型
* @param key 缓存键
* @param type 数据类型
* @param nullable 是否缓存null值
* @param localExpire 本地过期时长Duration.ZERO为永不过期为null表示不本地缓存
* @param remoteExpire 远程过期时长Duration.ZERO为永不过期为null表示不远程缓存
* @param supplier 数据函数
*
* @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);
}
/**
* 本地和远程缓存数据
*
* @param <T> 泛型
* @param hash 缓存hash
* @param key 缓存键
* @param type 数据类型
* @param value 数据值
* @param localExpire 本地过期时长Duration.ZERO为永不过期为null表示不本地缓存
* @param <T> 泛型
* @param hash 缓存hash
* @param key 缓存键
* @param type 数据类型
* @param value 数据值
* @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);
/**
* 本地和远程缓存数据
*
* @param <T> 泛型
* @param key 缓存键
* @param type 数据类型
* @param value 数据值
* @param localExpire 本地过期时长Duration.ZERO为永不过期为null表示不本地缓存
* @param <T> 泛型
* @param key 缓存键
* @param type 数据类型
* @param value 数据值
* @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);
}
/**
* 本地和远程缓存字符串数据
*
* @param hash 缓存hash
* @param key 缓存键
* @param value 数据值
* @param localExpire 本地过期时长Duration.ZERO为永不过期为null表示不本地缓存
* @param hash 缓存hash
* @param key 缓存键
* @param value 数据值
* @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);
}
/**
* 本地和远程缓存字符串数据
*
* @param key 缓存键
* @param value 数据值
* @param localExpire 本地过期时长Duration.ZERO为永不过期为null表示不本地缓存
* @param key 缓存键
* @param value 数据值
* @param localExpire 本地过期时长Duration.ZERO为永不过期为null表示不本地缓存
* @param remoteExpire 远程过期时长Duration.ZERO为永不过期为null表示不远程缓存
*/
default void bothSetString(final String key, final String value, Duration localExpire, Duration remoteExpire) {
@@ -736,60 +745,60 @@ public interface CacheManager {
/**
* 本地和远程异步缓存数据
*
* @param <T> 泛型
* @param hash 缓存hash
* @param key 缓存键
* @param type 数据类型
* @param value 数据值
* @param localExpire 本地过期时长Duration.ZERO为永不过期为null表示不本地缓存
* @param <T> 泛型
* @param hash 缓存hash
* @param key 缓存键
* @param type 数据类型
* @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);
/**
* 本地和远程异步缓存数据
*
* @param <T> 泛型
* @param key 缓存键
* @param type 数据类型
* @param value 数据值
* @param localExpire 本地过期时长Duration.ZERO为永不过期为null表示不本地缓存
* @param <T> 泛型
* @param key 缓存键
* @param type 数据类型
* @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);
}
/**
* 本地和远程异步缓存字符串数据
*
* @param hash 缓存hash
* @param key 缓存键
* @param value 数据值
* @param localExpire 本地过期时长Duration.ZERO为永不过期为null表示不本地缓存
* @param hash 缓存hash
* @param key 缓存键
* @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);
}
/**
* 本地和远程异步缓存字符串数据
*
* @param key 缓存键
* @param value 数据值
* @param localExpire 本地过期时长Duration.ZERO为永不过期为null表示不本地缓存
* @param key 缓存键
* @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);
}
@@ -797,8 +806,7 @@ public interface CacheManager {
* 本地和远程删除缓存数据
*
* @param hash 缓存hash
* @param key 缓存键
*
* @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) {
@@ -818,8 +825,7 @@ public interface CacheManager {
* 本地和远程异步删除缓存数据
*
* @param hash 缓存hash
* @param key 缓存键
*
* @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
@@ -40,46 +37,52 @@ public class CacheAction {
private final CacheEntry cached;
//Supplier对象的类型
// Supplier对象的类型
private final Type resultType;
//缓存方法是否异步
// 缓存方法是否异步
private final boolean async;
//是否可以缓存null
// 是否可以缓存null
private final boolean nullable;
//宿主对象的类
// 宿主对象的类
private final Class serviceClass;
//无法获取动态的Method只能存方法名
// 无法获取动态的Method只能存方法名
private final String methodName;
//获取动态的字段名
// 获取动态的字段名
private final String fieldName;
//方法参数类型
// 方法参数类型
@Nullable
private final Class[] paramTypes;
//方法参数名
// 方法参数名
@Nullable
private final String[] paramNames;
//缓存的hash
// 缓存的hash
private String hash;
//缓存的key
// 缓存的key
private MultiHashKey dynKey;
//本地缓存过期时长Duration.ZERO为永不过期为null表示不本地缓存
// 本地缓存过期时长Duration.ZERO为永不过期为null表示不本地缓存
private Duration localExpire;
//远程缓存过期时长Duration.ZERO为永不过期为null表示不远程缓存
// 远程缓存过期时长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,10 +95,9 @@ public class CacheAction {
}
void init() {
this.hash = cached.getHash().trim().isEmpty()
|| CacheManager.DEFAULT_HASH.equals(cached.getHash())
? CacheManager.DEFAULT_HASH
: environment.getPropertyValue(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());
this.dynKey = MultiHashKey.create(paramNames, key);
this.localExpire = createDuration(cached.getLocalExpire());
@@ -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);
}
}
@@ -140,14 +144,13 @@ public class CacheAction {
@Override
public String toString() {
return "{"
+ "\"serviceClass\":" + serviceClass.getName()
+ ",\"methodName\":\"" + methodName + "\""
+ ",\"fieldName\":\"" + fieldName + "\""
+ ",\"paramTypes\":" + JsonConvert.root().convertTo(paramTypes)
+ ",\"paramNames\":" + JsonConvert.root().convertTo(paramNames)
+ ",\"resultType\":\"" + resultType + "\""
+ ",\"cache\":" + cached
+ "}";
+ "\"serviceClass\":" + serviceClass.getName()
+ ",\"methodName\":\"" + methodName + "\""
+ ",\"fieldName\":\"" + fieldName + "\""
+ ",\"paramTypes\":" + JsonConvert.root().convertTo(paramTypes)
+ ",\"paramNames\":" + JsonConvert.root().convertTo(paramNames)
+ ",\"resultType\":\"" + resultType + "\""
+ ",\"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);
@@ -84,10 +89,10 @@ public class CacheAsmMethodBoost extends AsmMethodBoost {
final String rsMethodName = method.getName() + "_afterCache";
final String dynFieldName = fieldPrefix + "_" + method.getName() + "CacheAction" + actionIndex;
final AsmMethodBean methodBean = getMethodBean(method);
{ //定义一个新方法调用 this.rsMethodName
{ // 定义一个新方法调用 this.rsMethodName
final String cacheDynDesc = Type.getDescriptor(DynForCache.class);
final MethodVisitor mv = createMethodVisitor(cw, method, newMethodName, methodBean);
//mv.setDebug(true);
// mv.setDebug(true);
AnnotationVisitor av = mv.visitAnnotation(cacheDynDesc, true);
av.visit("dynField", dynFieldName);
Asms.visitAnnotation(av, cached);
@@ -98,13 +103,13 @@ 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[]{
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()))
});
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()))
});
mv.visitVarInsn(ASTORE, 1 + method.getParameterCount());
Label l1 = new Label();
mv.visitLabel(l1);
@@ -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,14 +165,22 @@ 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"});
//mv.setDebug(true);
{ // ThrowSupplier
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);
mv.visitVarInsn(ALOAD, 0);
@@ -171,12 +193,17 @@ public class CacheAsmMethodBoost extends AsmMethodBoost {
mv.visitMaxs(5, 5);
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;
}
@@ -184,7 +211,7 @@ public class CacheAsmMethodBoost extends AsmMethodBoost {
@Override
public void doInstance(ResourceFactory resourceFactory, Object service) {
Class clazz = service.getClass();
if (actionMap == null) { //为null表示没有调用过doMethod 动态类在编译是已经生成好了
if (actionMap == null) { // 为null表示没有调用过doMethod 动态类在编译是已经生成好了
actionMap = new LinkedHashMap<>();
Map<String, AsmMethodBean> methodBeans = AsmMethodBoost.getMethodBeans(clazz);
for (final Method method : clazz.getDeclaredMethods()) {
@@ -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);
}
}
@@ -210,7 +243,6 @@ public class CacheAsmMethodBoost extends AsmMethodBoost {
throw new RedkaleException("field (" + field + ") in " + clazz.getName() + " set error", e);
}
});
//do nothing
// do nothing
}
}

View File

@@ -7,10 +7,7 @@ import java.util.concurrent.TimeUnit;
import org.redkale.cache.Cached;
import org.redkale.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

@@ -42,38 +42,38 @@ import org.redkale.util.Utility;
@ResourceType(CacheManager.class)
public class CacheManagerService implements CacheManager, Service {
//是否开启缓存
// 是否开启缓存
protected boolean enabled = true;
//配置
// 配置
protected AnyValue config;
//数据类型与CacheValue泛型的对应关系
// 数据类型与CacheValue泛型的对应关系
private final ConcurrentHashMap<Type, Type> cacheValueTypes = new ConcurrentHashMap<>();
//本地缓存Source
// 本地缓存Source
protected final CacheMemorySource localSource = new CacheMemorySource("cache-local");
//缓存hash集合, 用于定时遍历删除过期数据
// 缓存hash集合, 用于定时遍历删除过期数据
protected final ConcurrentSkipListSet<String> hashNames = new ConcurrentSkipListSet<>();
//缓存无效时使用的同步锁
// 缓存无效时使用的同步锁
private final ConcurrentHashMap<String, CacheValue> syncLock = new ConcurrentHashMap<>();
//缓存无效时使用的异步锁
// 缓存无效时使用的异步锁
private final ConcurrentHashMap<String, CacheAsyncEntry> asyncLock = new ConcurrentHashMap<>();
@Resource(required = false)
protected Application application;
//远程缓存Source
// 远程缓存Source
protected CacheSource remoteSource;
protected CacheManagerService(@Nullable CacheSource remoteSource) {
this.remoteSource = remoteSource;
}
//一般用于独立组件
// 一般用于独立组件
public static CacheManagerService create(@Nullable CacheSource remoteSource) {
return new CacheManagerService(remoteSource);
}
@@ -105,7 +105,6 @@ public class CacheManagerService implements CacheManager, Service {
this.remoteSource = source;
}
}
}
@Override
@@ -124,15 +123,14 @@ public class CacheManagerService implements CacheManager, Service {
return this;
}
//-------------------------------------- 本地缓存 --------------------------------------
// -------------------------------------- 本地缓存 --------------------------------------
/**
* 本地获取缓存数据, 过期返回null
*
* @param <T> 泛型
* @param <T> 泛型
* @param hash 缓存hash
* @param key 缓存键
* @param key 缓存键
* @param type 数据类型
*
* @return 数据值
*/
@Override
@@ -144,47 +142,58 @@ public class CacheManagerService implements CacheManager, Service {
/**
* 本地获取缓存数据, 过期返回null
*
* @param <T> 泛型
* @param hash 缓存hash
* @param key 缓存键
* @param type 数据类型
* @param <T> 泛型
* @param hash 缓存hash
* @param key 缓存键
* @param type 数据类型
* @param nullable 是否缓存null值
* @param expire 过期时长Duration.ZERO为永不过期
* @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);
}
/**
* 本地异步获取缓存数据, 过期返回null
*
* @param <T> 泛型
* @param hash 缓存hash
* @param key 缓存键
* @param type 数据类型
* @param <T> 泛型
* @param hash 缓存hash
* @param key 缓存键
* @param type 数据类型
* @param nullable 是否缓存null值
* @param expire 过期时长Duration.ZERO为永不过期
* @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);
}
/**
* 本地缓存数据
*
* @param <T> 泛型
* @param hash 缓存hash
* @param key 缓存键
* @param type 数据类型
* @param value 数据值
* @param <T> 泛型
* @param hash 缓存hash
* @param key 缓存键
* @param type 数据类型
* @param value 数据值
* @param expire 过期时长Duration.ZERO为永不过期
*/
@Override
@@ -196,8 +205,7 @@ public class CacheManagerService implements CacheManager, Service {
* 本地删除缓存数据
*
* @param hash 缓存hash
* @param key 缓存键
*
* @param key 缓存键
* @return 删除数量
*/
@Override
@@ -206,15 +214,14 @@ public class CacheManagerService implements CacheManager, Service {
return localSource.del(idFor(hash, key));
}
//-------------------------------------- 远程缓存 --------------------------------------
// -------------------------------------- 远程缓存 --------------------------------------
/**
* 远程获取缓存数据, 过期返回null
*
* @param <T> 泛型
* @param <T> 泛型
* @param hash 缓存hash
* @param key 缓存键
* @param key 缓存键
* @param type 数据类型
*
* @return 数据值
*/
@Override
@@ -226,11 +233,10 @@ public class CacheManagerService implements CacheManager, Service {
/**
* 远程异步获取缓存数据, 过期返回null
*
* @param <T> 泛型
* @param <T> 泛型
* @param hash 缓存hash
* @param key 缓存键
* @param key 缓存键
* @param type 数据类型
*
* @return 数据值
*/
@Override
@@ -243,47 +249,58 @@ public class CacheManagerService implements CacheManager, Service {
/**
* 远程获取缓存数据, 过期返回null
*
* @param <T> 泛型
* @param hash 缓存hash
* @param key 缓存键
* @param type 数据类型
* @param <T> 泛型
* @param hash 缓存hash
* @param key 缓存键
* @param type 数据类型
* @param nullable 是否缓存null值
* @param expire 过期时长Duration.ZERO为永不过期
* @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);
}
/**
* 远程异步获取缓存数据, 过期返回null
*
* @param <T> 泛型
* @param hash 缓存hash
* @param key 缓存键
* @param type 数据类型
* @param <T> 泛型
* @param hash 缓存hash
* @param key 缓存键
* @param type 数据类型
* @param nullable 是否缓存null值
* @param expire 过期时长Duration.ZERO为永不过期
* @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);
}
/**
* 远程缓存数据
*
* @param <T> 泛型
* @param hash 缓存hash
* @param key 缓存键
* @param type 数据类型
* @param value 数据值
* @param <T> 泛型
* @param hash 缓存hash
* @param key 缓存键
* @param type 数据类型
* @param value 数据值
* @param expire 过期时长Duration.ZERO为永不过期
*/
@Override
@@ -294,11 +311,11 @@ public class CacheManagerService implements CacheManager, Service {
/**
* 远程异步缓存数据
*
* @param <T> 泛型
* @param hash 缓存hash
* @param key 缓存键
* @param type 数据类型
* @param value 数据值
* @param <T> 泛型
* @param hash 缓存hash
* @param key 缓存键
* @param type 数据类型
* @param value 数据值
* @param expire 过期时长Duration.ZERO为永不过期
*/
@Override
@@ -310,8 +327,7 @@ public class CacheManagerService implements CacheManager, Service {
* 远程删除缓存数据
*
* @param hash 缓存hash
* @param key 缓存键
*
* @param key 缓存键
* @return 删除数量
*/
@Override
@@ -324,8 +340,7 @@ public class CacheManagerService implements CacheManager, Service {
* 远程异步删除缓存数据
*
* @param hash 缓存hash
* @param key 缓存键
*
* @param key 缓存键
* @return 删除数量
*/
@Override
@@ -334,15 +349,14 @@ public class CacheManagerService implements CacheManager, Service {
return remoteSource.delAsync(idFor(hash, key));
}
//-------------------------------------- both缓存 --------------------------------------
// -------------------------------------- both缓存 --------------------------------------
/**
* 远程获取缓存数据, 过期返回null
*
* @param <T> 泛型
* @param <T> 泛型
* @param hash 缓存hash
* @param key 缓存键
* @param key 缓存键
* @param type 数据类型
*
* @return 数据值
*/
@Override
@@ -353,11 +367,10 @@ public class CacheManagerService implements CacheManager, Service {
/**
* 远程异步获取缓存数据, 过期返回null
*
* @param <T> 泛型
* @param <T> 泛型
* @param hash 缓存hash
* @param key 缓存键
* @param key 缓存键
* @param type 数据类型
*
* @return 数据值
*/
@Override
@@ -368,21 +381,25 @@ public class CacheManagerService implements CacheManager, Service {
/**
* 远程获取缓存数据, 过期返回null
*
* @param <T> 泛型
* @param hash 缓存hash
* @param key 缓存键
* @param type 数据类型
*
* @param nullable 是否缓存null值
* @param localExpire 本地过期时长Duration.ZERO为永不过期为null表示不本地缓存
* @param <T> 泛型
* @param hash 缓存hash
* @param key 缓存键
* @param type 数据类型
* @param nullable 是否缓存null值
* @param localExpire 本地过期时长Duration.ZERO为永不过期为null表示不本地缓存
* @param remoteExpire 远程过期时长Duration.ZERO为永不过期为null表示不远程缓存
* @param supplier 数据函数
*
* @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();
@@ -392,39 +409,52 @@ public class CacheManagerService implements CacheManager, Service {
throw new RedkaleException(t);
}
}
if (remoteExpire == null) { //只有本地缓存
if (remoteExpire == null) { // 只有本地缓存
Objects.requireNonNull(localExpire);
return localGetSet(hash, key, type, nullable, localExpire, supplier);
}
if (localExpire == null) { //只有远程缓存
if (localExpire == null) { // 只有远程缓存
Objects.requireNonNull(remoteExpire);
return remoteGetSet(hash, key, type, nullable, remoteExpire, supplier);
}
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);
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);
}
/**
* 远程异步获取缓存数据, 过期返回null
*
* @param <T> 泛型
* @param hash 缓存hash
* @param key 缓存键
* @param type 数据类型
* @param nullable 是否缓存null值
* @param localExpire 本地过期时长Duration.ZERO为永不过期为null表示不本地缓存
* @param <T> 泛型
* @param hash 缓存hash
* @param key 缓存键
* @param type 数据类型
* @param nullable 是否缓存null值
* @param localExpire 本地过期时长Duration.ZERO为永不过期为null表示不本地缓存
* @param remoteExpire 远程过期时长Duration.ZERO为永不过期为null表示不远程缓存
* @param supplier 数据函数
*
* @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();
@@ -432,37 +462,51 @@ public class CacheManagerService implements CacheManager, Service {
return CompletableFuture.failedFuture(t);
}
}
if (remoteExpire == null) { //只有本地缓存
if (remoteExpire == null) { // 只有本地缓存
Objects.requireNonNull(localExpire);
return localGetSetAsync(hash, key, type, nullable, localExpire, supplier);
}
if (localExpire == null) { //只有远程缓存
if (localExpire == null) { // 只有远程缓存
Objects.requireNonNull(remoteExpire);
return remoteGetSetAsync(hash, key, type, nullable, remoteExpire, supplier);
}
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);
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);
}
/**
* 远程缓存数据
*
* @param <T> 泛型
* @param hash 缓存hash
* @param key 缓存键
* @param type 数据类型
* @param value 数据值
* @param localExpire 本地过期时长Duration.ZERO为永不过期为null表示不本地缓存
* @param <T> 泛型
* @param hash 缓存hash
* @param key 缓存键
* @param type 数据类型
* @param value 数据值
* @param localExpire 本地过期时长Duration.ZERO为永不过期为null表示不本地缓存
* @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);
@@ -475,18 +519,18 @@ public class CacheManagerService implements CacheManager, Service {
/**
* 远程异步缓存数据
*
* @param <T> 泛型
* @param hash 缓存hash
* @param key 缓存键
* @param type 数据类型
* @param value 数据值
* @param localExpire 本地过期时长Duration.ZERO为永不过期为null表示不本地缓存
* @param <T> 泛型
* @param hash 缓存hash
* @param key 缓存键
* @param type 数据类型
* @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);
@@ -502,8 +546,7 @@ public class CacheManagerService implements CacheManager, Service {
* 远程删除缓存数据
*
* @param hash 缓存hash
* @param key 缓存键
*
* @param key 缓存键
* @return 删除数量
*/
@Override
@@ -522,15 +565,14 @@ public class CacheManagerService implements CacheManager, Service {
* 远程异步删除缓存数据
*
* @param hash 缓存hash
* @param key 缓存键
*
* @param key 缓存键
* @return 删除数量
*/
@Override
public CompletableFuture<Long> bothDelAsync(String hash, String key) {
checkEnable();
String id = idFor(hash, key);
long v = localSource.del(id); //内存操作,无需异步
long v = localSource.del(id); // 内存操作,无需异步
if (remoteSource != null) {
return remoteSource.delAsync(id);
} else {
@@ -538,24 +580,30 @@ public class CacheManagerService implements CacheManager, Service {
}
}
//-------------------------------------- 内部方法 --------------------------------------
// -------------------------------------- 内部方法 --------------------------------------
/**
* 获取缓存数据, 过期返回null
*
* @param <T> 泛型
* @param getter 获取数据函数
* @param setter 设置数据函数
* @param hash 缓存hash
* @param key 缓存键
* @param type 数据类型
* @param <T> 泛型
* @param getter 获取数据函数
* @param setter 设置数据函数
* @param hash 缓存hash
* @param key 缓存键
* @param type 数据类型
* @param nullable 是否缓存null值
* @param expire 过期时长Duration.ZERO为永不过期
* @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);
@@ -594,20 +642,26 @@ public class CacheManagerService implements CacheManager, Service {
/**
* 异步获取缓存数据, 过期返回null
*
* @param <T> 泛型
* @param getter 获取数据函数
* @param setter 设置数据函数
* @param hash 缓存hash
* @param key 缓存键
* @param type 数据类型
* @param <T> 泛型
* @param getter 获取数据函数
* @param setter 设置数据函数
* @param hash 缓存hash
* @param key 缓存键
* @param type 数据类型
* @param nullable 是否缓存null值
* @param expire 过期时长Duration.ZERO为永不过期
* @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);
@@ -628,7 +682,7 @@ public class CacheManagerService implements CacheManager, Service {
CacheValue<T> cacheVal = toCacheValue(nullable, v);
if (CacheValue.isValid(cacheVal)) {
setter.set(id, expire, cacheType, cacheVal)
.whenComplete((v2, e2) -> entry.success(CacheValue.get(cacheVal)));
.whenComplete((v2, e2) -> entry.success(CacheValue.get(cacheVal)));
} else {
entry.success(CacheValue.get(cacheVal));
}
@@ -641,11 +695,13 @@ public class CacheManagerService implements CacheManager, Service {
});
}
protected <T> CompletableFuture<Void> localSetCacheAsync(String id, Duration expire, Type cacheType, CacheValue<T> cacheVal) {
protected <T> CompletableFuture<Void> localSetCacheAsync(
String id, Duration expire, Type cacheType, CacheValue<T> cacheVal) {
return setCacheAsync(localSource, id, expire, cacheType, cacheVal);
}
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));
}
@@ -694,14 +753,14 @@ public class CacheManagerService implements CacheManager, Service {
/**
* 远程异步获取缓存数据, 过期返回null
*
* @param <T> 泛型
* @param <T> 泛型
* @param hash 缓存hash
* @param key 缓存键
* @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));
}
@@ -721,15 +780,14 @@ public class CacheManagerService implements CacheManager, Service {
/**
* 远程异步获取缓存数据, 过期返回null
*
* @param <T> 泛型
* @param id 缓存键
* @param <T> 泛型
* @param id 缓存键
* @param cacheType 数据类型
*
* @return 数据值
*/
protected <T> CompletableFuture<CacheValue<T>> bothGetCacheAsync(final String id, final Type cacheType) {
checkEnable();
CacheValue<T> val = localSource.get(id, cacheType); //内存操作,无需异步
CacheValue<T> val = localSource.get(id, cacheType); // 内存操作,无需异步
if (CacheValue.isValid(val)) {
return CompletableFuture.completedFuture(val);
}
@@ -750,8 +808,7 @@ public class CacheManagerService implements CacheManager, Service {
* 创建一个锁key
*
* @param hash 缓存hash
* @param key 缓存键
*
* @param key 缓存键
* @return key
*/
protected String idFor(String hash, String key) {
@@ -761,10 +818,9 @@ public class CacheManagerService implements CacheManager, Service {
/**
* 将原始数据函数转换成获取CacheValue数据函数
*
* @param <T> 泛型
* @param <T> 泛型
* @param nullable 是否缓存null值
* @param value 缓存值
*
* @param value 缓存值
* @return CacheValue函数
*/
protected <T> CacheValue<T> toCacheValue(boolean nullable, T value) {
@@ -777,10 +833,9 @@ public class CacheManagerService implements CacheManager, Service {
/**
* 将原始数据函数转换成获取CacheValue数据函数
*
* @param <T> 泛型
* @param <T> 泛型
* @param nullable 是否缓存null值
* @param supplier 数据函数
*
* @return CacheValue函数
*/
protected <T> ThrowSupplier<CacheValue<T>> toCacheSupplier(boolean nullable, ThrowSupplier<T> supplier) {
@@ -790,9 +845,8 @@ public class CacheManagerService implements CacheManager, Service {
/**
* 创建数据类型创建对应CacheValue泛型
*
* @param type 数据类型为null则取value的类型
* @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,13 +16,10 @@ import org.redkale.util.AnyValue;
import org.redkale.util.InstanceProvider;
import org.redkale.util.RedkaleClassLoader;
/**
*
* @author zhangjx
*/
/** @author zhangjx */
public class CacheModuleEngine extends ModuleEngine {
//全局缓存管理器
// 全局缓存管理器
private CacheManager cacheManager;
private AnyValue config;
@@ -35,10 +32,9 @@ public class CacheModuleEngine extends ModuleEngine {
* 判断模块的配置项合并策略, 返回null表示模块不识别此配置项
*
* @param path 配置项路径
* @param key 配置项名称
* @param key 配置项名称
* @param val1 配置项原值
* @param val2 配置项新值
*
* @return MergeEnum
*/
@Override
@@ -52,9 +48,8 @@ public class CacheModuleEngine extends ModuleEngine {
/**
* 动态扩展类的方法
*
* @param remote 是否远程模式
* @param remote 是否远程模式
* @param serviceClass 类
*
* @return 方法动态扩展器
*/
@Override
@@ -62,12 +57,10 @@ public class CacheModuleEngine extends ModuleEngine {
return new CacheAsmMethodBoost(remote, serviceClass);
}
/**
* 结束Application.init方法前被调用
*/
/** 结束Application.init方法前被调用 */
@Override
public void onAppPostInit() {
//设置缓存管理器
// 设置缓存管理器
this.config = application.getAppConfig().getAnyValue("cache");
this.cacheManager = createManager(this.config);
if (!application.isCompileMode()) {
@@ -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