Full Code Format
This commit is contained in:
23
my/pom.xml
23
my/pom.xml
@@ -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
21
pom.xml
@@ -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>
|
||||
|
||||
|
||||
@@ -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})
|
||||
|
||||
@@ -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 "";
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
|
||||
@@ -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:
|
||||
*
|
||||
* @Column(name="DESC", nullable=false, length=512)
|
||||
@@ -42,23 +43,21 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
||||
* @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 <= 16777215 then sqltype is MEDIUMTEXT <br>
|
||||
* if type==String and length > 16777215 then sqltype is LONGTEXT <br>
|
||||
* if type==byte[] and length <= 65535 then sqltype is BLOB <br>
|
||||
* if type==byte[] and length <= 16777215 then sqltype is MEDIUMBLOB <br>
|
||||
* if type==byte[] and length > 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 <= 16777215 then sqltype is MEDIUMTEXT <br>
|
||||
* if type==String and length > 16777215 then sqltype is LONGTEXT <br>
|
||||
* if type==byte[] and length <= 65535 then sqltype is BLOB <br>
|
||||
* if type==byte[] and length <= 16777215 then sqltype is MEDIUMBLOB <br>
|
||||
* if type==byte[] and length > 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
|
||||
*/
|
||||
|
||||
@@ -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.
|
||||
*
|
||||
|
||||
@@ -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 {}
|
||||
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
|
||||
@@ -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 "";
|
||||
|
||||
}
|
||||
|
||||
@@ -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 {}
|
||||
|
||||
@@ -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[]
|
||||
*/
|
||||
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
|
||||
@@ -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、被标记为@AutoLoad(false)的Service类不会被自动加载, 当被依赖时才会被加载
|
||||
* 2、被标记为@AutoLoad(false)的Servlet类不会被自动加载
|
||||
* 自动加载。 使用场景: 1、被标记为@AutoLoad(false)的Service类不会被自动加载, 当被依赖时才会被加载 2、被标记为@AutoLoad(false)的Servlet类不会被自动加载
|
||||
*
|
||||
* <p>详情见: https://redkale.org
|
||||
*
|
||||
* <p> 详情见: https://redkale.org
|
||||
* @author zhangjx
|
||||
*/
|
||||
@Documented
|
||||
|
||||
@@ -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 {}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 "";
|
||||
|
||||
@@ -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
|
||||
*/
|
||||
|
||||
@@ -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 {}
|
||||
|
||||
@@ -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
|
||||
*/
|
||||
|
||||
@@ -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>
|
||||
* @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
|
||||
*/
|
||||
|
||||
@@ -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
|
||||
*/
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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 {}
|
||||
|
||||
@@ -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 {}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 {}
|
||||
|
||||
@@ -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 {}
|
||||
|
||||
@@ -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;
|
||||
|
||||
/**
|
||||
|
||||
@@ -8,12 +8,11 @@ package org.redkale.annotation;
|
||||
import java.lang.annotation.*;
|
||||
|
||||
/**
|
||||
* @Resource(name = "@") 表示资源name采用所属对象的name <br>
|
||||
* @Resource(name = "#name") 表示资源对象自身的name <br>
|
||||
* @Resource(name = "#type") 表示资源对象自身的类型 <br>
|
||||
* @Resource(name = "@") 表示资源name采用所属对象的name <br>
|
||||
* @Resource(name = "#name") 表示资源对象自身的name <br>
|
||||
* @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;
|
||||
|
||||
}
|
||||
|
||||
@@ -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.*;
|
||||
|
||||
/**
|
||||
* @Resource资源被更新时的监听事件, 本注解只能标记在方法参数为ResourceEvent[]上 <br>
|
||||
* 注意: 一个类只能存在一个@ResourceChanged的方法, 多余的会被忽略 <br>
|
||||
* 方法在资源被更新以后调用。
|
||||
*
|
||||
* <blockquote><pre>
|
||||
* <blockquote>
|
||||
*
|
||||
* <pre>
|
||||
* public class RecordService implements Service {
|
||||
*
|
||||
* @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
|
||||
|
||||
@@ -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.*;
|
||||
|
||||
/**
|
||||
* @Resource资源被依赖注入时的监听事件。<br>
|
||||
* 本注解只能标记在空参数或者(String、Object、java.lang.reflect.Field)三个参数类型的任意组合方法上 <br>
|
||||
* 方法在资源被依赖注入后调用。
|
||||
*
|
||||
* <blockquote><pre>
|
||||
* <blockquote>
|
||||
*
|
||||
* <pre>
|
||||
* public class ResourceService implements Service {
|
||||
*
|
||||
* @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 {}
|
||||
|
||||
@@ -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()的类标记了@ResourceType, 则使用@ResourceType.value()的class值进行注入。
|
||||
*
|
||||
* <p>
|
||||
* 详情见: https://redkale.org
|
||||
*
|
||||
* <p>详情见: https://redkale.org
|
||||
*
|
||||
* @author zhangjx
|
||||
*/
|
||||
|
||||
@@ -1,4 +1,2 @@
|
||||
/**
|
||||
* 提供基础注解包
|
||||
*/
|
||||
/** 提供基础注解包 */
|
||||
package org.redkale.annotation;
|
||||
|
||||
@@ -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: ( <tt>visit</tt> | <tt>visitEnum</tt> |
|
||||
* <tt>visitAnnotation</tt> | <tt>visitArray</tt> )* <tt>visitEnd</tt>.
|
||||
* A visitor to visit a Java annotation. The methods of this class must be called in the following order: (
|
||||
* <tt>visit</tt> | <tt>visitEnum</tt> | <tt>visitAnnotation</tt> |
|
||||
* <tt>visitArray</tt> )* <tt>visitEnd</tt>.
|
||||
*
|
||||
* @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
|
||||
* <tt>null</tt> 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 <tt>null</tt> 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
|
||||
* <tt>null</tt> 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 <tt>null</tt> 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();
|
||||
|
||||
@@ -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;
|
||||
|
||||
/**
|
||||
* <tt>true<tt> if values are named, <tt>false</tt> otherwise. Annotation
|
||||
* writers used for annotation default and annotation arrays use unnamed
|
||||
* values.
|
||||
* <tt>true<tt> if values are named, <tt>false</tt> 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
|
||||
* <tt>true<tt> if values are named, <tt>false</tt> 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 <tt>parent</tt> the number of annotation values must
|
||||
* be stored.
|
||||
* @param cw the class writer to which this annotation must be added.
|
||||
* @param named <tt>true<tt> if values are named, <tt>false</tt> 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 <tt>parent</tt> 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
|
||||
* <tt>null</tt> 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 <tt>null</tt> 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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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 <tt>null</tt>.
|
||||
*/
|
||||
/** The next attribute in this attribute list. May be <tt>null</tt>. */
|
||||
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 <tt>true</tt> if this type of attribute is unknown. The default
|
||||
* implementation of this method always returns <tt>true</tt>.
|
||||
* Returns <tt>true</tt> if this type of attribute is unknown. The default implementation of this
|
||||
* method always returns <tt>true</tt>.
|
||||
*
|
||||
* @return <tt>true</tt> 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 <tt>null</tt> if
|
||||
* this attribute is not a code attribute that contains labels.
|
||||
* @return the labels corresponding to this attribute, or <tt>null</tt> 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 <tt>len</tt> 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 <tt>len</tt> 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 <tt>null</tt> 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 <tt>null</tt> 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 <tt>null</tt> if this attribute is not a code
|
||||
* attributes.
|
||||
* @param len
|
||||
* the length of the bytecode of the method corresponding to this
|
||||
* code attribute, or <tt>null</tt> 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 <tt>null</tt> if
|
||||
* this attribute is not a code attributes.
|
||||
* @param len the length of the bytecode of the method corresponding to this code attribute, or
|
||||
* <tt>null</tt> 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 <tt>null</tt> if these attributes are not code
|
||||
* attributes.
|
||||
* @param len
|
||||
* the length of the bytecode of the method corresponding to
|
||||
* these code attributes, or <tt>null</tt> 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 <tt>null</tt>
|
||||
* if these attributes are not code attributes.
|
||||
* @param len the length of the bytecode of the method corresponding to these code attributes, or
|
||||
* <tt>null</tt> 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 <tt>null</tt> if these attributes are not code
|
||||
* attributes.
|
||||
* @param len
|
||||
* the length of the bytecode of the method corresponding to
|
||||
* these code attributes, or <tt>null</tt> 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 <tt>null</tt>
|
||||
* if these attributes are not code attributes.
|
||||
* @param len the length of the bytecode of the method corresponding to these code attributes, or
|
||||
* <tt>null</tt> 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()};
|
||||
}
|
||||
|
||||
@@ -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 <tt>null</tt> to put <tt>len</tt>
|
||||
* 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 <tt>null</tt> to put <tt>len</tt> 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
@@ -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: <tt>visit</tt> [ <tt>visitSource</tt> ] [
|
||||
* <tt>visitModule</tt> ][ <tt>visitOuterClass</tt> ] ( <tt>visitAnnotation</tt> |
|
||||
* A visitor to visit a Java class. The methods of this class must be called in the following order:
|
||||
* <tt>visit</tt> [ <tt>visitSource</tt> ] [ <tt>visitModule</tt> ][
|
||||
* <tt>visitOuterClass</tt> ] ( <tt>visitAnnotation</tt> |
|
||||
* <tt>visitTypeAnnotation</tt> | <tt>visitAttribute</tt> )* (
|
||||
* <tt>visitInnerClass</tt> | <tt>visitField</tt> | <tt>visitMethod</tt> )*
|
||||
* <tt>visitEnd</tt>.
|
||||
* <tt>visitInnerClass</tt> | <tt>visitField</tt> | <tt>visitMethod</tt>
|
||||
* )* <tt>visitEnd</tt>.
|
||||
*
|
||||
* @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 <tt>null</tt> 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
|
||||
* <tt>null</tt>, but only for the {@link Object} class.
|
||||
* @param interfaces
|
||||
* the internal names of the class's interfaces (see
|
||||
* {@link Type#getInternalName() getInternalName}). May be
|
||||
* <tt>null</tt>.
|
||||
* @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 <tt>null</tt> 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 <tt>null</tt>, but only for the
|
||||
* {@link Object} class.
|
||||
* @param interfaces the internal names of the class's interfaces (see {@link Type#getInternalName()
|
||||
* getInternalName}). May be <tt>null</tt>.
|
||||
*/
|
||||
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 <tt>null</tt>.
|
||||
* @param debug
|
||||
* additional debug information to compute the correspondance
|
||||
* between source and compiled elements of the class. May be
|
||||
* <tt>null</tt>.
|
||||
* @param source the name of the source file from which the class was compiled. May be
|
||||
* <tt>null</tt>.
|
||||
* @param debug additional debug information to compute the correspondance between source and compiled elements of
|
||||
* the class. May be <tt>null</tt>.
|
||||
*/
|
||||
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 <tt>null</tt> 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 <tt>null</tt> 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
|
||||
* <tt>null</tt> 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
|
||||
* <tt>null</tt> 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 <tt>null</tt> 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 <tt>null</tt> 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
|
||||
* <tt>true</tt> if the annotation is visible at runtime.
|
||||
* @return a visitor to visit the annotation values, or <tt>null</tt> if
|
||||
* this visitor is not interested in visiting this annotation.
|
||||
* @param desc the class descriptor of the annotation class.
|
||||
* @param visible <tt>true</tt> if the annotation is visible at runtime.
|
||||
* @return a visitor to visit the annotation values, or <tt>null</tt> 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
|
||||
* <tt>null</tt> if the annotation targets 'typeRef' as a whole.
|
||||
* @param desc
|
||||
* the class descriptor of the annotation class.
|
||||
* @param visible
|
||||
* <tt>true</tt> if the annotation is visible at runtime.
|
||||
* @return a visitor to visit the annotation values, or <tt>null</tt> 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 <tt>null</tt> if the annotation targets 'typeRef' as a whole.
|
||||
* @param desc the class descriptor of the annotation class.
|
||||
* @param visible <tt>true</tt> if the annotation is visible at runtime.
|
||||
* @return a visitor to visit the annotation values, or <tt>null</tt> 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 <tt>null</tt> for not member classes.
|
||||
* @param innerName
|
||||
* the (simple) name of the inner class inside its enclosing
|
||||
* class. May be <tt>null</tt> 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 <tt>null</tt> for not member classes.
|
||||
* @param innerName the (simple) name of the inner class inside its enclosing class. May be
|
||||
* <tt>null</tt> 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 <tt>null</tt> if the field's
|
||||
* type does not use generic types.
|
||||
* @param value
|
||||
* the field's initial value. This parameter, which may be
|
||||
* <tt>null</tt> 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 <tt>int</tt>,
|
||||
* <tt>float</tt>, <tt>long</tt> or <tt>String</tt> 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
|
||||
* <tt>null</tt> 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 <tt>null</tt> if the field's type does not use
|
||||
* generic types.
|
||||
* @param value the field's initial value. This parameter, which may be <tt>null</tt> 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 <tt>int</tt>, <tt>float</tt>,
|
||||
* <tt>long</tt> or <tt>String</tt> 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 <tt>null</tt> 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 <tt>null</tt>) 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
|
||||
* <tt>null</tt>) 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 <tt>null</tt> 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
|
||||
* <tt>null</tt>.
|
||||
* @return an object to visit the byte code of the method, or <tt>null</tt>
|
||||
* 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 <tt>null</tt> 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 <tt>null</tt>.
|
||||
* @return an object to visit the byte code of the method, or <tt>null</tt> 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
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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: ( <tt>visitAnnotation</tt> |
|
||||
* <tt>visitTypeAnnotation</tt> | <tt>visitAttribute</tt> )* <tt>visitEnd</tt>.
|
||||
* A visitor to visit a Java field. The methods of this class must be called in the following order: (
|
||||
* <tt>visitAnnotation</tt> | <tt>visitTypeAnnotation</tt> |
|
||||
* <tt>visitAttribute</tt> )* <tt>visitEnd</tt>.
|
||||
*
|
||||
* @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
|
||||
* <tt>true</tt> if the annotation is visible at runtime.
|
||||
* @return a visitor to visit the annotation values, or <tt>null</tt> if
|
||||
* this visitor is not interested in visiting this annotation.
|
||||
* @param desc the class descriptor of the annotation class.
|
||||
* @param visible <tt>true</tt> if the annotation is visible at runtime.
|
||||
* @return a visitor to visit the annotation values, or <tt>null</tt> 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
|
||||
* <tt>null</tt> if the annotation targets 'typeRef' as a whole.
|
||||
* @param desc
|
||||
* the class descriptor of the annotation class.
|
||||
* @param visible
|
||||
* <tt>true</tt> if the annotation is visible at runtime.
|
||||
* @return a visitor to visit the annotation values, or <tt>null</tt> 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 <tt>null</tt> if the annotation targets 'typeRef' as a whole.
|
||||
* @param desc the class descriptor of the annotation class.
|
||||
* @param visible <tt>true</tt> if the annotation is visible at runtime.
|
||||
* @return a visitor to visit the annotation values, or <tt>null</tt> 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) {
|
||||
|
||||
@@ -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 <tt>null</tt>.
|
||||
*/
|
||||
/** The runtime visible annotations of this field. May be <tt>null</tt>. */
|
||||
private AnnotationWriter anns;
|
||||
|
||||
/**
|
||||
* The runtime invisible annotations of this field. May be <tt>null</tt>.
|
||||
*/
|
||||
/** The runtime invisible annotations of this field. May be <tt>null</tt>. */
|
||||
private AnnotationWriter ianns;
|
||||
|
||||
/**
|
||||
* The runtime visible type annotations of this field. May be <tt>null</tt>.
|
||||
*/
|
||||
/** The runtime visible type annotations of this field. May be <tt>null</tt>. */
|
||||
private AnnotationWriter tanns;
|
||||
|
||||
/**
|
||||
* The runtime invisible type annotations of this field. May be
|
||||
* <tt>null</tt>.
|
||||
*/
|
||||
/** The runtime invisible type annotations of this field. May be <tt>null</tt>. */
|
||||
private AnnotationWriter itanns;
|
||||
|
||||
/**
|
||||
* The non standard attributes of this field. May be <tt>null</tt>.
|
||||
*/
|
||||
/** The non standard attributes of this field. May be <tt>null</tt>. */
|
||||
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 <tt>null</tt>.
|
||||
* @param value
|
||||
* the field's constant value. May be <tt>null</tt>.
|
||||
* @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 <tt>null</tt>.
|
||||
* @param value the field's constant value. May be <tt>null</tt>.
|
||||
*/
|
||||
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
@@ -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" : "") + ')';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
* <tt>null</tt> to catch any exceptions.
|
||||
* Internal name of the type of exceptions handled by this handler, or <tt>null</tt> 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) {
|
||||
|
||||
@@ -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 <tt>true</tt> if the given item if equal to this one,
|
||||
* <tt>false</tt> otherwise.
|
||||
* @param i the item to be compared to this one. Both items must have the same {@link #type}.
|
||||
* @return <tt>true</tt> if the given item if equal to this one, <tt>false</tt>
|
||||
* 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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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
|
||||
* <tt>true</tt> if the reference must be stored in 4 bytes, or
|
||||
* <tt>false</tt> 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 <tt>true</tt> if the reference must be stored in 4 bytes, or
|
||||
* <tt>false</tt> 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 <tt>true</tt> 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 <tt>true</tt> 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
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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: ( <tt>visitParameter</tt> )* [
|
||||
* <tt>visitAnnotationDefault</tt> ] ( <tt>visitAnnotation</tt> |
|
||||
* <tt>visitParameterAnnotation</tt> <tt>visitTypeAnnotation</tt> |
|
||||
* <tt>visitAttribute</tt> )* [ <tt>visitCode</tt> ( <tt>visitFrame</tt> |
|
||||
* <tt>visit<i>X</i>Insn</tt> | <tt>visitLabel</tt> |
|
||||
* <tt>visitInsnAnnotation</tt> | <tt>visitTryCatchBlock</tt> |
|
||||
* <tt>visitTryCatchAnnotation</tt> | <tt>visitLocalVariable</tt> |
|
||||
* <tt>visitLocalVariableAnnotation</tt> | <tt>visitLineNumber</tt> )*
|
||||
* <tt>visitMaxs</tt> ] <tt>visitEnd</tt>. In addition, the
|
||||
* <tt>visit<i>X</i>Insn</tt> and <tt>visitLabel</tt> methods must be called in
|
||||
* the sequential order of the bytecode instructions of the visited code,
|
||||
* <tt>visitInsnAnnotation</tt> must be called <i>after</i> the annotated
|
||||
* instruction, <tt>visitTryCatchBlock</tt> must be called <i>before</i> the
|
||||
* labels passed as arguments have been visited,
|
||||
* <tt>visitTryCatchBlockAnnotation</tt> must be called <i>after</i> the
|
||||
* corresponding try catch block has been visited, and the
|
||||
* <tt>visitLocalVariable</tt>, <tt>visitLocalVariableAnnotation</tt> and
|
||||
* <tt>visitLineNumber</tt> 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: (
|
||||
* <tt>visitParameter</tt> )* [ <tt>visitAnnotationDefault</tt> ] (
|
||||
* <tt>visitAnnotation</tt> | <tt>visitParameterAnnotation</tt>
|
||||
* <tt>visitTypeAnnotation</tt> | <tt>visitAttribute</tt> )* [
|
||||
* <tt>visitCode</tt> ( <tt>visitFrame</tt> | <tt>visit<i>X</i>Insn</tt>
|
||||
* | <tt>visitLabel</tt> | <tt>visitInsnAnnotation</tt> |
|
||||
* <tt>visitTryCatchBlock</tt> | <tt>visitTryCatchAnnotation</tt> |
|
||||
* <tt>visitLocalVariable</tt> | <tt>visitLocalVariableAnnotation</tt> |
|
||||
* <tt>visitLineNumber</tt> )* <tt>visitMaxs</tt> ] <tt>visitEnd</tt>.
|
||||
* In addition, the <tt>visit<i>X</i>Insn</tt> and <tt>visitLabel</tt> methods must be
|
||||
* called in the sequential order of the bytecode instructions of the visited code,
|
||||
* <tt>visitInsnAnnotation</tt> must be called <i>after</i> the annotated instruction,
|
||||
* <tt>visitTryCatchBlock</tt> must be called <i>before</i> the labels passed as arguments have been
|
||||
* visited, <tt>visitTryCatchBlockAnnotation</tt> must be called <i>after</i> the corresponding try
|
||||
* catch block has been visited, and the <tt>visitLocalVariable</tt>,
|
||||
* <tt>visitLocalVariableAnnotation</tt> and <tt>visitLineNumber</tt> 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 <tt>ACC_FINAL</tt>,
|
||||
* <tt>ACC_SYNTHETIC</tt> or/and <tt>ACC_MANDATED</tt> are
|
||||
* allowed (see {@link Opcodes}).
|
||||
* @param name parameter name or null if none is provided.
|
||||
* @param access the parameter's access flags, only <tt>ACC_FINAL</tt>,
|
||||
* <tt>ACC_SYNTHETIC</tt> or/and <tt>ACC_MANDATED</tt> 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 <tt>null</tt> 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
|
||||
* <tt>null</tt> 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
|
||||
* <tt>true</tt> if the annotation is visible at runtime.
|
||||
* @return a visitor to visit the annotation values, or <tt>null</tt> if
|
||||
* this visitor is not interested in visiting this annotation.
|
||||
* @param desc the class descriptor of the annotation class.
|
||||
* @param visible <tt>true</tt> if the annotation is visible at runtime.
|
||||
* @return a visitor to visit the annotation values, or <tt>null</tt> 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
|
||||
* <tt>null</tt> if the annotation targets 'typeRef' as a whole.
|
||||
* @param desc
|
||||
* the class descriptor of the annotation class.
|
||||
* @param visible
|
||||
* <tt>true</tt> if the annotation is visible at runtime.
|
||||
* @return a visitor to visit the annotation values, or <tt>null</tt> 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 <tt>null</tt> if the annotation targets 'typeRef' as a whole.
|
||||
* @param desc the class descriptor of the annotation class.
|
||||
* @param visible <tt>true</tt> if the annotation is visible at runtime.
|
||||
* @return a visitor to visit the annotation values, or <tt>null</tt> 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
|
||||
* <tt>true</tt> if the annotation is visible at runtime.
|
||||
* @return a visitor to visit the annotation values, or <tt>null</tt> 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 <tt>true</tt> if the annotation is visible at runtime.
|
||||
* @return a visitor to visit the annotation values, or <tt>null</tt> 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 <tt>.class</tt> 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
|
||||
* <tt>.class</tt> 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. <tt>labels[i]</tt> is the
|
||||
* beginning of the handler block for the <tt>min + i</tt> 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. <tt>labels[i]</tt> is the beginning of the
|
||||
* handler block for the <tt>min + i</tt> 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. <tt>labels[i]</tt> is the
|
||||
* beginning of the handler block for the <tt>keys[i]</tt> key.
|
||||
* @param dflt beginning of the default handler block.
|
||||
* @param keys the values of the keys.
|
||||
* @param labels beginnings of the handler blocks. <tt>labels[i]</tt> is the beginning of the
|
||||
* handler block for the <tt>keys[i]</tt> 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
|
||||
* <tt>null</tt> if the annotation targets 'typeRef' as a whole.
|
||||
* @param desc
|
||||
* the class descriptor of the annotation class.
|
||||
* @param visible
|
||||
* <tt>true</tt> if the annotation is visible at runtime.
|
||||
* @return a visitor to visit the annotation values, or <tt>null</tt> 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 <tt>null</tt> if the annotation targets 'typeRef' as a whole.
|
||||
* @param desc the class descriptor of the annotation class.
|
||||
* @param visible <tt>true</tt> if the annotation is visible at runtime.
|
||||
* @return a visitor to visit the annotation values, or <tt>null</tt> 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 <tt>null</tt> 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 <tt>null</tt> 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
|
||||
* <tt>null</tt> if the annotation targets 'typeRef' as a whole.
|
||||
* @param desc
|
||||
* the class descriptor of the annotation class.
|
||||
* @param visible
|
||||
* <tt>true</tt> if the annotation is visible at runtime.
|
||||
* @return a visitor to visit the annotation values, or <tt>null</tt> 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 <tt>null</tt> if the annotation targets 'typeRef' as a whole.
|
||||
* @param desc the class descriptor of the annotation class.
|
||||
* @param visible <tt>true</tt> if the annotation is visible at runtime.
|
||||
* @return a visitor to visit the annotation values, or <tt>null</tt> 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
|
||||
* <tt>null</tt> 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 <tt>null</tt> 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
|
||||
* <tt>null</tt> 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
|
||||
* <tt>true</tt> if the annotation is visible at runtime.
|
||||
* @return a visitor to visit the annotation values, or <tt>null</tt> 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 <tt>null</tt> 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 <tt>true</tt> if the annotation is visible at runtime.
|
||||
* @return a visitor to visit the annotation values, or <tt>null</tt> 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 <tt>start</tt> 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 <tt>start</tt> 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
@@ -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: <tt>visitMainClass</tt> | ( <tt>visitPackage</tt> |
|
||||
* A visitor to visit a Java module. The methods of this class must be called in the following order:
|
||||
* <tt>visitMainClass</tt> | ( <tt>visitPackage</tt> |
|
||||
* <tt>visitRequire</tt> | <tt>visitExport</tt> | <tt>visitOpen</tt> |
|
||||
* <tt>visitUse</tt> | <tt>visitProvide</tt> )* <tt>visitEnd</tt>.
|
||||
*
|
||||
* 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
|
||||
* <tt>null</tt>.
|
||||
* @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 <tt>null</tt>.
|
||||
*/
|
||||
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
|
||||
* <tt>null</tt>.
|
||||
* @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 <tt>null</tt>.
|
||||
*/
|
||||
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) {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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 <tt>void</tt> type. See {@link #getSort getSort}.
|
||||
*/
|
||||
/** The sort of the <tt>void</tt> type. See {@link #getSort getSort}. */
|
||||
public static final int VOID = 0;
|
||||
|
||||
/**
|
||||
* The sort of the <tt>boolean</tt> type. See {@link #getSort getSort}.
|
||||
*/
|
||||
/** The sort of the <tt>boolean</tt> type. See {@link #getSort getSort}. */
|
||||
public static final int BOOLEAN = 1;
|
||||
|
||||
/**
|
||||
* The sort of the <tt>char</tt> type. See {@link #getSort getSort}.
|
||||
*/
|
||||
/** The sort of the <tt>char</tt> type. See {@link #getSort getSort}. */
|
||||
public static final int CHAR = 2;
|
||||
|
||||
/**
|
||||
* The sort of the <tt>byte</tt> type. See {@link #getSort getSort}.
|
||||
*/
|
||||
/** The sort of the <tt>byte</tt> type. See {@link #getSort getSort}. */
|
||||
public static final int BYTE = 3;
|
||||
|
||||
/**
|
||||
* The sort of the <tt>short</tt> type. See {@link #getSort getSort}.
|
||||
*/
|
||||
/** The sort of the <tt>short</tt> type. See {@link #getSort getSort}. */
|
||||
public static final int SHORT = 4;
|
||||
|
||||
/**
|
||||
* The sort of the <tt>int</tt> type. See {@link #getSort getSort}.
|
||||
*/
|
||||
/** The sort of the <tt>int</tt> type. See {@link #getSort getSort}. */
|
||||
public static final int INT = 5;
|
||||
|
||||
/**
|
||||
* The sort of the <tt>float</tt> type. See {@link #getSort getSort}.
|
||||
*/
|
||||
/** The sort of the <tt>float</tt> type. See {@link #getSort getSort}. */
|
||||
public static final int FLOAT = 6;
|
||||
|
||||
/**
|
||||
* The sort of the <tt>long</tt> type. See {@link #getSort getSort}.
|
||||
*/
|
||||
/** The sort of the <tt>long</tt> type. See {@link #getSort getSort}. */
|
||||
public static final int LONG = 7;
|
||||
|
||||
/**
|
||||
* The sort of the <tt>double</tt> type. See {@link #getSort getSort}.
|
||||
*/
|
||||
/** The sort of the <tt>double</tt> 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 <tt>void</tt> type.
|
||||
*/
|
||||
public static final Type VOID_TYPE = new Type(VOID, null, ('V' << 24)
|
||||
| (5 << 16) | (0 << 8) | 0, 1);
|
||||
/** The <tt>void</tt> type. */
|
||||
public static final Type VOID_TYPE = new Type(VOID, null, ('V' << 24) | (5 << 16) | (0 << 8) | 0, 1);
|
||||
|
||||
/**
|
||||
* The <tt>boolean</tt> type.
|
||||
*/
|
||||
public static final Type BOOLEAN_TYPE = new Type(BOOLEAN, null, ('Z' << 24)
|
||||
| (0 << 16) | (5 << 8) | 1, 1);
|
||||
/** The <tt>boolean</tt> type. */
|
||||
public static final Type BOOLEAN_TYPE = new Type(BOOLEAN, null, ('Z' << 24) | (0 << 16) | (5 << 8) | 1, 1);
|
||||
|
||||
/**
|
||||
* The <tt>char</tt> type.
|
||||
*/
|
||||
public static final Type CHAR_TYPE = new Type(CHAR, null, ('C' << 24)
|
||||
| (0 << 16) | (6 << 8) | 1, 1);
|
||||
/** The <tt>char</tt> type. */
|
||||
public static final Type CHAR_TYPE = new Type(CHAR, null, ('C' << 24) | (0 << 16) | (6 << 8) | 1, 1);
|
||||
|
||||
/**
|
||||
* The <tt>byte</tt> type.
|
||||
*/
|
||||
public static final Type BYTE_TYPE = new Type(BYTE, null, ('B' << 24)
|
||||
| (0 << 16) | (5 << 8) | 1, 1);
|
||||
/** The <tt>byte</tt> type. */
|
||||
public static final Type BYTE_TYPE = new Type(BYTE, null, ('B' << 24) | (0 << 16) | (5 << 8) | 1, 1);
|
||||
|
||||
/**
|
||||
* The <tt>short</tt> type.
|
||||
*/
|
||||
public static final Type SHORT_TYPE = new Type(SHORT, null, ('S' << 24)
|
||||
| (0 << 16) | (7 << 8) | 1, 1);
|
||||
/** The <tt>short</tt> type. */
|
||||
public static final Type SHORT_TYPE = new Type(SHORT, null, ('S' << 24) | (0 << 16) | (7 << 8) | 1, 1);
|
||||
|
||||
/**
|
||||
* The <tt>int</tt> type.
|
||||
*/
|
||||
public static final Type INT_TYPE = new Type(INT, null, ('I' << 24)
|
||||
| (0 << 16) | (0 << 8) | 1, 1);
|
||||
/** The <tt>int</tt> type. */
|
||||
public static final Type INT_TYPE = new Type(INT, null, ('I' << 24) | (0 << 16) | (0 << 8) | 1, 1);
|
||||
|
||||
/**
|
||||
* The <tt>float</tt> type.
|
||||
*/
|
||||
public static final Type FLOAT_TYPE = new Type(FLOAT, null, ('F' << 24)
|
||||
| (2 << 16) | (2 << 8) | 1, 1);
|
||||
/** The <tt>float</tt> type. */
|
||||
public static final Type FLOAT_TYPE = new Type(FLOAT, null, ('F' << 24) | (2 << 16) | (2 << 8) | 1, 1);
|
||||
|
||||
/**
|
||||
* The <tt>long</tt> type.
|
||||
*/
|
||||
public static final Type LONG_TYPE = new Type(LONG, null, ('J' << 24)
|
||||
| (1 << 16) | (1 << 8) | 2, 1);
|
||||
/** The <tt>long</tt> type. */
|
||||
public static final Type LONG_TYPE = new Type(LONG, null, ('J' << 24) | (1 << 16) | (1 << 8) | 2, 1);
|
||||
|
||||
/**
|
||||
* The <tt>double</tt> type.
|
||||
*/
|
||||
public static final Type DOUBLE_TYPE = new Type(DOUBLE, null, ('D' << 24)
|
||||
| (3 << 16) | (3 << 8) | 2, 1);
|
||||
/** The <tt>double</tt> 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 =
|
||||
* <tt>(argSize << 2) | retSize</tt> (argSize is therefore equal to
|
||||
* <tt>i >> 2</tt>, and retSize to <tt>i & 0x03</tt>).
|
||||
* @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 = <tt>(argSize << 2) |
|
||||
* retSize</tt> (argSize is therefore equal to <tt>i >> 2</tt>, and retSize to
|
||||
* <tt>i & 0x03</tt>).
|
||||
*/
|
||||
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 = <tt>(argSize << 2) | retSize</tt>
|
||||
* (argSize is therefore equal to <tt>i >> 2</tt>,
|
||||
* and retSize to <tt>i & 0x03</tt>).
|
||||
* @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 = <tt>(argSize << 2) | retSize</tt> (argSize
|
||||
* is therefore equal to <tt>i >> 2</tt>, and retSize to <tt>i &
|
||||
* 0x03</tt>).
|
||||
*/
|
||||
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 <tt>long</tt> and
|
||||
* <tt>double</tt>, 0 for <tt>void</tt> and 1 otherwise.
|
||||
* <tt>double</tt>, 0 for <tt>void</tt> 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 <tt>float</tt> and
|
||||
* <tt>opcode</tt> 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 <tt>float</tt> and <tt>opcode</tt> 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 <tt>true</tt> if the given object is equal to this type.
|
||||
*/
|
||||
@Override
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -1,4 +1,2 @@
|
||||
/**
|
||||
* 本包下所有代码均是从/java.base/jdk/internal/org/objectweb/asm 拷贝过来的
|
||||
*/
|
||||
/** 本包下所有代码均是从/java.base/jdk/internal/org/objectweb/asm 拷贝过来的 */
|
||||
package org.redkale.asm;
|
||||
|
||||
@@ -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);
|
||||
|
||||
}
|
||||
|
||||
@@ -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
@@ -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) {}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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) { // 不会发生
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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.");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -10,8 +10,7 @@ import java.lang.annotation.*;
|
||||
/**
|
||||
* 根据application.xml中的server节点中的protocol值来适配Server的加载逻辑, 只能注解在NodeServer子类上
|
||||
*
|
||||
* <p>
|
||||
* 详情见: https://redkale.org
|
||||
* <p>详情见: https://redkale.org
|
||||
*
|
||||
* @author zhangjx
|
||||
*/
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -1,4 +1,2 @@
|
||||
/**
|
||||
* 提供Redkale服务器的启动、初始化和加载功能
|
||||
*/
|
||||
/** 提供Redkale服务器的启动、初始化和加载功能 */
|
||||
package org.redkale.boot;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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 + ")");
|
||||
}
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,2 @@
|
||||
/**
|
||||
* 提供系统默认监控包
|
||||
*/
|
||||
/** 提供系统默认监控包 */
|
||||
package org.redkale.boot.watch;
|
||||
|
||||
520
src/main/java/org/redkale/cache/CacheManager.java
vendored
520
src/main/java/org/redkale/cache/CacheManager.java
vendored
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
17
src/main/java/org/redkale/cache/Cached.java
vendored
17
src/main/java/org/redkale/cache/Cached.java
vendored
@@ -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<Void>
|
||||
* 2、方法返回类型必须可json序列化
|
||||
* 3、方法必须是protected/public
|
||||
* 4、方法不能是final/static
|
||||
* 1、方法返回类型不能是void/CompletableFuture<Void> 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 过期时长
|
||||
*/
|
||||
|
||||
@@ -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
|
||||
+ "}";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -7,15 +7,11 @@ import org.redkale.cache.CacheManager;
|
||||
import org.redkale.util.InstanceProvider;
|
||||
|
||||
/**
|
||||
*
|
||||
* 自定义的CacheManager加载器, 如果标记@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> {}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
Reference in New Issue
Block a user