This commit is contained in:
redkale
2024-05-27 12:19:58 +08:00
parent 4d1eaa9766
commit 5079560037
356 changed files with 81489 additions and 81489 deletions

View File

@@ -1,147 +1,147 @@
/**
* ***************************************************************************** Copyright (c) 2008 - 2013 Oracle
* Corporation. All rights reserved.
*
* <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.
*
* <p>Contributors: Linda DeMichiel - Java Persistence 2.1 Linda DeMichiel - Java Persistence 2.0
*
* <p>****************************************************************************
*/
package javax.persistence;
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.
*
* <blockquote>
*
* <pre>
* Example 1:
*
* &#064;Column(name="DESC", nullable=false, length=512)
* public String getDescription() { return description; }
*
* Example 2:
*
* &#064;Column(name="DESC",
* columnDefinition="CLOB NOT NULL",
* table="EMP_DETAIL")
* &#064;Lob
* public String getDescription() { return description; }
*
* Example 3:
*
* &#064;Column(name="ORDER_COST", updatable=false, precision=12, scale=2)
* public BigDecimal getCost() { return cost; }
*
* </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")
@Target({METHOD, FIELD})
@Retention(RUNTIME)
public @interface Column {
/**
* (Optional) The name of the column. Defaults to the property or field name.
*
* @return String
*/
String name() default "";
/**
* (Optional) The comment of the column.
*
* @return String
*/
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.
*
* @return boolean
*/
boolean unique() default false;
/**
* (Optional) Whether the database column is required.
*
* @return boolean
*/
boolean nullable() default true;
/**
* for OpenAPI Specification 3
*
* @return String
*/
String example() default "";
/**
* (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.
*
* @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.
*
* @return String
*/
@Deprecated
String table() default "";
/**
* (Optional) The column length. (Applies only if a string-valued column is used.) if type==String and length ==
* 65535 then sqltype is TEXT <br>
* if type==String and length &#60;= 16777215 then sqltype is MEDIUMTEXT <br>
* if type==String and length &#62; 16777215 then sqltype is LONGTEXT <br>
* if type==byte[] and length &#60;= 65535 then sqltype is BLOB <br>
* if type==byte[] and length &#60;= 16777215 then sqltype is MEDIUMBLOB <br>
* if type==byte[] and length &#62; 16777215 then sqltype is LONGBLOB <br>
*
* @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.
*
* @return int
*/
int precision() default 0;
/**
* (Optional) The scale for a decimal (exact numeric) column. (Applies only if a decimal column is used.)
*
* @return int
*/
int scale() default 0;
}
/**
* ***************************************************************************** Copyright (c) 2008 - 2013 Oracle
* Corporation. All rights reserved.
*
* <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.
*
* <p>Contributors: Linda DeMichiel - Java Persistence 2.1 Linda DeMichiel - Java Persistence 2.0
*
* <p>****************************************************************************
*/
package javax.persistence;
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.
*
* <blockquote>
*
* <pre>
* Example 1:
*
* &#064;Column(name="DESC", nullable=false, length=512)
* public String getDescription() { return description; }
*
* Example 2:
*
* &#064;Column(name="DESC",
* columnDefinition="CLOB NOT NULL",
* table="EMP_DETAIL")
* &#064;Lob
* public String getDescription() { return description; }
*
* Example 3:
*
* &#064;Column(name="ORDER_COST", updatable=false, precision=12, scale=2)
* public BigDecimal getCost() { return cost; }
*
* </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")
@Target({METHOD, FIELD})
@Retention(RUNTIME)
public @interface Column {
/**
* (Optional) The name of the column. Defaults to the property or field name.
*
* @return String
*/
String name() default "";
/**
* (Optional) The comment of the column.
*
* @return String
*/
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.
*
* @return boolean
*/
boolean unique() default false;
/**
* (Optional) Whether the database column is required.
*
* @return boolean
*/
boolean nullable() default true;
/**
* for OpenAPI Specification 3
*
* @return String
*/
String example() default "";
/**
* (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.
*
* @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.
*
* @return String
*/
@Deprecated
String table() default "";
/**
* (Optional) The column length. (Applies only if a string-valued column is used.) if type==String and length ==
* 65535 then sqltype is TEXT <br>
* if type==String and length &#60;= 16777215 then sqltype is MEDIUMTEXT <br>
* if type==String and length &#62; 16777215 then sqltype is LONGTEXT <br>
* if type==byte[] and length &#60;= 65535 then sqltype is BLOB <br>
* if type==byte[] and length &#60;= 16777215 then sqltype is MEDIUMBLOB <br>
* if type==byte[] and length &#62; 16777215 then sqltype is LONGBLOB <br>
*
* @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.
*
* @return int
*/
int precision() default 0;
/**
* (Optional) The scale for a decimal (exact numeric) column. (Applies only if a decimal column is used.)
*
* @return int
*/
int scale() default 0;
}

View File

@@ -1,49 +1,49 @@
/**
* ***************************************************************************** Copyright (c) 2008 - 2013 Oracle
* Corporation. All rights reserved.
*
* <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.
*
* <p>Contributors: Linda DeMichiel - Java Persistence 2.1 Linda DeMichiel - Java Persistence 2.0
*
* <p>****************************************************************************
*/
package javax.persistence;
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.
*
* @since Java Persistence 1.0
* @deprecated replace by {@link org.redkale.persistence.Entity}
* @see org.redkale.persistence.Entity
*/
@Deprecated(since = "2.8.0")
@Inherited
@Documented
@Target(TYPE)
@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.
*
* @return String
*/
String name() default "";
/**
* (Optional) The comment of the entity.
*
* @return String
*/
String comment() default "";
}
/**
* ***************************************************************************** Copyright (c) 2008 - 2013 Oracle
* Corporation. All rights reserved.
*
* <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.
*
* <p>Contributors: Linda DeMichiel - Java Persistence 2.1 Linda DeMichiel - Java Persistence 2.0
*
* <p>****************************************************************************
*/
package javax.persistence;
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.
*
* @since Java Persistence 1.0
* @deprecated replace by {@link org.redkale.persistence.Entity}
* @see org.redkale.persistence.Entity
*/
@Deprecated(since = "2.8.0")
@Inherited
@Documented
@Target(TYPE)
@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.
*
* @return String
*/
String name() default "";
/**
* (Optional) The comment of the entity.
*
* @return String
*/
String comment() default "";
}

View File

@@ -1,46 +1,46 @@
/**
* ***************************************************************************** Copyright (c) 2008 - 2013 Oracle
* Corporation. All rights reserved.
*
* <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.
*
* <p>Contributors: Linda DeMichiel - Java Persistence 2.1 Linda DeMichiel - Java Persistence 2.0
*
* <p>****************************************************************************
*/
package javax.persistence;
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>.
*
* <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:
*
* &#064;Id
* public Long getId() { return id; }
* </pre>
*
* @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 {}
/**
* ***************************************************************************** Copyright (c) 2008 - 2013 Oracle
* Corporation. All rights reserved.
*
* <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.
*
* <p>Contributors: Linda DeMichiel - Java Persistence 2.1 Linda DeMichiel - Java Persistence 2.0
*
* <p>****************************************************************************
*/
package javax.persistence;
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>.
*
* <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:
*
* &#064;Id
* public Long getId() { return id; }
* </pre>
*
* @see Column see GeneratedValue
* @since Java Persistence 1.0
* @deprecated replace by {@link org.redkale.persistence.Id}
* @see org.redkale.persistence.Id
*/
@Deprecated(since = "2.8.0")
@Target({METHOD, FIELD})
@Retention(RUNTIME)
public @interface Id {}

View File

@@ -1,64 +1,64 @@
/**
* ***************************************************************************** Copyright (c) 2011 - 2013 Oracle
* Corporation. All rights reserved.
*
* <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.
*
* <p>Contributors: Linda DeMichiel - Java Persistence 2.1
*
* <p>****************************************************************************
*/
package javax.persistence;
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:
*
* <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.
*
* @since Java Persistence 2.1
* @deprecated replace by {@link org.redkale.persistence.Index}
* @see org.redkale.persistence.Index
*/
@Deprecated(since = "2.8.0")
@Target({})
@Retention(RUNTIME)
public @interface Index {
/**
* (Optional) The name of the index; defaults to a provider-generated name.
*
* @return String
*/
String name() default "";
/**
* (Required) The names of the columns to be included in the index, in order.
*
* @return String
*/
String columnList();
/**
* (Optional) Whether the index is unique.
*
* @return boolean
*/
boolean unique() default false;
}
/**
* ***************************************************************************** Copyright (c) 2011 - 2013 Oracle
* Corporation. All rights reserved.
*
* <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.
*
* <p>Contributors: Linda DeMichiel - Java Persistence 2.1
*
* <p>****************************************************************************
*/
package javax.persistence;
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:
*
* <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.
*
* @since Java Persistence 2.1
* @deprecated replace by {@link org.redkale.persistence.Index}
* @see org.redkale.persistence.Index
*/
@Deprecated(since = "2.8.0")
@Target({})
@Retention(RUNTIME)
public @interface Index {
/**
* (Optional) The name of the index; defaults to a provider-generated name.
*
* @return String
*/
String name() default "";
/**
* (Required) The names of the columns to be included in the index, in order.
*
* @return String
*/
String columnList();
/**
* (Optional) Whether the index is unique.
*
* @return boolean
*/
boolean unique() default false;
}

View File

@@ -1,88 +1,88 @@
/**
* ***************************************************************************** Copyright (c) 2008 - 2013 Oracle
* Corporation. All rights reserved.
*
* <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.
*
* <p>Contributors: Linda DeMichiel - Java Persistence 2.1 Linda DeMichiel - Java Persistence 2.0
*
* <p>****************************************************************************
*/
package javax.persistence;
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.
*
* <p>If no <code>Table</code> annotation is specified for an entity class, the default values apply.
*
* <pre>
* Example:
*
* &#064;Entity
* &#064;Table(name="CUST", schema="RECORDS")
* public class Customer { ... }
* </pre>
*
* @since Java Persistence 1.0
* @deprecated replace by {@link org.redkale.persistence.Table}
* @see org.redkale.persistence.Table
*/
@Deprecated(since = "2.8.0")
@Target(TYPE)
@Retention(RUNTIME)
public @interface Table {
/**
* (Optional) The name of the table.
*
* <p>Defaults to the entity name.
*
* @return String
*/
String name() default "";
/**
* (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.
*
* @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.
*
* @return indexes
* @since Java Persistence 2.1
*/
Index[] indexes() default {};
/**
* comment
*
* @return String
*/
String comment() default "";
}
/**
* ***************************************************************************** Copyright (c) 2008 - 2013 Oracle
* Corporation. All rights reserved.
*
* <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.
*
* <p>Contributors: Linda DeMichiel - Java Persistence 2.1 Linda DeMichiel - Java Persistence 2.0
*
* <p>****************************************************************************
*/
package javax.persistence;
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.
*
* <p>If no <code>Table</code> annotation is specified for an entity class, the default values apply.
*
* <pre>
* Example:
*
* &#064;Entity
* &#064;Table(name="CUST", schema="RECORDS")
* public class Customer { ... }
* </pre>
*
* @since Java Persistence 1.0
* @deprecated replace by {@link org.redkale.persistence.Table}
* @see org.redkale.persistence.Table
*/
@Deprecated(since = "2.8.0")
@Target(TYPE)
@Retention(RUNTIME)
public @interface Table {
/**
* (Optional) The name of the table.
*
* <p>Defaults to the entity name.
*
* @return String
*/
String name() default "";
/**
* (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.
*
* @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.
*
* @return indexes
* @since Java Persistence 2.1
*/
Index[] indexes() default {};
/**
* comment
*
* @return String
*/
String comment() default "";
}

View File

@@ -1,43 +1,43 @@
/**
* ***************************************************************************** Copyright (c) 2008 - 2013 Oracle
* Corporation. All rights reserved.
*
* <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.
*
* <p>Contributors: Linda DeMichiel - Java Persistence 2.1 Linda DeMichiel - Java Persistence 2.0
*
* <p>****************************************************************************
*/
package javax.persistence;
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.
*
* <pre>
* Example:
*
* &#064;Entity
* public class Employee {
* &#064;Id int id;
* &#064;Transient User currentUser;
* ...
* }
* </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 {}
/**
* ***************************************************************************** Copyright (c) 2008 - 2013 Oracle
* Corporation. All rights reserved.
*
* <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.
*
* <p>Contributors: Linda DeMichiel - Java Persistence 2.1 Linda DeMichiel - Java Persistence 2.0
*
* <p>****************************************************************************
*/
package javax.persistence;
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.
*
* <pre>
* Example:
*
* &#064;Entity
* public class Employee {
* &#064;Id int id;
* &#064;Transient User currentUser;
* ...
* }
* </pre>
*
* @since Java Persistence 1.0
* @deprecated replace by {@link org.redkale.persistence.Transient}
* @see org.redkale.persistence.Transient
*/
@Deprecated(since = "2.8.0")
@Target({METHOD, FIELD})
@Retention(RUNTIME)
public @interface Transient {}

View File

@@ -1,57 +1,57 @@
/**
* ***************************************************************************** Copyright (c) 2008 - 2013 Oracle
* Corporation. All rights reserved.
*
* <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.
*
* <p>Contributors: Linda DeMichiel - Java Persistence 2.1 Linda DeMichiel - Java Persistence 2.0
*
* <p>****************************************************************************
*/
package javax.persistence;
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.
*
* <pre>
* Example:
* &#064;Entity
* &#064;Table(
* name="EMPLOYEE",
* uniqueConstraints=
* &#064;UniqueConstraint(columnNames={"EMP_ID", "EMP_NAME"})
* )
* public class Employee { ... }
* </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.
*
* @return String
* @since Java Persistence 2.0
*/
String name() default "";
/**
* (Required) An array of the column names that make up the constraint.
*
* @return String[]
*/
String[] columnNames();
}
/**
* ***************************************************************************** Copyright (c) 2008 - 2013 Oracle
* Corporation. All rights reserved.
*
* <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.
*
* <p>Contributors: Linda DeMichiel - Java Persistence 2.1 Linda DeMichiel - Java Persistence 2.0
*
* <p>****************************************************************************
*/
package javax.persistence;
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.
*
* <pre>
* Example:
* &#064;Entity
* &#064;Table(
* name="EMPLOYEE",
* uniqueConstraints=
* &#064;UniqueConstraint(columnNames={"EMP_ID", "EMP_NAME"})
* )
* public class Employee { ... }
* </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.
*
* @return String
* @since Java Persistence 2.0
*/
String name() default "";
/**
* (Required) An array of the column names that make up the constraint.
*
* @return String[]
*/
String[] columnNames();
}

View File

@@ -1,54 +1,54 @@
/**
* see: https://redkale.org
*
* @author zhangjx
*/
module org.redkale {
requires java.base;
requires java.logging;
requires java.net.http;
requires java.sql;
requires jdk.unsupported; // sun.misc.Unsafe
exports org.redkale.annotation;
exports org.redkale.boot;
exports org.redkale.boot.watch;
exports org.redkale.cache;
exports org.redkale.cache.spi;
exports org.redkale.cluster;
exports org.redkale.cluster.spi;
exports org.redkale.convert;
exports org.redkale.convert.bson;
exports org.redkale.convert.ext;
exports org.redkale.convert.json;
exports org.redkale.convert.proto;
exports org.redkale.convert.spi;
exports org.redkale.inject;
exports org.redkale.lock;
exports org.redkale.lock.spi;
exports org.redkale.mq;
exports org.redkale.mq.spi;
exports org.redkale.net;
exports org.redkale.net.client;
exports org.redkale.net.http;
exports org.redkale.net.sncp;
exports org.redkale.persistence;
exports org.redkale.props.spi;
exports org.redkale.schedule;
exports org.redkale.schedule.spi;
exports org.redkale.service;
exports org.redkale.source;
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;
uses org.redkale.convert.spi.ConvertProvider;
uses org.redkale.mq.spi.MessageAgentProvider;
uses org.redkale.schedule.spi.ScheduleManagerProvider;
uses org.redkale.source.spi.CacheSourceProvider;
uses org.redkale.source.spi.DataSourceProvider;
uses org.redkale.source.spi.DataNativeSqlParserProvider;
}
/**
* see: https://redkale.org
*
* @author zhangjx
*/
module org.redkale {
requires java.base;
requires java.logging;
requires java.net.http;
requires java.sql;
requires jdk.unsupported; // sun.misc.Unsafe
exports org.redkale.annotation;
exports org.redkale.boot;
exports org.redkale.boot.watch;
exports org.redkale.cache;
exports org.redkale.cache.spi;
exports org.redkale.cluster;
exports org.redkale.cluster.spi;
exports org.redkale.convert;
exports org.redkale.convert.bson;
exports org.redkale.convert.ext;
exports org.redkale.convert.json;
exports org.redkale.convert.proto;
exports org.redkale.convert.spi;
exports org.redkale.inject;
exports org.redkale.lock;
exports org.redkale.lock.spi;
exports org.redkale.mq;
exports org.redkale.mq.spi;
exports org.redkale.net;
exports org.redkale.net.client;
exports org.redkale.net.http;
exports org.redkale.net.sncp;
exports org.redkale.persistence;
exports org.redkale.props.spi;
exports org.redkale.schedule;
exports org.redkale.schedule.spi;
exports org.redkale.service;
exports org.redkale.source;
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;
uses org.redkale.convert.spi.ConvertProvider;
uses org.redkale.mq.spi.MessageAgentProvider;
uses org.redkale.schedule.spi.ScheduleManagerProvider;
uses org.redkale.source.spi.CacheSourceProvider;
uses org.redkale.source.spi.DataSourceProvider;
uses org.redkale.source.spi.DataNativeSqlParserProvider;
}

View File

@@ -1,25 +1,25 @@
/*
*
*/
package org.redkale.annotation;
import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.*;
import java.lang.annotation.*;
/**
* 被标记的元素表示会被动态字节码调用
*
* <p>详情见: https://redkale.org
*
* @author zhangjx
* @since 2.8.0
*/
@Documented
@Target({TYPE, METHOD, FIELD})
@Retention(SOURCE)
public @interface ClassDepends {
Class[] value() default {};
}
/*
*
*/
package org.redkale.annotation;
import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.*;
import java.lang.annotation.*;
/**
* 被标记的元素表示会被动态字节码调用
*
* <p>详情见: https://redkale.org
*
* @author zhangjx
* @since 2.8.0
*/
@Documented
@Target({TYPE, METHOD, FIELD})
@Retention(SOURCE)
public @interface ClassDepends {
Class[] value() default {};
}

View File

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

View File

@@ -1,25 +1,25 @@
/*
*
*/
package org.redkale.annotation;
import java.lang.annotation.*;
/**
* 非阻塞模式标记, 标记在Service类和方法、Filter类、HttpServlet类上 <br>
* 一般情况下,没有显注此注解的方法视为阻塞时, 以下两种情况除外: <br>
* 1、返回类型是CompletionStage <br>
* 2、返回类型是void且参数存在CompletionHandler类型 <br>
* 阻塞模式的方法会在work线程池中运行 非阻塞在IO线程中运行。
*
* <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
boolean value() default true;
}
/*
*
*/
package org.redkale.annotation;
import java.lang.annotation.*;
/**
* 非阻塞模式标记, 标记在Service类和方法、Filter类、HttpServlet类上 <br>
* 一般情况下,没有显注此注解的方法视为阻塞时, 以下两种情况除外: <br>
* 1、返回类型是CompletionStage <br>
* 2、返回类型是void且参数存在CompletionHandler类型 <br>
* 阻塞模式的方法会在work线程池中运行 非阻塞在IO线程中运行。
*
* <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
boolean value() default true;
}

View File

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

View File

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

View File

@@ -1,29 +1,29 @@
/*
*
*/
package org.redkale.annotation;
import static java.lang.annotation.ElementType.PARAMETER;
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
*
* @author zhangjx
* @since 2.8.0
*/
@Documented
@Target({PARAMETER})
@Retention(RUNTIME)
public @interface Param {
String value();
String comment() default "";
}
/*
*
*/
package org.redkale.annotation;
import static java.lang.annotation.ElementType.PARAMETER;
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
*
* @author zhangjx
* @since 2.8.0
*/
@Documented
@Target({PARAMETER})
@Retention(RUNTIME)
public @interface Param {
String value();
String comment() default "";
}

View File

@@ -1,20 +1,20 @@
/*
*
*/
package org.redkale.annotation;
import static java.lang.annotation.ElementType.*;
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 {}
/*
*
*/
package org.redkale.annotation;
import static java.lang.annotation.ElementType.*;
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 {}

View File

@@ -1,18 +1,18 @@
/*
*
*/
package org.redkale.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 {}
/*
*
*/
package org.redkale.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 {}

View File

@@ -1,65 +1,65 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package org.redkale.annotation;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.*;
/**
* &#64;Resource资源被依赖注入时的监听事件。<br>
* 本注解只能标记在空参数或者(String、Object、java.lang.reflect.Field)三个参数类型的任意组合方法上 <br>
* 方法在资源被依赖注入后调用。
*
* <blockquote>
*
* <pre>
* public class ResourceService implements Service {
*
* &#64;Resource(name = "res.id")
* private int id;
*
* &#64;Resource(name = "res.name")
* private String name;
*
* &#64;ResourceInjected
* private void onInjected(Object src, String fieldName) {
* System.out .println("资源被注入到对象(" + src + ")的字段(" + fieldName + ")上");
* }
* }
*
* public class RecordService implements Service {
*
* &#64;Resource
* private ResourceService resService;
*
* public void test() {
* }
*
* public static void main(String[] args) throws Exception {
* ResourceFactory factory = ResourceFactory.create();
* factory.register("res.id", "2345");
* factory.register("res.name", "my old name");
* ResourceService res = new ResourceService();
* factory.inject(res);
* factory.register("", res);
* RecordService serice = new RecordService();
* factory.inject(record);
* }
* }
* </pre>
*
* </blockquote>
*
* <p>详情见: https://redkale.org
*
* @author zhangjx
*/
@Documented
@Target({METHOD})
@Retention(RUNTIME)
public @interface ResourceInjected {}
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package org.redkale.annotation;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.*;
/**
* &#64;Resource资源被依赖注入时的监听事件。<br>
* 本注解只能标记在空参数或者(String、Object、java.lang.reflect.Field)三个参数类型的任意组合方法上 <br>
* 方法在资源被依赖注入后调用。
*
* <blockquote>
*
* <pre>
* public class ResourceService implements Service {
*
* &#64;Resource(name = "res.id")
* private int id;
*
* &#64;Resource(name = "res.name")
* private String name;
*
* &#64;ResourceInjected
* private void onInjected(Object src, String fieldName) {
* System.out .println("资源被注入到对象(" + src + ")的字段(" + fieldName + ")上");
* }
* }
*
* public class RecordService implements Service {
*
* &#64;Resource
* private ResourceService resService;
*
* public void test() {
* }
*
* public static void main(String[] args) throws Exception {
* ResourceFactory factory = ResourceFactory.create();
* factory.register("res.id", "2345");
* factory.register("res.name", "my old name");
* ResourceService res = new ResourceService();
* factory.inject(res);
* factory.register("", res);
* RecordService serice = new RecordService();
* factory.inject(record);
* }
* }
* </pre>
*
* </blockquote>
*
* <p>详情见: https://redkale.org
*
* @author zhangjx
*/
@Documented
@Target({METHOD})
@Retention(RUNTIME)
public @interface ResourceInjected {}

View File

@@ -1,170 +1,170 @@
/*
* ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*/
/*
*
*
*
*
*
* ASM: a very small and fast Java bytecode manipulation framework
* Copyright (c) 2000-2011 INRIA, France Telecom
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.redkale.asm;
/**
* A visitor to visit a Java annotation. The methods of this class must be called in the following order: (
* &#60;tt&#62;visit&#60;/tt&#62; | &#60;tt&#62;visitEnum&#60;/tt&#62; | &#60;tt&#62;visitAnnotation&#60;/tt&#62; |
* &#60;tt&#62;visitArray&#60;/tt&#62; )* &#60;tt&#62;visitEnd&#60;/tt&#62;.
*
* @author Eric Bruneton
* @author Eugene Kuleshov
*/
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}.
*/
protected final int api;
/** 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}.
*/
public AnnotationVisitor(final int api) {
this(api, null);
}
/**
* 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.
*/
public AnnotationVisitor(final int api, final AnnotationVisitor av) {
this.api = api;
this.av = av;
}
/**
* 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).
*/
public void visit(String name, Object value) {
if (av != null) {
av.visit(name, value);
}
}
/**
* 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.
*/
public void visitEnum(String name, String desc, String value) {
if (av != null) {
av.visitEnum(name, desc, value);
}
}
/**
* Visits a nested annotation value of the annotation.
*
* @param name the value name.
* @param desc the class descriptor of the nested annotation class.
* @return a visitor to visit the actual nested annotation value, or &#60;tt&#62;null&#60;/tt&#62; if this visitor
* is not interested in visiting this nested annotation. <i>The nested annotation value must be fully visited
* before calling other methods on this annotation visitor</i>.
*/
public AnnotationVisitor visitAnnotation(String name, String desc) {
if (av != null) {
return av.visitAnnotation(name, desc);
}
return null;
}
/**
* Visits an array value of the annotation. Note that arrays of primitive types (such as byte, boolean, short, char,
* int, long, float or double) can be passed as value to {@link #visit visit}. This is what {@link ClassReader}
* does.
*
* @param name the value name.
* @return a visitor to visit the actual array value elements, or &#60;tt&#62;null&#60;/tt&#62; if this visitor is
* not interested in visiting these values. The 'name' parameters passed to the methods of this visitor are
* ignored. <i>All the array values must be visited before calling other methods on this annotation visitor</i>.
*/
public AnnotationVisitor visitArray(String name) {
if (av != null) {
return av.visitArray(name);
}
return null;
}
/** Visits the end of the annotation. */
public void visitEnd() {
if (av != null) {
av.visitEnd();
}
}
}
/*
* ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*/
/*
*
*
*
*
*
* ASM: a very small and fast Java bytecode manipulation framework
* Copyright (c) 2000-2011 INRIA, France Telecom
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.redkale.asm;
/**
* A visitor to visit a Java annotation. The methods of this class must be called in the following order: (
* &#60;tt&#62;visit&#60;/tt&#62; | &#60;tt&#62;visitEnum&#60;/tt&#62; | &#60;tt&#62;visitAnnotation&#60;/tt&#62; |
* &#60;tt&#62;visitArray&#60;/tt&#62; )* &#60;tt&#62;visitEnd&#60;/tt&#62;.
*
* @author Eric Bruneton
* @author Eugene Kuleshov
*/
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}.
*/
protected final int api;
/** 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}.
*/
public AnnotationVisitor(final int api) {
this(api, null);
}
/**
* 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.
*/
public AnnotationVisitor(final int api, final AnnotationVisitor av) {
this.api = api;
this.av = av;
}
/**
* 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).
*/
public void visit(String name, Object value) {
if (av != null) {
av.visit(name, value);
}
}
/**
* 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.
*/
public void visitEnum(String name, String desc, String value) {
if (av != null) {
av.visitEnum(name, desc, value);
}
}
/**
* Visits a nested annotation value of the annotation.
*
* @param name the value name.
* @param desc the class descriptor of the nested annotation class.
* @return a visitor to visit the actual nested annotation value, or &#60;tt&#62;null&#60;/tt&#62; if this visitor
* is not interested in visiting this nested annotation. <i>The nested annotation value must be fully visited
* before calling other methods on this annotation visitor</i>.
*/
public AnnotationVisitor visitAnnotation(String name, String desc) {
if (av != null) {
return av.visitAnnotation(name, desc);
}
return null;
}
/**
* Visits an array value of the annotation. Note that arrays of primitive types (such as byte, boolean, short, char,
* int, long, float or double) can be passed as value to {@link #visit visit}. This is what {@link ClassReader}
* does.
*
* @param name the value name.
* @return a visitor to visit the actual array value elements, or &#60;tt&#62;null&#60;/tt&#62; if this visitor is
* not interested in visiting these values. The 'name' parameters passed to the methods of this visitor are
* ignored. <i>All the array values must be visited before calling other methods on this annotation visitor</i>.
*/
public AnnotationVisitor visitArray(String name) {
if (av != null) {
return av.visitArray(name);
}
return null;
}
/** Visits the end of the annotation. */
public void visitEnd() {
if (av != null) {
av.visitEnd();
}
}
}

View File

@@ -1,366 +1,366 @@
/*
* ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*/
/*
*
*
*
*
*
* ASM: a very small and fast Java bytecode manipulation framework
* Copyright (c) 2000-2011 INRIA, France Telecom
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.redkale.asm;
/**
* An {@link AnnotationVisitor} that generates annotations in bytecode form.
*
* @author Eric Bruneton
* @author Eugene Kuleshov
*/
final class AnnotationWriter extends AnnotationVisitor {
/** The class writer to which this annotation must be added. */
private final ClassWriter cw;
/** The number of values in this annotation. */
private int size;
/**
* &#60;tt&#62;true&#60;tt&#62; if values are named, &#60;tt&#62;false&#60;/tt&#62; otherwise. Annotation writers
* used for annotation default and annotation arrays use unnamed values.
*/
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.
*/
private final ByteVector 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}. */
private final int offset;
/** Next annotation writer. This field is used to store annotation lists. */
AnnotationWriter next;
/** Previous annotation writer. This field is used to store annotation lists. */
AnnotationWriter prev;
// ------------------------------------------------------------------------
// Constructor
// ------------------------------------------------------------------------
/**
* Constructs a new {@link AnnotationWriter}.
*
* @param cw the class writer to which this annotation must be added.
* @param named &#60;tt&#62;true&#60;tt&#62; if values are named, &#60;tt&#62;false&#60;/tt&#62; otherwise.
* @param bv where the annotation values must be stored.
* @param parent where the number of annotation values must be stored.
* @param offset where in &#60;tt&#62;parent&#60;/tt&#62; the number of annotation values must be stored.
*/
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;
this.bv = bv;
this.parent = parent;
this.offset = offset;
}
// ------------------------------------------------------------------------
// Implementation of the AnnotationVisitor abstract class
// ------------------------------------------------------------------------
@Override
public void visit(final String name, final Object value) {
++size;
if (named) {
bv.putShort(cw.newUTF8(name));
}
if (value instanceof String) {
bv.put12('s', cw.newUTF8((String) value));
} else if (value instanceof Byte) {
bv.put12('B', cw.newInteger(((Byte) value).byteValue()).index);
} else if (value instanceof Boolean) {
int v = ((Boolean) value).booleanValue() ? 1 : 0;
bv.put12('Z', cw.newInteger(v).index);
} else if (value instanceof Character) {
bv.put12('C', cw.newInteger(((Character) value).charValue()).index);
} else if (value instanceof Short) {
bv.put12('S', cw.newInteger(((Short) value).shortValue()).index);
} else if (value instanceof Type) {
bv.put12('c', cw.newUTF8(((Type) value).getDescriptor()));
} else if (value instanceof byte[]) {
byte[] v = (byte[]) value;
bv.put12('[', v.length);
for (int i = 0; i < v.length; i++) {
bv.put12('B', cw.newInteger(v[i]).index);
}
} else if (value instanceof boolean[]) {
boolean[] v = (boolean[]) value;
bv.put12('[', v.length);
for (int i = 0; i < v.length; i++) {
bv.put12('Z', cw.newInteger(v[i] ? 1 : 0).index);
}
} else if (value instanceof short[]) {
short[] v = (short[]) value;
bv.put12('[', v.length);
for (int i = 0; i < v.length; i++) {
bv.put12('S', cw.newInteger(v[i]).index);
}
} else if (value instanceof char[]) {
char[] v = (char[]) value;
bv.put12('[', v.length);
for (int i = 0; i < v.length; i++) {
bv.put12('C', cw.newInteger(v[i]).index);
}
} else if (value instanceof int[]) {
int[] v = (int[]) value;
bv.put12('[', v.length);
for (int i = 0; i < v.length; i++) {
bv.put12('I', cw.newInteger(v[i]).index);
}
} else if (value instanceof long[]) {
long[] v = (long[]) value;
bv.put12('[', v.length);
for (int i = 0; i < v.length; i++) {
bv.put12('J', cw.newLong(v[i]).index);
}
} else if (value instanceof float[]) {
float[] v = (float[]) value;
bv.put12('[', v.length);
for (int i = 0; i < v.length; i++) {
bv.put12('F', cw.newFloat(v[i]).index);
}
} else if (value instanceof double[]) {
double[] v = (double[]) value;
bv.put12('[', v.length);
for (int i = 0; i < v.length; i++) {
bv.put12('D', cw.newDouble(v[i]).index);
}
} else {
Item i = cw.newConstItem(value);
bv.put12(".s.IFJDCS".charAt(i.type), i.index);
}
}
@Override
public void visitEnum(final String name, final String desc, final String value) {
++size;
if (named) {
bv.putShort(cw.newUTF8(name));
}
bv.put12('e', cw.newUTF8(desc)).putShort(cw.newUTF8(value));
}
@Override
public AnnotationVisitor visitAnnotation(final String name, final String desc) {
++size;
if (named) {
bv.putShort(cw.newUTF8(name));
}
// write tag and type, and reserve space for values count
bv.put12('@', cw.newUTF8(desc)).putShort(0);
return new AnnotationWriter(cw, true, bv, bv, bv.length - 2);
}
@Override
public AnnotationVisitor visitArray(final String name) {
++size;
if (named) {
bv.putShort(cw.newUTF8(name));
}
// write tag, and reserve space for array size
bv.put12('[', 0);
return new AnnotationWriter(cw, false, bv, bv, bv.length - 2);
}
@Override
public void visitEnd() {
if (parent != null) {
byte[] data = parent.data;
data[offset] = (byte) (size >>> 8);
data[offset + 1] = (byte) size;
}
}
// ------------------------------------------------------------------------
// Utility methods
// ------------------------------------------------------------------------
/**
* Returns the size of this annotation writer list.
*
* @return the size of this annotation writer list.
*/
int getSize() {
int size = 0;
AnnotationWriter aw = this;
while (aw != null) {
size += aw.bv.length;
aw = aw.next;
}
return size;
}
/**
* Puts the annotations of this annotation writer list into the given byte vector.
*
* @param out where the annotations must be put.
*/
void put(final ByteVector out) {
int n = 0;
int size = 2;
AnnotationWriter aw = this;
AnnotationWriter last = null;
while (aw != null) {
++n;
size += aw.bv.length;
aw.visitEnd(); // in case user forgot to call visitEnd
aw.prev = last;
last = aw;
aw = aw.next;
}
out.putInt(size);
out.putShort(n);
aw = last;
while (aw != null) {
out.putByteArray(aw.bv.data, 0, aw.bv.length);
aw = aw.prev;
}
}
/**
* 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.
*/
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();
}
out.putInt(size).putByte(panns.length - off);
for (int i = off; i < panns.length; ++i) {
AnnotationWriter aw = panns[i];
AnnotationWriter last = null;
int n = 0;
while (aw != null) {
++n;
aw.visitEnd(); // in case user forgot to call visitEnd
aw.prev = last;
last = aw;
aw = aw.next;
}
out.putShort(n);
aw = last;
while (aw != null) {
out.putByteArray(aw.bv.data, 0, aw.bv.length);
aw = aw.prev;
}
}
}
/**
* Puts the given type reference and type path into the given bytevector. LOCAL_VARIABLE and RESOURCE_VARIABLE
* target types are not supported.
*
* @param typeRef a reference to the annotated type. See {@link TypeReference}.
* @param typePath the path to the annotated type argument, wildcard bound, array element type, or static inner type
* within 'typeRef'. May be &#60;tt&#62;null&#60;/tt&#62; if the annotation targets 'typeRef' as a whole.
* @param out where the type reference and type path must be put.
*/
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;
}
if (typePath == null) {
out.putByte(0);
} else {
int length = typePath.b[typePath.offset] * 2 + 1;
out.putByteArray(typePath.b, typePath.offset, length);
}
}
}
/*
* ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*/
/*
*
*
*
*
*
* ASM: a very small and fast Java bytecode manipulation framework
* Copyright (c) 2000-2011 INRIA, France Telecom
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.redkale.asm;
/**
* An {@link AnnotationVisitor} that generates annotations in bytecode form.
*
* @author Eric Bruneton
* @author Eugene Kuleshov
*/
final class AnnotationWriter extends AnnotationVisitor {
/** The class writer to which this annotation must be added. */
private final ClassWriter cw;
/** The number of values in this annotation. */
private int size;
/**
* &#60;tt&#62;true&#60;tt&#62; if values are named, &#60;tt&#62;false&#60;/tt&#62; otherwise. Annotation writers
* used for annotation default and annotation arrays use unnamed values.
*/
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.
*/
private final ByteVector 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}. */
private final int offset;
/** Next annotation writer. This field is used to store annotation lists. */
AnnotationWriter next;
/** Previous annotation writer. This field is used to store annotation lists. */
AnnotationWriter prev;
// ------------------------------------------------------------------------
// Constructor
// ------------------------------------------------------------------------
/**
* Constructs a new {@link AnnotationWriter}.
*
* @param cw the class writer to which this annotation must be added.
* @param named &#60;tt&#62;true&#60;tt&#62; if values are named, &#60;tt&#62;false&#60;/tt&#62; otherwise.
* @param bv where the annotation values must be stored.
* @param parent where the number of annotation values must be stored.
* @param offset where in &#60;tt&#62;parent&#60;/tt&#62; the number of annotation values must be stored.
*/
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;
this.bv = bv;
this.parent = parent;
this.offset = offset;
}
// ------------------------------------------------------------------------
// Implementation of the AnnotationVisitor abstract class
// ------------------------------------------------------------------------
@Override
public void visit(final String name, final Object value) {
++size;
if (named) {
bv.putShort(cw.newUTF8(name));
}
if (value instanceof String) {
bv.put12('s', cw.newUTF8((String) value));
} else if (value instanceof Byte) {
bv.put12('B', cw.newInteger(((Byte) value).byteValue()).index);
} else if (value instanceof Boolean) {
int v = ((Boolean) value).booleanValue() ? 1 : 0;
bv.put12('Z', cw.newInteger(v).index);
} else if (value instanceof Character) {
bv.put12('C', cw.newInteger(((Character) value).charValue()).index);
} else if (value instanceof Short) {
bv.put12('S', cw.newInteger(((Short) value).shortValue()).index);
} else if (value instanceof Type) {
bv.put12('c', cw.newUTF8(((Type) value).getDescriptor()));
} else if (value instanceof byte[]) {
byte[] v = (byte[]) value;
bv.put12('[', v.length);
for (int i = 0; i < v.length; i++) {
bv.put12('B', cw.newInteger(v[i]).index);
}
} else if (value instanceof boolean[]) {
boolean[] v = (boolean[]) value;
bv.put12('[', v.length);
for (int i = 0; i < v.length; i++) {
bv.put12('Z', cw.newInteger(v[i] ? 1 : 0).index);
}
} else if (value instanceof short[]) {
short[] v = (short[]) value;
bv.put12('[', v.length);
for (int i = 0; i < v.length; i++) {
bv.put12('S', cw.newInteger(v[i]).index);
}
} else if (value instanceof char[]) {
char[] v = (char[]) value;
bv.put12('[', v.length);
for (int i = 0; i < v.length; i++) {
bv.put12('C', cw.newInteger(v[i]).index);
}
} else if (value instanceof int[]) {
int[] v = (int[]) value;
bv.put12('[', v.length);
for (int i = 0; i < v.length; i++) {
bv.put12('I', cw.newInteger(v[i]).index);
}
} else if (value instanceof long[]) {
long[] v = (long[]) value;
bv.put12('[', v.length);
for (int i = 0; i < v.length; i++) {
bv.put12('J', cw.newLong(v[i]).index);
}
} else if (value instanceof float[]) {
float[] v = (float[]) value;
bv.put12('[', v.length);
for (int i = 0; i < v.length; i++) {
bv.put12('F', cw.newFloat(v[i]).index);
}
} else if (value instanceof double[]) {
double[] v = (double[]) value;
bv.put12('[', v.length);
for (int i = 0; i < v.length; i++) {
bv.put12('D', cw.newDouble(v[i]).index);
}
} else {
Item i = cw.newConstItem(value);
bv.put12(".s.IFJDCS".charAt(i.type), i.index);
}
}
@Override
public void visitEnum(final String name, final String desc, final String value) {
++size;
if (named) {
bv.putShort(cw.newUTF8(name));
}
bv.put12('e', cw.newUTF8(desc)).putShort(cw.newUTF8(value));
}
@Override
public AnnotationVisitor visitAnnotation(final String name, final String desc) {
++size;
if (named) {
bv.putShort(cw.newUTF8(name));
}
// write tag and type, and reserve space for values count
bv.put12('@', cw.newUTF8(desc)).putShort(0);
return new AnnotationWriter(cw, true, bv, bv, bv.length - 2);
}
@Override
public AnnotationVisitor visitArray(final String name) {
++size;
if (named) {
bv.putShort(cw.newUTF8(name));
}
// write tag, and reserve space for array size
bv.put12('[', 0);
return new AnnotationWriter(cw, false, bv, bv, bv.length - 2);
}
@Override
public void visitEnd() {
if (parent != null) {
byte[] data = parent.data;
data[offset] = (byte) (size >>> 8);
data[offset + 1] = (byte) size;
}
}
// ------------------------------------------------------------------------
// Utility methods
// ------------------------------------------------------------------------
/**
* Returns the size of this annotation writer list.
*
* @return the size of this annotation writer list.
*/
int getSize() {
int size = 0;
AnnotationWriter aw = this;
while (aw != null) {
size += aw.bv.length;
aw = aw.next;
}
return size;
}
/**
* Puts the annotations of this annotation writer list into the given byte vector.
*
* @param out where the annotations must be put.
*/
void put(final ByteVector out) {
int n = 0;
int size = 2;
AnnotationWriter aw = this;
AnnotationWriter last = null;
while (aw != null) {
++n;
size += aw.bv.length;
aw.visitEnd(); // in case user forgot to call visitEnd
aw.prev = last;
last = aw;
aw = aw.next;
}
out.putInt(size);
out.putShort(n);
aw = last;
while (aw != null) {
out.putByteArray(aw.bv.data, 0, aw.bv.length);
aw = aw.prev;
}
}
/**
* 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.
*/
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();
}
out.putInt(size).putByte(panns.length - off);
for (int i = off; i < panns.length; ++i) {
AnnotationWriter aw = panns[i];
AnnotationWriter last = null;
int n = 0;
while (aw != null) {
++n;
aw.visitEnd(); // in case user forgot to call visitEnd
aw.prev = last;
last = aw;
aw = aw.next;
}
out.putShort(n);
aw = last;
while (aw != null) {
out.putByteArray(aw.bv.data, 0, aw.bv.length);
aw = aw.prev;
}
}
}
/**
* Puts the given type reference and type path into the given bytevector. LOCAL_VARIABLE and RESOURCE_VARIABLE
* target types are not supported.
*
* @param typeRef a reference to the annotated type. See {@link TypeReference}.
* @param typePath the path to the annotated type argument, wildcard bound, array element type, or static inner type
* within 'typeRef'. May be &#60;tt&#62;null&#60;/tt&#62; if the annotation targets 'typeRef' as a whole.
* @param out where the type reference and type path must be put.
*/
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;
}
if (typePath == null) {
out.putByte(0);
} else {
int length = typePath.b[typePath.offset] * 2 + 1;
out.putByteArray(typePath.b, typePath.offset, length);
}
}
}

View File

@@ -1,140 +1,140 @@
/*
*
*/
package org.redkale.asm;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.redkale.convert.json.JsonConvert;
/**
* 存放方法的字节信息
*
* @see org.redkale.asm.AsmMethodBoost
* @since 2.8.0
*/
public class AsmMethodBean {
private List<AsmMethodParam> params;
private int access;
private String name;
private String desc;
private String signature;
private String[] exceptions;
public AsmMethodBean() {}
public AsmMethodBean(int access, String name, String desc, String signature, String[] exceptions) {
this.access = access;
this.name = name;
this.desc = desc;
this.signature = signature;
this.exceptions = exceptions;
this.params = new ArrayList<>();
}
public static AsmMethodBean get(Map<String, AsmMethodBean> map, Method method) {
return map == null ? null : map.get(method.getName() + ":" + Type.getMethodDescriptor(method));
}
void removeEmptyNames() {
if (params != null) {
List<AsmMethodParam> dels = null;
for (AsmMethodParam p : params) {
if (" ".equals(p.getName())) {
if (dels == null) {
dels = new ArrayList<>();
}
dels.add(p);
}
}
if (dels != null) {
for (AsmMethodParam p : dels) {
params.remove(p);
}
}
}
}
public List<String> fieldNameList() {
if (params == null) {
return new ArrayList<>();
}
List<String> rs = new ArrayList<>(params.size());
for (AsmMethodParam p : params) {
rs.add(p.getName());
}
return rs;
}
public String[] fieldNameArray() {
if (params == null) {
return null;
}
String[] rs = new String[params.size()];
for (int i = 0; i < rs.length; i++) {
rs[i] = params.get(i).getName();
}
return rs;
}
public List<AsmMethodParam> getParams() {
return params;
}
public void setParams(List<AsmMethodParam> params) {
this.params = params;
}
public int getAccess() {
return access;
}
public void setAccess(int access) {
this.access = access;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDesc() {
return desc;
}
public void setDesc(String desc) {
this.desc = desc;
}
public String getSignature() {
return signature;
}
public void setSignature(String signature) {
this.signature = signature;
}
public String[] getExceptions() {
return exceptions;
}
public void setExceptions(String[] exceptions) {
this.exceptions = exceptions;
}
@Override
public String toString() {
return JsonConvert.root().convertTo(this);
}
}
/*
*
*/
package org.redkale.asm;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.redkale.convert.json.JsonConvert;
/**
* 存放方法的字节信息
*
* @see org.redkale.asm.AsmMethodBoost
* @since 2.8.0
*/
public class AsmMethodBean {
private List<AsmMethodParam> params;
private int access;
private String name;
private String desc;
private String signature;
private String[] exceptions;
public AsmMethodBean() {}
public AsmMethodBean(int access, String name, String desc, String signature, String[] exceptions) {
this.access = access;
this.name = name;
this.desc = desc;
this.signature = signature;
this.exceptions = exceptions;
this.params = new ArrayList<>();
}
public static AsmMethodBean get(Map<String, AsmMethodBean> map, Method method) {
return map == null ? null : map.get(method.getName() + ":" + Type.getMethodDescriptor(method));
}
void removeEmptyNames() {
if (params != null) {
List<AsmMethodParam> dels = null;
for (AsmMethodParam p : params) {
if (" ".equals(p.getName())) {
if (dels == null) {
dels = new ArrayList<>();
}
dels.add(p);
}
}
if (dels != null) {
for (AsmMethodParam p : dels) {
params.remove(p);
}
}
}
}
public List<String> fieldNameList() {
if (params == null) {
return new ArrayList<>();
}
List<String> rs = new ArrayList<>(params.size());
for (AsmMethodParam p : params) {
rs.add(p.getName());
}
return rs;
}
public String[] fieldNameArray() {
if (params == null) {
return null;
}
String[] rs = new String[params.size()];
for (int i = 0; i < rs.length; i++) {
rs[i] = params.get(i).getName();
}
return rs;
}
public List<AsmMethodParam> getParams() {
return params;
}
public void setParams(List<AsmMethodParam> params) {
this.params = params;
}
public int getAccess() {
return access;
}
public void setAccess(int access) {
this.access = access;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDesc() {
return desc;
}
public void setDesc(String desc) {
this.desc = desc;
}
public String getSignature() {
return signature;
}
public void setSignature(String signature) {
this.signature = signature;
}
public String[] getExceptions() {
return exceptions;
}
public void setExceptions(String[] exceptions) {
this.exceptions = exceptions;
}
@Override
public String toString() {
return JsonConvert.root().convertTo(this);
}
}

View File

@@ -1,409 +1,409 @@
/*
*
*/
package org.redkale.asm;
import static org.redkale.asm.Opcodes.ACC_PRIVATE;
import static org.redkale.asm.Opcodes.ACC_PROTECTED;
import static org.redkale.asm.Opcodes.ACC_PUBLIC;
import static org.redkale.asm.Opcodes.ALOAD;
import static org.redkale.asm.Opcodes.ARETURN;
import static org.redkale.asm.Opcodes.DLOAD;
import static org.redkale.asm.Opcodes.DRETURN;
import static org.redkale.asm.Opcodes.FLOAD;
import static org.redkale.asm.Opcodes.FRETURN;
import static org.redkale.asm.Opcodes.ILOAD;
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;
/**
* 生产动态字节码的方法扩展器, 可以进行方法加强动作
*
* @param <T> 泛型
* @since 2.8.0
*/
public abstract class AsmMethodBoost<T> {
protected final AtomicInteger fieldIndex = new AtomicInteger();
protected final boolean remote;
protected final Class serviceType;
protected AsmMethodBoost(boolean remote, Class serviceType) {
this.remote = remote;
this.serviceType = serviceType;
}
public static AsmMethodBoost create(boolean remote, Collection<AsmMethodBoost> list) {
return new AsmMethodBoosts(remote, list);
}
public static AsmMethodBoost create(boolean remote, AsmMethodBoost... items) {
return new AsmMethodBoosts(remote, items);
}
/**
* 返回一个类所有方法的字节信息, 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的元素集合比方法的参数多
rs.values().forEach(AsmMethodBean::removeEmptyNames);
return rs;
}
public static String getMethodBeanKey(Method method) {
return method.getName() + ":" + Type.getMethodDescriptor(method);
}
/**
* 获取需屏蔽的方法上的注解
*
* @param method 方法
* @return 需要屏蔽的注解
*/
public abstract List<Class<? extends Annotation>> filterMethodAnnotations(Method 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);
/**
* 处理所有动态方法后调用
*
* @param classLoader ClassLoader
* @param cw 动态字节码Writer
* @param newDynName 动态新类名
* @param fieldPrefix 动态字段的前缀
*/
public void doAfterMethods(ClassLoader classLoader, ClassWriter cw, String newDynName, String fieldPrefix) {}
/**
* 实例对象进行操作,通常用于给动态的字段赋值
*
* @param resourceFactory ResourceFactory
* @param service 实例对象
*/
public abstract void doInstance(ResourceFactory resourceFactory, T service);
protected AsmMethodBean getMethodBean(Method method) {
Map<String, AsmMethodBean> methodBeans = AsmMethodBoost.getMethodBeans(serviceType);
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 int getAcc(Method method, String newMethodName) {
if (newMethodName != null) {
return ACC_PRIVATE;
}
return Modifier.isProtected(method.getModifiers()) ? ACC_PROTECTED : ACC_PUBLIC;
}
protected String getNowMethodName(Method method, String newMethodName) {
return newMethodName == null ? method.getName() : newMethodName;
}
protected String getMethodSignature(Method method, AsmMethodBean methodBean) {
return methodBean != null ? methodBean.getSignature() : null;
}
protected String[] getMethodExceptions(Method method, AsmMethodBean methodBean) {
if (methodBean == null) {
String[] exceptions = null;
Class<?>[] expTypes = method.getExceptionTypes();
if (expTypes.length > 0) {
exceptions = new String[expTypes.length];
for (int i = 0; i < expTypes.length; i++) {
exceptions[i] = expTypes[i].getName().replace('.', '/');
}
}
return exceptions;
} else {
return methodBean.getExceptions();
}
}
protected void visitRawAnnotation(
Method method, String newMethodName, MethodVisitor mv, Class selfAnnType, List filterAnns) {
if (newMethodName == null) {
// 给方法加上原有的Annotation
final Annotation[] anns = method.getAnnotations();
for (Annotation ann : anns) {
if (ann.annotationType() != selfAnnType
&& (filterAnns == null || !filterAnns.contains(ann.annotationType()))) {
Asms.visitAnnotation(mv.visitAnnotation(Type.getDescriptor(ann.annotationType()), true), ann);
}
}
// 给参数加上原有的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);
}
}
}
}
protected List<Integer> visitVarInsnParamTypes(MethodVisitor mv, Method method, int insn) {
// 传参数
Class[] paramTypes = method.getParameterTypes();
List<Integer> insns = new ArrayList<>();
for (Class pt : paramTypes) {
insn++;
if (pt.isPrimitive()) {
if (pt == long.class) {
mv.visitVarInsn(LLOAD, insn++);
} else if (pt == float.class) {
mv.visitVarInsn(FLOAD, insn++);
} else if (pt == double.class) {
mv.visitVarInsn(DLOAD, insn++);
} else {
mv.visitVarInsn(ILOAD, insn);
}
} else {
mv.visitVarInsn(ALOAD, insn);
}
insns.add(insn);
}
return insns;
}
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));
}
}
}
protected void visitInsnReturn(
MethodVisitor mv, Method method, Label l0, List<Integer> insns, AsmMethodBean methodBean) {
if (method.getGenericReturnType() == void.class) {
mv.visitInsn(RETURN);
} else {
Class returnclz = method.getReturnType();
if (returnclz.isPrimitive()) {
if (returnclz == long.class) {
mv.visitInsn(LRETURN);
} else if (returnclz == float.class) {
mv.visitInsn(FRETURN);
} else if (returnclz == double.class) {
mv.visitInsn(DRETURN);
} else {
mv.visitInsn(IRETURN);
}
} else {
mv.visitInsn(ARETURN);
}
}
visitParamTypesLocalVariable(mv, method, l0, new Label(), insns, methodBean);
}
/**
* 生产动态字节码的方法扩展器, 可以进行方法加强动作
*
* @param <T> 泛型
* @since 2.8.0
*/
static class AsmMethodBoosts<T> extends AsmMethodBoost<T> {
private final AsmMethodBoost[] items;
public AsmMethodBoosts(boolean remote, Collection<AsmMethodBoost> list) {
super(remote, null);
this.items = list.toArray(new AsmMethodBoost[list.size()]);
}
public AsmMethodBoosts(boolean remote, AsmMethodBoost... items) {
super(remote, null);
this.items = items;
}
@Override
public List<Class<? extends Annotation>> filterMethodAnnotations(Method method) {
List<Class<? extends Annotation>> list = null;
for (AsmMethodBoost item : items) {
if (item != null) {
List<Class<? extends Annotation>> sub = item.filterMethodAnnotations(method);
if (sub != null) {
if (list == null) {
list = new ArrayList<>();
}
list.addAll(sub);
}
}
}
return list;
}
@Override
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) {
newName = item.doMethod(classLoader, cw, newDynName, fieldPrefix, filterAnns, method, newName);
}
}
return newName;
}
@Override
public void doAfterMethods(ClassLoader classLoader, ClassWriter cw, String newDynName, String fieldPrefix) {
for (AsmMethodBoost item : items) {
if (item != null) {
item.doAfterMethods(classLoader, cw, newDynName, fieldPrefix);
}
}
}
@Override
public void doInstance(ResourceFactory resourceFactory, T service) {
for (AsmMethodBoost item : items) {
if (item != null) {
item.doInstance(resourceFactory, service);
}
}
}
}
static class MethodParamClassVisitor extends ClassVisitor {
private Class serviceType;
private final Map<String, AsmMethodBean> methodBeanMap;
public MethodParamClassVisitor(int api, Class serviceType, final Map<String, AsmMethodBean> methodBeanMap) {
super(api);
this.serviceType = serviceType;
this.methodBeanMap = methodBeanMap;
}
@Override
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;
}
String key = methodName + ":" + methodDesc;
if (methodBeanMap.containsKey(key)) {
return null;
}
AsmMethodBean bean =
new AsmMethodBean(methodAccess, methodName, methodDesc, methodSignature, methodExceptions);
List<AsmMethodParam> paramList = bean.getParams();
methodBeanMap.put(key, bean);
return new MethodVisitor(Opcodes.ASM6) {
@Override
public void visitParameter(String paramName, int paramAccess) {
paramList.add(new AsmMethodParam(paramName));
}
@Override
public void visitLocalVariable(
String varName, String varDesc, String varSignature, Label start, Label end, int varIndex) {
if (varIndex < 1) {
return;
}
int size = paramList.size();
// index并不会按顺序执行
if (varIndex > size) {
for (int i = size; i < varIndex; i++) {
paramList.add(new AsmMethodParam(" ", varDesc, varSignature));
}
paramList.set(varIndex - 1, new AsmMethodParam(varName, varDesc, varSignature));
}
paramList.set(varIndex - 1, new AsmMethodParam(varName, varDesc, varSignature));
}
};
}
// 返回的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");
if (in == null) {
return map;
}
try {
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
return map;
}
return getMethodParamNames(map, superClass);
}
}
}
/*
*
*/
package org.redkale.asm;
import static org.redkale.asm.Opcodes.ACC_PRIVATE;
import static org.redkale.asm.Opcodes.ACC_PROTECTED;
import static org.redkale.asm.Opcodes.ACC_PUBLIC;
import static org.redkale.asm.Opcodes.ALOAD;
import static org.redkale.asm.Opcodes.ARETURN;
import static org.redkale.asm.Opcodes.DLOAD;
import static org.redkale.asm.Opcodes.DRETURN;
import static org.redkale.asm.Opcodes.FLOAD;
import static org.redkale.asm.Opcodes.FRETURN;
import static org.redkale.asm.Opcodes.ILOAD;
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;
/**
* 生产动态字节码的方法扩展器, 可以进行方法加强动作
*
* @param <T> 泛型
* @since 2.8.0
*/
public abstract class AsmMethodBoost<T> {
protected final AtomicInteger fieldIndex = new AtomicInteger();
protected final boolean remote;
protected final Class serviceType;
protected AsmMethodBoost(boolean remote, Class serviceType) {
this.remote = remote;
this.serviceType = serviceType;
}
public static AsmMethodBoost create(boolean remote, Collection<AsmMethodBoost> list) {
return new AsmMethodBoosts(remote, list);
}
public static AsmMethodBoost create(boolean remote, AsmMethodBoost... items) {
return new AsmMethodBoosts(remote, items);
}
/**
* 返回一个类所有方法的字节信息, 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的元素集合比方法的参数多
rs.values().forEach(AsmMethodBean::removeEmptyNames);
return rs;
}
public static String getMethodBeanKey(Method method) {
return method.getName() + ":" + Type.getMethodDescriptor(method);
}
/**
* 获取需屏蔽的方法上的注解
*
* @param method 方法
* @return 需要屏蔽的注解
*/
public abstract List<Class<? extends Annotation>> filterMethodAnnotations(Method 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);
/**
* 处理所有动态方法后调用
*
* @param classLoader ClassLoader
* @param cw 动态字节码Writer
* @param newDynName 动态新类名
* @param fieldPrefix 动态字段的前缀
*/
public void doAfterMethods(ClassLoader classLoader, ClassWriter cw, String newDynName, String fieldPrefix) {}
/**
* 实例对象进行操作,通常用于给动态的字段赋值
*
* @param resourceFactory ResourceFactory
* @param service 实例对象
*/
public abstract void doInstance(ResourceFactory resourceFactory, T service);
protected AsmMethodBean getMethodBean(Method method) {
Map<String, AsmMethodBean> methodBeans = AsmMethodBoost.getMethodBeans(serviceType);
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 int getAcc(Method method, String newMethodName) {
if (newMethodName != null) {
return ACC_PRIVATE;
}
return Modifier.isProtected(method.getModifiers()) ? ACC_PROTECTED : ACC_PUBLIC;
}
protected String getNowMethodName(Method method, String newMethodName) {
return newMethodName == null ? method.getName() : newMethodName;
}
protected String getMethodSignature(Method method, AsmMethodBean methodBean) {
return methodBean != null ? methodBean.getSignature() : null;
}
protected String[] getMethodExceptions(Method method, AsmMethodBean methodBean) {
if (methodBean == null) {
String[] exceptions = null;
Class<?>[] expTypes = method.getExceptionTypes();
if (expTypes.length > 0) {
exceptions = new String[expTypes.length];
for (int i = 0; i < expTypes.length; i++) {
exceptions[i] = expTypes[i].getName().replace('.', '/');
}
}
return exceptions;
} else {
return methodBean.getExceptions();
}
}
protected void visitRawAnnotation(
Method method, String newMethodName, MethodVisitor mv, Class selfAnnType, List filterAnns) {
if (newMethodName == null) {
// 给方法加上原有的Annotation
final Annotation[] anns = method.getAnnotations();
for (Annotation ann : anns) {
if (ann.annotationType() != selfAnnType
&& (filterAnns == null || !filterAnns.contains(ann.annotationType()))) {
Asms.visitAnnotation(mv.visitAnnotation(Type.getDescriptor(ann.annotationType()), true), ann);
}
}
// 给参数加上原有的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);
}
}
}
}
protected List<Integer> visitVarInsnParamTypes(MethodVisitor mv, Method method, int insn) {
// 传参数
Class[] paramTypes = method.getParameterTypes();
List<Integer> insns = new ArrayList<>();
for (Class pt : paramTypes) {
insn++;
if (pt.isPrimitive()) {
if (pt == long.class) {
mv.visitVarInsn(LLOAD, insn++);
} else if (pt == float.class) {
mv.visitVarInsn(FLOAD, insn++);
} else if (pt == double.class) {
mv.visitVarInsn(DLOAD, insn++);
} else {
mv.visitVarInsn(ILOAD, insn);
}
} else {
mv.visitVarInsn(ALOAD, insn);
}
insns.add(insn);
}
return insns;
}
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));
}
}
}
protected void visitInsnReturn(
MethodVisitor mv, Method method, Label l0, List<Integer> insns, AsmMethodBean methodBean) {
if (method.getGenericReturnType() == void.class) {
mv.visitInsn(RETURN);
} else {
Class returnclz = method.getReturnType();
if (returnclz.isPrimitive()) {
if (returnclz == long.class) {
mv.visitInsn(LRETURN);
} else if (returnclz == float.class) {
mv.visitInsn(FRETURN);
} else if (returnclz == double.class) {
mv.visitInsn(DRETURN);
} else {
mv.visitInsn(IRETURN);
}
} else {
mv.visitInsn(ARETURN);
}
}
visitParamTypesLocalVariable(mv, method, l0, new Label(), insns, methodBean);
}
/**
* 生产动态字节码的方法扩展器, 可以进行方法加强动作
*
* @param <T> 泛型
* @since 2.8.0
*/
static class AsmMethodBoosts<T> extends AsmMethodBoost<T> {
private final AsmMethodBoost[] items;
public AsmMethodBoosts(boolean remote, Collection<AsmMethodBoost> list) {
super(remote, null);
this.items = list.toArray(new AsmMethodBoost[list.size()]);
}
public AsmMethodBoosts(boolean remote, AsmMethodBoost... items) {
super(remote, null);
this.items = items;
}
@Override
public List<Class<? extends Annotation>> filterMethodAnnotations(Method method) {
List<Class<? extends Annotation>> list = null;
for (AsmMethodBoost item : items) {
if (item != null) {
List<Class<? extends Annotation>> sub = item.filterMethodAnnotations(method);
if (sub != null) {
if (list == null) {
list = new ArrayList<>();
}
list.addAll(sub);
}
}
}
return list;
}
@Override
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) {
newName = item.doMethod(classLoader, cw, newDynName, fieldPrefix, filterAnns, method, newName);
}
}
return newName;
}
@Override
public void doAfterMethods(ClassLoader classLoader, ClassWriter cw, String newDynName, String fieldPrefix) {
for (AsmMethodBoost item : items) {
if (item != null) {
item.doAfterMethods(classLoader, cw, newDynName, fieldPrefix);
}
}
}
@Override
public void doInstance(ResourceFactory resourceFactory, T service) {
for (AsmMethodBoost item : items) {
if (item != null) {
item.doInstance(resourceFactory, service);
}
}
}
}
static class MethodParamClassVisitor extends ClassVisitor {
private Class serviceType;
private final Map<String, AsmMethodBean> methodBeanMap;
public MethodParamClassVisitor(int api, Class serviceType, final Map<String, AsmMethodBean> methodBeanMap) {
super(api);
this.serviceType = serviceType;
this.methodBeanMap = methodBeanMap;
}
@Override
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;
}
String key = methodName + ":" + methodDesc;
if (methodBeanMap.containsKey(key)) {
return null;
}
AsmMethodBean bean =
new AsmMethodBean(methodAccess, methodName, methodDesc, methodSignature, methodExceptions);
List<AsmMethodParam> paramList = bean.getParams();
methodBeanMap.put(key, bean);
return new MethodVisitor(Opcodes.ASM6) {
@Override
public void visitParameter(String paramName, int paramAccess) {
paramList.add(new AsmMethodParam(paramName));
}
@Override
public void visitLocalVariable(
String varName, String varDesc, String varSignature, Label start, Label end, int varIndex) {
if (varIndex < 1) {
return;
}
int size = paramList.size();
// index并不会按顺序执行
if (varIndex > size) {
for (int i = size; i < varIndex; i++) {
paramList.add(new AsmMethodParam(" ", varDesc, varSignature));
}
paramList.set(varIndex - 1, new AsmMethodParam(varName, varDesc, varSignature));
}
paramList.set(varIndex - 1, new AsmMethodParam(varName, varDesc, varSignature));
}
};
}
// 返回的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");
if (in == null) {
return map;
}
try {
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
return map;
}
return getMethodParamNames(map, superClass);
}
}
}

View File

@@ -1,72 +1,72 @@
/*
*
*/
package org.redkale.asm;
import org.redkale.convert.json.JsonConvert;
import org.redkale.util.TypeToken;
/**
* 存放方法参数的字节信息
*
* @see org.redkale.asm.AsmMethodBean
* @see org.redkale.asm.AsmMethodBoost
* @since 2.8.0
*/
public class AsmMethodParam {
private String name;
private String description;
private String signature;
public AsmMethodParam() {}
public AsmMethodParam(String name) {
this.name = name;
}
public AsmMethodParam(String name, String description, String signature) {
this.name = name;
this.description = description;
this.signature = signature;
}
public String description(java.lang.reflect.Type type) {
return description == null ? Type.getDescriptor(TypeToken.typeToClass(type)) : description;
}
public String signature(java.lang.reflect.Type type) {
return signature;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getSignature() {
return signature;
}
public void setSignature(String signature) {
this.signature = signature;
}
@Override
public String toString() {
return JsonConvert.root().convertTo(this);
}
}
/*
*
*/
package org.redkale.asm;
import org.redkale.convert.json.JsonConvert;
import org.redkale.util.TypeToken;
/**
* 存放方法参数的字节信息
*
* @see org.redkale.asm.AsmMethodBean
* @see org.redkale.asm.AsmMethodBoost
* @since 2.8.0
*/
public class AsmMethodParam {
private String name;
private String description;
private String signature;
public AsmMethodParam() {}
public AsmMethodParam(String name) {
this.name = name;
}
public AsmMethodParam(String name, String description, String signature) {
this.name = name;
this.description = description;
this.signature = signature;
}
public String description(java.lang.reflect.Type type) {
return description == null ? Type.getDescriptor(TypeToken.typeToClass(type)) : description;
}
public String signature(java.lang.reflect.Type type) {
return signature;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getSignature() {
return signature;
}
public void setSignature(String signature) {
this.signature = signature;
}
@Override
public String toString() {
return JsonConvert.root().convertTo(this);
}
}

View File

@@ -1,197 +1,197 @@
/*
*
*/
package org.redkale.asm;
import static org.redkale.asm.Opcodes.BIPUSH;
import static org.redkale.asm.Opcodes.CHECKCAST;
import static org.redkale.asm.Opcodes.GETSTATIC;
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
*
* @author zhangjx
* @since 2.8.0
*/
public final class 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);
}
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)) {
continue;
}
final Object r = anm.invoke(ann);
if (r instanceof String[]) {
AnnotationVisitor av1 = av.visitArray(mname);
for (String item : (String[]) r) {
av1.visit(null, item);
}
av1.visitEnd();
} else if (r instanceof Class[]) {
AnnotationVisitor av1 = av.visitArray(mname);
for (Class item : (Class[]) r) {
av1.visit(null, Type.getType(item));
}
av1.visitEnd();
} else if (r instanceof Enum[]) {
AnnotationVisitor av1 = av.visitArray(mname);
for (Enum item : (Enum[]) r) {
av1.visitEnum(null, Type.getDescriptor(item.getClass()), ((Enum) item).name());
}
av1.visitEnd();
} 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);
}
av1.visitEnd();
} else if (r instanceof Class) {
av.visit(mname, Type.getType((Class) r));
} 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);
} else {
av.visit(mname, r);
}
}
av.visitEnd();
} catch (Exception e) {
throw new RedkaleException(e);
}
}
public static void visitInsn(MethodVisitor mv, int num) {
if (num < 6) {
mv.visitInsn(ICONST_0 + num);
} else if (num <= Byte.MAX_VALUE) {
mv.visitIntInsn(BIPUSH, num);
} else if (num <= Short.MAX_VALUE) {
mv.visitIntInsn(SIPUSH, num);
} else {
mv.visitLdcInsn(num);
}
}
public static void visitFieldInsn(MethodVisitor mv, Class clazz) {
if (clazz == boolean.class) {
mv.visitFieldInsn(GETSTATIC, "java/lang/Boolean", "TYPE", "Ljava/lang/Class;");
} else if (clazz == byte.class) {
mv.visitFieldInsn(GETSTATIC, "java/lang/Byte", "TYPE", "Ljava/lang/Class;");
} else if (clazz == char.class) {
mv.visitFieldInsn(GETSTATIC, "java/lang/Character", "TYPE", "Ljava/lang/Class;");
} else if (clazz == short.class) {
mv.visitFieldInsn(GETSTATIC, "java/lang/Short", "TYPE", "Ljava/lang/Class;");
} else if (clazz == int.class) {
mv.visitFieldInsn(GETSTATIC, "java/lang/Integer", "TYPE", "Ljava/lang/Class;");
} else if (clazz == float.class) {
mv.visitFieldInsn(GETSTATIC, "java/lang/Float", "TYPE", "Ljava/lang/Class;");
} else if (clazz == long.class) {
mv.visitFieldInsn(GETSTATIC, "java/lang/Long", "TYPE", "Ljava/lang/Class;");
} else if (clazz == double.class) {
mv.visitFieldInsn(GETSTATIC, "java/lang/Double", "TYPE", "Ljava/lang/Class;");
} else {
mv.visitLdcInsn(Type.getType(Type.getDescriptor(clazz)));
}
}
public static void visitPrimitiveValueOf(MethodVisitor mv, Class clazz) {
if (clazz == boolean.class) {
mv.visitMethodInsn(INVOKESTATIC, "java/lang/Boolean", "valueOf", "(Z)Ljava/lang/Boolean;", false);
} else if (clazz == byte.class) {
mv.visitMethodInsn(INVOKESTATIC, "java/lang/Byte", "valueOf", "(B)Ljava/lang/Byte;", false);
} else if (clazz == short.class) {
mv.visitMethodInsn(INVOKESTATIC, "java/lang/Short", "valueOf", "(S)Ljava/lang/Short;", false);
} else if (clazz == char.class) {
mv.visitMethodInsn(INVOKESTATIC, "java/lang/Character", "valueOf", "(C)Ljava/lang/Character;", false);
} else if (clazz == int.class) {
mv.visitMethodInsn(INVOKESTATIC, "java/lang/Integer", "valueOf", "(I)Ljava/lang/Integer;", false);
} else if (clazz == float.class) {
mv.visitMethodInsn(INVOKESTATIC, "java/lang/Float", "valueOf", "(F)Ljava/lang/Float;", false);
} else if (clazz == long.class) {
mv.visitMethodInsn(INVOKESTATIC, "java/lang/Long", "valueOf", "(J)Ljava/lang/Long;", false);
} else if (clazz == double.class) {
mv.visitMethodInsn(INVOKESTATIC, "java/lang/Double", "valueOf", "(D)Ljava/lang/Double;", false);
}
}
public static void visitCheckCast(MethodVisitor mv, Class clazz) {
if (clazz == boolean.class) {
mv.visitTypeInsn(CHECKCAST, "java/lang/Boolean");
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Boolean", "booleanValue", "()Z", false);
} else if (clazz == byte.class) {
mv.visitTypeInsn(CHECKCAST, "java/lang/Byte");
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Byte", "byteValue", "()B", false);
} else if (clazz == short.class) {
mv.visitTypeInsn(CHECKCAST, "java/lang/Short");
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Short", "shortValue", "()S", false);
} else if (clazz == char.class) {
mv.visitTypeInsn(CHECKCAST, "java/lang/Character");
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Character", "charValue", "()C", false);
} else if (clazz == int.class) {
mv.visitTypeInsn(CHECKCAST, "java/lang/Integer");
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Integer", "intValue", "()I", false);
} else if (clazz == float.class) {
mv.visitTypeInsn(CHECKCAST, "java/lang/Float");
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Float", "floatValue", "()F", false);
} else if (clazz == long.class) {
mv.visitTypeInsn(CHECKCAST, "java/lang/Long");
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Long", "longValue", "()J", false);
} else if (clazz == double.class) {
mv.visitTypeInsn(CHECKCAST, "java/lang/Double");
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Double", "doubleValue", "()D", false);
} else {
mv.visitTypeInsn(CHECKCAST, clazz.getName().replace('.', '/'));
}
}
public static void visitPrimitiveVirtual(MethodVisitor mv, Class clazz) {
if (clazz == boolean.class) {
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Boolean", "booleanValue", "()Z", false);
} else if (clazz == byte.class) {
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Byte", "byteValue", "()B", false);
} else if (clazz == short.class) {
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Short", "shortValue", "()S", false);
} else if (clazz == char.class) {
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Character", "charValue", "()C", false);
} else if (clazz == int.class) {
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Integer", "intValue", "()I", false);
} else if (clazz == float.class) {
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Float", "floatValue", "()F", false);
} else if (clazz == long.class) {
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Long", "longValue", "()J", false);
} else if (clazz == double.class) {
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Double", "doubleValue", "()D", false);
}
}
}
/*
*
*/
package org.redkale.asm;
import static org.redkale.asm.Opcodes.BIPUSH;
import static org.redkale.asm.Opcodes.CHECKCAST;
import static org.redkale.asm.Opcodes.GETSTATIC;
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
*
* @author zhangjx
* @since 2.8.0
*/
public final class 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);
}
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)) {
continue;
}
final Object r = anm.invoke(ann);
if (r instanceof String[]) {
AnnotationVisitor av1 = av.visitArray(mname);
for (String item : (String[]) r) {
av1.visit(null, item);
}
av1.visitEnd();
} else if (r instanceof Class[]) {
AnnotationVisitor av1 = av.visitArray(mname);
for (Class item : (Class[]) r) {
av1.visit(null, Type.getType(item));
}
av1.visitEnd();
} else if (r instanceof Enum[]) {
AnnotationVisitor av1 = av.visitArray(mname);
for (Enum item : (Enum[]) r) {
av1.visitEnum(null, Type.getDescriptor(item.getClass()), ((Enum) item).name());
}
av1.visitEnd();
} 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);
}
av1.visitEnd();
} else if (r instanceof Class) {
av.visit(mname, Type.getType((Class) r));
} 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);
} else {
av.visit(mname, r);
}
}
av.visitEnd();
} catch (Exception e) {
throw new RedkaleException(e);
}
}
public static void visitInsn(MethodVisitor mv, int num) {
if (num < 6) {
mv.visitInsn(ICONST_0 + num);
} else if (num <= Byte.MAX_VALUE) {
mv.visitIntInsn(BIPUSH, num);
} else if (num <= Short.MAX_VALUE) {
mv.visitIntInsn(SIPUSH, num);
} else {
mv.visitLdcInsn(num);
}
}
public static void visitFieldInsn(MethodVisitor mv, Class clazz) {
if (clazz == boolean.class) {
mv.visitFieldInsn(GETSTATIC, "java/lang/Boolean", "TYPE", "Ljava/lang/Class;");
} else if (clazz == byte.class) {
mv.visitFieldInsn(GETSTATIC, "java/lang/Byte", "TYPE", "Ljava/lang/Class;");
} else if (clazz == char.class) {
mv.visitFieldInsn(GETSTATIC, "java/lang/Character", "TYPE", "Ljava/lang/Class;");
} else if (clazz == short.class) {
mv.visitFieldInsn(GETSTATIC, "java/lang/Short", "TYPE", "Ljava/lang/Class;");
} else if (clazz == int.class) {
mv.visitFieldInsn(GETSTATIC, "java/lang/Integer", "TYPE", "Ljava/lang/Class;");
} else if (clazz == float.class) {
mv.visitFieldInsn(GETSTATIC, "java/lang/Float", "TYPE", "Ljava/lang/Class;");
} else if (clazz == long.class) {
mv.visitFieldInsn(GETSTATIC, "java/lang/Long", "TYPE", "Ljava/lang/Class;");
} else if (clazz == double.class) {
mv.visitFieldInsn(GETSTATIC, "java/lang/Double", "TYPE", "Ljava/lang/Class;");
} else {
mv.visitLdcInsn(Type.getType(Type.getDescriptor(clazz)));
}
}
public static void visitPrimitiveValueOf(MethodVisitor mv, Class clazz) {
if (clazz == boolean.class) {
mv.visitMethodInsn(INVOKESTATIC, "java/lang/Boolean", "valueOf", "(Z)Ljava/lang/Boolean;", false);
} else if (clazz == byte.class) {
mv.visitMethodInsn(INVOKESTATIC, "java/lang/Byte", "valueOf", "(B)Ljava/lang/Byte;", false);
} else if (clazz == short.class) {
mv.visitMethodInsn(INVOKESTATIC, "java/lang/Short", "valueOf", "(S)Ljava/lang/Short;", false);
} else if (clazz == char.class) {
mv.visitMethodInsn(INVOKESTATIC, "java/lang/Character", "valueOf", "(C)Ljava/lang/Character;", false);
} else if (clazz == int.class) {
mv.visitMethodInsn(INVOKESTATIC, "java/lang/Integer", "valueOf", "(I)Ljava/lang/Integer;", false);
} else if (clazz == float.class) {
mv.visitMethodInsn(INVOKESTATIC, "java/lang/Float", "valueOf", "(F)Ljava/lang/Float;", false);
} else if (clazz == long.class) {
mv.visitMethodInsn(INVOKESTATIC, "java/lang/Long", "valueOf", "(J)Ljava/lang/Long;", false);
} else if (clazz == double.class) {
mv.visitMethodInsn(INVOKESTATIC, "java/lang/Double", "valueOf", "(D)Ljava/lang/Double;", false);
}
}
public static void visitCheckCast(MethodVisitor mv, Class clazz) {
if (clazz == boolean.class) {
mv.visitTypeInsn(CHECKCAST, "java/lang/Boolean");
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Boolean", "booleanValue", "()Z", false);
} else if (clazz == byte.class) {
mv.visitTypeInsn(CHECKCAST, "java/lang/Byte");
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Byte", "byteValue", "()B", false);
} else if (clazz == short.class) {
mv.visitTypeInsn(CHECKCAST, "java/lang/Short");
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Short", "shortValue", "()S", false);
} else if (clazz == char.class) {
mv.visitTypeInsn(CHECKCAST, "java/lang/Character");
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Character", "charValue", "()C", false);
} else if (clazz == int.class) {
mv.visitTypeInsn(CHECKCAST, "java/lang/Integer");
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Integer", "intValue", "()I", false);
} else if (clazz == float.class) {
mv.visitTypeInsn(CHECKCAST, "java/lang/Float");
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Float", "floatValue", "()F", false);
} else if (clazz == long.class) {
mv.visitTypeInsn(CHECKCAST, "java/lang/Long");
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Long", "longValue", "()J", false);
} else if (clazz == double.class) {
mv.visitTypeInsn(CHECKCAST, "java/lang/Double");
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Double", "doubleValue", "()D", false);
} else {
mv.visitTypeInsn(CHECKCAST, clazz.getName().replace('.', '/'));
}
}
public static void visitPrimitiveVirtual(MethodVisitor mv, Class clazz) {
if (clazz == boolean.class) {
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Boolean", "booleanValue", "()Z", false);
} else if (clazz == byte.class) {
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Byte", "byteValue", "()B", false);
} else if (clazz == short.class) {
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Short", "shortValue", "()S", false);
} else if (clazz == char.class) {
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Character", "charValue", "()C", false);
} else if (clazz == int.class) {
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Integer", "intValue", "()I", false);
} else if (clazz == float.class) {
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Float", "floatValue", "()F", false);
} else if (clazz == long.class) {
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Long", "longValue", "()J", false);
} else if (clazz == double.class) {
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Double", "doubleValue", "()D", false);
}
}
}

View File

@@ -1,312 +1,312 @@
/*
* ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*/
/*
*
*
*
*
*
* ASM: a very small and fast Java bytecode manipulation framework
* Copyright (c) 2000-2011 INRIA, France Telecom
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.redkale.asm;
import java.util.Arrays;
/**
* A non standard class, field, method or code attribute.
*
* @author Eric Bruneton
* @author Eugene Kuleshov
*/
public class Attribute {
/** The type of this attribute. */
public final String type;
/** The raw value of this attribute, used only for unknown attributes. */
byte[] value;
/** The next attribute in this attribute list. May be &#60;tt&#62;null&#60;/tt&#62;. */
Attribute next;
/**
* Constructs a new empty attribute.
*
* @param type the type of the attribute.
*/
protected Attribute(final String type) {
this.type = type;
}
/**
* Returns &#60;tt&#62;true&#60;/tt&#62; if this type of attribute is unknown. The default implementation of this
* method always returns &#60;tt&#62;true&#60;/tt&#62;.
*
* @return &#60;tt&#62;true&#60;/tt&#62; if this type of attribute is unknown.
*/
public boolean isUnknown() {
return true;
}
/**
* Returns &#60;tt&#62;true&#60;/tt&#62; if this type of attribute is a code attribute.
*
* @return &#60;tt&#62;true&#60;/tt&#62; if this type of attribute is a code attribute.
*/
public boolean isCodeAttribute() {
return false;
}
/**
* Returns the labels corresponding to this attribute.
*
* @return the labels corresponding to this attribute, or &#60;tt&#62;null&#60;/tt&#62; if this attribute is not a
* code attribute that contains labels.
*/
protected Label[] getLabels() {
return null;
}
/**
* Reads a {@link #type type} attribute. This method must return a <i>new</i> {@link Attribute} object, of type
* {@link #type type}, corresponding to the &#60;tt&#62;len&#60;/tt&#62; bytes starting at the given offset, in the
* given class reader.
*
* @param cr the class that contains the attribute to be read.
* @param off index of the first byte of the attribute's content in {@link ClassReader#b cr.b}. The 6 attribute
* header bytes, containing the type and the length of the attribute, are not taken into account here.
* @param len the length of the attribute's content.
* @param buf buffer to be used to call {@link ClassReader#readUTF8 readUTF8},
* {@link ClassReader#readClass(int,char[]) readClass} or {@link ClassReader#readConst readConst}.
* @param codeOff index of the first byte of code's attribute content in {@link ClassReader#b cr.b}, or -1 if the
* attribute to be read is not a code attribute. The 6 attribute header bytes, containing the type and the
* length of the attribute, are not taken into account here.
* @param labels the labels of the method's code, or &#60;tt&#62;null&#60;/tt&#62; if the attribute to be read is
* not a code attribute.
* @return a <i>new</i> {@link Attribute} object corresponding to the given bytes.
*/
protected Attribute read(
final ClassReader cr,
final int off,
final int len,
final char[] buf,
final int codeOff,
final Label[] labels) {
Attribute attr = new Attribute(type);
attr.value = new byte[len];
System.arraycopy(cr.b, off, attr.value, 0, len);
return attr;
}
/**
* Returns the byte array form of this attribute.
*
* @param cw the class to which this attribute must be added. This parameter can be used to add to the constant pool
* of this class the items that corresponds to this attribute.
* @param code the bytecode of the method corresponding to this code attribute, or &#60;tt&#62;null&#60;/tt&#62; if
* this attribute is not a code attributes.
* @param len the length of the bytecode of the method corresponding to this code attribute, or
* &#60;tt&#62;null&#60;/tt&#62; if this attribute is not a code attribute.
* @param maxStack the maximum stack size of the method corresponding to this code attribute, or -1 if this
* attribute is not a code attribute.
* @param maxLocals the maximum number of local variables of the method corresponding to this code attribute, or -1
* if this attribute is not a code attribute.
* @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) {
ByteVector v = new ByteVector();
v.data = value;
v.length = value.length;
return v;
}
/**
* Returns the length of the attribute list that begins with this attribute.
*
* @return the length of the attribute list that begins with this attribute.
*/
final int getCount() {
int count = 0;
Attribute attr = this;
while (attr != null) {
count += 1;
attr = attr.next;
}
return count;
}
/**
* Returns the size of all the attributes in this attribute list.
*
* @param cw the class writer to be used to convert the attributes into byte arrays, with the {@link #write write}
* method.
* @param code the bytecode of the method corresponding to these code attributes, or &#60;tt&#62;null&#60;/tt&#62;
* if these attributes are not code attributes.
* @param len the length of the bytecode of the method corresponding to these code attributes, or
* &#60;tt&#62;null&#60;/tt&#62; if these attributes are not code attributes.
* @param maxStack the maximum stack size of the method corresponding to these code attributes, or -1 if these
* attributes are not code attributes.
* @param maxLocals the maximum number of local variables of the method corresponding to these code attributes, or
* -1 if these attributes are not code attributes.
* @return the size of all the attributes in this attribute list. This size includes the size of the attribute
* headers.
*/
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) {
cw.newUTF8(attr.type);
size += attr.write(cw, code, len, maxStack, maxLocals).length + 6;
attr = attr.next;
}
return size;
}
/**
* Writes all the attributes of this attribute list in the given byte vector.
*
* @param cw the class writer to be used to convert the attributes into byte arrays, with the {@link #write write}
* method.
* @param code the bytecode of the method corresponding to these code attributes, or &#60;tt&#62;null&#60;/tt&#62;
* if these attributes are not code attributes.
* @param len the length of the bytecode of the method corresponding to these code attributes, or
* &#60;tt&#62;null&#60;/tt&#62; if these attributes are not code attributes.
* @param maxStack the maximum stack size of the method corresponding to these code attributes, or -1 if these
* attributes are not code attributes.
* @param maxLocals the maximum number of local variables of the method corresponding to these code attributes, or
* -1 if these attributes are not code attributes.
* @param out where the attributes must be written.
*/
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);
out.putShort(cw.newUTF8(attr.type)).putInt(b.length);
out.putByteArray(b.data, 0, b.length);
attr = attr.next;
}
}
// 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");
}
byte[] bytes;
String[] classes;
@Override
protected Attribute read(ClassReader cr, int off, int len, char[] buf, int codeOff, Label[] labels) {
int offset = off;
NestMembers a = new NestMembers();
int size = cr.readShort(off);
a.classes = new String[size];
off += 2;
for (int i = 0; i < size; i++) {
a.classes[i] = cr.readClass(off, buf);
off += 2;
}
a.bytes = Arrays.copyOfRange(cr.b, offset, offset + len);
return a;
}
@Override
protected ByteVector write(ClassWriter cw, byte[] code, int len, int maxStack, int maxLocals) {
ByteVector v = new ByteVector(bytes.length);
v.putShort(classes.length);
for (String s : classes) {
v.putShort(cw.newClass(s));
}
return v;
}
}
/** */
public static class NestHost extends Attribute {
byte[] bytes;
String clazz;
/** */
public NestHost() {
super("NestHost");
}
@Override
protected Attribute read(ClassReader cr, int off, int len, char[] buf, int codeOff, Label[] labels) {
int offset = off;
NestHost a = new NestHost();
a.clazz = cr.readClass(off, buf);
a.bytes = Arrays.copyOfRange(cr.b, offset, offset + len);
return a;
}
@Override
protected ByteVector write(ClassWriter cw, byte[] code, int len, int maxStack, int maxLocals) {
ByteVector v = new ByteVector(bytes.length);
v.putShort(cw.newClass(clazz));
return v;
}
}
static final Attribute[] DEFAULT_ATTRIBUTE_PROTOS = new Attribute[] {new NestMembers(), new NestHost()};
}
/*
* ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*/
/*
*
*
*
*
*
* ASM: a very small and fast Java bytecode manipulation framework
* Copyright (c) 2000-2011 INRIA, France Telecom
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.redkale.asm;
import java.util.Arrays;
/**
* A non standard class, field, method or code attribute.
*
* @author Eric Bruneton
* @author Eugene Kuleshov
*/
public class Attribute {
/** The type of this attribute. */
public final String type;
/** The raw value of this attribute, used only for unknown attributes. */
byte[] value;
/** The next attribute in this attribute list. May be &#60;tt&#62;null&#60;/tt&#62;. */
Attribute next;
/**
* Constructs a new empty attribute.
*
* @param type the type of the attribute.
*/
protected Attribute(final String type) {
this.type = type;
}
/**
* Returns &#60;tt&#62;true&#60;/tt&#62; if this type of attribute is unknown. The default implementation of this
* method always returns &#60;tt&#62;true&#60;/tt&#62;.
*
* @return &#60;tt&#62;true&#60;/tt&#62; if this type of attribute is unknown.
*/
public boolean isUnknown() {
return true;
}
/**
* Returns &#60;tt&#62;true&#60;/tt&#62; if this type of attribute is a code attribute.
*
* @return &#60;tt&#62;true&#60;/tt&#62; if this type of attribute is a code attribute.
*/
public boolean isCodeAttribute() {
return false;
}
/**
* Returns the labels corresponding to this attribute.
*
* @return the labels corresponding to this attribute, or &#60;tt&#62;null&#60;/tt&#62; if this attribute is not a
* code attribute that contains labels.
*/
protected Label[] getLabels() {
return null;
}
/**
* Reads a {@link #type type} attribute. This method must return a <i>new</i> {@link Attribute} object, of type
* {@link #type type}, corresponding to the &#60;tt&#62;len&#60;/tt&#62; bytes starting at the given offset, in the
* given class reader.
*
* @param cr the class that contains the attribute to be read.
* @param off index of the first byte of the attribute's content in {@link ClassReader#b cr.b}. The 6 attribute
* header bytes, containing the type and the length of the attribute, are not taken into account here.
* @param len the length of the attribute's content.
* @param buf buffer to be used to call {@link ClassReader#readUTF8 readUTF8},
* {@link ClassReader#readClass(int,char[]) readClass} or {@link ClassReader#readConst readConst}.
* @param codeOff index of the first byte of code's attribute content in {@link ClassReader#b cr.b}, or -1 if the
* attribute to be read is not a code attribute. The 6 attribute header bytes, containing the type and the
* length of the attribute, are not taken into account here.
* @param labels the labels of the method's code, or &#60;tt&#62;null&#60;/tt&#62; if the attribute to be read is
* not a code attribute.
* @return a <i>new</i> {@link Attribute} object corresponding to the given bytes.
*/
protected Attribute read(
final ClassReader cr,
final int off,
final int len,
final char[] buf,
final int codeOff,
final Label[] labels) {
Attribute attr = new Attribute(type);
attr.value = new byte[len];
System.arraycopy(cr.b, off, attr.value, 0, len);
return attr;
}
/**
* Returns the byte array form of this attribute.
*
* @param cw the class to which this attribute must be added. This parameter can be used to add to the constant pool
* of this class the items that corresponds to this attribute.
* @param code the bytecode of the method corresponding to this code attribute, or &#60;tt&#62;null&#60;/tt&#62; if
* this attribute is not a code attributes.
* @param len the length of the bytecode of the method corresponding to this code attribute, or
* &#60;tt&#62;null&#60;/tt&#62; if this attribute is not a code attribute.
* @param maxStack the maximum stack size of the method corresponding to this code attribute, or -1 if this
* attribute is not a code attribute.
* @param maxLocals the maximum number of local variables of the method corresponding to this code attribute, or -1
* if this attribute is not a code attribute.
* @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) {
ByteVector v = new ByteVector();
v.data = value;
v.length = value.length;
return v;
}
/**
* Returns the length of the attribute list that begins with this attribute.
*
* @return the length of the attribute list that begins with this attribute.
*/
final int getCount() {
int count = 0;
Attribute attr = this;
while (attr != null) {
count += 1;
attr = attr.next;
}
return count;
}
/**
* Returns the size of all the attributes in this attribute list.
*
* @param cw the class writer to be used to convert the attributes into byte arrays, with the {@link #write write}
* method.
* @param code the bytecode of the method corresponding to these code attributes, or &#60;tt&#62;null&#60;/tt&#62;
* if these attributes are not code attributes.
* @param len the length of the bytecode of the method corresponding to these code attributes, or
* &#60;tt&#62;null&#60;/tt&#62; if these attributes are not code attributes.
* @param maxStack the maximum stack size of the method corresponding to these code attributes, or -1 if these
* attributes are not code attributes.
* @param maxLocals the maximum number of local variables of the method corresponding to these code attributes, or
* -1 if these attributes are not code attributes.
* @return the size of all the attributes in this attribute list. This size includes the size of the attribute
* headers.
*/
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) {
cw.newUTF8(attr.type);
size += attr.write(cw, code, len, maxStack, maxLocals).length + 6;
attr = attr.next;
}
return size;
}
/**
* Writes all the attributes of this attribute list in the given byte vector.
*
* @param cw the class writer to be used to convert the attributes into byte arrays, with the {@link #write write}
* method.
* @param code the bytecode of the method corresponding to these code attributes, or &#60;tt&#62;null&#60;/tt&#62;
* if these attributes are not code attributes.
* @param len the length of the bytecode of the method corresponding to these code attributes, or
* &#60;tt&#62;null&#60;/tt&#62; if these attributes are not code attributes.
* @param maxStack the maximum stack size of the method corresponding to these code attributes, or -1 if these
* attributes are not code attributes.
* @param maxLocals the maximum number of local variables of the method corresponding to these code attributes, or
* -1 if these attributes are not code attributes.
* @param out where the attributes must be written.
*/
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);
out.putShort(cw.newUTF8(attr.type)).putInt(b.length);
out.putByteArray(b.data, 0, b.length);
attr = attr.next;
}
}
// 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");
}
byte[] bytes;
String[] classes;
@Override
protected Attribute read(ClassReader cr, int off, int len, char[] buf, int codeOff, Label[] labels) {
int offset = off;
NestMembers a = new NestMembers();
int size = cr.readShort(off);
a.classes = new String[size];
off += 2;
for (int i = 0; i < size; i++) {
a.classes[i] = cr.readClass(off, buf);
off += 2;
}
a.bytes = Arrays.copyOfRange(cr.b, offset, offset + len);
return a;
}
@Override
protected ByteVector write(ClassWriter cw, byte[] code, int len, int maxStack, int maxLocals) {
ByteVector v = new ByteVector(bytes.length);
v.putShort(classes.length);
for (String s : classes) {
v.putShort(cw.newClass(s));
}
return v;
}
}
/** */
public static class NestHost extends Attribute {
byte[] bytes;
String clazz;
/** */
public NestHost() {
super("NestHost");
}
@Override
protected Attribute read(ClassReader cr, int off, int len, char[] buf, int codeOff, Label[] labels) {
int offset = off;
NestHost a = new NestHost();
a.clazz = cr.readClass(off, buf);
a.bytes = Arrays.copyOfRange(cr.b, offset, offset + len);
return a;
}
@Override
protected ByteVector write(ClassWriter cw, byte[] code, int len, int maxStack, int maxLocals) {
ByteVector v = new ByteVector(bytes.length);
v.putShort(cw.newClass(clazz));
return v;
}
}
static final Attribute[] DEFAULT_ATTRIBUTE_PROTOS = new Attribute[] {new NestMembers(), new NestHost()};
}

View File

@@ -1,331 +1,331 @@
/*
* ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*/
/*
*
*
*
*
*
* ASM: a very small and fast Java bytecode manipulation framework
* Copyright (c) 2000-2011 INRIA, France Telecom
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
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.
*
* @author Eric Bruneton
*/
public class ByteVector {
/** The content of this vector. */
byte[] data;
/** Actual number of bytes in this vector. */
int length;
/** 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.
*
* @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.
*
* @param b a byte.
* @return this byte vector.
*/
public ByteVector putByte(final int b) {
int length = this.length;
if (length + 1 > data.length) {
enlarge(1);
}
data[length++] = (byte) b;
this.length = length;
return this;
}
/**
* Puts two bytes into this byte vector. The byte vector is automatically enlarged if necessary.
*
* @param b1 a byte.
* @param b2 another byte.
* @return this byte vector.
*/
ByteVector put11(final int b1, final int b2) {
int length = this.length;
if (length + 2 > data.length) {
enlarge(2);
}
byte[] data = this.data;
data[length++] = (byte) b1;
data[length++] = (byte) b2;
this.length = length;
return this;
}
/**
* Puts a short into this byte vector. The byte vector is automatically enlarged if necessary.
*
* @param s a short.
* @return this byte vector.
*/
public ByteVector putShort(final int s) {
int length = this.length;
if (length + 2 > data.length) {
enlarge(2);
}
byte[] data = this.data;
data[length++] = (byte) (s >>> 8);
data[length++] = (byte) s;
this.length = length;
return this;
}
/**
* 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.
* @return this byte vector.
*/
ByteVector put12(final int b, final int s) {
int length = this.length;
if (length + 3 > data.length) {
enlarge(3);
}
byte[] data = this.data;
data[length++] = (byte) b;
data[length++] = (byte) (s >>> 8);
data[length++] = (byte) s;
this.length = length;
return this;
}
/**
* Puts an int into this byte vector. The byte vector is automatically enlarged if necessary.
*
* @param i an int.
* @return this byte vector.
*/
public ByteVector putInt(final int i) {
int length = this.length;
if (length + 4 > data.length) {
enlarge(4);
}
byte[] data = this.data;
data[length++] = (byte) (i >>> 24);
data[length++] = (byte) (i >>> 16);
data[length++] = (byte) (i >>> 8);
data[length++] = (byte) i;
this.length = length;
return this;
}
/**
* Puts a long into this byte vector. The byte vector is automatically enlarged if necessary.
*
* @param l a long.
* @return this byte vector.
*/
public ByteVector putLong(final long l) {
int length = this.length;
if (length + 8 > data.length) {
enlarge(8);
}
byte[] data = this.data;
int i = (int) (l >>> 32);
data[length++] = (byte) (i >>> 24);
data[length++] = (byte) (i >>> 16);
data[length++] = (byte) (i >>> 8);
data[length++] = (byte) i;
i = (int) l;
data[length++] = (byte) (i >>> 24);
data[length++] = (byte) (i >>> 16);
data[length++] = (byte) (i >>> 8);
data[length++] = (byte) i;
this.length = length;
return this;
}
/**
* 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.
* @return this byte vector.
*/
public ByteVector putUTF8(final String s) {
int charLength = s.length();
if (charLength > 65535) {
throw new IllegalArgumentException();
}
int len = length;
if (len + 2 + charLength > data.length) {
enlarge(2 + charLength);
}
byte[] data = this.data;
// optimistic algorithm: instead of computing the byte length and then
// serializing the string (which requires two loops), we assume the byte
// length is equal to char length (which is the most frequent case), and
// we start serializing the string right away. During the serialization,
// if we find that this assumption is wrong, we continue with the
// general method.
data[len++] = (byte) (charLength >>> 8);
data[len++] = (byte) charLength;
for (int i = 0; i < charLength; ++i) {
char c = s.charAt(i);
if (c >= '\001' && c <= '\177') {
data[len++] = (byte) c;
} else {
length = len;
return encodeUTF8(s, i, 65535);
}
}
length = len;
return this;
}
/**
* 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.
* @return this byte vector.
*/
ByteVector encodeUTF8(final String s, int i, int maxByteLength) {
int charLength = s.length();
int byteLength = i;
char c;
for (int j = i; j < charLength; ++j) {
c = s.charAt(j);
if (c >= '\001' && c <= '\177') {
byteLength++;
} else if (c > '\u07FF') {
byteLength += 3;
} else {
byteLength += 2;
}
}
if (byteLength > maxByteLength) {
throw new IllegalArgumentException();
}
int start = length - i - 2;
if (start >= 0) {
data[start] = (byte) (byteLength >>> 8);
data[start + 1] = (byte) byteLength;
}
if (length + byteLength - i > data.length) {
enlarge(byteLength - i);
}
int len = length;
for (int j = i; j < charLength; ++j) {
c = s.charAt(j);
if (c >= '\001' && c <= '\177') {
data[len++] = (byte) c;
} else if (c > '\u07FF') {
data[len++] = (byte) (0xE0 | c >> 12 & 0xF);
data[len++] = (byte) (0x80 | c >> 6 & 0x3F);
data[len++] = (byte) (0x80 | c & 0x3F);
} else {
data[len++] = (byte) (0xC0 | c >> 6 & 0x1F);
data[len++] = (byte) (0x80 | c & 0x3F);
}
}
length = len;
return this;
}
/**
* Puts an array of bytes into this byte vector. The byte vector is automatically enlarged if necessary.
*
* @param b an array of bytes. May be &#60;tt&#62;null&#60;/tt&#62; to put &#60;tt&#62;len&#60;/tt&#62; null bytes
* into this byte vector.
* @param off index of the fist byte of b that must be copied.
* @param len number of bytes of b that must be copied.
* @return this byte vector.
*/
public ByteVector putByteArray(final byte[] b, final int off, final int len) {
if (length + len > data.length) {
enlarge(len);
}
if (b != null) {
System.arraycopy(b, off, data, length, len);
}
length += len;
return this;
}
/**
* 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.
*/
private void enlarge(final int size) {
int length1 = 2 * data.length;
int length2 = length + size;
byte[] newData = new byte[length1 > length2 ? length1 : length2];
System.arraycopy(data, 0, newData, 0, length);
data = newData;
}
}
/*
* ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*/
/*
*
*
*
*
*
* ASM: a very small and fast Java bytecode manipulation framework
* Copyright (c) 2000-2011 INRIA, France Telecom
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
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.
*
* @author Eric Bruneton
*/
public class ByteVector {
/** The content of this vector. */
byte[] data;
/** Actual number of bytes in this vector. */
int length;
/** 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.
*
* @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.
*
* @param b a byte.
* @return this byte vector.
*/
public ByteVector putByte(final int b) {
int length = this.length;
if (length + 1 > data.length) {
enlarge(1);
}
data[length++] = (byte) b;
this.length = length;
return this;
}
/**
* Puts two bytes into this byte vector. The byte vector is automatically enlarged if necessary.
*
* @param b1 a byte.
* @param b2 another byte.
* @return this byte vector.
*/
ByteVector put11(final int b1, final int b2) {
int length = this.length;
if (length + 2 > data.length) {
enlarge(2);
}
byte[] data = this.data;
data[length++] = (byte) b1;
data[length++] = (byte) b2;
this.length = length;
return this;
}
/**
* Puts a short into this byte vector. The byte vector is automatically enlarged if necessary.
*
* @param s a short.
* @return this byte vector.
*/
public ByteVector putShort(final int s) {
int length = this.length;
if (length + 2 > data.length) {
enlarge(2);
}
byte[] data = this.data;
data[length++] = (byte) (s >>> 8);
data[length++] = (byte) s;
this.length = length;
return this;
}
/**
* 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.
* @return this byte vector.
*/
ByteVector put12(final int b, final int s) {
int length = this.length;
if (length + 3 > data.length) {
enlarge(3);
}
byte[] data = this.data;
data[length++] = (byte) b;
data[length++] = (byte) (s >>> 8);
data[length++] = (byte) s;
this.length = length;
return this;
}
/**
* Puts an int into this byte vector. The byte vector is automatically enlarged if necessary.
*
* @param i an int.
* @return this byte vector.
*/
public ByteVector putInt(final int i) {
int length = this.length;
if (length + 4 > data.length) {
enlarge(4);
}
byte[] data = this.data;
data[length++] = (byte) (i >>> 24);
data[length++] = (byte) (i >>> 16);
data[length++] = (byte) (i >>> 8);
data[length++] = (byte) i;
this.length = length;
return this;
}
/**
* Puts a long into this byte vector. The byte vector is automatically enlarged if necessary.
*
* @param l a long.
* @return this byte vector.
*/
public ByteVector putLong(final long l) {
int length = this.length;
if (length + 8 > data.length) {
enlarge(8);
}
byte[] data = this.data;
int i = (int) (l >>> 32);
data[length++] = (byte) (i >>> 24);
data[length++] = (byte) (i >>> 16);
data[length++] = (byte) (i >>> 8);
data[length++] = (byte) i;
i = (int) l;
data[length++] = (byte) (i >>> 24);
data[length++] = (byte) (i >>> 16);
data[length++] = (byte) (i >>> 8);
data[length++] = (byte) i;
this.length = length;
return this;
}
/**
* 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.
* @return this byte vector.
*/
public ByteVector putUTF8(final String s) {
int charLength = s.length();
if (charLength > 65535) {
throw new IllegalArgumentException();
}
int len = length;
if (len + 2 + charLength > data.length) {
enlarge(2 + charLength);
}
byte[] data = this.data;
// optimistic algorithm: instead of computing the byte length and then
// serializing the string (which requires two loops), we assume the byte
// length is equal to char length (which is the most frequent case), and
// we start serializing the string right away. During the serialization,
// if we find that this assumption is wrong, we continue with the
// general method.
data[len++] = (byte) (charLength >>> 8);
data[len++] = (byte) charLength;
for (int i = 0; i < charLength; ++i) {
char c = s.charAt(i);
if (c >= '\001' && c <= '\177') {
data[len++] = (byte) c;
} else {
length = len;
return encodeUTF8(s, i, 65535);
}
}
length = len;
return this;
}
/**
* 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.
* @return this byte vector.
*/
ByteVector encodeUTF8(final String s, int i, int maxByteLength) {
int charLength = s.length();
int byteLength = i;
char c;
for (int j = i; j < charLength; ++j) {
c = s.charAt(j);
if (c >= '\001' && c <= '\177') {
byteLength++;
} else if (c > '\u07FF') {
byteLength += 3;
} else {
byteLength += 2;
}
}
if (byteLength > maxByteLength) {
throw new IllegalArgumentException();
}
int start = length - i - 2;
if (start >= 0) {
data[start] = (byte) (byteLength >>> 8);
data[start + 1] = (byte) byteLength;
}
if (length + byteLength - i > data.length) {
enlarge(byteLength - i);
}
int len = length;
for (int j = i; j < charLength; ++j) {
c = s.charAt(j);
if (c >= '\001' && c <= '\177') {
data[len++] = (byte) c;
} else if (c > '\u07FF') {
data[len++] = (byte) (0xE0 | c >> 12 & 0xF);
data[len++] = (byte) (0x80 | c >> 6 & 0x3F);
data[len++] = (byte) (0x80 | c & 0x3F);
} else {
data[len++] = (byte) (0xC0 | c >> 6 & 0x1F);
data[len++] = (byte) (0x80 | c & 0x3F);
}
}
length = len;
return this;
}
/**
* Puts an array of bytes into this byte vector. The byte vector is automatically enlarged if necessary.
*
* @param b an array of bytes. May be &#60;tt&#62;null&#60;/tt&#62; to put &#60;tt&#62;len&#60;/tt&#62; null bytes
* into this byte vector.
* @param off index of the fist byte of b that must be copied.
* @param len number of bytes of b that must be copied.
* @return this byte vector.
*/
public ByteVector putByteArray(final byte[] b, final int off, final int len) {
if (length + len > data.length) {
enlarge(len);
}
if (b != null) {
System.arraycopy(b, off, data, length, len);
}
length += len;
return this;
}
/**
* 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.
*/
private void enlarge(final int size) {
int length1 = 2 * data.length;
int length2 = length + size;
byte[] newData = new byte[length1 > length2 ? length1 : length2];
System.arraycopy(data, 0, newData, 0, length);
data = newData;
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,292 +1,292 @@
/*
* ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*/
/*
*
*
*
*
*
* ASM: a very small and fast Java bytecode manipulation framework
* Copyright (c) 2000-2011 INRIA, France Telecom
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.redkale.asm;
/**
* A visitor to visit a Java class. The methods of this class must be called in the following order:
* &#60;tt&#62;visit&#60;/tt&#62; [ &#60;tt&#62;visitSource&#60;/tt&#62; ] [ &#60;tt&#62;visitModule&#60;/tt&#62; ][
* &#60;tt&#62;visitOuterClass&#60;/tt&#62; ] ( &#60;tt&#62;visitAnnotation&#60;/tt&#62; |
* &#60;tt&#62;visitTypeAnnotation&#60;/tt&#62; | &#60;tt&#62;visitAttribute&#60;/tt&#62; )* (
* &#60;tt&#62;visitInnerClass&#60;/tt&#62; | &#60;tt&#62;visitField&#60;/tt&#62; | &#60;tt&#62;visitMethod&#60;/tt&#62;
* )* &#60;tt&#62;visitEnd&#60;/tt&#62;.
*
* @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}.
*/
protected final int api;
/** 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}.
*/
public ClassVisitor(final int api) {
this(api, null);
}
/**
* 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.
*/
public ClassVisitor(final int api, final ClassVisitor cv) {
this.api = api;
this.cv = cv;
}
/**
* Visits the header of the class.
*
* @param version the class version.
* @param access the class's access flags (see {@link Opcodes}). This parameter also indicates if the class is
* deprecated.
* @param name the internal name of the class (see {@link Type#getInternalName() getInternalName}).
* @param signature the signature of this class. May be &#60;tt&#62;null&#60;/tt&#62; if the class is not a generic
* one, and does not extend or implement generic classes or interfaces.
* @param superName the internal of name of the super class (see {@link Type#getInternalName() getInternalName}).
* For interfaces, the super class is {@link Object}. May be &#60;tt&#62;null&#60;/tt&#62;, but only for the
* {@link Object} class.
* @param interfaces the internal names of the class's interfaces (see {@link Type#getInternalName()
* getInternalName}). May be &#60;tt&#62;null&#60;/tt&#62;.
*/
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);
}
}
/**
* Visits the source of the class.
*
* @param source the name of the source file from which the class was compiled. May be
* &#60;tt&#62;null&#60;/tt&#62;.
* @param debug additional debug information to compute the correspondance between source and compiled elements of
* the class. May be &#60;tt&#62;null&#60;/tt&#62;.
*/
public void visitSource(String source, String debug) {
if (cv != null) {
cv.visitSource(source, debug);
}
}
/**
* Visit the module corresponding to the class.
*
* @param name module name
* @param access module flags, among {@code ACC_OPEN}, {@code ACC_SYNTHETIC} and {@code ACC_MANDATED}.
* @param version module version or null.
* @return a visitor to visit the module values, or &#60;tt&#62;null&#60;/tt&#62; if this visitor is not interested
* in visiting this module.
*/
public ModuleVisitor visitModule(String name, int access, String version) {
if (api < Opcodes.ASM6) {
throw new RuntimeException();
}
if (cv != null) {
return cv.visitModule(name, access, version);
}
return null;
}
/**
* Visits the enclosing class of the class. This method must be called only if the class has an enclosing class.
*
* @param owner internal name of the enclosing class of the class.
* @param name the name of the method that contains the class, or &#60;tt&#62;null&#60;/tt&#62; if the class is not
* enclosed in a method of its enclosing class.
* @param desc the descriptor of the method that contains the class, or &#60;tt&#62;null&#60;/tt&#62; if the class
* is not enclosed in a method of its enclosing class.
*/
public void visitOuterClass(String owner, String name, String desc) {
if (cv != null) {
cv.visitOuterClass(owner, name, desc);
}
}
/**
* Visits an annotation of the class.
*
* @param desc the class descriptor of the annotation class.
* @param visible &#60;tt&#62;true&#60;/tt&#62; if the annotation is visible at runtime.
* @return a visitor to visit the annotation values, or &#60;tt&#62;null&#60;/tt&#62; if this visitor is not
* interested in visiting this annotation.
*/
public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
if (cv != null) {
return cv.visitAnnotation(desc, visible);
}
return null;
}
/**
* Visits an annotation on a type in the class signature.
*
* @param typeRef a reference to the annotated type. The sort of this type reference must be
* {@link TypeReference#CLASS_TYPE_PARAMETER CLASS_TYPE_PARAMETER},
* {@link TypeReference#CLASS_TYPE_PARAMETER_BOUND CLASS_TYPE_PARAMETER_BOUND} or
* {@link TypeReference#CLASS_EXTENDS CLASS_EXTENDS}. See {@link TypeReference}.
* @param typePath the path to the annotated type argument, wildcard bound, array element type, or static inner type
* within 'typeRef'. May be &#60;tt&#62;null&#60;/tt&#62; if the annotation targets 'typeRef' as a whole.
* @param desc the class descriptor of the annotation class.
* @param visible &#60;tt&#62;true&#60;/tt&#62; if the annotation is visible at runtime.
* @return a visitor to visit the annotation values, or &#60;tt&#62;null&#60;/tt&#62; if this visitor is not
* interested in visiting this annotation.
*/
public AnnotationVisitor visitTypeAnnotation(int typeRef, TypePath typePath, String desc, boolean visible) {
if (cv != null) {
return cv.visitTypeAnnotation(typeRef, typePath, desc, visible);
}
return null;
}
/**
* Visits a non standard attribute of the class.
*
* @param attr an attribute.
*/
public void visitAttribute(Attribute attr) {
if (cv != null) {
cv.visitAttribute(attr);
}
}
/**
* Visits information about an inner class. This inner class is not necessarily a member of the class being visited.
*
* @param name the internal name of an inner class (see {@link Type#getInternalName() getInternalName}).
* @param outerName the internal name of the class to which the inner class belongs (see
* {@link Type#getInternalName() getInternalName}). May be &#60;tt&#62;null&#60;/tt&#62; for not member classes.
* @param innerName the (simple) name of the inner class inside its enclosing class. May be
* &#60;tt&#62;null&#60;/tt&#62; for anonymous inner classes.
* @param access the access flags of the inner class as originally declared in the enclosing class.
*/
public void visitInnerClass(String name, String outerName, String innerName, int access) {
if (cv != null) {
cv.visitInnerClass(name, outerName, innerName, access);
}
}
/**
* Visits a field of the class.
*
* @param access the field's access flags (see {@link Opcodes}). This parameter also indicates if the field is
* synthetic and/or deprecated.
* @param name the field's name.
* @param desc the field's descriptor (see {@link Type Type}).
* @param signature the field's signature. May be &#60;tt&#62;null&#60;/tt&#62; if the field's type does not use
* generic types.
* @param value the field's initial value. This parameter, which may be &#60;tt&#62;null&#60;/tt&#62; if the field
* does not have an initial value, must be an {@link Integer}, a {@link Float}, a {@link Long}, a {@link Double}
* or a {@link String} (for &#60;tt&#62;int&#60;/tt&#62;, &#60;tt&#62;float&#60;/tt&#62;,
* &#60;tt&#62;long&#60;/tt&#62; or &#60;tt&#62;String&#60;/tt&#62; fields respectively). <i>This parameter is
* only used for static fields</i>. Its value is ignored for non static fields, which must be initialized
* through bytecode instructions in constructors or methods.
* @return a visitor to visit field annotations and attributes, or &#60;tt&#62;null&#60;/tt&#62; if this class
* visitor is not interested in visiting these annotations and attributes.
*/
public FieldVisitor visitField(int access, String name, String desc, String signature, Object value) {
if (cv != null) {
return cv.visitField(access, name, desc, signature, value);
}
return null;
}
/**
* Visits a method of the class. This method <i>must</i> return a new {@link MethodVisitor} instance (or
* &#60;tt&#62;null&#60;/tt&#62;) each time it is called, i.e., it should not return a previously returned visitor.
*
* @param access the method's access flags (see {@link Opcodes}). This parameter also indicates if the method is
* synthetic and/or deprecated.
* @param name the method's name.
* @param desc the method's descriptor (see {@link Type Type}).
* @param signature the method's signature. May be &#60;tt&#62;null&#60;/tt&#62; if the method parameters, return
* type and exceptions do not use generic types.
* @param exceptions the internal names of the method's exception classes (see {@link Type#getInternalName()
* getInternalName}). May be &#60;tt&#62;null&#60;/tt&#62;.
* @return an object to visit the byte code of the method, or &#60;tt&#62;null&#60;/tt&#62; if this class visitor is
* not interested in visiting the code of this method.
*/
public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
if (cv != null) {
return cv.visitMethod(access, name, desc, signature, exceptions);
}
return null;
}
/**
* 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) {
cv.visitEnd();
}
}
}
/*
* ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*/
/*
*
*
*
*
*
* ASM: a very small and fast Java bytecode manipulation framework
* Copyright (c) 2000-2011 INRIA, France Telecom
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.redkale.asm;
/**
* A visitor to visit a Java class. The methods of this class must be called in the following order:
* &#60;tt&#62;visit&#60;/tt&#62; [ &#60;tt&#62;visitSource&#60;/tt&#62; ] [ &#60;tt&#62;visitModule&#60;/tt&#62; ][
* &#60;tt&#62;visitOuterClass&#60;/tt&#62; ] ( &#60;tt&#62;visitAnnotation&#60;/tt&#62; |
* &#60;tt&#62;visitTypeAnnotation&#60;/tt&#62; | &#60;tt&#62;visitAttribute&#60;/tt&#62; )* (
* &#60;tt&#62;visitInnerClass&#60;/tt&#62; | &#60;tt&#62;visitField&#60;/tt&#62; | &#60;tt&#62;visitMethod&#60;/tt&#62;
* )* &#60;tt&#62;visitEnd&#60;/tt&#62;.
*
* @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}.
*/
protected final int api;
/** 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}.
*/
public ClassVisitor(final int api) {
this(api, null);
}
/**
* 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.
*/
public ClassVisitor(final int api, final ClassVisitor cv) {
this.api = api;
this.cv = cv;
}
/**
* Visits the header of the class.
*
* @param version the class version.
* @param access the class's access flags (see {@link Opcodes}). This parameter also indicates if the class is
* deprecated.
* @param name the internal name of the class (see {@link Type#getInternalName() getInternalName}).
* @param signature the signature of this class. May be &#60;tt&#62;null&#60;/tt&#62; if the class is not a generic
* one, and does not extend or implement generic classes or interfaces.
* @param superName the internal of name of the super class (see {@link Type#getInternalName() getInternalName}).
* For interfaces, the super class is {@link Object}. May be &#60;tt&#62;null&#60;/tt&#62;, but only for the
* {@link Object} class.
* @param interfaces the internal names of the class's interfaces (see {@link Type#getInternalName()
* getInternalName}). May be &#60;tt&#62;null&#60;/tt&#62;.
*/
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);
}
}
/**
* Visits the source of the class.
*
* @param source the name of the source file from which the class was compiled. May be
* &#60;tt&#62;null&#60;/tt&#62;.
* @param debug additional debug information to compute the correspondance between source and compiled elements of
* the class. May be &#60;tt&#62;null&#60;/tt&#62;.
*/
public void visitSource(String source, String debug) {
if (cv != null) {
cv.visitSource(source, debug);
}
}
/**
* Visit the module corresponding to the class.
*
* @param name module name
* @param access module flags, among {@code ACC_OPEN}, {@code ACC_SYNTHETIC} and {@code ACC_MANDATED}.
* @param version module version or null.
* @return a visitor to visit the module values, or &#60;tt&#62;null&#60;/tt&#62; if this visitor is not interested
* in visiting this module.
*/
public ModuleVisitor visitModule(String name, int access, String version) {
if (api < Opcodes.ASM6) {
throw new RuntimeException();
}
if (cv != null) {
return cv.visitModule(name, access, version);
}
return null;
}
/**
* Visits the enclosing class of the class. This method must be called only if the class has an enclosing class.
*
* @param owner internal name of the enclosing class of the class.
* @param name the name of the method that contains the class, or &#60;tt&#62;null&#60;/tt&#62; if the class is not
* enclosed in a method of its enclosing class.
* @param desc the descriptor of the method that contains the class, or &#60;tt&#62;null&#60;/tt&#62; if the class
* is not enclosed in a method of its enclosing class.
*/
public void visitOuterClass(String owner, String name, String desc) {
if (cv != null) {
cv.visitOuterClass(owner, name, desc);
}
}
/**
* Visits an annotation of the class.
*
* @param desc the class descriptor of the annotation class.
* @param visible &#60;tt&#62;true&#60;/tt&#62; if the annotation is visible at runtime.
* @return a visitor to visit the annotation values, or &#60;tt&#62;null&#60;/tt&#62; if this visitor is not
* interested in visiting this annotation.
*/
public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
if (cv != null) {
return cv.visitAnnotation(desc, visible);
}
return null;
}
/**
* Visits an annotation on a type in the class signature.
*
* @param typeRef a reference to the annotated type. The sort of this type reference must be
* {@link TypeReference#CLASS_TYPE_PARAMETER CLASS_TYPE_PARAMETER},
* {@link TypeReference#CLASS_TYPE_PARAMETER_BOUND CLASS_TYPE_PARAMETER_BOUND} or
* {@link TypeReference#CLASS_EXTENDS CLASS_EXTENDS}. See {@link TypeReference}.
* @param typePath the path to the annotated type argument, wildcard bound, array element type, or static inner type
* within 'typeRef'. May be &#60;tt&#62;null&#60;/tt&#62; if the annotation targets 'typeRef' as a whole.
* @param desc the class descriptor of the annotation class.
* @param visible &#60;tt&#62;true&#60;/tt&#62; if the annotation is visible at runtime.
* @return a visitor to visit the annotation values, or &#60;tt&#62;null&#60;/tt&#62; if this visitor is not
* interested in visiting this annotation.
*/
public AnnotationVisitor visitTypeAnnotation(int typeRef, TypePath typePath, String desc, boolean visible) {
if (cv != null) {
return cv.visitTypeAnnotation(typeRef, typePath, desc, visible);
}
return null;
}
/**
* Visits a non standard attribute of the class.
*
* @param attr an attribute.
*/
public void visitAttribute(Attribute attr) {
if (cv != null) {
cv.visitAttribute(attr);
}
}
/**
* Visits information about an inner class. This inner class is not necessarily a member of the class being visited.
*
* @param name the internal name of an inner class (see {@link Type#getInternalName() getInternalName}).
* @param outerName the internal name of the class to which the inner class belongs (see
* {@link Type#getInternalName() getInternalName}). May be &#60;tt&#62;null&#60;/tt&#62; for not member classes.
* @param innerName the (simple) name of the inner class inside its enclosing class. May be
* &#60;tt&#62;null&#60;/tt&#62; for anonymous inner classes.
* @param access the access flags of the inner class as originally declared in the enclosing class.
*/
public void visitInnerClass(String name, String outerName, String innerName, int access) {
if (cv != null) {
cv.visitInnerClass(name, outerName, innerName, access);
}
}
/**
* Visits a field of the class.
*
* @param access the field's access flags (see {@link Opcodes}). This parameter also indicates if the field is
* synthetic and/or deprecated.
* @param name the field's name.
* @param desc the field's descriptor (see {@link Type Type}).
* @param signature the field's signature. May be &#60;tt&#62;null&#60;/tt&#62; if the field's type does not use
* generic types.
* @param value the field's initial value. This parameter, which may be &#60;tt&#62;null&#60;/tt&#62; if the field
* does not have an initial value, must be an {@link Integer}, a {@link Float}, a {@link Long}, a {@link Double}
* or a {@link String} (for &#60;tt&#62;int&#60;/tt&#62;, &#60;tt&#62;float&#60;/tt&#62;,
* &#60;tt&#62;long&#60;/tt&#62; or &#60;tt&#62;String&#60;/tt&#62; fields respectively). <i>This parameter is
* only used for static fields</i>. Its value is ignored for non static fields, which must be initialized
* through bytecode instructions in constructors or methods.
* @return a visitor to visit field annotations and attributes, or &#60;tt&#62;null&#60;/tt&#62; if this class
* visitor is not interested in visiting these annotations and attributes.
*/
public FieldVisitor visitField(int access, String name, String desc, String signature, Object value) {
if (cv != null) {
return cv.visitField(access, name, desc, signature, value);
}
return null;
}
/**
* Visits a method of the class. This method <i>must</i> return a new {@link MethodVisitor} instance (or
* &#60;tt&#62;null&#60;/tt&#62;) each time it is called, i.e., it should not return a previously returned visitor.
*
* @param access the method's access flags (see {@link Opcodes}). This parameter also indicates if the method is
* synthetic and/or deprecated.
* @param name the method's name.
* @param desc the method's descriptor (see {@link Type Type}).
* @param signature the method's signature. May be &#60;tt&#62;null&#60;/tt&#62; if the method parameters, return
* type and exceptions do not use generic types.
* @param exceptions the internal names of the method's exception classes (see {@link Type#getInternalName()
* getInternalName}). May be &#60;tt&#62;null&#60;/tt&#62;.
* @return an object to visit the byte code of the method, or &#60;tt&#62;null&#60;/tt&#62; if this class visitor is
* not interested in visiting the code of this method.
*/
public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
if (cv != null) {
return cv.visitMethod(access, name, desc, signature, exceptions);
}
return null;
}
/**
* 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) {
cv.visitEnd();
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,143 +1,143 @@
/*
* ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*/
/*
*
*
*
*
*
* ASM: a very small and fast Java bytecode manipulation framework
* Copyright (c) 2000-2011 INRIA, France Telecom
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.redkale.asm;
/**
* Information about a class being parsed in a {@link ClassReader}.
*
* @author Eric Bruneton
*/
class Context {
/** Prototypes of the attributes that must be parsed for this class. */
Attribute[] attrs;
/** The {@link ClassReader} option flags for the parsing of this class. */
int flags;
/** The buffer used to read strings. */
char[] buffer;
/** The start index of each bootstrap method. */
int[] bootstrapMethods;
/** The access flags of the method currently being parsed. */
int access;
/** The name of the method currently being parsed. */
String name;
/** 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).
*/
Label[] labels;
/** The target of the type annotation currently being parsed. */
int typeRef;
/** The path of the type annotation currently being parsed. */
TypePath typePath;
/** 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.
*/
Label[] start;
/**
* 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.
*/
int[] index;
/** 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. */
int localCount;
/**
* 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. */
Object[] local;
/** 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. */
Object[] stack;
}
/*
* ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*/
/*
*
*
*
*
*
* ASM: a very small and fast Java bytecode manipulation framework
* Copyright (c) 2000-2011 INRIA, France Telecom
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.redkale.asm;
/**
* Information about a class being parsed in a {@link ClassReader}.
*
* @author Eric Bruneton
*/
class Context {
/** Prototypes of the attributes that must be parsed for this class. */
Attribute[] attrs;
/** The {@link ClassReader} option flags for the parsing of this class. */
int flags;
/** The buffer used to read strings. */
char[] buffer;
/** The start index of each bootstrap method. */
int[] bootstrapMethods;
/** The access flags of the method currently being parsed. */
int access;
/** The name of the method currently being parsed. */
String name;
/** 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).
*/
Label[] labels;
/** The target of the type annotation currently being parsed. */
int typeRef;
/** The path of the type annotation currently being parsed. */
TypePath typePath;
/** 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.
*/
Label[] start;
/**
* 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.
*/
int[] index;
/** 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. */
int localCount;
/**
* 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. */
Object[] local;
/** 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. */
Object[] stack;
}

View File

@@ -1,83 +1,83 @@
/*
* ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*/
/*
*
*
*
*
*
* ASM: a very small and fast Java bytecode manipulation framework
* Copyright (c) 2000-2011 INRIA, France Telecom
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
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.
*
* @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
* frame status just before the given instruction is executed.
*/
@Override
void execute(int opcode, int arg, ClassWriter cw, Item item) {
super.execute(opcode, arg, cw, item);
Frame successor = new Frame();
merge(cw, successor, 0);
set(successor);
owner.inputStackTop = 0;
}
}
/*
* ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*/
/*
*
*
*
*
*
* ASM: a very small and fast Java bytecode manipulation framework
* Copyright (c) 2000-2011 INRIA, France Telecom
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
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.
*
* @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
* frame status just before the given instruction is executed.
*/
@Override
void execute(int opcode, int arg, ClassWriter cw, Item item) {
super.execute(opcode, arg, cw, item);
Frame successor = new Frame();
merge(cw, successor, 0);
set(successor);
owner.inputStackTop = 0;
}
}

View File

@@ -1,94 +1,94 @@
/*
* ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*/
/*
*
*
*
*
*
* ASM: a very small and fast Java bytecode manipulation framework
* Copyright (c) 2000-2011 INRIA, France Telecom
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.redkale.asm;
/**
* An edge in the control flow graph of a method body. See {@link Label Label}.
*
* @author Eric Bruneton
*/
class 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.
*/
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).
*/
int info;
/** 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}.
*/
Edge next;
}
/*
* ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*/
/*
*
*
*
*
*
* ASM: a very small and fast Java bytecode manipulation framework
* Copyright (c) 2000-2011 INRIA, France Telecom
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.redkale.asm;
/**
* An edge in the control flow graph of a method body. See {@link Label Label}.
*
* @author Eric Bruneton
*/
class 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.
*/
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).
*/
int info;
/** 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}.
*/
Edge next;
}

View File

@@ -1,155 +1,155 @@
/*
* ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*/
/*
*
*
*
*
*
* ASM: a very small and fast Java bytecode manipulation framework
* Copyright (c) 2000-2011 INRIA, France Telecom
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.redkale.asm;
/**
* A visitor to visit a Java field. The methods of this class must be called in the following order: (
* &#60;tt&#62;visitAnnotation&#60;/tt&#62; | &#60;tt&#62;visitTypeAnnotation&#60;/tt&#62; |
* &#60;tt&#62;visitAttribute&#60;/tt&#62; )* &#60;tt&#62;visitEnd&#60;/tt&#62;.
*
* @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}.
*/
protected final int api;
/** 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}.
*/
public FieldVisitor(final int api) {
this(api, null);
}
/**
* 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.
*/
public FieldVisitor(final int api, final FieldVisitor fv) {
this.api = api;
this.fv = fv;
}
/**
* Visits an annotation of the field.
*
* @param desc the class descriptor of the annotation class.
* @param visible &#60;tt&#62;true&#60;/tt&#62; if the annotation is visible at runtime.
* @return a visitor to visit the annotation values, or &#60;tt&#62;null&#60;/tt&#62; if this visitor is not
* interested in visiting this annotation.
*/
public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
if (fv != null) {
return fv.visitAnnotation(desc, visible);
}
return null;
}
/**
* Visits an annotation on the type of the field.
*
* @param typeRef a reference to the annotated type. The sort of this type reference must be
* {@link TypeReference#FIELD FIELD}. See {@link TypeReference}.
* @param typePath the path to the annotated type argument, wildcard bound, array element type, or static inner type
* within 'typeRef'. May be &#60;tt&#62;null&#60;/tt&#62; if the annotation targets 'typeRef' as a whole.
* @param desc the class descriptor of the annotation class.
* @param visible &#60;tt&#62;true&#60;/tt&#62; if the annotation is visible at runtime.
* @return a visitor to visit the annotation values, or &#60;tt&#62;null&#60;/tt&#62; if this visitor is not
* interested in visiting this annotation.
*/
public AnnotationVisitor visitTypeAnnotation(int typeRef, TypePath typePath, String desc, boolean visible) {
if (fv != null) {
return fv.visitTypeAnnotation(typeRef, typePath, desc, visible);
}
return null;
}
/**
* Visits a non standard attribute of the field.
*
* @param attr an attribute.
*/
public void visitAttribute(Attribute attr) {
if (fv != null) {
fv.visitAttribute(attr);
}
}
/**
* 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) {
fv.visitEnd();
}
}
}
/*
* ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*/
/*
*
*
*
*
*
* ASM: a very small and fast Java bytecode manipulation framework
* Copyright (c) 2000-2011 INRIA, France Telecom
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.redkale.asm;
/**
* A visitor to visit a Java field. The methods of this class must be called in the following order: (
* &#60;tt&#62;visitAnnotation&#60;/tt&#62; | &#60;tt&#62;visitTypeAnnotation&#60;/tt&#62; |
* &#60;tt&#62;visitAttribute&#60;/tt&#62; )* &#60;tt&#62;visitEnd&#60;/tt&#62;.
*
* @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}.
*/
protected final int api;
/** 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}.
*/
public FieldVisitor(final int api) {
this(api, null);
}
/**
* 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.
*/
public FieldVisitor(final int api, final FieldVisitor fv) {
this.api = api;
this.fv = fv;
}
/**
* Visits an annotation of the field.
*
* @param desc the class descriptor of the annotation class.
* @param visible &#60;tt&#62;true&#60;/tt&#62; if the annotation is visible at runtime.
* @return a visitor to visit the annotation values, or &#60;tt&#62;null&#60;/tt&#62; if this visitor is not
* interested in visiting this annotation.
*/
public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
if (fv != null) {
return fv.visitAnnotation(desc, visible);
}
return null;
}
/**
* Visits an annotation on the type of the field.
*
* @param typeRef a reference to the annotated type. The sort of this type reference must be
* {@link TypeReference#FIELD FIELD}. See {@link TypeReference}.
* @param typePath the path to the annotated type argument, wildcard bound, array element type, or static inner type
* within 'typeRef'. May be &#60;tt&#62;null&#60;/tt&#62; if the annotation targets 'typeRef' as a whole.
* @param desc the class descriptor of the annotation class.
* @param visible &#60;tt&#62;true&#60;/tt&#62; if the annotation is visible at runtime.
* @return a visitor to visit the annotation values, or &#60;tt&#62;null&#60;/tt&#62; if this visitor is not
* interested in visiting this annotation.
*/
public AnnotationVisitor visitTypeAnnotation(int typeRef, TypePath typePath, String desc, boolean visible) {
if (fv != null) {
return fv.visitTypeAnnotation(typeRef, typePath, desc, visible);
}
return null;
}
/**
* Visits a non standard attribute of the field.
*
* @param attr an attribute.
*/
public void visitAttribute(Attribute attr) {
if (fv != null) {
fv.visitAttribute(attr);
}
}
/**
* 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) {
fv.visitEnd();
}
}
}

View File

@@ -1,320 +1,320 @@
/*
* ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*/
/*
*
*
*
*
*
* ASM: a very small and fast Java bytecode manipulation framework
* Copyright (c) 2000-2011 INRIA, France Telecom
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.redkale.asm;
/**
* An {@link FieldVisitor} that generates Java fields in bytecode form.
*
* @author Eric Bruneton
*/
final class FieldWriter extends FieldVisitor {
/** The class writer to which this field must be added. */
private final ClassWriter cw;
/** Access flags of this field. */
private final int access;
/** 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. */
private final int desc;
/** 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. */
private int value;
/** The runtime visible annotations of this field. May be &#60;tt&#62;null&#60;/tt&#62;. */
private AnnotationWriter anns;
/** The runtime invisible annotations of this field. May be &#60;tt&#62;null&#60;/tt&#62;. */
private AnnotationWriter ianns;
/** The runtime visible type annotations of this field. May be &#60;tt&#62;null&#60;/tt&#62;. */
private AnnotationWriter tanns;
/** The runtime invisible type annotations of this field. May be &#60;tt&#62;null&#60;/tt&#62;. */
private AnnotationWriter itanns;
/** The non standard attributes of this field. May be &#60;tt&#62;null&#60;/tt&#62;. */
private Attribute attrs;
// ------------------------------------------------------------------------
// Constructor
// ------------------------------------------------------------------------
/**
* Constructs a new {@link FieldWriter}.
*
* @param cw the class writer to which this field must be added.
* @param access the field's access flags (see {@link Opcodes}).
* @param name the field's name.
* @param desc the field's descriptor (see {@link Type}).
* @param signature the field's signature. May be &#60;tt&#62;null&#60;/tt&#62;.
* @param value the field's constant value. May be &#60;tt&#62;null&#60;/tt&#62;.
*/
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;
} else {
cw.lastField.fv = this;
}
cw.lastField = this;
this.cw = cw;
this.access = access;
this.name = cw.newUTF8(name);
this.desc = cw.newUTF8(desc);
if (signature != null) {
this.signature = cw.newUTF8(signature);
}
if (value != null) {
this.value = cw.newConstItem(value).index;
}
}
// ------------------------------------------------------------------------
// Implementation of the FieldVisitor abstract class
// ------------------------------------------------------------------------
@Override
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);
AnnotationWriter aw = new AnnotationWriter(cw, true, bv, bv, 2);
if (visible) {
aw.next = anns;
anns = aw;
} else {
aw.next = ianns;
ianns = aw;
}
return aw;
}
@Override
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);
if (visible) {
aw.next = tanns;
tanns = aw;
} else {
aw.next = itanns;
itanns = aw;
}
return aw;
}
@Override
public void visitAttribute(final Attribute attr) {
attr.next = attrs;
attrs = attr;
}
@Override
public void visitEnd() {
// do nothing
}
// ------------------------------------------------------------------------
// Utility methods
// ------------------------------------------------------------------------
/**
* Returns the size of this field.
*
* @return the size of this field.
*/
int getSize() {
int size = 8;
if (value != 0) {
cw.newUTF8("ConstantValue");
size += 8;
}
if ((access & Opcodes.ACC_SYNTHETIC) != 0) {
if ((cw.version & 0xFFFF) < Opcodes.V1_5 || (access & ClassWriter.ACC_SYNTHETIC_ATTRIBUTE) != 0) {
cw.newUTF8("Synthetic");
size += 6;
}
}
if ((access & Opcodes.ACC_DEPRECATED) != 0) {
cw.newUTF8("Deprecated");
size += 6;
}
if (signature != 0) {
cw.newUTF8("Signature");
size += 8;
}
if (anns != null) {
cw.newUTF8("RuntimeVisibleAnnotations");
size += 8 + anns.getSize();
}
if (ianns != null) {
cw.newUTF8("RuntimeInvisibleAnnotations");
size += 8 + ianns.getSize();
}
if (tanns != null) {
cw.newUTF8("RuntimeVisibleTypeAnnotations");
size += 8 + tanns.getSize();
}
if (itanns != null) {
cw.newUTF8("RuntimeInvisibleTypeAnnotations");
size += 8 + itanns.getSize();
}
if (attrs != null) {
size += attrs.getSize(cw, null, 0, -1, -1);
}
return size;
}
/**
* Puts the content of this field into the given byte vector.
*
* @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
| ((access & ClassWriter.ACC_SYNTHETIC_ATTRIBUTE) / FACTOR);
out.putShort(access & ~mask).putShort(name).putShort(desc);
int attributeCount = 0;
if (value != 0) {
++attributeCount;
}
if ((access & Opcodes.ACC_SYNTHETIC) != 0) {
if ((cw.version & 0xFFFF) < Opcodes.V1_5 || (access & ClassWriter.ACC_SYNTHETIC_ATTRIBUTE) != 0) {
++attributeCount;
}
}
if ((access & Opcodes.ACC_DEPRECATED) != 0) {
++attributeCount;
}
if (signature != 0) {
++attributeCount;
}
if (anns != null) {
++attributeCount;
}
if (ianns != null) {
++attributeCount;
}
if (tanns != null) {
++attributeCount;
}
if (itanns != null) {
++attributeCount;
}
if (attrs != null) {
attributeCount += attrs.getCount();
}
out.putShort(attributeCount);
if (value != 0) {
out.putShort(cw.newUTF8("ConstantValue"));
out.putInt(2).putShort(value);
}
if ((access & Opcodes.ACC_SYNTHETIC) != 0) {
if ((cw.version & 0xFFFF) < Opcodes.V1_5 || (access & ClassWriter.ACC_SYNTHETIC_ATTRIBUTE) != 0) {
out.putShort(cw.newUTF8("Synthetic")).putInt(0);
}
}
if ((access & Opcodes.ACC_DEPRECATED) != 0) {
out.putShort(cw.newUTF8("Deprecated")).putInt(0);
}
if (signature != 0) {
out.putShort(cw.newUTF8("Signature"));
out.putInt(2).putShort(signature);
}
if (anns != null) {
out.putShort(cw.newUTF8("RuntimeVisibleAnnotations"));
anns.put(out);
}
if (ianns != null) {
out.putShort(cw.newUTF8("RuntimeInvisibleAnnotations"));
ianns.put(out);
}
if (tanns != null) {
out.putShort(cw.newUTF8("RuntimeVisibleTypeAnnotations"));
tanns.put(out);
}
if (itanns != null) {
out.putShort(cw.newUTF8("RuntimeInvisibleTypeAnnotations"));
itanns.put(out);
}
if (attrs != null) {
attrs.put(cw, null, 0, -1, -1, out);
}
}
}
/*
* ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*/
/*
*
*
*
*
*
* ASM: a very small and fast Java bytecode manipulation framework
* Copyright (c) 2000-2011 INRIA, France Telecom
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.redkale.asm;
/**
* An {@link FieldVisitor} that generates Java fields in bytecode form.
*
* @author Eric Bruneton
*/
final class FieldWriter extends FieldVisitor {
/** The class writer to which this field must be added. */
private final ClassWriter cw;
/** Access flags of this field. */
private final int access;
/** 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. */
private final int desc;
/** 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. */
private int value;
/** The runtime visible annotations of this field. May be &#60;tt&#62;null&#60;/tt&#62;. */
private AnnotationWriter anns;
/** The runtime invisible annotations of this field. May be &#60;tt&#62;null&#60;/tt&#62;. */
private AnnotationWriter ianns;
/** The runtime visible type annotations of this field. May be &#60;tt&#62;null&#60;/tt&#62;. */
private AnnotationWriter tanns;
/** The runtime invisible type annotations of this field. May be &#60;tt&#62;null&#60;/tt&#62;. */
private AnnotationWriter itanns;
/** The non standard attributes of this field. May be &#60;tt&#62;null&#60;/tt&#62;. */
private Attribute attrs;
// ------------------------------------------------------------------------
// Constructor
// ------------------------------------------------------------------------
/**
* Constructs a new {@link FieldWriter}.
*
* @param cw the class writer to which this field must be added.
* @param access the field's access flags (see {@link Opcodes}).
* @param name the field's name.
* @param desc the field's descriptor (see {@link Type}).
* @param signature the field's signature. May be &#60;tt&#62;null&#60;/tt&#62;.
* @param value the field's constant value. May be &#60;tt&#62;null&#60;/tt&#62;.
*/
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;
} else {
cw.lastField.fv = this;
}
cw.lastField = this;
this.cw = cw;
this.access = access;
this.name = cw.newUTF8(name);
this.desc = cw.newUTF8(desc);
if (signature != null) {
this.signature = cw.newUTF8(signature);
}
if (value != null) {
this.value = cw.newConstItem(value).index;
}
}
// ------------------------------------------------------------------------
// Implementation of the FieldVisitor abstract class
// ------------------------------------------------------------------------
@Override
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);
AnnotationWriter aw = new AnnotationWriter(cw, true, bv, bv, 2);
if (visible) {
aw.next = anns;
anns = aw;
} else {
aw.next = ianns;
ianns = aw;
}
return aw;
}
@Override
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);
if (visible) {
aw.next = tanns;
tanns = aw;
} else {
aw.next = itanns;
itanns = aw;
}
return aw;
}
@Override
public void visitAttribute(final Attribute attr) {
attr.next = attrs;
attrs = attr;
}
@Override
public void visitEnd() {
// do nothing
}
// ------------------------------------------------------------------------
// Utility methods
// ------------------------------------------------------------------------
/**
* Returns the size of this field.
*
* @return the size of this field.
*/
int getSize() {
int size = 8;
if (value != 0) {
cw.newUTF8("ConstantValue");
size += 8;
}
if ((access & Opcodes.ACC_SYNTHETIC) != 0) {
if ((cw.version & 0xFFFF) < Opcodes.V1_5 || (access & ClassWriter.ACC_SYNTHETIC_ATTRIBUTE) != 0) {
cw.newUTF8("Synthetic");
size += 6;
}
}
if ((access & Opcodes.ACC_DEPRECATED) != 0) {
cw.newUTF8("Deprecated");
size += 6;
}
if (signature != 0) {
cw.newUTF8("Signature");
size += 8;
}
if (anns != null) {
cw.newUTF8("RuntimeVisibleAnnotations");
size += 8 + anns.getSize();
}
if (ianns != null) {
cw.newUTF8("RuntimeInvisibleAnnotations");
size += 8 + ianns.getSize();
}
if (tanns != null) {
cw.newUTF8("RuntimeVisibleTypeAnnotations");
size += 8 + tanns.getSize();
}
if (itanns != null) {
cw.newUTF8("RuntimeInvisibleTypeAnnotations");
size += 8 + itanns.getSize();
}
if (attrs != null) {
size += attrs.getSize(cw, null, 0, -1, -1);
}
return size;
}
/**
* Puts the content of this field into the given byte vector.
*
* @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
| ((access & ClassWriter.ACC_SYNTHETIC_ATTRIBUTE) / FACTOR);
out.putShort(access & ~mask).putShort(name).putShort(desc);
int attributeCount = 0;
if (value != 0) {
++attributeCount;
}
if ((access & Opcodes.ACC_SYNTHETIC) != 0) {
if ((cw.version & 0xFFFF) < Opcodes.V1_5 || (access & ClassWriter.ACC_SYNTHETIC_ATTRIBUTE) != 0) {
++attributeCount;
}
}
if ((access & Opcodes.ACC_DEPRECATED) != 0) {
++attributeCount;
}
if (signature != 0) {
++attributeCount;
}
if (anns != null) {
++attributeCount;
}
if (ianns != null) {
++attributeCount;
}
if (tanns != null) {
++attributeCount;
}
if (itanns != null) {
++attributeCount;
}
if (attrs != null) {
attributeCount += attrs.getCount();
}
out.putShort(attributeCount);
if (value != 0) {
out.putShort(cw.newUTF8("ConstantValue"));
out.putInt(2).putShort(value);
}
if ((access & Opcodes.ACC_SYNTHETIC) != 0) {
if ((cw.version & 0xFFFF) < Opcodes.V1_5 || (access & ClassWriter.ACC_SYNTHETIC_ATTRIBUTE) != 0) {
out.putShort(cw.newUTF8("Synthetic")).putInt(0);
}
}
if ((access & Opcodes.ACC_DEPRECATED) != 0) {
out.putShort(cw.newUTF8("Deprecated")).putInt(0);
}
if (signature != 0) {
out.putShort(cw.newUTF8("Signature"));
out.putInt(2).putShort(signature);
}
if (anns != null) {
out.putShort(cw.newUTF8("RuntimeVisibleAnnotations"));
anns.put(out);
}
if (ianns != null) {
out.putShort(cw.newUTF8("RuntimeInvisibleAnnotations"));
ianns.put(out);
}
if (tanns != null) {
out.putShort(cw.newUTF8("RuntimeVisibleTypeAnnotations"));
tanns.put(out);
}
if (itanns != null) {
out.putShort(cw.newUTF8("RuntimeInvisibleTypeAnnotations"));
itanns.put(out);
}
if (attrs != null) {
attrs.put(cw, null, 0, -1, -1, out);
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,190 +1,190 @@
/*
* ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*/
/*
*
*
*
*
*
* ASM: a very small and fast Java bytecode manipulation framework
* Copyright (c) 2000-2011 INRIA, France Telecom
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.redkale.asm;
/**
* A reference to a field or a method.
*
* @author Remi Forax
* @author Eric Bruneton
*/
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}.
*/
final int tag;
/** 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. */
final String name;
/** The descriptor of the field or method designated by this handle. */
final String desc;
/** 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.
*/
public Handle(int tag, String owner, String name, String desc, boolean itf) {
this.tag = tag;
this.owner = owner;
this.name = name;
this.desc = desc;
this.itf = itf;
}
/**
* 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}.
*/
public int getTag() {
return tag;
}
/**
* 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.
*/
public String getOwner() {
return owner;
}
/**
* Returns the name of the field or method designated by this handle.
*
* @return the name of the field or method designated by this handle.
*/
public String getName() {
return name;
}
/**
* Returns the descriptor of the field or method designated by this handle.
*
* @return the descriptor of the field or method designated by this handle.
*/
public String getDesc() {
return desc;
}
/**
* 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.
*/
public boolean isInterface() {
return itf;
}
@Override
public boolean equals(Object obj) {
if (obj == this) {
return true;
}
if (!(obj instanceof 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);
}
@Override
public int hashCode() {
return tag + (itf ? 64 : 0) + owner.hashCode() * name.hashCode() * desc.hashCode();
}
/**
* Returns the textual representation of this handle. The textual representation is:
*
* <pre>
* for a reference to a class:
* owner '.' name desc ' ' '(' tag ')'
* for a reference to an interface:
* owner '.' name desc ' ' '(' tag ' ' itf ')'
* </pre>
*
* . As this format is unambiguous, it can be parsed if necessary.
*/
@Override
public String toString() {
return owner + '.' + name + desc + " (" + tag + (itf ? " itf" : "") + ')';
}
}
/*
* ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*/
/*
*
*
*
*
*
* ASM: a very small and fast Java bytecode manipulation framework
* Copyright (c) 2000-2011 INRIA, France Telecom
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.redkale.asm;
/**
* A reference to a field or a method.
*
* @author Remi Forax
* @author Eric Bruneton
*/
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}.
*/
final int tag;
/** 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. */
final String name;
/** The descriptor of the field or method designated by this handle. */
final String desc;
/** 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.
*/
public Handle(int tag, String owner, String name, String desc, boolean itf) {
this.tag = tag;
this.owner = owner;
this.name = name;
this.desc = desc;
this.itf = itf;
}
/**
* 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}.
*/
public int getTag() {
return tag;
}
/**
* 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.
*/
public String getOwner() {
return owner;
}
/**
* Returns the name of the field or method designated by this handle.
*
* @return the name of the field or method designated by this handle.
*/
public String getName() {
return name;
}
/**
* Returns the descriptor of the field or method designated by this handle.
*
* @return the descriptor of the field or method designated by this handle.
*/
public String getDesc() {
return desc;
}
/**
* 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.
*/
public boolean isInterface() {
return itf;
}
@Override
public boolean equals(Object obj) {
if (obj == this) {
return true;
}
if (!(obj instanceof 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);
}
@Override
public int hashCode() {
return tag + (itf ? 64 : 0) + owner.hashCode() * name.hashCode() * desc.hashCode();
}
/**
* Returns the textual representation of this handle. The textual representation is:
*
* <pre>
* for a reference to a class:
* owner '.' name desc ' ' '(' tag ')'
* for a reference to an interface:
* owner '.' name desc ' ' '(' tag ' ' itf ')'
* </pre>
*
* . As this format is unambiguous, it can be parsed if necessary.
*/
@Override
public String toString() {
return owner + '.' + name + desc + " (" + tag + (itf ? " itf" : "") + ')';
}
}

View File

@@ -1,138 +1,138 @@
/*
* ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*/
/*
*
*
*
*
*
* ASM: a very small and fast Java bytecode manipulation framework
* Copyright (c) 2000-2011 INRIA, France Telecom
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.redkale.asm;
/**
* Information about an exception handler block.
*
* @author Eric Bruneton
*/
class Handler {
/** Beginning of the exception handler's scope (inclusive). */
Label start;
/** End of the exception handler's scope (exclusive). */
Label end;
/** Beginning of the exception handler's code. */
Label handler;
/**
* Internal name of the type of exceptions handled by this handler, or &#60;tt&#62;null&#60;/tt&#62; to catch any
* exceptions.
*/
String desc;
/**
* 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. */
Handler next;
/**
* 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.
* @return the exception handler list with the start-end range removed.
*/
static Handler remove(Handler h, Label start, Label end) {
if (h == null) {
return null;
} else {
h.next = remove(h.next, start, end);
}
int hstart = h.start.position;
int hend = h.end.position;
int s = start.position;
int e = end == null ? Integer.MAX_VALUE : end.position;
// if [hstart,hend[ and [s,e[ intervals intersect...
if (s < hend && e > hstart) {
if (s <= hstart) {
if (e >= hend) {
// [hstart,hend[ fully included in [s,e[, h removed
h = h.next;
} else {
// [hstart,hend[ minus [s,e[ = [e,hend[
h.start = end;
}
} else if (e >= hend) {
// [hstart,hend[ minus [s,e[ = [hstart,s[
h.end = start;
} else {
// [hstart,hend[ minus [s,e[ = [hstart,s[ + [e,hend[
Handler g = new Handler();
g.start = end;
g.end = h.end;
g.handler = h.handler;
g.desc = h.desc;
g.type = h.type;
g.next = h.next;
h.end = start;
h.next = g;
}
}
return h;
}
}
/*
* ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*/
/*
*
*
*
*
*
* ASM: a very small and fast Java bytecode manipulation framework
* Copyright (c) 2000-2011 INRIA, France Telecom
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.redkale.asm;
/**
* Information about an exception handler block.
*
* @author Eric Bruneton
*/
class Handler {
/** Beginning of the exception handler's scope (inclusive). */
Label start;
/** End of the exception handler's scope (exclusive). */
Label end;
/** Beginning of the exception handler's code. */
Label handler;
/**
* Internal name of the type of exceptions handled by this handler, or &#60;tt&#62;null&#60;/tt&#62; to catch any
* exceptions.
*/
String desc;
/**
* 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. */
Handler next;
/**
* 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.
* @return the exception handler list with the start-end range removed.
*/
static Handler remove(Handler h, Label start, Label end) {
if (h == null) {
return null;
} else {
h.next = remove(h.next, start, end);
}
int hstart = h.start.position;
int hend = h.end.position;
int s = start.position;
int e = end == null ? Integer.MAX_VALUE : end.position;
// if [hstart,hend[ and [s,e[ intervals intersect...
if (s < hend && e > hstart) {
if (s <= hstart) {
if (e >= hend) {
// [hstart,hend[ fully included in [s,e[, h removed
h = h.next;
} else {
// [hstart,hend[ minus [s,e[ = [e,hend[
h.start = end;
}
} else if (e >= hend) {
// [hstart,hend[ minus [s,e[ = [hstart,s[
h.end = start;
} else {
// [hstart,hend[ minus [s,e[ = [hstart,s[ + [e,hend[
Handler g = new Handler();
g.start = end;
g.end = h.end;
g.handler = h.handler;
g.desc = h.desc;
g.type = h.type;
g.next = h.next;
h.end = start;
h.next = g;
}
}
return h;
}
}

View File

@@ -1,289 +1,289 @@
/*
* ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*/
/*
*
*
*
*
*
* ASM: a very small and fast Java bytecode manipulation framework
* Copyright (c) 2000-2011 INRIA, France Telecom
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.redkale.asm;
/**
* 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. */
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},
* {@link ClassWriter#MTYPE}, {@link ClassWriter#INDY}.
*
* <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.
*
* <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. */
int intVal;
/** 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. */
String strVal1;
/** 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. */
String strVal3;
/** 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. */
Item next;
/** Constructs an uninitialized {@link Item}. */
Item() {}
/**
* Constructs an uninitialized {@link Item} for constant pool element at given position.
*
* @param index index of the item to be constructed.
*/
Item(final int index) {
this.index = index;
}
/**
* 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.
*/
Item(final int index, final Item i) {
this.index = index;
type = i.type;
intVal = i.intVal;
longVal = i.longVal;
strVal1 = i.strVal1;
strVal2 = i.strVal2;
strVal3 = i.strVal3;
hashCode = i.hashCode;
}
/**
* Sets this item to an integer item.
*
* @param intVal the value of this item.
*/
void set(final int intVal) {
this.type = ClassWriter.INT;
this.intVal = intVal;
this.hashCode = 0x7FFFFFFF & (type + intVal);
}
/**
* Sets this item to a long item.
*
* @param longVal the value of this item.
*/
void set(final long longVal) {
this.type = ClassWriter.LONG;
this.longVal = longVal;
this.hashCode = 0x7FFFFFFF & (type + (int) longVal);
}
/**
* Sets this item to a float item.
*
* @param floatVal the value of this item.
*/
void set(final float floatVal) {
this.type = ClassWriter.FLOAT;
this.intVal = Float.floatToRawIntBits(floatVal);
this.hashCode = 0x7FFFFFFF & (type + (int) floatVal);
}
/**
* Sets this item to a double item.
*
* @param doubleVal the value of this item.
*/
void set(final double doubleVal) {
this.type = ClassWriter.DOUBLE;
this.longVal = Double.doubleToRawLongBits(doubleVal);
this.hashCode = 0x7FFFFFFF & (type + (int) doubleVal);
}
/**
* 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.
*/
@SuppressWarnings("fallthrough")
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());
}
}
/**
* 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.
*/
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());
}
/**
* 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.
*/
void set(int position, int hashCode) {
this.type = ClassWriter.BSM;
this.intVal = position;
this.hashCode = hashCode;
}
/**
* Indicates if the given item is equal to this one. <i>This method assumes that the two items have the same
* {@link #type}</i>.
*
* @param i the item to be compared to this one. Both items must have the same {@link #type}.
* @return &#60;tt&#62;true&#60;/tt&#62; if the given item if equal to this one, &#60;tt&#62;false&#60;/tt&#62;
* otherwise.
*/
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);
}
}
}
/*
* ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*/
/*
*
*
*
*
*
* ASM: a very small and fast Java bytecode manipulation framework
* Copyright (c) 2000-2011 INRIA, France Telecom
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.redkale.asm;
/**
* 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. */
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},
* {@link ClassWriter#MTYPE}, {@link ClassWriter#INDY}.
*
* <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.
*
* <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. */
int intVal;
/** 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. */
String strVal1;
/** 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. */
String strVal3;
/** 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. */
Item next;
/** Constructs an uninitialized {@link Item}. */
Item() {}
/**
* Constructs an uninitialized {@link Item} for constant pool element at given position.
*
* @param index index of the item to be constructed.
*/
Item(final int index) {
this.index = index;
}
/**
* 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.
*/
Item(final int index, final Item i) {
this.index = index;
type = i.type;
intVal = i.intVal;
longVal = i.longVal;
strVal1 = i.strVal1;
strVal2 = i.strVal2;
strVal3 = i.strVal3;
hashCode = i.hashCode;
}
/**
* Sets this item to an integer item.
*
* @param intVal the value of this item.
*/
void set(final int intVal) {
this.type = ClassWriter.INT;
this.intVal = intVal;
this.hashCode = 0x7FFFFFFF & (type + intVal);
}
/**
* Sets this item to a long item.
*
* @param longVal the value of this item.
*/
void set(final long longVal) {
this.type = ClassWriter.LONG;
this.longVal = longVal;
this.hashCode = 0x7FFFFFFF & (type + (int) longVal);
}
/**
* Sets this item to a float item.
*
* @param floatVal the value of this item.
*/
void set(final float floatVal) {
this.type = ClassWriter.FLOAT;
this.intVal = Float.floatToRawIntBits(floatVal);
this.hashCode = 0x7FFFFFFF & (type + (int) floatVal);
}
/**
* Sets this item to a double item.
*
* @param doubleVal the value of this item.
*/
void set(final double doubleVal) {
this.type = ClassWriter.DOUBLE;
this.longVal = Double.doubleToRawLongBits(doubleVal);
this.hashCode = 0x7FFFFFFF & (type + (int) doubleVal);
}
/**
* 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.
*/
@SuppressWarnings("fallthrough")
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());
}
}
/**
* 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.
*/
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());
}
/**
* 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.
*/
void set(int position, int hashCode) {
this.type = ClassWriter.BSM;
this.intVal = position;
this.hashCode = hashCode;
}
/**
* Indicates if the given item is equal to this one. <i>This method assumes that the two items have the same
* {@link #type}</i>.
*
* @param i the item to be compared to this one. Both items must have the same {@link #type}.
* @return &#60;tt&#62;true&#60;/tt&#62; if the given item if equal to this one, &#60;tt&#62;false&#60;/tt&#62;
* otherwise.
*/
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);
}
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,202 +1,202 @@
/*
* ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*/
/*
*
*
*
*
*
* ASM: a very small and fast Java bytecode manipulation framework
* Copyright (c) 2000-2011 INRIA, France Telecom
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.redkale.asm;
/**
* A visitor to visit a Java module. The methods of this class must be called in the following order:
* &#60;tt&#62;visitMainClass&#60;/tt&#62; | ( &#60;tt&#62;visitPackage&#60;/tt&#62; |
* &#60;tt&#62;visitRequire&#60;/tt&#62; | &#60;tt&#62;visitExport&#60;/tt&#62; | &#60;tt&#62;visitOpen&#60;/tt&#62; |
* &#60;tt&#62;visitUse&#60;/tt&#62; | &#60;tt&#62;visitProvide&#60;/tt&#62; )* &#60;tt&#62;visitEnd&#60;/tt&#62;.
*
* <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}. */
protected final int api;
/** 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}.
*/
public ModuleVisitor(final int api) {
this(api, null);
}
/**
* 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.
*/
public ModuleVisitor(final int api, final ModuleVisitor mv) {
if (api != Opcodes.ASM6) {
throw new IllegalArgumentException();
}
this.api = api;
this.mv = mv;
}
/**
* Visit the main class of the current module.
*
* @param mainClass the internal name of the main class of the current module.
*/
public void visitMainClass(String mainClass) {
if (mv != null) {
mv.visitMainClass(mainClass);
}
}
/**
* Visit a package of the current module.
*
* @param packaze the qualified name of a package.
*/
public void visitPackage(String packaze) {
if (mv != null) {
mv.visitPackage(packaze);
}
}
/**
* 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 version the module version at compile time or null.
*/
public void visitRequire(String module, int access, String version) {
if (mv != null) {
mv.visitRequire(module, access, version);
}
}
/**
* Visit an exported package of the current module.
*
* @param packaze the qualified name of the exported package.
* @param access the access flag of the exported package, valid values are among {@code ACC_SYNTHETIC} and
* {@code ACC_MANDATED}.
* @param modules the qualified names of the modules that can access to the public classes of the exported package
* or &#60;tt&#62;null&#60;/tt&#62;.
*/
public void visitExport(String packaze, int access, String... modules) {
if (mv != null) {
mv.visitExport(packaze, access, modules);
}
}
/**
* Visit an open package of the current module.
*
* @param packaze the qualified name of the opened package.
* @param access the access flag of the opened package, valid values are among {@code ACC_SYNTHETIC} and
* {@code ACC_MANDATED}.
* @param modules the qualified names of the modules that can use deep reflection to the classes of the open package
* or &#60;tt&#62;null&#60;/tt&#62;.
*/
public void visitOpen(String packaze, int access, String... modules) {
if (mv != null) {
mv.visitOpen(packaze, access, modules);
}
}
/**
* 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.
*/
public void visitUse(String service) {
if (mv != null) {
mv.visitUse(service);
}
}
/**
* 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).
*/
public void visitProvide(String service, String... providers) {
if (mv != null) {
mv.visitProvide(service, providers);
}
}
/**
* 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) {
mv.visitEnd();
}
}
}
/*
* ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*/
/*
*
*
*
*
*
* ASM: a very small and fast Java bytecode manipulation framework
* Copyright (c) 2000-2011 INRIA, France Telecom
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.redkale.asm;
/**
* A visitor to visit a Java module. The methods of this class must be called in the following order:
* &#60;tt&#62;visitMainClass&#60;/tt&#62; | ( &#60;tt&#62;visitPackage&#60;/tt&#62; |
* &#60;tt&#62;visitRequire&#60;/tt&#62; | &#60;tt&#62;visitExport&#60;/tt&#62; | &#60;tt&#62;visitOpen&#60;/tt&#62; |
* &#60;tt&#62;visitUse&#60;/tt&#62; | &#60;tt&#62;visitProvide&#60;/tt&#62; )* &#60;tt&#62;visitEnd&#60;/tt&#62;.
*
* <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}. */
protected final int api;
/** 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}.
*/
public ModuleVisitor(final int api) {
this(api, null);
}
/**
* 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.
*/
public ModuleVisitor(final int api, final ModuleVisitor mv) {
if (api != Opcodes.ASM6) {
throw new IllegalArgumentException();
}
this.api = api;
this.mv = mv;
}
/**
* Visit the main class of the current module.
*
* @param mainClass the internal name of the main class of the current module.
*/
public void visitMainClass(String mainClass) {
if (mv != null) {
mv.visitMainClass(mainClass);
}
}
/**
* Visit a package of the current module.
*
* @param packaze the qualified name of a package.
*/
public void visitPackage(String packaze) {
if (mv != null) {
mv.visitPackage(packaze);
}
}
/**
* 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 version the module version at compile time or null.
*/
public void visitRequire(String module, int access, String version) {
if (mv != null) {
mv.visitRequire(module, access, version);
}
}
/**
* Visit an exported package of the current module.
*
* @param packaze the qualified name of the exported package.
* @param access the access flag of the exported package, valid values are among {@code ACC_SYNTHETIC} and
* {@code ACC_MANDATED}.
* @param modules the qualified names of the modules that can access to the public classes of the exported package
* or &#60;tt&#62;null&#60;/tt&#62;.
*/
public void visitExport(String packaze, int access, String... modules) {
if (mv != null) {
mv.visitExport(packaze, access, modules);
}
}
/**
* Visit an open package of the current module.
*
* @param packaze the qualified name of the opened package.
* @param access the access flag of the opened package, valid values are among {@code ACC_SYNTHETIC} and
* {@code ACC_MANDATED}.
* @param modules the qualified names of the modules that can use deep reflection to the classes of the open package
* or &#60;tt&#62;null&#60;/tt&#62;.
*/
public void visitOpen(String packaze, int access, String... modules) {
if (mv != null) {
mv.visitOpen(packaze, access, modules);
}
}
/**
* 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.
*/
public void visitUse(String service) {
if (mv != null) {
mv.visitUse(service);
}
}
/**
* 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).
*/
public void visitProvide(String service, String... providers) {
if (mv != null) {
mv.visitProvide(service, providers);
}
}
/**
* 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) {
mv.visitEnd();
}
}
}

View File

@@ -1,288 +1,288 @@
/*
* ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*/
/*
*
*
*
*
*
* ASM: a very small and fast Java bytecode manipulation framework
* Copyright (c) 2000-2011 INRIA, France Telecom
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.redkale.asm;
/** @author Remi Forax */
final class ModuleWriter extends ModuleVisitor {
/** The class writer to which this Module attribute must be added. */
private final ClassWriter cw;
/** size in byte of the Module attribute. */
int size;
/** Number of attributes associated with the current module (Version, ConcealPackages, etc) */
int attributeCount;
/** Size in bytes of the attributes associated with the current module */
int attributesSize;
/** module name index in the constant pool */
private final int name;
/** module access flags */
private final int access;
/** module version index in the constant pool or 0 */
private final int version;
/** module main class index in the constant pool or 0 */
private int mainClass;
/** 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
*/
private ByteVector packages;
/** 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
*/
private ByteVector requires;
/** 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
*/
private ByteVector exports;
/** 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
*/
private ByteVector opens;
/** 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
*/
private ByteVector uses;
/** 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
*/
private ByteVector provides;
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.name = name;
this.access = access;
this.version = version;
}
@Override
public void visitMainClass(String mainClass) {
if (this.mainClass == 0) { // protect against several calls to visitMainClass
cw.newUTF8("ModuleMainClass");
attributeCount++;
attributesSize += 8;
}
this.mainClass = cw.newClass(mainClass);
}
@Override
public void visitPackage(String packaze) {
if (packages == null) {
// protect against several calls to visitPackage
cw.newUTF8("ModulePackages");
packages = new ByteVector();
attributeCount++;
attributesSize += 8;
}
packages.putShort(cw.newPackage(packaze));
packageCount++;
attributesSize += 2;
}
@Override
public void visitRequire(String module, int access, String version) {
if (requires == null) {
requires = new ByteVector();
}
requires.putShort(cw.newModule(module)).putShort(access).putShort(version == null ? 0 : cw.newUTF8(version));
requireCount++;
size += 6;
}
@Override
public void visitExport(String packaze, int access, String... modules) {
if (exports == null) {
exports = new ByteVector();
}
exports.putShort(cw.newPackage(packaze)).putShort(access);
if (modules == null) {
exports.putShort(0);
size += 6;
} else {
exports.putShort(modules.length);
for (String module : modules) {
exports.putShort(cw.newModule(module));
}
size += 6 + 2 * modules.length;
}
exportCount++;
}
@Override
public void visitOpen(String packaze, int access, String... modules) {
if (opens == null) {
opens = new ByteVector();
}
opens.putShort(cw.newPackage(packaze)).putShort(access);
if (modules == null) {
opens.putShort(0);
size += 6;
} else {
opens.putShort(modules.length);
for (String module : modules) {
opens.putShort(cw.newModule(module));
}
size += 6 + 2 * modules.length;
}
openCount++;
}
@Override
public void visitUse(String service) {
if (uses == null) {
uses = new ByteVector();
}
uses.putShort(cw.newClass(service));
useCount++;
size += 2;
}
@Override
public void visitProvide(String service, String... providers) {
if (provides == null) {
provides = new ByteVector();
}
provides.putShort(cw.newClass(service));
provides.putShort(providers.length);
for (String provider : providers) {
provides.putShort(cw.newClass(provider));
}
provideCount++;
size += 4 + 2 * providers.length;
}
@Override
public void visitEnd() {
// empty
}
void putAttributes(ByteVector out) {
if (mainClass != 0) {
out.putShort(cw.newUTF8("ModuleMainClass")).putInt(2).putShort(mainClass);
}
if (packages != null) {
out.putShort(cw.newUTF8("ModulePackages"))
.putInt(2 + 2 * packageCount)
.putShort(packageCount)
.putByteArray(packages.data, 0, packages.length);
}
}
void put(ByteVector out) {
out.putInt(size);
out.putShort(name).putShort(access).putShort(version);
out.putShort(requireCount);
if (requires != null) {
out.putByteArray(requires.data, 0, requires.length);
}
out.putShort(exportCount);
if (exports != null) {
out.putByteArray(exports.data, 0, exports.length);
}
out.putShort(openCount);
if (opens != null) {
out.putByteArray(opens.data, 0, opens.length);
}
out.putShort(useCount);
if (uses != null) {
out.putByteArray(uses.data, 0, uses.length);
}
out.putShort(provideCount);
if (provides != null) {
out.putByteArray(provides.data, 0, provides.length);
}
}
}
/*
* ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*/
/*
*
*
*
*
*
* ASM: a very small and fast Java bytecode manipulation framework
* Copyright (c) 2000-2011 INRIA, France Telecom
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.redkale.asm;
/** @author Remi Forax */
final class ModuleWriter extends ModuleVisitor {
/** The class writer to which this Module attribute must be added. */
private final ClassWriter cw;
/** size in byte of the Module attribute. */
int size;
/** Number of attributes associated with the current module (Version, ConcealPackages, etc) */
int attributeCount;
/** Size in bytes of the attributes associated with the current module */
int attributesSize;
/** module name index in the constant pool */
private final int name;
/** module access flags */
private final int access;
/** module version index in the constant pool or 0 */
private final int version;
/** module main class index in the constant pool or 0 */
private int mainClass;
/** 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
*/
private ByteVector packages;
/** 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
*/
private ByteVector requires;
/** 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
*/
private ByteVector exports;
/** 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
*/
private ByteVector opens;
/** 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
*/
private ByteVector uses;
/** 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
*/
private ByteVector provides;
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.name = name;
this.access = access;
this.version = version;
}
@Override
public void visitMainClass(String mainClass) {
if (this.mainClass == 0) { // protect against several calls to visitMainClass
cw.newUTF8("ModuleMainClass");
attributeCount++;
attributesSize += 8;
}
this.mainClass = cw.newClass(mainClass);
}
@Override
public void visitPackage(String packaze) {
if (packages == null) {
// protect against several calls to visitPackage
cw.newUTF8("ModulePackages");
packages = new ByteVector();
attributeCount++;
attributesSize += 8;
}
packages.putShort(cw.newPackage(packaze));
packageCount++;
attributesSize += 2;
}
@Override
public void visitRequire(String module, int access, String version) {
if (requires == null) {
requires = new ByteVector();
}
requires.putShort(cw.newModule(module)).putShort(access).putShort(version == null ? 0 : cw.newUTF8(version));
requireCount++;
size += 6;
}
@Override
public void visitExport(String packaze, int access, String... modules) {
if (exports == null) {
exports = new ByteVector();
}
exports.putShort(cw.newPackage(packaze)).putShort(access);
if (modules == null) {
exports.putShort(0);
size += 6;
} else {
exports.putShort(modules.length);
for (String module : modules) {
exports.putShort(cw.newModule(module));
}
size += 6 + 2 * modules.length;
}
exportCount++;
}
@Override
public void visitOpen(String packaze, int access, String... modules) {
if (opens == null) {
opens = new ByteVector();
}
opens.putShort(cw.newPackage(packaze)).putShort(access);
if (modules == null) {
opens.putShort(0);
size += 6;
} else {
opens.putShort(modules.length);
for (String module : modules) {
opens.putShort(cw.newModule(module));
}
size += 6 + 2 * modules.length;
}
openCount++;
}
@Override
public void visitUse(String service) {
if (uses == null) {
uses = new ByteVector();
}
uses.putShort(cw.newClass(service));
useCount++;
size += 2;
}
@Override
public void visitProvide(String service, String... providers) {
if (provides == null) {
provides = new ByteVector();
}
provides.putShort(cw.newClass(service));
provides.putShort(providers.length);
for (String provider : providers) {
provides.putShort(cw.newClass(provider));
}
provideCount++;
size += 4 + 2 * providers.length;
}
@Override
public void visitEnd() {
// empty
}
void putAttributes(ByteVector out) {
if (mainClass != 0) {
out.putShort(cw.newUTF8("ModuleMainClass")).putInt(2).putShort(mainClass);
}
if (packages != null) {
out.putShort(cw.newUTF8("ModulePackages"))
.putInt(2 + 2 * packageCount)
.putShort(packageCount)
.putByteArray(packages.data, 0, packages.length);
}
}
void put(ByteVector out) {
out.putInt(size);
out.putShort(name).putShort(access).putShort(version);
out.putShort(requireCount);
if (requires != null) {
out.putByteArray(requires.data, 0, requires.length);
}
out.putShort(exportCount);
if (exports != null) {
out.putByteArray(exports.data, 0, exports.length);
}
out.putShort(openCount);
if (opens != null) {
out.putByteArray(opens.data, 0, opens.length);
}
out.putShort(useCount);
if (uses != null) {
out.putByteArray(uses.data, 0, uses.length);
}
out.putShort(provideCount);
if (provides != null) {
out.putByteArray(provides.data, 0, provides.length);
}
}
}

View File

@@ -1,402 +1,402 @@
/*
* ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*/
/*
*
*
*
*
*
* ASM: a very small and fast Java bytecode manipulation framework
* Copyright (c) 2000-2011 INRIA, France Telecom
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
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.
*
* @author Eric Bruneton
* @author Eugene Kuleshov
*/
public interface Opcodes {
// ASM API versions
int ASM4 = 4 << 16 | 0 << 8;
int ASM5 = 5 << 16 | 0 << 8;
int ASM6 = 6 << 16 | 0 << 8;
// versions
int V1_1 = 3 << 16 | 45;
int V1_2 = 0 << 16 | 46;
int V1_3 = 0 << 16 | 47;
int V1_4 = 0 << 16 | 48;
int V1_5 = 0 << 16 | 49;
int V1_6 = 0 << 16 | 50;
int V1_7 = 0 << 16 | 51;
int V1_8 = 0 << 16 | 52;
int V9 = 0 << 16 | 53;
int V10 = 0 << 16 | 54;
int V11 = 0 << 16 | 55;
// access flags
int ACC_PUBLIC = 0x0001; // class, field, method
int ACC_PRIVATE = 0x0002; // class, field, method
int ACC_PROTECTED = 0x0004; // class, field, method
int ACC_STATIC = 0x0008; // field, method
int ACC_FINAL = 0x0010; // class, field, method, parameter
int ACC_SUPER = 0x0020; // class
int ACC_SYNCHRONIZED = 0x0020; // method
int ACC_OPEN = 0x0020; // module
int ACC_TRANSITIVE = 0x0020; // module requires
int ACC_VOLATILE = 0x0040; // field
int ACC_BRIDGE = 0x0040; // method
int ACC_STATIC_PHASE = 0x0040; // module requires
int ACC_VARARGS = 0x0080; // method
int ACC_TRANSIENT = 0x0080; // field
int ACC_NATIVE = 0x0100; // method
int ACC_INTERFACE = 0x0200; // class
int ACC_ABSTRACT = 0x0400; // class, method
int ACC_STRICT = 0x0800; // method
int ACC_SYNTHETIC = 0x1000; // class, field, method, parameter, module *
int ACC_ANNOTATION = 0x2000; // class
int ACC_ENUM = 0x4000; // class(?) field inner
int ACC_MANDATED = 0x8000; // parameter, module, module *
int ACC_MODULE = 0x8000; // class
// ASM specific pseudo access flags
int ACC_DEPRECATED = 0x20000; // class, field, method
// types for NEWARRAY
int T_BOOLEAN = 4;
int T_CHAR = 5;
int T_FLOAT = 6;
int T_DOUBLE = 7;
int T_BYTE = 8;
int T_SHORT = 9;
int T_INT = 10;
int T_LONG = 11;
// tags for Handle
int H_GETFIELD = 1;
int H_GETSTATIC = 2;
int H_PUTFIELD = 3;
int H_PUTSTATIC = 4;
int H_INVOKEVIRTUAL = 5;
int H_INVOKESTATIC = 6;
int H_INVOKESPECIAL = 7;
int H_NEWINVOKESPECIAL = 8;
int H_INVOKEINTERFACE = 9;
// stack map frame types
/** Represents an expanded frame. See {@link ClassReader#EXPAND_FRAMES}. */
int F_NEW = -1;
/** 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.
*/
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.
*/
int F_CHOP = 2;
/** 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.
*/
int F_SAME1 = 4;
// Do not try to change the following code to use auto-boxing,
// 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);
// opcodes // visit method (- = idem)
int NOP = 0; // visitInsn
int ACONST_NULL = 1; // -
int ICONST_M1 = 2; // -
int ICONST_0 = 3; // -
int ICONST_1 = 4; // -
int ICONST_2 = 5; // -
int ICONST_3 = 6; // -
int ICONST_4 = 7; // -
int ICONST_5 = 8; // -
int LCONST_0 = 9; // -
int LCONST_1 = 10; // -
int FCONST_0 = 11; // -
int FCONST_1 = 12; // -
int FCONST_2 = 13; // -
int DCONST_0 = 14; // -
int DCONST_1 = 15; // -
int BIPUSH = 16; // visitIntInsn
int SIPUSH = 17; // -
int LDC = 18; // visitLdcInsn
// int LDC_W = 19; // -
// int LDC2_W = 20; // -
int ILOAD = 21; // visitVarInsn
int LLOAD = 22; // -
int FLOAD = 23; // -
int DLOAD = 24; // -
int ALOAD = 25; // -
// int ILOAD_0 = 26; // -
// int ILOAD_1 = 27; // -
// int ILOAD_2 = 28; // -
// int ILOAD_3 = 29; // -
// int LLOAD_0 = 30; // -
// int LLOAD_1 = 31; // -
// int LLOAD_2 = 32; // -
// int LLOAD_3 = 33; // -
// int FLOAD_0 = 34; // -
// int FLOAD_1 = 35; // -
// int FLOAD_2 = 36; // -
// int FLOAD_3 = 37; // -
// int DLOAD_0 = 38; // -
// int DLOAD_1 = 39; // -
// int DLOAD_2 = 40; // -
// int DLOAD_3 = 41; // -
// int ALOAD_0 = 42; // -
// int ALOAD_1 = 43; // -
// int ALOAD_2 = 44; // -
// int ALOAD_3 = 45; // -
int IALOAD = 46; // visitInsn
int LALOAD = 47; // -
int FALOAD = 48; // -
int DALOAD = 49; // -
int AALOAD = 50; // -
int BALOAD = 51; // -
int CALOAD = 52; // -
int SALOAD = 53; // -
int ISTORE = 54; // visitVarInsn
int LSTORE = 55; // -
int FSTORE = 56; // -
int DSTORE = 57; // -
int ASTORE = 58; // -
// int ISTORE_0 = 59; // -
// int ISTORE_1 = 60; // -
// int ISTORE_2 = 61; // -
// int ISTORE_3 = 62; // -
// int LSTORE_0 = 63; // -
// int LSTORE_1 = 64; // -
// int LSTORE_2 = 65; // -
// int LSTORE_3 = 66; // -
// int FSTORE_0 = 67; // -
// int FSTORE_1 = 68; // -
// int FSTORE_2 = 69; // -
// int FSTORE_3 = 70; // -
// int DSTORE_0 = 71; // -
// int DSTORE_1 = 72; // -
// int DSTORE_2 = 73; // -
// int DSTORE_3 = 74; // -
// int ASTORE_0 = 75; // -
// int ASTORE_1 = 76; // -
// int ASTORE_2 = 77; // -
// int ASTORE_3 = 78; // -
int IASTORE = 79; // visitInsn
int LASTORE = 80; // -
int FASTORE = 81; // -
int DASTORE = 82; // -
int AASTORE = 83; // -
int BASTORE = 84; // -
int CASTORE = 85; // -
int SASTORE = 86; // -
int POP = 87; // -
int POP2 = 88; // -
int DUP = 89; // -
int DUP_X1 = 90; // -
int DUP_X2 = 91; // -
int DUP2 = 92; // -
int DUP2_X1 = 93; // -
int DUP2_X2 = 94; // -
int SWAP = 95; // -
int IADD = 96; // -
int LADD = 97; // -
int FADD = 98; // -
int DADD = 99; // -
int ISUB = 100; // -
int LSUB = 101; // -
int FSUB = 102; // -
int DSUB = 103; // -
int IMUL = 104; // -
int LMUL = 105; // -
int FMUL = 106; // -
int DMUL = 107; // -
int IDIV = 108; // -
int LDIV = 109; // -
int FDIV = 110; // -
int DDIV = 111; // -
int IREM = 112; // -
int LREM = 113; // -
int FREM = 114; // -
int DREM = 115; // -
int INEG = 116; // -
int LNEG = 117; // -
int FNEG = 118; // -
int DNEG = 119; // -
int ISHL = 120; // -
int LSHL = 121; // -
int ISHR = 122; // -
int LSHR = 123; // -
int IUSHR = 124; // -
int LUSHR = 125; // -
int IAND = 126; // -
int LAND = 127; // -
int IOR = 128; // -
int LOR = 129; // -
int IXOR = 130; // -
int LXOR = 131; // -
int IINC = 132; // visitIincInsn
int I2L = 133; // visitInsn
int I2F = 134; // -
int I2D = 135; // -
int L2I = 136; // -
int L2F = 137; // -
int L2D = 138; // -
int F2I = 139; // -
int F2L = 140; // -
int F2D = 141; // -
int D2I = 142; // -
int D2L = 143; // -
int D2F = 144; // -
int I2B = 145; // -
int I2C = 146; // -
int I2S = 147; // -
int LCMP = 148; // -
int FCMPL = 149; // -
int FCMPG = 150; // -
int DCMPL = 151; // -
int DCMPG = 152; // -
int IFEQ = 153; // visitJumpInsn
int IFNE = 154; // -
int IFLT = 155; // -
int IFGE = 156; // -
int IFGT = 157; // -
int IFLE = 158; // -
int IF_ICMPEQ = 159; // -
int IF_ICMPNE = 160; // -
int IF_ICMPLT = 161; // -
int IF_ICMPGE = 162; // -
int IF_ICMPGT = 163; // -
int IF_ICMPLE = 164; // -
int IF_ACMPEQ = 165; // -
int IF_ACMPNE = 166; // -
int GOTO = 167; // -
int JSR = 168; // -
int RET = 169; // visitVarInsn
int TABLESWITCH = 170; // visiTableSwitchInsn
int LOOKUPSWITCH = 171; // visitLookupSwitch
int IRETURN = 172; // visitInsn
int LRETURN = 173; // -
int FRETURN = 174; // -
int DRETURN = 175; // -
int ARETURN = 176; // -
int RETURN = 177; // -
int GETSTATIC = 178; // visitFieldInsn
int PUTSTATIC = 179; // -
int GETFIELD = 180; // -
int PUTFIELD = 181; // -
int INVOKEVIRTUAL = 182; // visitMethodInsn
int INVOKESPECIAL = 183; // -
int INVOKESTATIC = 184; // -
int INVOKEINTERFACE = 185; // -
int INVOKEDYNAMIC = 186; // visitInvokeDynamicInsn
int NEW = 187; // visitTypeInsn
int NEWARRAY = 188; // visitIntInsn
int ANEWARRAY = 189; // visitTypeInsn
int ARRAYLENGTH = 190; // visitInsn
int ATHROW = 191; // -
int CHECKCAST = 192; // visitTypeInsn
int INSTANCEOF = 193; // -
int MONITORENTER = 194; // visitInsn
int MONITOREXIT = 195; // -
// int WIDE = 196; // NOT VISITED
int MULTIANEWARRAY = 197; // visitMultiANewArrayInsn
int IFNULL = 198; // visitJumpInsn
int IFNONNULL = 199; // -
// int GOTO_W = 200; // -
// int JSR_W = 201; // -
}
/*
* ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*/
/*
*
*
*
*
*
* ASM: a very small and fast Java bytecode manipulation framework
* Copyright (c) 2000-2011 INRIA, France Telecom
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
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.
*
* @author Eric Bruneton
* @author Eugene Kuleshov
*/
public interface Opcodes {
// ASM API versions
int ASM4 = 4 << 16 | 0 << 8;
int ASM5 = 5 << 16 | 0 << 8;
int ASM6 = 6 << 16 | 0 << 8;
// versions
int V1_1 = 3 << 16 | 45;
int V1_2 = 0 << 16 | 46;
int V1_3 = 0 << 16 | 47;
int V1_4 = 0 << 16 | 48;
int V1_5 = 0 << 16 | 49;
int V1_6 = 0 << 16 | 50;
int V1_7 = 0 << 16 | 51;
int V1_8 = 0 << 16 | 52;
int V9 = 0 << 16 | 53;
int V10 = 0 << 16 | 54;
int V11 = 0 << 16 | 55;
// access flags
int ACC_PUBLIC = 0x0001; // class, field, method
int ACC_PRIVATE = 0x0002; // class, field, method
int ACC_PROTECTED = 0x0004; // class, field, method
int ACC_STATIC = 0x0008; // field, method
int ACC_FINAL = 0x0010; // class, field, method, parameter
int ACC_SUPER = 0x0020; // class
int ACC_SYNCHRONIZED = 0x0020; // method
int ACC_OPEN = 0x0020; // module
int ACC_TRANSITIVE = 0x0020; // module requires
int ACC_VOLATILE = 0x0040; // field
int ACC_BRIDGE = 0x0040; // method
int ACC_STATIC_PHASE = 0x0040; // module requires
int ACC_VARARGS = 0x0080; // method
int ACC_TRANSIENT = 0x0080; // field
int ACC_NATIVE = 0x0100; // method
int ACC_INTERFACE = 0x0200; // class
int ACC_ABSTRACT = 0x0400; // class, method
int ACC_STRICT = 0x0800; // method
int ACC_SYNTHETIC = 0x1000; // class, field, method, parameter, module *
int ACC_ANNOTATION = 0x2000; // class
int ACC_ENUM = 0x4000; // class(?) field inner
int ACC_MANDATED = 0x8000; // parameter, module, module *
int ACC_MODULE = 0x8000; // class
// ASM specific pseudo access flags
int ACC_DEPRECATED = 0x20000; // class, field, method
// types for NEWARRAY
int T_BOOLEAN = 4;
int T_CHAR = 5;
int T_FLOAT = 6;
int T_DOUBLE = 7;
int T_BYTE = 8;
int T_SHORT = 9;
int T_INT = 10;
int T_LONG = 11;
// tags for Handle
int H_GETFIELD = 1;
int H_GETSTATIC = 2;
int H_PUTFIELD = 3;
int H_PUTSTATIC = 4;
int H_INVOKEVIRTUAL = 5;
int H_INVOKESTATIC = 6;
int H_INVOKESPECIAL = 7;
int H_NEWINVOKESPECIAL = 8;
int H_INVOKEINTERFACE = 9;
// stack map frame types
/** Represents an expanded frame. See {@link ClassReader#EXPAND_FRAMES}. */
int F_NEW = -1;
/** 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.
*/
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.
*/
int F_CHOP = 2;
/** 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.
*/
int F_SAME1 = 4;
// Do not try to change the following code to use auto-boxing,
// 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);
// opcodes // visit method (- = idem)
int NOP = 0; // visitInsn
int ACONST_NULL = 1; // -
int ICONST_M1 = 2; // -
int ICONST_0 = 3; // -
int ICONST_1 = 4; // -
int ICONST_2 = 5; // -
int ICONST_3 = 6; // -
int ICONST_4 = 7; // -
int ICONST_5 = 8; // -
int LCONST_0 = 9; // -
int LCONST_1 = 10; // -
int FCONST_0 = 11; // -
int FCONST_1 = 12; // -
int FCONST_2 = 13; // -
int DCONST_0 = 14; // -
int DCONST_1 = 15; // -
int BIPUSH = 16; // visitIntInsn
int SIPUSH = 17; // -
int LDC = 18; // visitLdcInsn
// int LDC_W = 19; // -
// int LDC2_W = 20; // -
int ILOAD = 21; // visitVarInsn
int LLOAD = 22; // -
int FLOAD = 23; // -
int DLOAD = 24; // -
int ALOAD = 25; // -
// int ILOAD_0 = 26; // -
// int ILOAD_1 = 27; // -
// int ILOAD_2 = 28; // -
// int ILOAD_3 = 29; // -
// int LLOAD_0 = 30; // -
// int LLOAD_1 = 31; // -
// int LLOAD_2 = 32; // -
// int LLOAD_3 = 33; // -
// int FLOAD_0 = 34; // -
// int FLOAD_1 = 35; // -
// int FLOAD_2 = 36; // -
// int FLOAD_3 = 37; // -
// int DLOAD_0 = 38; // -
// int DLOAD_1 = 39; // -
// int DLOAD_2 = 40; // -
// int DLOAD_3 = 41; // -
// int ALOAD_0 = 42; // -
// int ALOAD_1 = 43; // -
// int ALOAD_2 = 44; // -
// int ALOAD_3 = 45; // -
int IALOAD = 46; // visitInsn
int LALOAD = 47; // -
int FALOAD = 48; // -
int DALOAD = 49; // -
int AALOAD = 50; // -
int BALOAD = 51; // -
int CALOAD = 52; // -
int SALOAD = 53; // -
int ISTORE = 54; // visitVarInsn
int LSTORE = 55; // -
int FSTORE = 56; // -
int DSTORE = 57; // -
int ASTORE = 58; // -
// int ISTORE_0 = 59; // -
// int ISTORE_1 = 60; // -
// int ISTORE_2 = 61; // -
// int ISTORE_3 = 62; // -
// int LSTORE_0 = 63; // -
// int LSTORE_1 = 64; // -
// int LSTORE_2 = 65; // -
// int LSTORE_3 = 66; // -
// int FSTORE_0 = 67; // -
// int FSTORE_1 = 68; // -
// int FSTORE_2 = 69; // -
// int FSTORE_3 = 70; // -
// int DSTORE_0 = 71; // -
// int DSTORE_1 = 72; // -
// int DSTORE_2 = 73; // -
// int DSTORE_3 = 74; // -
// int ASTORE_0 = 75; // -
// int ASTORE_1 = 76; // -
// int ASTORE_2 = 77; // -
// int ASTORE_3 = 78; // -
int IASTORE = 79; // visitInsn
int LASTORE = 80; // -
int FASTORE = 81; // -
int DASTORE = 82; // -
int AASTORE = 83; // -
int BASTORE = 84; // -
int CASTORE = 85; // -
int SASTORE = 86; // -
int POP = 87; // -
int POP2 = 88; // -
int DUP = 89; // -
int DUP_X1 = 90; // -
int DUP_X2 = 91; // -
int DUP2 = 92; // -
int DUP2_X1 = 93; // -
int DUP2_X2 = 94; // -
int SWAP = 95; // -
int IADD = 96; // -
int LADD = 97; // -
int FADD = 98; // -
int DADD = 99; // -
int ISUB = 100; // -
int LSUB = 101; // -
int FSUB = 102; // -
int DSUB = 103; // -
int IMUL = 104; // -
int LMUL = 105; // -
int FMUL = 106; // -
int DMUL = 107; // -
int IDIV = 108; // -
int LDIV = 109; // -
int FDIV = 110; // -
int DDIV = 111; // -
int IREM = 112; // -
int LREM = 113; // -
int FREM = 114; // -
int DREM = 115; // -
int INEG = 116; // -
int LNEG = 117; // -
int FNEG = 118; // -
int DNEG = 119; // -
int ISHL = 120; // -
int LSHL = 121; // -
int ISHR = 122; // -
int LSHR = 123; // -
int IUSHR = 124; // -
int LUSHR = 125; // -
int IAND = 126; // -
int LAND = 127; // -
int IOR = 128; // -
int LOR = 129; // -
int IXOR = 130; // -
int LXOR = 131; // -
int IINC = 132; // visitIincInsn
int I2L = 133; // visitInsn
int I2F = 134; // -
int I2D = 135; // -
int L2I = 136; // -
int L2F = 137; // -
int L2D = 138; // -
int F2I = 139; // -
int F2L = 140; // -
int F2D = 141; // -
int D2I = 142; // -
int D2L = 143; // -
int D2F = 144; // -
int I2B = 145; // -
int I2C = 146; // -
int I2S = 147; // -
int LCMP = 148; // -
int FCMPL = 149; // -
int FCMPG = 150; // -
int DCMPL = 151; // -
int DCMPG = 152; // -
int IFEQ = 153; // visitJumpInsn
int IFNE = 154; // -
int IFLT = 155; // -
int IFGE = 156; // -
int IFGT = 157; // -
int IFLE = 158; // -
int IF_ICMPEQ = 159; // -
int IF_ICMPNE = 160; // -
int IF_ICMPLT = 161; // -
int IF_ICMPGE = 162; // -
int IF_ICMPGT = 163; // -
int IF_ICMPLE = 164; // -
int IF_ACMPEQ = 165; // -
int IF_ACMPNE = 166; // -
int GOTO = 167; // -
int JSR = 168; // -
int RET = 169; // visitVarInsn
int TABLESWITCH = 170; // visiTableSwitchInsn
int LOOKUPSWITCH = 171; // visitLookupSwitch
int IRETURN = 172; // visitInsn
int LRETURN = 173; // -
int FRETURN = 174; // -
int DRETURN = 175; // -
int ARETURN = 176; // -
int RETURN = 177; // -
int GETSTATIC = 178; // visitFieldInsn
int PUTSTATIC = 179; // -
int GETFIELD = 180; // -
int PUTFIELD = 181; // -
int INVOKEVIRTUAL = 182; // visitMethodInsn
int INVOKESPECIAL = 183; // -
int INVOKESTATIC = 184; // -
int INVOKEINTERFACE = 185; // -
int INVOKEDYNAMIC = 186; // visitInvokeDynamicInsn
int NEW = 187; // visitTypeInsn
int NEWARRAY = 188; // visitIntInsn
int ANEWARRAY = 189; // visitTypeInsn
int ARRAYLENGTH = 190; // visitInsn
int ATHROW = 191; // -
int CHECKCAST = 192; // visitTypeInsn
int INSTANCEOF = 193; // -
int MONITORENTER = 194; // visitInsn
int MONITOREXIT = 195; // -
// int WIDE = 196; // NOT VISITED
int MULTIANEWARRAY = 197; // visitMultiANewArrayInsn
int IFNULL = 198; // visitJumpInsn
int IFNONNULL = 199; // -
// int GOTO_W = 200; // -
// int JSR_W = 201; // -
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,195 +1,195 @@
/*
* ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*/
/*
*
*
*
*
*
* ASM: a very small and fast Java bytecode manipulation framework
* Copyright (c) 2000-2013 INRIA, France Telecom
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.redkale.asm;
/**
* 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 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 static final int INNER_TYPE = 1;
/** 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 static final int TYPE_ARGUMENT = 3;
/** 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'. */
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'.
*/
TypePath(byte[] b, int offset) {
this.b = b;
this.offset = offset;
}
/**
* Returns the length of this path.
*
* @return the length of this path.
*/
public int getLength() {
return b[offset];
}
/**
* 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}.
*/
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}.
*
* @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.
*
* @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) {
if (typePath == null || typePath.isEmpty()) {
return null;
}
int n = typePath.length();
ByteVector out = new ByteVector(n);
out.putByte(0);
for (int i = 0; i < n; ) {
char c = typePath.charAt(i++);
if (c == '[') {
out.put11(ARRAY_ELEMENT, 0);
} else if (c == '.') {
out.put11(INNER_TYPE, 0);
} else if (c == '*') {
out.put11(WILDCARD_BOUND, 0);
} else if (c >= '0' && c <= '9') {
int typeArg = c - '0';
while (i < n && (c = typePath.charAt(i)) >= '0' && c <= '9') {
typeArg = typeArg * 10 + c - '0';
i += 1;
}
if (i < n && typePath.charAt(i) == ';') {
i += 1;
}
out.put11(TYPE_ARGUMENT, typeArg);
}
}
out.data[0] = (byte) (out.length / 2);
return new TypePath(out.data, 0);
}
/**
* 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() {
int length = getLength();
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('_');
}
}
return result.toString();
}
}
/*
* ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*/
/*
*
*
*
*
*
* ASM: a very small and fast Java bytecode manipulation framework
* Copyright (c) 2000-2013 INRIA, France Telecom
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.redkale.asm;
/**
* 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 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 static final int INNER_TYPE = 1;
/** 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 static final int TYPE_ARGUMENT = 3;
/** 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'. */
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'.
*/
TypePath(byte[] b, int offset) {
this.b = b;
this.offset = offset;
}
/**
* Returns the length of this path.
*
* @return the length of this path.
*/
public int getLength() {
return b[offset];
}
/**
* 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}.
*/
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}.
*
* @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.
*
* @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) {
if (typePath == null || typePath.isEmpty()) {
return null;
}
int n = typePath.length();
ByteVector out = new ByteVector(n);
out.putByte(0);
for (int i = 0; i < n; ) {
char c = typePath.charAt(i++);
if (c == '[') {
out.put11(ARRAY_ELEMENT, 0);
} else if (c == '.') {
out.put11(INNER_TYPE, 0);
} else if (c == '*') {
out.put11(WILDCARD_BOUND, 0);
} else if (c >= '0' && c <= '9') {
int typeArg = c - '0';
while (i < n && (c = typePath.charAt(i)) >= '0' && c <= '9') {
typeArg = typeArg * 10 + c - '0';
i += 1;
}
if (i < n && typePath.charAt(i) == ';') {
i += 1;
}
out.put11(TYPE_ARGUMENT, typeArg);
}
}
out.data[0] = (byte) (out.length / 2);
return new TypePath(out.data, 0);
}
/**
* 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() {
int length = getLength();
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('_');
}
}
return result.toString();
}
}

View File

@@ -1,402 +1,402 @@
/*
* ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*/
/*
*
*
*
*
*
* ASM: a very small and fast Java bytecode manipulation framework
* Copyright (c) 2000-2013 INRIA, France Telecom
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
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).
*
* @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 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 the super class of a class or one of the interfaces it implements. See
* {@link #getSort getSort}.
*/
public static final 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 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 static final int THROWS = 0x17;
/**
* The sort of type references that target the type of a local variable in a method. See {@link #getSort getSort}.
*/
public static final int LOCAL_VARIABLE = 0x40;
/**
* The sort of type references that target the type of a resource variable in a method. See {@link #getSort
* getSort}.
*/
public static final int RESOURCE_VARIABLE = 0x41;
/**
* The sort of type references that target the type of the exception of a 'catch' clause in a method. See
* {@link #getSort getSort}.
*/
public static final int EXCEPTION_PARAMETER = 0x42;
/**
* The sort of type references that target the type declared in an 'instanceof' instruction. See {@link #getSort
* getSort}.
*/
public static final int INSTANCEOF = 0x43;
/**
* The sort of type references that target the type of the object created by a 'new' instruction. See
* {@link #getSort getSort}.
*/
public static final int NEW = 0x44;
/**
* The sort of type references that target the receiver type of a constructor reference. See {@link #getSort
* getSort}.
*/
public static final int CONSTRUCTOR_REFERENCE = 0x45;
/**
* The sort of type references that target the receiver type of a method reference. See {@link #getSort getSort}.
*/
public static final int METHOD_REFERENCE = 0x46;
/**
* The sort of type references that target the type declared in an explicit or implicit cast instruction. See
* {@link #getSort getSort}.
*/
public static final int CAST = 0x47;
/**
* The sort of type references that target a type parameter of a generic constructor in a constructor call. See
* {@link #getSort getSort}.
*/
public static final int CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT = 0x48;
/**
* The sort of type references that target a type parameter of a generic method in a method call. See
* {@link #getSort getSort}.
*/
public static final 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 static final 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 static final int METHOD_REFERENCE_TYPE_ARGUMENT = 0x4B;
/** 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.
*/
public TypeReference(int typeRef) {
this.value = typeRef;
}
/**
* 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}.
* @return a type reference of the given sort.
*/
public static TypeReference newTypeReference(int sort) {
return new TypeReference(sort << 24);
}
/**
* 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.
* @return a reference to the given generic class or method type parameter.
*/
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.
*
* @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));
}
/**
* 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.
* @return a reference to the given super type of a class.
*/
public static TypeReference newSuperTypeReference(int itfIndex) {
itfIndex &= 0xFFFF;
return new TypeReference((CLASS_EXTENDS << 24) | (itfIndex << 8));
}
/**
* Returns a reference to the type of a formal parameter of a method.
*
* @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));
}
/**
* 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) {
return new TypeReference((THROWS << 24) | (exceptionIndex << 8));
}
/**
* 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));
}
/**
* 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) {
return new TypeReference((sort << 24) | argIndex);
}
/**
* 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}.
*/
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
* {@link #METHOD_TYPE_PARAMETER_BOUND METHOD_TYPE_PARAMETER_BOUND}.
*
* @return a type parameter index.
*/
public int getTypeParameterIndex() {
return (value & 0x00FF0000) >> 16;
}
/**
* 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.
*/
public int getTypeParameterBoundIndex() {
return (value & 0x0000FF00) >> 8;
}
/**
* 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.
*/
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}.
*
* @return a formal parameter index.
*/
public int getFormalParameterIndex() {
return (value & 0x00FF0000) >> 16;
}
/**
* 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.
*/
public int getExceptionIndex() {
return (value & 0x00FFFF00) >> 8;
}
/**
* 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.
*/
public int getTryCatchBlockIndex() {
return (value & 0x00FFFF00) >> 8;
}
/**
* 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.
*/
public int getTypeArgumentIndex() {
return value & 0xFF;
}
/**
* 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.
*/
public int getValue() {
return value;
}
}
/*
* ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*/
/*
*
*
*
*
*
* ASM: a very small and fast Java bytecode manipulation framework
* Copyright (c) 2000-2013 INRIA, France Telecom
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
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).
*
* @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 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 the super class of a class or one of the interfaces it implements. See
* {@link #getSort getSort}.
*/
public static final 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 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 static final int THROWS = 0x17;
/**
* The sort of type references that target the type of a local variable in a method. See {@link #getSort getSort}.
*/
public static final int LOCAL_VARIABLE = 0x40;
/**
* The sort of type references that target the type of a resource variable in a method. See {@link #getSort
* getSort}.
*/
public static final int RESOURCE_VARIABLE = 0x41;
/**
* The sort of type references that target the type of the exception of a 'catch' clause in a method. See
* {@link #getSort getSort}.
*/
public static final int EXCEPTION_PARAMETER = 0x42;
/**
* The sort of type references that target the type declared in an 'instanceof' instruction. See {@link #getSort
* getSort}.
*/
public static final int INSTANCEOF = 0x43;
/**
* The sort of type references that target the type of the object created by a 'new' instruction. See
* {@link #getSort getSort}.
*/
public static final int NEW = 0x44;
/**
* The sort of type references that target the receiver type of a constructor reference. See {@link #getSort
* getSort}.
*/
public static final int CONSTRUCTOR_REFERENCE = 0x45;
/**
* The sort of type references that target the receiver type of a method reference. See {@link #getSort getSort}.
*/
public static final int METHOD_REFERENCE = 0x46;
/**
* The sort of type references that target the type declared in an explicit or implicit cast instruction. See
* {@link #getSort getSort}.
*/
public static final int CAST = 0x47;
/**
* The sort of type references that target a type parameter of a generic constructor in a constructor call. See
* {@link #getSort getSort}.
*/
public static final int CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT = 0x48;
/**
* The sort of type references that target a type parameter of a generic method in a method call. See
* {@link #getSort getSort}.
*/
public static final 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 static final 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 static final int METHOD_REFERENCE_TYPE_ARGUMENT = 0x4B;
/** 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.
*/
public TypeReference(int typeRef) {
this.value = typeRef;
}
/**
* 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}.
* @return a type reference of the given sort.
*/
public static TypeReference newTypeReference(int sort) {
return new TypeReference(sort << 24);
}
/**
* 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.
* @return a reference to the given generic class or method type parameter.
*/
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.
*
* @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));
}
/**
* 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.
* @return a reference to the given super type of a class.
*/
public static TypeReference newSuperTypeReference(int itfIndex) {
itfIndex &= 0xFFFF;
return new TypeReference((CLASS_EXTENDS << 24) | (itfIndex << 8));
}
/**
* Returns a reference to the type of a formal parameter of a method.
*
* @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));
}
/**
* 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) {
return new TypeReference((THROWS << 24) | (exceptionIndex << 8));
}
/**
* 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));
}
/**
* 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) {
return new TypeReference((sort << 24) | argIndex);
}
/**
* 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}.
*/
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
* {@link #METHOD_TYPE_PARAMETER_BOUND METHOD_TYPE_PARAMETER_BOUND}.
*
* @return a type parameter index.
*/
public int getTypeParameterIndex() {
return (value & 0x00FF0000) >> 16;
}
/**
* 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.
*/
public int getTypeParameterBoundIndex() {
return (value & 0x0000FF00) >> 8;
}
/**
* 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.
*/
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}.
*
* @return a formal parameter index.
*/
public int getFormalParameterIndex() {
return (value & 0x00FF0000) >> 16;
}
/**
* 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.
*/
public int getExceptionIndex() {
return (value & 0x00FFFF00) >> 8;
}
/**
* 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.
*/
public int getTryCatchBlockIndex() {
return (value & 0x00FFFF00) >> 8;
}
/**
* 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.
*/
public int getTypeArgumentIndex() {
return value & 0xFF;
}
/**
* 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.
*/
public int getValue() {
return value;
}
}

View File

@@ -1,494 +1,494 @@
/*
*
*/
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;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.URI;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Properties;
import java.util.Set;
import java.util.logging.SimpleFormatter;
import org.redkale.source.DataSources;
import org.redkale.util.AnyValue;
import org.redkale.util.AnyValueWriter;
import org.redkale.util.RedkaleClassLoader;
import org.redkale.util.RedkaleException;
import org.redkale.util.Utility;
/**
* 加载系统参数配置
*
* @author zhangjx
*/
class AppConfig {
/**
* 当前进程的配置文件, 类型String、URI、File、Path <br>
* 一般命名为: application.xml、application.onlyLogProps 若配置文件不是本地文件, 则File、Path类型的值为null
*/
static final String PARAM_APP_CONF_FILE = "APP_CONF_FILE";
// 是否用于main方法运行
final boolean singletonMode;
// 是否用于编译模式运行
final boolean compileMode;
// application.xml原始配置信息
AnyValue config;
// 是否从/META-INF中读取配置
boolean configFromCache;
// 本进程节点ID
String nodeid;
// 本进程节点ID
String name;
// 本地IP地址
InetSocketAddress localAddress;
// 进程根目录
File home;
// 配置文件目录
File confFile;
// 配置文件目录
URI confDir;
// 根ClassLoader
RedkaleClassLoader classLoader;
// Server根ClassLoader
RedkaleClassLoader serverClassLoader;
// 本地文件日志配置项
final Properties locaLogProperties = new Properties();
// 本地文件除logging配置之外的所有的配置项, 包含system.property.、mimetype.property.开头的
final Properties localEnvProperties = new Properties();
public AppConfig(boolean singletonMode, boolean compileMode) {
this.singletonMode = singletonMode;
this.compileMode = compileMode;
}
public static AppConfig create(boolean singletonMode, boolean compileMode) throws IOException {
AppConfig rs = new AppConfig(singletonMode, compileMode);
rs.init(loadAppConfig());
return rs;
}
private void init(AnyValue conf) {
this.config = conf;
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
this.initClassLoader();
// 初始化home、confDir、localAddress等信息
this.initAppHome();
// 读取本地参数配置
this.initLocalProperties();
// 读取本地日志配置
this.initLogProperties();
// 读取本地数据库配置
this.initSourceProperties();
}
/** 初始化classLoader、serverClassLoader */
private void initClassLoader() {
ClassLoader currClassLoader = Thread.currentThread().getContextClassLoader();
if (currClassLoader instanceof RedkaleClassLoader) {
this.classLoader = (RedkaleClassLoader) currClassLoader;
} else {
Set<String> cacheClasses = null;
if (!singletonMode && !compileMode) {
try {
InputStream in =
Application.class.getResourceAsStream(RedkaleClassLoader.RESOURCE_CACHE_CLASSES_PATH);
if (in != null) {
BufferedReader reader =
new BufferedReader(new InputStreamReader(in, StandardCharsets.UTF_8), 1024);
List<String> list = new ArrayList<>();
reader.lines().forEach(list::add);
Collections.sort(list);
if (!list.isEmpty()) {
cacheClasses = new LinkedHashSet<>(list);
}
in.close();
}
} catch (Exception e) {
// do nothing
}
}
if (cacheClasses == null) {
this.classLoader = new RedkaleClassLoader(currClassLoader);
} else {
this.classLoader = new RedkaleClassLoader.RedkaleCacheClassLoader(currClassLoader, cacheClasses);
}
Thread.currentThread().setContextClassLoader(this.classLoader);
}
if (compileMode || this.classLoader instanceof RedkaleClassLoader.RedkaleCacheClassLoader) {
this.serverClassLoader = this.classLoader;
} else {
this.serverClassLoader = new RedkaleClassLoader(this.classLoader);
}
}
/** 初始化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
this.confDir = URI.create(confDir);
if (confDir.startsWith("file:")) {
this.confFile = getCanonicalFile(new File(this.confDir.getPath()));
}
} else if (confDir.charAt(0) == '/' || confDir.indexOf(':') > -1) {
this.confFile = getCanonicalFile(new File(confDir));
this.confDir = confFile.toURI();
} else {
this.confFile = new File(getCanonicalPath(new File(this.home, confDir)));
this.confDir = confFile.toURI();
}
String localaddr = config.getValue("address", "").trim();
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);
}
});
AnyValue propsConf = this.config.getAnyValue("properties");
if (propsConf == null) {
final AnyValue resources = config.getAnyValue("resources");
if (resources != null) {
System.err.println("<resources> in application config file is deprecated");
propsConf = resources.getAnyValue("properties");
}
}
if (propsConf != null) { // 设置配置文件中的系统变量
for (AnyValue prop : propsConf.getAnyValues("property")) {
String key = prop.getValue("name", "");
String value = prop.getValue("value");
if (value != null) {
localEnvProperties.put(key, value);
}
}
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());
if (df == null) {
continue;
}
if (!"file".equals(df.getScheme()) || df.toString().contains("!") || new File(df).isFile()) {
Properties props = new Properties();
try {
InputStream in = df.toURL().openStream();
props.load(in);
in.close();
localEnvProperties.putAll(props);
} catch (Exception e) {
throw new RedkaleException(e);
}
}
}
}
}
// 设置Convert默认配置项
if (System.getProperty("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.put("system.property.redkale.convert.writer.buffer.defsize", "4096");
}
}
/** 读取本地DataSource、CacheSource配置 */
private void initSourceProperties() {
if ("file".equals(this.confDir.getScheme())) {
File sourceFile = new File(new File(confDir), "source.properties");
if (sourceFile.isFile() && sourceFile.canRead()) {
Properties props = new Properties();
try {
InputStream in = new FileInputStream(sourceFile);
props.load(in);
in.close();
} catch (IOException e) {
throw new RedkaleException(e);
}
this.localEnvProperties.putAll(props);
} else {
// 兼容 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");
try {
InputStream in = new FileInputStream(persist);
this.localEnvProperties.putAll(DataSources.loadSourceProperties(in));
in.close();
} catch (IOException e) {
throw new RedkaleException(e);
}
}
}
} else { // 从url或jar文件中resources读取
try {
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;
if (configFromCache) {
logConfURI = RedkaleClassLoader.getConfResourceAsURI(null, "logging.properties");
} else if ("file".equals(confDir.getScheme())) {
logConfFile = new File(confDir.getPath(), "logging.properties");
logConfURI = logConfFile.toURI();
if (!logConfFile.isFile() || !logConfFile.canRead()) {
logConfFile = null;
}
} else {
logConfURI = URI.create(confDir + (confDir.toString().endsWith("/") ? "" : "/") + "logging.properties");
}
if (!"file".equals(confDir.getScheme()) || logConfFile != null) {
try {
InputStream fin = logConfURI.toURL().openStream();
Properties properties0 = new Properties();
properties0.load(fin);
fin.close();
properties0.forEach(locaLogProperties::put);
} catch (IOException e) {
throw new RedkaleException("read logging.properties error", e);
}
}
if (compileMode) {
putReflectionClass(java.lang.Class.class.getName());
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());
}
}
/**
* 从本地application.xml或application.properties文件加载配置信息
*
* @return 配置信息
* @throws IOException
*/
static AnyValue loadAppConfig() throws IOException {
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;
if (sysConfFile.contains("://")) {
text = Utility.readThenClose(URI.create(sysConfFile).toURL().openStream());
} else {
File f = new File(sysConfFile);
if (f.isFile() && f.canRead()) {
text = Utility.readThenClose(new FileInputStream(f));
} else {
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");
}
String confDir = System.getProperty(RESNAME_APP_CONF_DIR, "conf");
URI appConfFile;
boolean fromCache = false;
if (confDir.contains("://")) { // jar内部资源
appConfFile = URI.create(confDir + (confDir.endsWith("/") ? "" : "/") + "application.xml");
try {
appConfFile.toURL().openStream().close();
} catch (IOException e) { // 没有application.xml就尝试读application.properties
appConfFile = URI.create(confDir + (confDir.endsWith("/") ? "" : "/") + "application.properties");
}
} else if (confDir.charAt(0) == '/' || confDir.indexOf(':') > 0) { // 绝对路径
File f = new File(confDir, "application.xml");
if (f.isFile() && f.canRead()) {
appConfFile = f.toURI();
confDir = f.getParentFile().getCanonicalPath();
} else {
f = new File(confDir, "application.properties");
if (f.isFile() && f.canRead()) {
appConfFile = f.toURI();
confDir = f.getParentFile().getCanonicalPath();
} else {
appConfFile = RedkaleClassLoader.getConfResourceAsURI(null, "application.xml"); // 不能传confDir
try {
appConfFile.toURL().openStream().close();
} catch (IOException e) { // 没有application.xml就尝试读application.properties
appConfFile = RedkaleClassLoader.getConfResourceAsURI(null, "application.properties");
}
confDir = appConfFile
.toString()
.replace("/application.xml", "")
.replace("/application.properties", "");
fromCache = true;
}
}
} else { // 相对路径
File f = new File(new File(home, confDir), "application.xml");
if (f.isFile() && f.canRead()) {
appConfFile = f.toURI();
confDir = f.getParentFile().getCanonicalPath();
} else {
f = new File(new File(home, confDir), "application.properties");
if (f.isFile() && f.canRead()) {
appConfFile = f.toURI();
confDir = f.getParentFile().getCanonicalPath();
} else {
appConfFile = RedkaleClassLoader.getConfResourceAsURI(null, "application.xml"); // 不能传confDir
try {
appConfFile.toURL().openStream().close();
} catch (IOException e) { // 没有application.xml就尝试读application.properties
appConfFile = RedkaleClassLoader.getConfResourceAsURI(null, "application.properties");
}
confDir = appConfFile
.toString()
.replace("/application.xml", "")
.replace("/application.properties", "");
fromCache = true;
}
}
}
System.setProperty(RESNAME_APP_CONF_DIR, confDir);
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");
} else {
conf = AnyValue.loadFromProperties(text).getAnyValue("redkale");
}
if (fromCache) {
((AnyValueWriter) conf).addValue("[config-from-cache]", "true");
}
return conf;
}
/**
* 检查name是否含特殊字符
*
* @param name
* @return
*/
private static String checkName(String name) {
if (name == null || name.isEmpty()) {
return name;
}
for (char ch : name.toCharArray()) {
if (!((ch >= '0' && ch <= '9')
|| (ch >= 'a' && ch <= 'z')
|| (ch >= 'A' && ch <= 'Z')
|| ch == '_'
|| ch == '.'
|| ch == '-')) { // 不能含特殊字符
throw new RedkaleException("name only 0-9 a-z A-Z _ - .");
}
}
return name;
}
/**
* 检查node是否含特殊字符
*
* @param name
* @return
*/
private static String checkNodeid(String nodeid) {
if (nodeid == null || nodeid.isEmpty()) {
return nodeid;
}
for (char ch : nodeid.toCharArray()) {
if (!((ch >= '0' && ch <= '9')
|| (ch >= 'a' && ch <= 'z')
|| (ch >= 'A' && ch <= 'Z')
|| ch == '_'
|| ch == '.'
|| ch == '-')) { // 不能含特殊字符
throw new RedkaleException("nodeid only 0-9 a-z A-Z _ - .");
}
}
return nodeid;
}
private String getCanonicalPath(File file) {
try {
return file.getCanonicalPath();
} catch (IOException e) {
return file.getAbsolutePath();
}
}
private File getCanonicalFile(File file) {
try {
return file.getCanonicalFile();
} catch (IOException e) {
return file;
}
}
}
/*
*
*/
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;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.URI;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Properties;
import java.util.Set;
import java.util.logging.SimpleFormatter;
import org.redkale.source.DataSources;
import org.redkale.util.AnyValue;
import org.redkale.util.AnyValueWriter;
import org.redkale.util.RedkaleClassLoader;
import org.redkale.util.RedkaleException;
import org.redkale.util.Utility;
/**
* 加载系统参数配置
*
* @author zhangjx
*/
class AppConfig {
/**
* 当前进程的配置文件, 类型String、URI、File、Path <br>
* 一般命名为: application.xml、application.onlyLogProps 若配置文件不是本地文件, 则File、Path类型的值为null
*/
static final String PARAM_APP_CONF_FILE = "APP_CONF_FILE";
// 是否用于main方法运行
final boolean singletonMode;
// 是否用于编译模式运行
final boolean compileMode;
// application.xml原始配置信息
AnyValue config;
// 是否从/META-INF中读取配置
boolean configFromCache;
// 本进程节点ID
String nodeid;
// 本进程节点ID
String name;
// 本地IP地址
InetSocketAddress localAddress;
// 进程根目录
File home;
// 配置文件目录
File confFile;
// 配置文件目录
URI confDir;
// 根ClassLoader
RedkaleClassLoader classLoader;
// Server根ClassLoader
RedkaleClassLoader serverClassLoader;
// 本地文件日志配置项
final Properties locaLogProperties = new Properties();
// 本地文件除logging配置之外的所有的配置项, 包含system.property.、mimetype.property.开头的
final Properties localEnvProperties = new Properties();
public AppConfig(boolean singletonMode, boolean compileMode) {
this.singletonMode = singletonMode;
this.compileMode = compileMode;
}
public static AppConfig create(boolean singletonMode, boolean compileMode) throws IOException {
AppConfig rs = new AppConfig(singletonMode, compileMode);
rs.init(loadAppConfig());
return rs;
}
private void init(AnyValue conf) {
this.config = conf;
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
this.initClassLoader();
// 初始化home、confDir、localAddress等信息
this.initAppHome();
// 读取本地参数配置
this.initLocalProperties();
// 读取本地日志配置
this.initLogProperties();
// 读取本地数据库配置
this.initSourceProperties();
}
/** 初始化classLoader、serverClassLoader */
private void initClassLoader() {
ClassLoader currClassLoader = Thread.currentThread().getContextClassLoader();
if (currClassLoader instanceof RedkaleClassLoader) {
this.classLoader = (RedkaleClassLoader) currClassLoader;
} else {
Set<String> cacheClasses = null;
if (!singletonMode && !compileMode) {
try {
InputStream in =
Application.class.getResourceAsStream(RedkaleClassLoader.RESOURCE_CACHE_CLASSES_PATH);
if (in != null) {
BufferedReader reader =
new BufferedReader(new InputStreamReader(in, StandardCharsets.UTF_8), 1024);
List<String> list = new ArrayList<>();
reader.lines().forEach(list::add);
Collections.sort(list);
if (!list.isEmpty()) {
cacheClasses = new LinkedHashSet<>(list);
}
in.close();
}
} catch (Exception e) {
// do nothing
}
}
if (cacheClasses == null) {
this.classLoader = new RedkaleClassLoader(currClassLoader);
} else {
this.classLoader = new RedkaleClassLoader.RedkaleCacheClassLoader(currClassLoader, cacheClasses);
}
Thread.currentThread().setContextClassLoader(this.classLoader);
}
if (compileMode || this.classLoader instanceof RedkaleClassLoader.RedkaleCacheClassLoader) {
this.serverClassLoader = this.classLoader;
} else {
this.serverClassLoader = new RedkaleClassLoader(this.classLoader);
}
}
/** 初始化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
this.confDir = URI.create(confDir);
if (confDir.startsWith("file:")) {
this.confFile = getCanonicalFile(new File(this.confDir.getPath()));
}
} else if (confDir.charAt(0) == '/' || confDir.indexOf(':') > -1) {
this.confFile = getCanonicalFile(new File(confDir));
this.confDir = confFile.toURI();
} else {
this.confFile = new File(getCanonicalPath(new File(this.home, confDir)));
this.confDir = confFile.toURI();
}
String localaddr = config.getValue("address", "").trim();
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);
}
});
AnyValue propsConf = this.config.getAnyValue("properties");
if (propsConf == null) {
final AnyValue resources = config.getAnyValue("resources");
if (resources != null) {
System.err.println("<resources> in application config file is deprecated");
propsConf = resources.getAnyValue("properties");
}
}
if (propsConf != null) { // 设置配置文件中的系统变量
for (AnyValue prop : propsConf.getAnyValues("property")) {
String key = prop.getValue("name", "");
String value = prop.getValue("value");
if (value != null) {
localEnvProperties.put(key, value);
}
}
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());
if (df == null) {
continue;
}
if (!"file".equals(df.getScheme()) || df.toString().contains("!") || new File(df).isFile()) {
Properties props = new Properties();
try {
InputStream in = df.toURL().openStream();
props.load(in);
in.close();
localEnvProperties.putAll(props);
} catch (Exception e) {
throw new RedkaleException(e);
}
}
}
}
}
// 设置Convert默认配置项
if (System.getProperty("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.put("system.property.redkale.convert.writer.buffer.defsize", "4096");
}
}
/** 读取本地DataSource、CacheSource配置 */
private void initSourceProperties() {
if ("file".equals(this.confDir.getScheme())) {
File sourceFile = new File(new File(confDir), "source.properties");
if (sourceFile.isFile() && sourceFile.canRead()) {
Properties props = new Properties();
try {
InputStream in = new FileInputStream(sourceFile);
props.load(in);
in.close();
} catch (IOException e) {
throw new RedkaleException(e);
}
this.localEnvProperties.putAll(props);
} else {
// 兼容 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");
try {
InputStream in = new FileInputStream(persist);
this.localEnvProperties.putAll(DataSources.loadSourceProperties(in));
in.close();
} catch (IOException e) {
throw new RedkaleException(e);
}
}
}
} else { // 从url或jar文件中resources读取
try {
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;
if (configFromCache) {
logConfURI = RedkaleClassLoader.getConfResourceAsURI(null, "logging.properties");
} else if ("file".equals(confDir.getScheme())) {
logConfFile = new File(confDir.getPath(), "logging.properties");
logConfURI = logConfFile.toURI();
if (!logConfFile.isFile() || !logConfFile.canRead()) {
logConfFile = null;
}
} else {
logConfURI = URI.create(confDir + (confDir.toString().endsWith("/") ? "" : "/") + "logging.properties");
}
if (!"file".equals(confDir.getScheme()) || logConfFile != null) {
try {
InputStream fin = logConfURI.toURL().openStream();
Properties properties0 = new Properties();
properties0.load(fin);
fin.close();
properties0.forEach(locaLogProperties::put);
} catch (IOException e) {
throw new RedkaleException("read logging.properties error", e);
}
}
if (compileMode) {
putReflectionClass(java.lang.Class.class.getName());
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());
}
}
/**
* 从本地application.xml或application.properties文件加载配置信息
*
* @return 配置信息
* @throws IOException
*/
static AnyValue loadAppConfig() throws IOException {
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;
if (sysConfFile.contains("://")) {
text = Utility.readThenClose(URI.create(sysConfFile).toURL().openStream());
} else {
File f = new File(sysConfFile);
if (f.isFile() && f.canRead()) {
text = Utility.readThenClose(new FileInputStream(f));
} else {
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");
}
String confDir = System.getProperty(RESNAME_APP_CONF_DIR, "conf");
URI appConfFile;
boolean fromCache = false;
if (confDir.contains("://")) { // jar内部资源
appConfFile = URI.create(confDir + (confDir.endsWith("/") ? "" : "/") + "application.xml");
try {
appConfFile.toURL().openStream().close();
} catch (IOException e) { // 没有application.xml就尝试读application.properties
appConfFile = URI.create(confDir + (confDir.endsWith("/") ? "" : "/") + "application.properties");
}
} else if (confDir.charAt(0) == '/' || confDir.indexOf(':') > 0) { // 绝对路径
File f = new File(confDir, "application.xml");
if (f.isFile() && f.canRead()) {
appConfFile = f.toURI();
confDir = f.getParentFile().getCanonicalPath();
} else {
f = new File(confDir, "application.properties");
if (f.isFile() && f.canRead()) {
appConfFile = f.toURI();
confDir = f.getParentFile().getCanonicalPath();
} else {
appConfFile = RedkaleClassLoader.getConfResourceAsURI(null, "application.xml"); // 不能传confDir
try {
appConfFile.toURL().openStream().close();
} catch (IOException e) { // 没有application.xml就尝试读application.properties
appConfFile = RedkaleClassLoader.getConfResourceAsURI(null, "application.properties");
}
confDir = appConfFile
.toString()
.replace("/application.xml", "")
.replace("/application.properties", "");
fromCache = true;
}
}
} else { // 相对路径
File f = new File(new File(home, confDir), "application.xml");
if (f.isFile() && f.canRead()) {
appConfFile = f.toURI();
confDir = f.getParentFile().getCanonicalPath();
} else {
f = new File(new File(home, confDir), "application.properties");
if (f.isFile() && f.canRead()) {
appConfFile = f.toURI();
confDir = f.getParentFile().getCanonicalPath();
} else {
appConfFile = RedkaleClassLoader.getConfResourceAsURI(null, "application.xml"); // 不能传confDir
try {
appConfFile.toURL().openStream().close();
} catch (IOException e) { // 没有application.xml就尝试读application.properties
appConfFile = RedkaleClassLoader.getConfResourceAsURI(null, "application.properties");
}
confDir = appConfFile
.toString()
.replace("/application.xml", "")
.replace("/application.properties", "");
fromCache = true;
}
}
}
System.setProperty(RESNAME_APP_CONF_DIR, confDir);
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");
} else {
conf = AnyValue.loadFromProperties(text).getAnyValue("redkale");
}
if (fromCache) {
((AnyValueWriter) conf).addValue("[config-from-cache]", "true");
}
return conf;
}
/**
* 检查name是否含特殊字符
*
* @param name
* @return
*/
private static String checkName(String name) {
if (name == null || name.isEmpty()) {
return name;
}
for (char ch : name.toCharArray()) {
if (!((ch >= '0' && ch <= '9')
|| (ch >= 'a' && ch <= 'z')
|| (ch >= 'A' && ch <= 'Z')
|| ch == '_'
|| ch == '.'
|| ch == '-')) { // 不能含特殊字符
throw new RedkaleException("name only 0-9 a-z A-Z _ - .");
}
}
return name;
}
/**
* 检查node是否含特殊字符
*
* @param name
* @return
*/
private static String checkNodeid(String nodeid) {
if (nodeid == null || nodeid.isEmpty()) {
return nodeid;
}
for (char ch : nodeid.toCharArray()) {
if (!((ch >= '0' && ch <= '9')
|| (ch >= 'a' && ch <= 'z')
|| (ch >= 'A' && ch <= 'Z')
|| ch == '_'
|| ch == '.'
|| ch == '-')) { // 不能含特殊字符
throw new RedkaleException("nodeid only 0-9 a-z A-Z _ - .");
}
}
return nodeid;
}
private String getCanonicalPath(File file) {
try {
return file.getCanonicalPath();
} catch (IOException e) {
return file.getAbsolutePath();
}
}
private File getCanonicalFile(File file) {
try {
return file.getCanonicalFile();
} catch (IOException e) {
return file;
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,52 +1,52 @@
/*
*
*/
package org.redkale.boot;
import java.util.List;
import java.util.Objects;
import java.util.Properties;
import org.redkale.inject.ResourceEvent;
import org.redkale.inject.ResourceFactory;
import org.redkale.util.Environment;
/** @author zhangjx */
public abstract class BootModule {
protected final Application application;
protected final ResourceFactory resourceFactory;
protected final Environment environment;
protected BootModule(Application application) {
this.application = application;
this.resourceFactory = Objects.requireNonNull(application.resourceFactory);
this.environment = Objects.requireNonNull(application.getEnvironment());
}
protected void removeEnvValue(String name) {
application.envProperties.remove(name);
}
protected void putEnvValue(Object name, Object value) {
application.envProperties.put(name, value);
}
protected List<ModuleEngine> getModuleEngines() {
return application.getModuleEngines();
}
protected void reconfigLogging(boolean first, Properties allProps) {
application.loggingModule.reconfigLogging(first, allProps);
}
protected void onEnvironmentChanged(String namespace, List<ResourceEvent> events) {
if (namespace != null && namespace.contains("logging")) {
// 日志配置单独处理
application.loggingModule.onEnvironmentUpdated(events);
} else {
application.onEnvironmentChanged(namespace, events);
}
}
}
/*
*
*/
package org.redkale.boot;
import java.util.List;
import java.util.Objects;
import java.util.Properties;
import org.redkale.inject.ResourceEvent;
import org.redkale.inject.ResourceFactory;
import org.redkale.util.Environment;
/** @author zhangjx */
public abstract class BootModule {
protected final Application application;
protected final ResourceFactory resourceFactory;
protected final Environment environment;
protected BootModule(Application application) {
this.application = application;
this.resourceFactory = Objects.requireNonNull(application.resourceFactory);
this.environment = Objects.requireNonNull(application.getEnvironment());
}
protected void removeEnvValue(String name) {
application.envProperties.remove(name);
}
protected void putEnvValue(Object name, Object value) {
application.envProperties.put(name, value);
}
protected List<ModuleEngine> getModuleEngines() {
return application.getModuleEngines();
}
protected void reconfigLogging(boolean first, Properties allProps) {
application.loggingModule.reconfigLogging(first, allProps);
}
protected void onEnvironmentChanged(String namespace, List<ResourceEvent> events) {
if (namespace != null && namespace.contains("logging")) {
// 日志配置单独处理
application.loggingModule.onEnvironmentUpdated(events);
} else {
application.onEnvironmentChanged(namespace, events);
}
}
}

View File

@@ -1,192 +1,192 @@
/*
*
*/
package org.redkale.boot;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.logging.Handler;
import java.util.logging.LogManager;
import java.util.logging.SimpleFormatter;
import org.redkale.inject.ResourceEvent;
import org.redkale.net.sncp.SncpClient;
import org.redkale.util.Environment;
/**
* 日志模块组件
*
* <p>详情见: https://redkale.org
*
* @author zhangjx
* @since 2.8.0
*/
class LoggingModule extends BootModule {
// 日志配置资源
private final Properties loggingProperties = new Properties();
LoggingModule(Application application) {
super(application);
}
/**
* 配置变更
*
* @param events 变更项
*/
public void onEnvironmentUpdated(List<ResourceEvent> events) {
Set<String> loggingRemovedKeys = new HashSet<>();
Properties loggingChangedProps = new Properties();
for (ResourceEvent event : events) {
if (event.newValue() == null) {
if (loggingProperties.containsKey(event.name())) {
loggingRemovedKeys.add(event.name());
}
} else {
loggingChangedProps.put(event.name(), event.newValue());
}
}
if (!loggingRemovedKeys.isEmpty() || !loggingChangedProps.isEmpty()) {
Properties newProps = new Properties(this.loggingProperties);
loggingRemovedKeys.forEach(newProps::remove);
newProps.putAll(loggingChangedProps);
reconfigLogging(false, newProps);
}
}
/**
* 设置日志策略
*
* @param first 是否首次设置
* @param allProps 配置项全量
*/
public void reconfigLogging(boolean first, Properties allProps) {
String searchRawHandler = "java.util.logging.SearchHandler";
String searchReadHandler = LoggingSearchHandler.class.getName();
Properties onlyLogProps = new Properties();
Environment envs = this.environment;
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));
onlyLogProps.put(key.replace(searchRawHandler, searchReadHandler), val);
}
});
if (onlyLogProps.getProperty("java.util.logging.FileHandler.formatter") == null) {
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"));
}
} else {
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"));
}
} else {
onlyLogProps.setProperty(
"java.util.logging.ConsoleHandler.formatter",
LoggingFileHandler.LoggingFormater.class.getName());
}
}
if (!application.isCompileMode()) { // ConsoleHandler替换成LoggingConsoleHandler
final String handlers = onlyLogProps.getProperty("handlers");
if (handlers != null && handlers.contains("java.util.logging.ConsoleHandler")) {
final String consoleHandlerClass = LoggingFileHandler.LoggingConsoleHandler.class.getName();
onlyLogProps.setProperty(
"handlers", handlers.replace("java.util.logging.ConsoleHandler", consoleHandlerClass));
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.entrySet().forEach(x -> {
onlyLogProps.put(x.getKey(), x.getValue());
});
}
}
String fileHandlerPattern = onlyLogProps.getProperty("java.util.logging.FileHandler.pattern");
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));
}
if (!prop.isEmpty()) {
String prefix = fileHandlerClass + ".";
onlyLogProps.entrySet().forEach(x -> {
if (x.getKey().toString().startsWith("java.util.logging.FileHandler.")) {
prop.put(x.getKey().toString().replace("java.util.logging.FileHandler.", prefix), x.getValue());
}
});
prop.entrySet().forEach(x -> onlyLogProps.put(x.getKey(), x.getValue()));
}
if (!application.isCompileMode()) {
onlyLogProps.put(
SncpClient.class.getSimpleName() + ".handlers",
LoggingFileHandler.LoggingSncpFileHandler.class.getName());
}
}
if (application.isCompileMode()) {
onlyLogProps.put("handlers", "java.util.logging.ConsoleHandler");
Map newprop = new HashMap(onlyLogProps);
newprop.forEach((k, v) -> {
if (k.toString().startsWith("java.util.logging.FileHandler.")) {
onlyLogProps.remove(k);
}
});
}
ByteArrayOutputStream out = new ByteArrayOutputStream();
final PrintStream ps = new PrintStream(out);
onlyLogProps.forEach((x, y) -> ps.println(x + "=" + y));
try {
LogManager manager = LogManager.getLogManager();
manager.readConfiguration(new ByteArrayInputStream(out.toByteArray()));
this.loggingProperties.clear();
this.loggingProperties.putAll(onlyLogProps);
Enumeration<String> en = manager.getLoggerNames();
while (en.hasMoreElements()) {
for (Handler handler : manager.getLogger(en.nextElement()).getHandlers()) {
if (handler instanceof LoggingSearchHandler) {
((LoggingSearchHandler) handler).application = application;
}
}
}
} catch (IOException e) { // 不会发生
}
}
}
/*
*
*/
package org.redkale.boot;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.logging.Handler;
import java.util.logging.LogManager;
import java.util.logging.SimpleFormatter;
import org.redkale.inject.ResourceEvent;
import org.redkale.net.sncp.SncpClient;
import org.redkale.util.Environment;
/**
* 日志模块组件
*
* <p>详情见: https://redkale.org
*
* @author zhangjx
* @since 2.8.0
*/
class LoggingModule extends BootModule {
// 日志配置资源
private final Properties loggingProperties = new Properties();
LoggingModule(Application application) {
super(application);
}
/**
* 配置变更
*
* @param events 变更项
*/
public void onEnvironmentUpdated(List<ResourceEvent> events) {
Set<String> loggingRemovedKeys = new HashSet<>();
Properties loggingChangedProps = new Properties();
for (ResourceEvent event : events) {
if (event.newValue() == null) {
if (loggingProperties.containsKey(event.name())) {
loggingRemovedKeys.add(event.name());
}
} else {
loggingChangedProps.put(event.name(), event.newValue());
}
}
if (!loggingRemovedKeys.isEmpty() || !loggingChangedProps.isEmpty()) {
Properties newProps = new Properties(this.loggingProperties);
loggingRemovedKeys.forEach(newProps::remove);
newProps.putAll(loggingChangedProps);
reconfigLogging(false, newProps);
}
}
/**
* 设置日志策略
*
* @param first 是否首次设置
* @param allProps 配置项全量
*/
public void reconfigLogging(boolean first, Properties allProps) {
String searchRawHandler = "java.util.logging.SearchHandler";
String searchReadHandler = LoggingSearchHandler.class.getName();
Properties onlyLogProps = new Properties();
Environment envs = this.environment;
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));
onlyLogProps.put(key.replace(searchRawHandler, searchReadHandler), val);
}
});
if (onlyLogProps.getProperty("java.util.logging.FileHandler.formatter") == null) {
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"));
}
} else {
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"));
}
} else {
onlyLogProps.setProperty(
"java.util.logging.ConsoleHandler.formatter",
LoggingFileHandler.LoggingFormater.class.getName());
}
}
if (!application.isCompileMode()) { // ConsoleHandler替换成LoggingConsoleHandler
final String handlers = onlyLogProps.getProperty("handlers");
if (handlers != null && handlers.contains("java.util.logging.ConsoleHandler")) {
final String consoleHandlerClass = LoggingFileHandler.LoggingConsoleHandler.class.getName();
onlyLogProps.setProperty(
"handlers", handlers.replace("java.util.logging.ConsoleHandler", consoleHandlerClass));
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.entrySet().forEach(x -> {
onlyLogProps.put(x.getKey(), x.getValue());
});
}
}
String fileHandlerPattern = onlyLogProps.getProperty("java.util.logging.FileHandler.pattern");
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));
}
if (!prop.isEmpty()) {
String prefix = fileHandlerClass + ".";
onlyLogProps.entrySet().forEach(x -> {
if (x.getKey().toString().startsWith("java.util.logging.FileHandler.")) {
prop.put(x.getKey().toString().replace("java.util.logging.FileHandler.", prefix), x.getValue());
}
});
prop.entrySet().forEach(x -> onlyLogProps.put(x.getKey(), x.getValue()));
}
if (!application.isCompileMode()) {
onlyLogProps.put(
SncpClient.class.getSimpleName() + ".handlers",
LoggingFileHandler.LoggingSncpFileHandler.class.getName());
}
}
if (application.isCompileMode()) {
onlyLogProps.put("handlers", "java.util.logging.ConsoleHandler");
Map newprop = new HashMap(onlyLogProps);
newprop.forEach((k, v) -> {
if (k.toString().startsWith("java.util.logging.FileHandler.")) {
onlyLogProps.remove(k);
}
});
}
ByteArrayOutputStream out = new ByteArrayOutputStream();
final PrintStream ps = new PrintStream(out);
onlyLogProps.forEach((x, y) -> ps.println(x + "=" + y));
try {
LogManager manager = LogManager.getLogManager();
manager.readConfiguration(new ByteArrayInputStream(out.toByteArray()));
this.loggingProperties.clear();
this.loggingProperties.putAll(onlyLogProps);
Enumeration<String> en = manager.getLoggerNames();
while (en.hasMoreElements()) {
for (Handler handler : manager.getLogger(en.nextElement()).getHandlers()) {
if (handler instanceof LoggingSearchHandler) {
((LoggingSearchHandler) handler).application = application;
}
}
}
} catch (IOException e) { // 不会发生
}
}
}

View File

@@ -1,179 +1,179 @@
/*
*
*/
package org.redkale.boot;
import java.util.List;
import java.util.Objects;
import java.util.Properties;
import java.util.logging.Logger;
import org.redkale.asm.AsmMethodBoost;
import org.redkale.inject.ResourceEvent;
import org.redkale.inject.ResourceFactory;
import org.redkale.service.Service;
import org.redkale.util.AnyValue;
import org.redkale.util.Environment;
/**
* 各组件的引擎类, 由Application管理
*
* <p>详情见: https://redkale.org
*
* @author zhangjx
* @since 2.8.0
*/
public abstract class ModuleEngine {
protected final Logger logger = Logger.getLogger(getClass().getSimpleName());
protected final Application application;
protected final ResourceFactory resourceFactory;
protected final Environment environment;
public ModuleEngine(Application application) {
this.application = application;
this.resourceFactory = Objects.requireNonNull(application.resourceFactory);
this.environment = Objects.requireNonNull(application.getEnvironment());
}
/**
* 判断模块的配置项合并策略, 返回null表示模块不识别此配置项
*
* @param path 配置项路径
* @param key 配置项名称
* @param val1 配置项原值
* @param val2 配置项新值
* @return MergeEnum
*/
public AnyValue.MergeEnum mergeAppConfigStrategy(String path, String key, AnyValue val1, AnyValue val2) {
return null;
}
/**
* 动态扩展类的方法
*
* @param remote 是否远程模式
* @param serviceClass 类
* @return 方法动态扩展器
*/
public AsmMethodBoost createAsmMethodBoost(boolean remote, Class serviceClass) {
return null;
}
/** 进入Application.init方法时被调用 此时状态: 1、远程配置项未获取 2、WorkExecutor未初始化 */
public void onAppPreInit() {
// do nothing
}
/** 结束Application.init方法前被调用 */
public void onAppPostInit() {
// do nothing
}
/** 进入Application.start方法被调用 */
public void onAppPreStart() {
// do nothing
}
/** 结束Application.start方法前被调用 */
public void onAppPostStart() {
// do nothing
}
/**
* 配置项加载后被调用
*
* @param allProps 配置项全量
*/
public void onEnvironmentLoaded(Properties allProps) {
// do nothing
}
/**
* 配置项变更时被调用
*
* @param namespace 命名空间
* @param events 变更项
*/
public void onEnvironmentChanged(String namespace, List<ResourceEvent> events) {
// do nothing
}
/** Application 在运行Compile前调用 */
public void onPreCompile() {
// do nothing
}
/** Application 在运行Compile后调用 */
public void onPostCompile() {
// do nothing
}
/** 服务全部启动前被调用 */
public void onServersPreStart() {
// do nothing
}
/** 服务全部启动后被调用 */
public void onServersPostStart() {
// do nothing
}
/**
* 执行Service.init方法前被调用
*
* @param service Service
*/
public void onServicePreInit(Service service) {
// do nothing
}
/**
* 执行Service.init方法后被调用
*
* @param service Service
*/
public void onServicePostInit(Service service) {
// do nothing
}
/**
* 执行Service.destroy方法前被调用
*
* @param service Service
*/
public void onServicePreDestroy(Service service) {
// do nothing
}
/**
* 执行Service.destroy方法后被调用
*
* @param service Service
*/
public void onServicePostDestroy(Service service) {
// do nothing
}
/** 服务全部停掉前被调用 */
public void onServersPreStop() {
// do nothing
}
/** 服务全部停掉后被调用 */
public void onServersPostStop() {
// do nothing
}
/** 进入Application.shutdown方法被调用 */
public void onAppPreShutdown() {
// do nothing
}
/** 结束Application.shutdown方法前被调用 */
public void onAppPostShutdown() {
// do nothing
}
}
/*
*
*/
package org.redkale.boot;
import java.util.List;
import java.util.Objects;
import java.util.Properties;
import java.util.logging.Logger;
import org.redkale.asm.AsmMethodBoost;
import org.redkale.inject.ResourceEvent;
import org.redkale.inject.ResourceFactory;
import org.redkale.service.Service;
import org.redkale.util.AnyValue;
import org.redkale.util.Environment;
/**
* 各组件的引擎类, 由Application管理
*
* <p>详情见: https://redkale.org
*
* @author zhangjx
* @since 2.8.0
*/
public abstract class ModuleEngine {
protected final Logger logger = Logger.getLogger(getClass().getSimpleName());
protected final Application application;
protected final ResourceFactory resourceFactory;
protected final Environment environment;
public ModuleEngine(Application application) {
this.application = application;
this.resourceFactory = Objects.requireNonNull(application.resourceFactory);
this.environment = Objects.requireNonNull(application.getEnvironment());
}
/**
* 判断模块的配置项合并策略, 返回null表示模块不识别此配置项
*
* @param path 配置项路径
* @param key 配置项名称
* @param val1 配置项原值
* @param val2 配置项新值
* @return MergeEnum
*/
public AnyValue.MergeEnum mergeAppConfigStrategy(String path, String key, AnyValue val1, AnyValue val2) {
return null;
}
/**
* 动态扩展类的方法
*
* @param remote 是否远程模式
* @param serviceClass 类
* @return 方法动态扩展器
*/
public AsmMethodBoost createAsmMethodBoost(boolean remote, Class serviceClass) {
return null;
}
/** 进入Application.init方法时被调用 此时状态: 1、远程配置项未获取 2、WorkExecutor未初始化 */
public void onAppPreInit() {
// do nothing
}
/** 结束Application.init方法前被调用 */
public void onAppPostInit() {
// do nothing
}
/** 进入Application.start方法被调用 */
public void onAppPreStart() {
// do nothing
}
/** 结束Application.start方法前被调用 */
public void onAppPostStart() {
// do nothing
}
/**
* 配置项加载后被调用
*
* @param allProps 配置项全量
*/
public void onEnvironmentLoaded(Properties allProps) {
// do nothing
}
/**
* 配置项变更时被调用
*
* @param namespace 命名空间
* @param events 变更项
*/
public void onEnvironmentChanged(String namespace, List<ResourceEvent> events) {
// do nothing
}
/** Application 在运行Compile前调用 */
public void onPreCompile() {
// do nothing
}
/** Application 在运行Compile后调用 */
public void onPostCompile() {
// do nothing
}
/** 服务全部启动前被调用 */
public void onServersPreStart() {
// do nothing
}
/** 服务全部启动后被调用 */
public void onServersPostStart() {
// do nothing
}
/**
* 执行Service.init方法前被调用
*
* @param service Service
*/
public void onServicePreInit(Service service) {
// do nothing
}
/**
* 执行Service.init方法后被调用
*
* @param service Service
*/
public void onServicePostInit(Service service) {
// do nothing
}
/**
* 执行Service.destroy方法前被调用
*
* @param service Service
*/
public void onServicePreDestroy(Service service) {
// do nothing
}
/**
* 执行Service.destroy方法后被调用
*
* @param service Service
*/
public void onServicePostDestroy(Service service) {
// do nothing
}
/** 服务全部停掉前被调用 */
public void onServersPreStop() {
// do nothing
}
/** 服务全部停掉后被调用 */
public void onServersPostStop() {
// do nothing
}
/** 进入Application.shutdown方法被调用 */
public void onAppPreShutdown() {
// do nothing
}
/** 结束Application.shutdown方法前被调用 */
public void onAppPostShutdown() {
// do nothing
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,85 +1,85 @@
/*
*
*/
package org.redkale.cache;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import java.util.concurrent.TimeUnit;
import org.redkale.service.LoadMode;
/**
* 标记在Service的缓存接口, 方法有以下限制: <br>
* 1、方法返回类型不能是void/CompletableFuture&#60;Void&#62; 2、方法返回类型必须可json序列化 3、方法必须是protected/public 4、方法不能是final/static
*
* @since 2.8.0
*/
@Documented
@Target(METHOD)
@Retention(RUNTIME)
public @interface Cached {
/**
* 缓存的key支持参数动态组合比如"key_#{id}"
*
* @return 键
*/
String key();
/**
* 缓存的hash, 不能含有':'、'#'、'@'字符
*
* @return hash
*/
String hash() default CacheManager.DEFAULT_HASH;
/**
* 本地缓存过期时长, 0表示永不过期 -1表示不作本地缓存。<br>
* 参数值支持方式:<br>
* 100: 设置数值 ${env.cache.expires}: 读取系统配置项
*
* @return 过期时长
*/
String localExpire() default "-1";
/**
* 远程缓存过期时长, 0表示永不过期 -1表示不作远程缓存。<br>
* 参数值支持方式:<br>
* 100: 设置数值 ${env.cache.expires}: 读取系统配置项
*
* @return 过期时长
*/
String remoteExpire() default "-1";
/**
* 是否可以缓存null值
*
* @return 是否可以缓存null
*/
boolean nullable() default false;
/**
* 过期时长的时间单位
*
* @return 时间单位
*/
TimeUnit timeUnit() default TimeUnit.SECONDS;
/**
* 备注
*
* @return 备注
*/
String comment() default "";
/**
* Service加载模式
*
* @return 模式
*/
LoadMode mode() default LoadMode.ANY;
}
/*
*
*/
package org.redkale.cache;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import java.util.concurrent.TimeUnit;
import org.redkale.service.LoadMode;
/**
* 标记在Service的缓存接口, 方法有以下限制: <br>
* 1、方法返回类型不能是void/CompletableFuture&#60;Void&#62; 2、方法返回类型必须可json序列化 3、方法必须是protected/public 4、方法不能是final/static
*
* @since 2.8.0
*/
@Documented
@Target(METHOD)
@Retention(RUNTIME)
public @interface Cached {
/**
* 缓存的key支持参数动态组合比如"key_#{id}"
*
* @return 键
*/
String key();
/**
* 缓存的hash, 不能含有':'、'#'、'@'字符
*
* @return hash
*/
String hash() default CacheManager.DEFAULT_HASH;
/**
* 本地缓存过期时长, 0表示永不过期 -1表示不作本地缓存。<br>
* 参数值支持方式:<br>
* 100: 设置数值 ${env.cache.expires}: 读取系统配置项
*
* @return 过期时长
*/
String localExpire() default "-1";
/**
* 远程缓存过期时长, 0表示永不过期 -1表示不作远程缓存。<br>
* 参数值支持方式:<br>
* 100: 设置数值 ${env.cache.expires}: 读取系统配置项
*
* @return 过期时长
*/
String remoteExpire() default "-1";
/**
* 是否可以缓存null值
*
* @return 是否可以缓存null
*/
boolean nullable() default false;
/**
* 过期时长的时间单位
*
* @return 时间单位
*/
TimeUnit timeUnit() default TimeUnit.SECONDS;
/**
* 备注
*
* @return 备注
*/
String comment() default "";
/**
* Service加载模式
*
* @return 模式
*/
LoadMode mode() default LoadMode.ANY;
}

View File

@@ -1,156 +1,156 @@
/*
*
*/
package org.redkale.cache.spi;
import java.lang.reflect.ParameterizedType;
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;
import org.redkale.convert.json.JsonConvert;
import org.redkale.util.Environment;
import org.redkale.util.MultiHashKey;
import org.redkale.util.ThrowSupplier;
import org.redkale.util.TypeToken;
/**
* 缓存的方法对象
*
* <p>详情见: https://redkale.org
*
* @author zhangjx
* @since 2.8.0
*/
@ClassDepends
public class CacheAction {
@Resource
private Environment environment;
@Resource
private CacheManager manager;
private final CacheEntry cached;
// Supplier对象的类型
private final Type resultType;
// 缓存方法是否异步
private final boolean async;
// 是否可以缓存null
private final boolean nullable;
// 宿主对象的类
private final Class serviceClass;
// 无法获取动态的Method只能存方法名
private final String methodName;
// 获取动态的字段名
private final String fieldName;
// 方法参数类型
@Nullable
private final Class[] paramTypes;
// 方法参数名
@Nullable
private final String[] paramNames;
// 缓存的hash
private String hash;
// 缓存的key
private MultiHashKey dynKey;
// 本地缓存过期时长Duration.ZERO为永不过期为null表示不本地缓存
private Duration localExpire;
// 远程缓存过期时长Duration.ZERO为永不过期为null表示不远程缓存
private Duration remoteExpire;
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);
this.paramTypes = paramTypes;
this.paramNames = paramNames;
this.methodName = Objects.requireNonNull(methodName);
this.fieldName = Objects.requireNonNull(fieldName);
this.async = CompletableFuture.class.isAssignableFrom(TypeToken.typeToClass(returnType));
this.resultType = this.async ? ((ParameterizedType) returnType).getActualTypeArguments()[0] : returnType;
}
void init() {
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());
this.remoteExpire = createDuration(cached.getRemoteExpire());
}
@ClassDepends
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);
} else {
return manager.bothGetSet(
hash, dynKey.keyFor(args), resultType, nullable, localExpire, remoteExpire, supplier);
}
}
private Duration createDuration(String val) {
String str = environment.getPropertyValue(val);
if ("-1".equals(str) || "null".equalsIgnoreCase(str)) {
return null;
} else if ("0".equals(str)) {
return Duration.ZERO;
} else if (str.indexOf('*') > -1) {
long rs = 1;
for (String v : str.split("\\*")) {
if (!v.trim().isEmpty()) {
rs *= Long.parseLong(v.trim());
}
}
if (rs < 0) {
return null;
} else if (rs == 0) {
return Duration.ZERO;
} else {
return Duration.ofMillis(cached.getTimeUnit().toMillis(rs));
}
} else {
return Duration.ofMillis(cached.getTimeUnit().toMillis(Long.parseLong(str)));
}
}
@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
+ "}";
}
}
/*
*
*/
package org.redkale.cache.spi;
import java.lang.reflect.ParameterizedType;
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;
import org.redkale.convert.json.JsonConvert;
import org.redkale.util.Environment;
import org.redkale.util.MultiHashKey;
import org.redkale.util.ThrowSupplier;
import org.redkale.util.TypeToken;
/**
* 缓存的方法对象
*
* <p>详情见: https://redkale.org
*
* @author zhangjx
* @since 2.8.0
*/
@ClassDepends
public class CacheAction {
@Resource
private Environment environment;
@Resource
private CacheManager manager;
private final CacheEntry cached;
// Supplier对象的类型
private final Type resultType;
// 缓存方法是否异步
private final boolean async;
// 是否可以缓存null
private final boolean nullable;
// 宿主对象的类
private final Class serviceClass;
// 无法获取动态的Method只能存方法名
private final String methodName;
// 获取动态的字段名
private final String fieldName;
// 方法参数类型
@Nullable
private final Class[] paramTypes;
// 方法参数名
@Nullable
private final String[] paramNames;
// 缓存的hash
private String hash;
// 缓存的key
private MultiHashKey dynKey;
// 本地缓存过期时长Duration.ZERO为永不过期为null表示不本地缓存
private Duration localExpire;
// 远程缓存过期时长Duration.ZERO为永不过期为null表示不远程缓存
private Duration remoteExpire;
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);
this.paramTypes = paramTypes;
this.paramNames = paramNames;
this.methodName = Objects.requireNonNull(methodName);
this.fieldName = Objects.requireNonNull(fieldName);
this.async = CompletableFuture.class.isAssignableFrom(TypeToken.typeToClass(returnType));
this.resultType = this.async ? ((ParameterizedType) returnType).getActualTypeArguments()[0] : returnType;
}
void init() {
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());
this.remoteExpire = createDuration(cached.getRemoteExpire());
}
@ClassDepends
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);
} else {
return manager.bothGetSet(
hash, dynKey.keyFor(args), resultType, nullable, localExpire, remoteExpire, supplier);
}
}
private Duration createDuration(String val) {
String str = environment.getPropertyValue(val);
if ("-1".equals(str) || "null".equalsIgnoreCase(str)) {
return null;
} else if ("0".equals(str)) {
return Duration.ZERO;
} else if (str.indexOf('*') > -1) {
long rs = 1;
for (String v : str.split("\\*")) {
if (!v.trim().isEmpty()) {
rs *= Long.parseLong(v.trim());
}
}
if (rs < 0) {
return null;
} else if (rs == 0) {
return Duration.ZERO;
} else {
return Duration.ofMillis(cached.getTimeUnit().toMillis(rs));
}
} else {
return Duration.ofMillis(cached.getTimeUnit().toMillis(Long.parseLong(str)));
}
}
@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
+ "}";
}
}

View File

@@ -1,248 +1,248 @@
/*
*
*/
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;
import java.lang.reflect.Modifier;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import org.redkale.asm.AnnotationVisitor;
import org.redkale.asm.AsmMethodBean;
import org.redkale.asm.AsmMethodBoost;
import org.redkale.asm.Asms;
import org.redkale.asm.ClassWriter;
import org.redkale.asm.FieldVisitor;
import org.redkale.asm.Handle;
import org.redkale.asm.Label;
import org.redkale.asm.MethodVisitor;
import org.redkale.asm.Opcodes;
import org.redkale.asm.Type;
import org.redkale.cache.Cached;
import org.redkale.inject.ResourceFactory;
import org.redkale.service.LoadMode;
import org.redkale.util.RedkaleClassLoader;
import org.redkale.util.RedkaleException;
import org.redkale.util.ThrowSupplier;
import org.redkale.util.TypeToken;
/** @author zhangjx */
public class CacheAsmMethodBoost extends AsmMethodBoost {
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);
private Map<String, CacheAction> actionMap;
public CacheAsmMethodBoost(boolean remote, Class serviceType) {
super(remote, serviceType);
}
@Override
public List<Class<? extends Annotation>> filterMethodAnnotations(Method method) {
return FILTER_ANN;
}
@Override
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<>();
this.actionMap = actions;
}
Cached cached = method.getAnnotation(Cached.class);
if (cached == null) {
return newMethodName;
}
if (!LoadMode.matches(remote, cached.mode())) {
return newMethodName;
}
if (method.getAnnotation(DynForCache.class) != null) {
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);
}
if (!Modifier.isProtected(method.getModifiers()) && !Modifier.isPublic(method.getModifiers())) {
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);
}
final int actionIndex = fieldIndex.incrementAndGet();
final String rsMethodName = method.getName() + "_afterCache";
final String dynFieldName = fieldPrefix + "_" + method.getName() + "CacheAction" + actionIndex;
final AsmMethodBean methodBean = getMethodBean(method);
{ // 定义一个新方法调用 this.rsMethodName
final String cacheDynDesc = Type.getDescriptor(DynForCache.class);
final MethodVisitor mv = createMethodVisitor(cw, method, newMethodName, methodBean);
// mv.setDebug(true);
AnnotationVisitor av = mv.visitAnnotation(cacheDynDesc, true);
av.visit("dynField", dynFieldName);
Asms.visitAnnotation(av, cached);
visitRawAnnotation(method, newMethodName, mv, Cached.class, filterAnns);
Label l0 = new Label();
mv.visitLabel(l0);
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()))
});
mv.visitVarInsn(ASTORE, 1 + method.getParameterCount());
Label l1 = new Label();
mv.visitLabel(l1);
mv.visitVarInsn(ALOAD, 0);
mv.visitFieldInsn(GETFIELD, newDynName, dynFieldName, Type.getDescriptor(CacheAction.class));
mv.visitVarInsn(ALOAD, 1 + method.getParameterCount());
Asms.visitInsn(mv, method.getParameterCount());
mv.visitTypeInsn(ANEWARRAY, "java/lang/Object");
int insn = 0;
Class[] paramtypes = method.getParameterTypes();
for (int j = 0; j < paramtypes.length; j++) {
final Class pt = paramtypes[j];
mv.visitInsn(DUP);
insn++;
Asms.visitInsn(mv, j);
if (pt.isPrimitive()) {
if (pt == long.class) {
mv.visitVarInsn(LLOAD, insn++);
} else if (pt == float.class) {
mv.visitVarInsn(FLOAD, insn++);
} else if (pt == double.class) {
mv.visitVarInsn(DLOAD, insn++);
} else {
mv.visitVarInsn(ILOAD, insn);
}
Class bigclaz = TypeToken.primitiveToWrapper(pt);
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.visitTypeInsn(CHECKCAST, method.getReturnType().getName().replace('.', '/'));
mv.visitInsn(ARETURN);
Label l2 = new Label();
mv.visitLabel(l2);
mv.visitLocalVariable("this", "L" + newDynName + ";", null, l0, l2, 0);
visitParamTypesLocalVariable(mv, method, l0, l2, insns, methodBean);
mv.visitLocalVariable("_redkale_supplier", Type.getDescriptor(ThrowSupplier.class), null, l1, l2, ++insn);
mv.visitMaxs(20, 20);
mv.visitEnd();
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);
Label l0 = new Label();
mv.visitLabel(l0);
mv.visitVarInsn(ALOAD, 0);
visitVarInsnParamTypes(mv, method, 0);
mv.visitMethodInsn(INVOKESPECIAL, newDynName, rsMethodName, methodBean.getDesc(), false);
mv.visitInsn(ARETURN);
Label l1 = new Label();
mv.visitLabel(l1);
mv.visitLocalVariable("this", "L" + newDynName + ";", null, l0, l1, 0);
mv.visitMaxs(5, 5);
mv.visitEnd();
}
{ // 定义字段
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);
}
return rsMethodName;
}
@Override
public void doInstance(ResourceFactory resourceFactory, Object service) {
Class clazz = service.getClass();
if (actionMap == null) { // 为null表示没有调用过doMethod 动态类在编译是已经生成好了
actionMap = new LinkedHashMap<>();
Map<String, AsmMethodBean> methodBeans = AsmMethodBoost.getMethodBeans(clazz);
for (final Method method : clazz.getDeclaredMethods()) {
DynForCache cached = method.getAnnotation(DynForCache.class);
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);
actionMap.put(dynFieldName, action);
}
}
}
actionMap.forEach((field, action) -> {
try {
Field c = clazz.getDeclaredField(field);
c.setAccessible(true);
resourceFactory.inject(action);
action.init();
c.set(service, action);
RedkaleClassLoader.putReflectionField(clazz.getName(), c);
} catch (Exception e) {
throw new RedkaleException("field (" + field + ") in " + clazz.getName() + " set error", e);
}
});
// do nothing
}
}
/*
*
*/
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;
import java.lang.reflect.Modifier;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import org.redkale.asm.AnnotationVisitor;
import org.redkale.asm.AsmMethodBean;
import org.redkale.asm.AsmMethodBoost;
import org.redkale.asm.Asms;
import org.redkale.asm.ClassWriter;
import org.redkale.asm.FieldVisitor;
import org.redkale.asm.Handle;
import org.redkale.asm.Label;
import org.redkale.asm.MethodVisitor;
import org.redkale.asm.Opcodes;
import org.redkale.asm.Type;
import org.redkale.cache.Cached;
import org.redkale.inject.ResourceFactory;
import org.redkale.service.LoadMode;
import org.redkale.util.RedkaleClassLoader;
import org.redkale.util.RedkaleException;
import org.redkale.util.ThrowSupplier;
import org.redkale.util.TypeToken;
/** @author zhangjx */
public class CacheAsmMethodBoost extends AsmMethodBoost {
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);
private Map<String, CacheAction> actionMap;
public CacheAsmMethodBoost(boolean remote, Class serviceType) {
super(remote, serviceType);
}
@Override
public List<Class<? extends Annotation>> filterMethodAnnotations(Method method) {
return FILTER_ANN;
}
@Override
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<>();
this.actionMap = actions;
}
Cached cached = method.getAnnotation(Cached.class);
if (cached == null) {
return newMethodName;
}
if (!LoadMode.matches(remote, cached.mode())) {
return newMethodName;
}
if (method.getAnnotation(DynForCache.class) != null) {
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);
}
if (!Modifier.isProtected(method.getModifiers()) && !Modifier.isPublic(method.getModifiers())) {
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);
}
final int actionIndex = fieldIndex.incrementAndGet();
final String rsMethodName = method.getName() + "_afterCache";
final String dynFieldName = fieldPrefix + "_" + method.getName() + "CacheAction" + actionIndex;
final AsmMethodBean methodBean = getMethodBean(method);
{ // 定义一个新方法调用 this.rsMethodName
final String cacheDynDesc = Type.getDescriptor(DynForCache.class);
final MethodVisitor mv = createMethodVisitor(cw, method, newMethodName, methodBean);
// mv.setDebug(true);
AnnotationVisitor av = mv.visitAnnotation(cacheDynDesc, true);
av.visit("dynField", dynFieldName);
Asms.visitAnnotation(av, cached);
visitRawAnnotation(method, newMethodName, mv, Cached.class, filterAnns);
Label l0 = new Label();
mv.visitLabel(l0);
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()))
});
mv.visitVarInsn(ASTORE, 1 + method.getParameterCount());
Label l1 = new Label();
mv.visitLabel(l1);
mv.visitVarInsn(ALOAD, 0);
mv.visitFieldInsn(GETFIELD, newDynName, dynFieldName, Type.getDescriptor(CacheAction.class));
mv.visitVarInsn(ALOAD, 1 + method.getParameterCount());
Asms.visitInsn(mv, method.getParameterCount());
mv.visitTypeInsn(ANEWARRAY, "java/lang/Object");
int insn = 0;
Class[] paramtypes = method.getParameterTypes();
for (int j = 0; j < paramtypes.length; j++) {
final Class pt = paramtypes[j];
mv.visitInsn(DUP);
insn++;
Asms.visitInsn(mv, j);
if (pt.isPrimitive()) {
if (pt == long.class) {
mv.visitVarInsn(LLOAD, insn++);
} else if (pt == float.class) {
mv.visitVarInsn(FLOAD, insn++);
} else if (pt == double.class) {
mv.visitVarInsn(DLOAD, insn++);
} else {
mv.visitVarInsn(ILOAD, insn);
}
Class bigclaz = TypeToken.primitiveToWrapper(pt);
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.visitTypeInsn(CHECKCAST, method.getReturnType().getName().replace('.', '/'));
mv.visitInsn(ARETURN);
Label l2 = new Label();
mv.visitLabel(l2);
mv.visitLocalVariable("this", "L" + newDynName + ";", null, l0, l2, 0);
visitParamTypesLocalVariable(mv, method, l0, l2, insns, methodBean);
mv.visitLocalVariable("_redkale_supplier", Type.getDescriptor(ThrowSupplier.class), null, l1, l2, ++insn);
mv.visitMaxs(20, 20);
mv.visitEnd();
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);
Label l0 = new Label();
mv.visitLabel(l0);
mv.visitVarInsn(ALOAD, 0);
visitVarInsnParamTypes(mv, method, 0);
mv.visitMethodInsn(INVOKESPECIAL, newDynName, rsMethodName, methodBean.getDesc(), false);
mv.visitInsn(ARETURN);
Label l1 = new Label();
mv.visitLabel(l1);
mv.visitLocalVariable("this", "L" + newDynName + ";", null, l0, l1, 0);
mv.visitMaxs(5, 5);
mv.visitEnd();
}
{ // 定义字段
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);
}
return rsMethodName;
}
@Override
public void doInstance(ResourceFactory resourceFactory, Object service) {
Class clazz = service.getClass();
if (actionMap == null) { // 为null表示没有调用过doMethod 动态类在编译是已经生成好了
actionMap = new LinkedHashMap<>();
Map<String, AsmMethodBean> methodBeans = AsmMethodBoost.getMethodBeans(clazz);
for (final Method method : clazz.getDeclaredMethods()) {
DynForCache cached = method.getAnnotation(DynForCache.class);
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);
actionMap.put(dynFieldName, action);
}
}
}
actionMap.forEach((field, action) -> {
try {
Field c = clazz.getDeclaredField(field);
c.setAccessible(true);
resourceFactory.inject(action);
action.init();
c.set(service, action);
RedkaleClassLoader.putReflectionField(clazz.getName(), c);
} catch (Exception e) {
throw new RedkaleException("field (" + field + ") in " + clazz.getName() + " set error", e);
}
});
// do nothing
}
}

View File

@@ -1,97 +1,97 @@
/*
*
*/
package org.redkale.cache.spi;
import java.util.concurrent.TimeUnit;
import org.redkale.cache.Cached;
import org.redkale.convert.json.JsonConvert;
/** @author zhangjx */
public class CacheEntry {
private String key;
private String hash;
private String localExpire;
private String remoteExpire;
private TimeUnit timeUnit;
private boolean nullable;
public CacheEntry() {}
public CacheEntry(DynForCache cached) {
this.key = cached.key();
this.hash = cached.hash();
this.localExpire = cached.localExpire();
this.remoteExpire = cached.remoteExpire();
this.timeUnit = cached.timeUnit();
this.nullable = cached.nullable();
}
public CacheEntry(Cached cached) {
this.key = cached.key();
this.hash = cached.hash();
this.localExpire = cached.localExpire();
this.remoteExpire = cached.remoteExpire();
this.timeUnit = cached.timeUnit();
this.nullable = cached.nullable();
}
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
public String getHash() {
return hash;
}
public void setHash(String hash) {
this.hash = hash;
}
public String getLocalExpire() {
return localExpire;
}
public void setLocalExpire(String localExpire) {
this.localExpire = localExpire;
}
public String getRemoteExpire() {
return remoteExpire;
}
public void setRemoteExpire(String remoteExpire) {
this.remoteExpire = remoteExpire;
}
public TimeUnit getTimeUnit() {
return timeUnit;
}
public void setTimeUnit(TimeUnit timeUnit) {
this.timeUnit = timeUnit;
}
public boolean isNullable() {
return nullable;
}
public void setNullable(boolean nullable) {
this.nullable = nullable;
}
@Override
public String toString() {
return JsonConvert.root().convertTo(this);
}
}
/*
*
*/
package org.redkale.cache.spi;
import java.util.concurrent.TimeUnit;
import org.redkale.cache.Cached;
import org.redkale.convert.json.JsonConvert;
/** @author zhangjx */
public class CacheEntry {
private String key;
private String hash;
private String localExpire;
private String remoteExpire;
private TimeUnit timeUnit;
private boolean nullable;
public CacheEntry() {}
public CacheEntry(DynForCache cached) {
this.key = cached.key();
this.hash = cached.hash();
this.localExpire = cached.localExpire();
this.remoteExpire = cached.remoteExpire();
this.timeUnit = cached.timeUnit();
this.nullable = cached.nullable();
}
public CacheEntry(Cached cached) {
this.key = cached.key();
this.hash = cached.hash();
this.localExpire = cached.localExpire();
this.remoteExpire = cached.remoteExpire();
this.timeUnit = cached.timeUnit();
this.nullable = cached.nullable();
}
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
public String getHash() {
return hash;
}
public void setHash(String hash) {
this.hash = hash;
}
public String getLocalExpire() {
return localExpire;
}
public void setLocalExpire(String localExpire) {
this.localExpire = localExpire;
}
public String getRemoteExpire() {
return remoteExpire;
}
public void setRemoteExpire(String remoteExpire) {
this.remoteExpire = remoteExpire;
}
public TimeUnit getTimeUnit() {
return timeUnit;
}
public void setTimeUnit(TimeUnit timeUnit) {
this.timeUnit = timeUnit;
}
public boolean isNullable() {
return nullable;
}
public void setNullable(boolean nullable) {
this.nullable = nullable;
}
@Override
public String toString() {
return JsonConvert.root().convertTo(this);
}
}

View File

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

File diff suppressed because it is too large Load Diff

View File

@@ -1,101 +1,101 @@
/*
*
*/
package org.redkale.cache.spi;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.ServiceLoader;
import org.redkale.asm.AsmMethodBoost;
import org.redkale.boot.Application;
import org.redkale.boot.ModuleEngine;
import org.redkale.cache.CacheManager;
import org.redkale.service.Service;
import org.redkale.util.AnyValue;
import org.redkale.util.InstanceProvider;
import org.redkale.util.RedkaleClassLoader;
/** @author zhangjx */
public class CacheModuleEngine extends ModuleEngine {
// 全局缓存管理器
private CacheManager cacheManager;
private AnyValue config;
public CacheModuleEngine(Application application) {
super(application);
}
/**
* 判断模块的配置项合并策略, 返回null表示模块不识别此配置项
*
* @param path 配置项路径
* @param key 配置项名称
* @param val1 配置项原值
* @param val2 配置项新值
* @return MergeEnum
*/
@Override
public AnyValue.MergeEnum mergeAppConfigStrategy(String path, String key, AnyValue val1, AnyValue val2) {
if ("".equals(path) && "cache".equals(key)) {
return AnyValue.MergeEnum.REPLACE;
}
return null;
}
/**
* 动态扩展类的方法
*
* @param remote 是否远程模式
* @param serviceClass 类
* @return 方法动态扩展器
*/
@Override
public AsmMethodBoost createAsmMethodBoost(boolean remote, Class serviceClass) {
return new CacheAsmMethodBoost(remote, serviceClass);
}
/** 结束Application.init方法前被调用 */
@Override
public void onAppPostInit() {
// 设置缓存管理器
this.config = application.getAppConfig().getAnyValue("cache");
this.cacheManager = createManager(this.config);
if (!application.isCompileMode()) {
this.resourceFactory.inject(this.cacheManager);
if (this.cacheManager instanceof Service) {
((Service) this.cacheManager).init(this.config);
}
}
this.resourceFactory.register("", CacheManager.class, this.cacheManager);
}
/** 进入Application.shutdown方法被调用 */
@Override
public void onAppPreShutdown() {
if (!application.isCompileMode() && this.cacheManager instanceof Service) {
((Service) this.cacheManager).destroy(this.config);
}
}
private CacheManager createManager(AnyValue conf) {
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());
providers.add(provider);
}
}
for (CacheManagerProvider provider : InstanceProvider.sort(providers)) {
return provider.createInstance();
}
return CacheManagerService.create(null).enabled(false);
}
}
/*
*
*/
package org.redkale.cache.spi;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.ServiceLoader;
import org.redkale.asm.AsmMethodBoost;
import org.redkale.boot.Application;
import org.redkale.boot.ModuleEngine;
import org.redkale.cache.CacheManager;
import org.redkale.service.Service;
import org.redkale.util.AnyValue;
import org.redkale.util.InstanceProvider;
import org.redkale.util.RedkaleClassLoader;
/** @author zhangjx */
public class CacheModuleEngine extends ModuleEngine {
// 全局缓存管理器
private CacheManager cacheManager;
private AnyValue config;
public CacheModuleEngine(Application application) {
super(application);
}
/**
* 判断模块的配置项合并策略, 返回null表示模块不识别此配置项
*
* @param path 配置项路径
* @param key 配置项名称
* @param val1 配置项原值
* @param val2 配置项新值
* @return MergeEnum
*/
@Override
public AnyValue.MergeEnum mergeAppConfigStrategy(String path, String key, AnyValue val1, AnyValue val2) {
if ("".equals(path) && "cache".equals(key)) {
return AnyValue.MergeEnum.REPLACE;
}
return null;
}
/**
* 动态扩展类的方法
*
* @param remote 是否远程模式
* @param serviceClass 类
* @return 方法动态扩展器
*/
@Override
public AsmMethodBoost createAsmMethodBoost(boolean remote, Class serviceClass) {
return new CacheAsmMethodBoost(remote, serviceClass);
}
/** 结束Application.init方法前被调用 */
@Override
public void onAppPostInit() {
// 设置缓存管理器
this.config = application.getAppConfig().getAnyValue("cache");
this.cacheManager = createManager(this.config);
if (!application.isCompileMode()) {
this.resourceFactory.inject(this.cacheManager);
if (this.cacheManager instanceof Service) {
((Service) this.cacheManager).init(this.config);
}
}
this.resourceFactory.register("", CacheManager.class, this.cacheManager);
}
/** 进入Application.shutdown方法被调用 */
@Override
public void onAppPreShutdown() {
if (!application.isCompileMode() && this.cacheManager instanceof Service) {
((Service) this.cacheManager).destroy(this.config);
}
}
private CacheManager createManager(AnyValue conf) {
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());
providers.add(provider);
}
}
for (CacheManagerProvider provider : InstanceProvider.sort(providers)) {
return provider.createInstance();
}
return CacheManagerService.create(null).enabled(false);
}
}

View File

@@ -1,53 +1,53 @@
/*
*
*/
package org.redkale.cache.spi;
import org.redkale.convert.ConvertColumn;
import org.redkale.convert.json.JsonConvert;
/**
* 内部缓存对象
*
* <p>详情见: https://redkale.org
*
* @author zhangjx
* @param <T> 泛型
* @since 2.8.0
*/
public class CacheValue<T> {
@ConvertColumn(index = 1)
private T val;
public CacheValue() {}
protected CacheValue(T value) {
this.val = value;
}
public static <T> CacheValue<T> create(T value) {
return new CacheValue(value);
}
public static boolean isValid(CacheValue val) {
return val != null;
}
public static <T> T get(CacheValue val) {
return isValid(val) ? (T) val.getVal() : null;
}
public T getVal() {
return val;
}
public void setVal(T val) {
this.val = val;
}
@Override
public String toString() {
return JsonConvert.root().convertTo(this);
}
}
/*
*
*/
package org.redkale.cache.spi;
import org.redkale.convert.ConvertColumn;
import org.redkale.convert.json.JsonConvert;
/**
* 内部缓存对象
*
* <p>详情见: https://redkale.org
*
* @author zhangjx
* @param <T> 泛型
* @since 2.8.0
*/
public class CacheValue<T> {
@ConvertColumn(index = 1)
private T val;
public CacheValue() {}
protected CacheValue(T value) {
this.val = value;
}
public static <T> CacheValue<T> create(T value) {
return new CacheValue(value);
}
public static boolean isValid(CacheValue val) {
return val != null;
}
public static <T> T get(CacheValue val) {
return isValid(val) ? (T) val.getVal() : null;
}
public T getVal() {
return val;
}
public void setVal(T val) {
this.val = val;
}
@Override
public String toString() {
return JsonConvert.root().convertTo(this);
}
}

View File

@@ -1,41 +1,41 @@
/*
*
*/
package org.redkale.cache.spi;
import static java.lang.annotation.ElementType.METHOD;
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}注解的动态扩展版,会多一个字段信息 用于识别方法是否已经动态处理过
*
* @author zhangjx
* @since 2.8.0
*/
@Documented
@Target({METHOD})
@Retention(RUNTIME)
public @interface DynForCache {
String dynField();
String key();
String hash();
String localExpire();
String remoteExpire();
TimeUnit timeUnit();
boolean nullable();
LoadMode mode() default LoadMode.ANY;
}
/*
*
*/
package org.redkale.cache.spi;
import static java.lang.annotation.ElementType.METHOD;
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}注解的动态扩展版,会多一个字段信息 用于识别方法是否已经动态处理过
*
* @author zhangjx
* @since 2.8.0
*/
@Documented
@Target({METHOD})
@Retention(RUNTIME)
public @interface DynForCache {
String dynField();
String key();
String hash();
String localExpire();
String remoteExpire();
TimeUnit timeUnit();
boolean nullable();
LoadMode mode() default LoadMode.ANY;
}

View File

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

View File

@@ -1,253 +1,253 @@
/*
*
*/
package org.redkale.cluster.spi;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Objects;
import java.util.Properties;
import java.util.ServiceLoader;
import java.util.Set;
import java.util.logging.Level;
import org.redkale.boot.Application;
import org.redkale.boot.ModuleEngine;
import org.redkale.inject.ResourceEvent;
import org.redkale.source.SourceManager;
import org.redkale.util.AnyValue;
import org.redkale.util.AnyValueWriter;
import org.redkale.util.RedkaleClassLoader;
/** @author zhangjx */
public class ClusterModuleEngine extends ModuleEngine {
// 第三方服务配置资源
// @since 2.8.0
private Properties clusterProperties = new Properties();
// 第三方服务发现管理接口
// @since 2.1.0
private ClusterAgent clusterAgent;
public ClusterModuleEngine(Application application) {
super(application);
}
/** 结束Application.init方法前被调用 */
@Override
public void onAppPostInit() {
ClusterAgent cluster = null;
AnyValue clusterConf = application.getAppConfig().getAnyValue("cluster");
if (clusterConf != null) {
try {
String classVal = environment.getPropertyValue(
clusterConf.getValue("type", clusterConf.getValue("value"))); // 兼容value字段
if (classVal == null
|| classVal.isEmpty()
|| classVal.indexOf('.') < 0) { // 不包含.表示非类名,比如值: consul, nacos
Iterator<ClusterAgentProvider> it = ServiceLoader.load(
ClusterAgentProvider.class, application.getClassLoader())
.iterator();
RedkaleClassLoader.putServiceLoader(ClusterAgentProvider.class);
while (it.hasNext()) {
ClusterAgentProvider provider = it.next();
if (provider != null) {
RedkaleClassLoader.putReflectionPublicConstructors(
provider.getClass(), provider.getClass().getName()); // loader class
}
if (provider != null && provider.acceptsConf(clusterConf)) {
cluster = provider.createInstance();
cluster.setConfig(clusterConf);
break;
}
}
if (cluster == null) {
ClusterAgent cacheClusterAgent = new CacheClusterAgent();
if (cacheClusterAgent.acceptsConf(clusterConf)) {
cluster = cacheClusterAgent;
cluster.setConfig(clusterConf);
}
}
if (cluster == null) {
logger.log(
Level.SEVERE,
"load application cluster resource, but not found name='type' value error: "
+ clusterConf);
}
} else {
Class type = application.getClassLoader().loadClass(classVal);
if (!ClusterAgent.class.isAssignableFrom(type)) {
logger.log(
Level.SEVERE,
"load application cluster resource, but not found " + ClusterAgent.class.getSimpleName()
+ " implements class error: " + clusterConf);
} else {
RedkaleClassLoader.putReflectionDeclaredConstructors(type, type.getName());
cluster = (ClusterAgent) type.getDeclaredConstructor().newInstance();
cluster.setConfig(clusterConf);
}
}
// 此时不能执行cluster.init因内置的对象可能依赖config.properties配置项
} catch (Exception e) {
logger.log(Level.SEVERE, "load application cluster resource error: " + clusterConf, e);
}
}
this.clusterAgent = cluster;
if (this.clusterAgent != null) {
if (logger.isLoggable(Level.FINER)) {
logger.log(
Level.FINER,
"ClusterAgent (type = " + this.clusterAgent.getClass().getSimpleName() + ") initing");
}
long s = System.currentTimeMillis();
if (this.clusterAgent instanceof CacheClusterAgent) {
String sourceName =
((CacheClusterAgent) clusterAgent).getSourceName(); // 必须在inject前调用需要赋值Resourcable.name
SourceManager sourceManager = application.getResourceFactory().find(SourceManager.class);
sourceManager.loadCacheSource(sourceName, false);
}
this.resourceFactory.inject(clusterAgent);
clusterAgent.init(clusterAgent.getConfig());
this.resourceFactory.register(ClusterAgent.class, clusterAgent);
logger.info("ClusterAgent (type = " + this.clusterAgent.getClass().getSimpleName() + ") init in "
+ (System.currentTimeMillis() - s) + " ms");
}
}
/** 配置项加载后被调用 */
@Override
public void onEnvironmentLoaded(Properties allProps) {
allProps.forEach((key, val) -> {
if (key.toString().startsWith("redkale.cluster.")) {
this.clusterProperties.put(key, val);
}
});
}
/**
* 配置项变更时被调用
*
* @param namespace 命名空间
* @param events 变更项
*/
@Override
public void onEnvironmentChanged(String namespace, List<ResourceEvent> events) {
Set<String> clusterRemovedKeys = new HashSet<>();
Properties clusterChangedProps = new Properties();
for (ResourceEvent<String> event : events) {
if (event.name().startsWith("redkale.cluster.")) {
if (!Objects.equals(event.newValue(), this.clusterProperties.getProperty(event.name()))) {
if (event.newValue() == null) {
if (this.clusterProperties.containsKey(event.name())) {
clusterRemovedKeys.add(event.name());
}
} else {
clusterChangedProps.put(event.name(), event.newValue());
}
}
}
}
// 第三方服务注册配置项的变更
if (!clusterChangedProps.isEmpty() || !clusterRemovedKeys.isEmpty()) {
if (this.clusterAgent != null) {
final AnyValueWriter old =
(AnyValueWriter) application.getAppConfig().getAnyValue("cluster");
Properties newProps = new Properties();
newProps.putAll(clusterProperties);
List<ResourceEvent> changeEvents = new ArrayList<>();
clusterChangedProps.forEach((k, v) -> {
final String key = k.toString();
newProps.put(k, v);
changeEvents.add(ResourceEvent.create(
key.substring("redkale.cluster.".length()), v, this.clusterProperties.getProperty(key)));
});
clusterRemovedKeys.forEach(k -> {
final String key = k;
newProps.remove(k);
changeEvents.add(ResourceEvent.create(
key.substring("redkale.cluster.".length()), null, this.clusterProperties.getProperty(key)));
});
if (!changeEvents.isEmpty()) {
AnyValueWriter back = old.copy();
try {
old.replace(AnyValue.loadFromProperties(newProps)
.getAnyValue("redkale")
.getAnyValue("cluster"));
clusterAgent.onResourceChange(changeEvents.toArray(new ResourceEvent[changeEvents.size()]));
} catch (RuntimeException e) {
old.replace(back); // 还原配置
throw e;
}
}
} else {
StringBuilder sb = new StringBuilder();
clusterChangedProps.forEach((k, v) -> {
sb.append(ClusterAgent.class.getSimpleName())
.append(" skip change '")
.append(k)
.append("'\r\n");
});
clusterRemovedKeys.forEach(k -> {
sb.append(ClusterAgent.class.getSimpleName())
.append(" skip change '")
.append(k)
.append("'\r\n");
});
if (sb.length() > 0) {
logger.log(Level.INFO, sb.toString());
}
}
clusterRemovedKeys.forEach(k -> this.clusterProperties.remove(k));
this.clusterProperties.putAll(clusterChangedProps);
}
}
/**
* 判断模块的配置项合并策略, 返回null表示模块不识别此配置项
*
* @param path 配置项路径
* @param key 配置项名称
* @param val1 配置项原值
* @param val2 配置项新值
* @return MergeEnum
*/
@Override
public AnyValue.MergeEnum mergeAppConfigStrategy(String path, String key, AnyValue val1, AnyValue val2) {
if ("".equals(path) && "cluster".equals(key)) {
return AnyValue.MergeEnum.REPLACE;
}
return null;
}
/** 进入Application.start方法被调用 */
@Override
public void onAppPreStart() {
if (!application.isSingletonMode() && !application.isCompileMode() && this.clusterAgent != null) {
this.clusterAgent.register(application);
}
}
/** 服务全部启动后被调用 */
public void onServersPostStart() {
if (this.clusterAgent != null) {
this.clusterAgent.start();
}
}
/** 服务全部停掉后被调用 */
public void onServersPostStop() {
if (!application.isCompileMode() && clusterAgent != null) {
if (logger.isLoggable(Level.FINER)) {
logger.log(Level.FINER, "ClusterAgent destroying");
}
long s = System.currentTimeMillis();
clusterAgent.deregister(application);
clusterAgent.destroy(clusterAgent.getConfig());
logger.info("ClusterAgent destroy in " + (System.currentTimeMillis() - s) + " ms");
}
}
}
/*
*
*/
package org.redkale.cluster.spi;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Objects;
import java.util.Properties;
import java.util.ServiceLoader;
import java.util.Set;
import java.util.logging.Level;
import org.redkale.boot.Application;
import org.redkale.boot.ModuleEngine;
import org.redkale.inject.ResourceEvent;
import org.redkale.source.SourceManager;
import org.redkale.util.AnyValue;
import org.redkale.util.AnyValueWriter;
import org.redkale.util.RedkaleClassLoader;
/** @author zhangjx */
public class ClusterModuleEngine extends ModuleEngine {
// 第三方服务配置资源
// @since 2.8.0
private Properties clusterProperties = new Properties();
// 第三方服务发现管理接口
// @since 2.1.0
private ClusterAgent clusterAgent;
public ClusterModuleEngine(Application application) {
super(application);
}
/** 结束Application.init方法前被调用 */
@Override
public void onAppPostInit() {
ClusterAgent cluster = null;
AnyValue clusterConf = application.getAppConfig().getAnyValue("cluster");
if (clusterConf != null) {
try {
String classVal = environment.getPropertyValue(
clusterConf.getValue("type", clusterConf.getValue("value"))); // 兼容value字段
if (classVal == null
|| classVal.isEmpty()
|| classVal.indexOf('.') < 0) { // 不包含.表示非类名,比如值: consul, nacos
Iterator<ClusterAgentProvider> it = ServiceLoader.load(
ClusterAgentProvider.class, application.getClassLoader())
.iterator();
RedkaleClassLoader.putServiceLoader(ClusterAgentProvider.class);
while (it.hasNext()) {
ClusterAgentProvider provider = it.next();
if (provider != null) {
RedkaleClassLoader.putReflectionPublicConstructors(
provider.getClass(), provider.getClass().getName()); // loader class
}
if (provider != null && provider.acceptsConf(clusterConf)) {
cluster = provider.createInstance();
cluster.setConfig(clusterConf);
break;
}
}
if (cluster == null) {
ClusterAgent cacheClusterAgent = new CacheClusterAgent();
if (cacheClusterAgent.acceptsConf(clusterConf)) {
cluster = cacheClusterAgent;
cluster.setConfig(clusterConf);
}
}
if (cluster == null) {
logger.log(
Level.SEVERE,
"load application cluster resource, but not found name='type' value error: "
+ clusterConf);
}
} else {
Class type = application.getClassLoader().loadClass(classVal);
if (!ClusterAgent.class.isAssignableFrom(type)) {
logger.log(
Level.SEVERE,
"load application cluster resource, but not found " + ClusterAgent.class.getSimpleName()
+ " implements class error: " + clusterConf);
} else {
RedkaleClassLoader.putReflectionDeclaredConstructors(type, type.getName());
cluster = (ClusterAgent) type.getDeclaredConstructor().newInstance();
cluster.setConfig(clusterConf);
}
}
// 此时不能执行cluster.init因内置的对象可能依赖config.properties配置项
} catch (Exception e) {
logger.log(Level.SEVERE, "load application cluster resource error: " + clusterConf, e);
}
}
this.clusterAgent = cluster;
if (this.clusterAgent != null) {
if (logger.isLoggable(Level.FINER)) {
logger.log(
Level.FINER,
"ClusterAgent (type = " + this.clusterAgent.getClass().getSimpleName() + ") initing");
}
long s = System.currentTimeMillis();
if (this.clusterAgent instanceof CacheClusterAgent) {
String sourceName =
((CacheClusterAgent) clusterAgent).getSourceName(); // 必须在inject前调用需要赋值Resourcable.name
SourceManager sourceManager = application.getResourceFactory().find(SourceManager.class);
sourceManager.loadCacheSource(sourceName, false);
}
this.resourceFactory.inject(clusterAgent);
clusterAgent.init(clusterAgent.getConfig());
this.resourceFactory.register(ClusterAgent.class, clusterAgent);
logger.info("ClusterAgent (type = " + this.clusterAgent.getClass().getSimpleName() + ") init in "
+ (System.currentTimeMillis() - s) + " ms");
}
}
/** 配置项加载后被调用 */
@Override
public void onEnvironmentLoaded(Properties allProps) {
allProps.forEach((key, val) -> {
if (key.toString().startsWith("redkale.cluster.")) {
this.clusterProperties.put(key, val);
}
});
}
/**
* 配置项变更时被调用
*
* @param namespace 命名空间
* @param events 变更项
*/
@Override
public void onEnvironmentChanged(String namespace, List<ResourceEvent> events) {
Set<String> clusterRemovedKeys = new HashSet<>();
Properties clusterChangedProps = new Properties();
for (ResourceEvent<String> event : events) {
if (event.name().startsWith("redkale.cluster.")) {
if (!Objects.equals(event.newValue(), this.clusterProperties.getProperty(event.name()))) {
if (event.newValue() == null) {
if (this.clusterProperties.containsKey(event.name())) {
clusterRemovedKeys.add(event.name());
}
} else {
clusterChangedProps.put(event.name(), event.newValue());
}
}
}
}
// 第三方服务注册配置项的变更
if (!clusterChangedProps.isEmpty() || !clusterRemovedKeys.isEmpty()) {
if (this.clusterAgent != null) {
final AnyValueWriter old =
(AnyValueWriter) application.getAppConfig().getAnyValue("cluster");
Properties newProps = new Properties();
newProps.putAll(clusterProperties);
List<ResourceEvent> changeEvents = new ArrayList<>();
clusterChangedProps.forEach((k, v) -> {
final String key = k.toString();
newProps.put(k, v);
changeEvents.add(ResourceEvent.create(
key.substring("redkale.cluster.".length()), v, this.clusterProperties.getProperty(key)));
});
clusterRemovedKeys.forEach(k -> {
final String key = k;
newProps.remove(k);
changeEvents.add(ResourceEvent.create(
key.substring("redkale.cluster.".length()), null, this.clusterProperties.getProperty(key)));
});
if (!changeEvents.isEmpty()) {
AnyValueWriter back = old.copy();
try {
old.replace(AnyValue.loadFromProperties(newProps)
.getAnyValue("redkale")
.getAnyValue("cluster"));
clusterAgent.onResourceChange(changeEvents.toArray(new ResourceEvent[changeEvents.size()]));
} catch (RuntimeException e) {
old.replace(back); // 还原配置
throw e;
}
}
} else {
StringBuilder sb = new StringBuilder();
clusterChangedProps.forEach((k, v) -> {
sb.append(ClusterAgent.class.getSimpleName())
.append(" skip change '")
.append(k)
.append("'\r\n");
});
clusterRemovedKeys.forEach(k -> {
sb.append(ClusterAgent.class.getSimpleName())
.append(" skip change '")
.append(k)
.append("'\r\n");
});
if (sb.length() > 0) {
logger.log(Level.INFO, sb.toString());
}
}
clusterRemovedKeys.forEach(k -> this.clusterProperties.remove(k));
this.clusterProperties.putAll(clusterChangedProps);
}
}
/**
* 判断模块的配置项合并策略, 返回null表示模块不识别此配置项
*
* @param path 配置项路径
* @param key 配置项名称
* @param val1 配置项原值
* @param val2 配置项新值
* @return MergeEnum
*/
@Override
public AnyValue.MergeEnum mergeAppConfigStrategy(String path, String key, AnyValue val1, AnyValue val2) {
if ("".equals(path) && "cluster".equals(key)) {
return AnyValue.MergeEnum.REPLACE;
}
return null;
}
/** 进入Application.start方法被调用 */
@Override
public void onAppPreStart() {
if (!application.isSingletonMode() && !application.isCompileMode() && this.clusterAgent != null) {
this.clusterAgent.register(application);
}
}
/** 服务全部启动后被调用 */
public void onServersPostStart() {
if (this.clusterAgent != null) {
this.clusterAgent.start();
}
}
/** 服务全部停掉后被调用 */
public void onServersPostStop() {
if (!application.isCompileMode() && clusterAgent != null) {
if (logger.isLoggable(Level.FINER)) {
logger.log(Level.FINER, "ClusterAgent destroying");
}
long s = System.currentTimeMillis();
clusterAgent.deregister(application);
clusterAgent.destroy(clusterAgent.getConfig());
logger.info("ClusterAgent destroy in " + (System.currentTimeMillis() - s) + " ms");
}
}
}

View File

@@ -1,228 +1,228 @@
package org.redkale.cluster.spi;
import static org.redkale.util.Utility.isEmpty;
import static org.redkale.util.Utility.isNotEmpty;
import java.io.Serializable;
import java.net.*;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.*;
import java.util.concurrent.*;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.redkale.annotation.Resource;
import org.redkale.boot.Application;
import org.redkale.cluster.HttpRpcClient;
import org.redkale.net.http.*;
import org.redkale.util.Traces;
import org.redkale.util.Utility;
/**
* 没有配置MQ的情况下依赖ClusterAgent实现的默认HttpRpcClient实例
*
* <p>详情见: https://redkale.org
*
* @author zhangjx
* @since 2.1.0
*/
public class HttpClusterRpcClient extends HttpRpcClient {
// jdk.internal.net.http.common.Utils.DISALLOWED_HEADERS_SET
private static final Set<String> DISALLOWED_HEADERS_SET = Utility.ofSet(
"connection",
"content-length",
"date",
"expect",
"from",
"host",
"origin",
"referer",
"upgrade",
"via",
"warning");
protected final Logger logger = Logger.getLogger(this.getClass().getSimpleName());
protected final HttpLocalRpcClient localClient;
protected final ConcurrentHashMap<String, Boolean> topicServletMap = new ConcurrentHashMap<>();
protected ClusterAgent clusterAgent;
@Resource(name = "cluster.httpClient", required = false)
protected WebClient webClient;
@Resource(name = "cluster.httpClient", required = false)
protected java.net.http.HttpClient httpClient;
public HttpClusterRpcClient(Application application, String resourceName, ClusterAgent clusterAgent) {
Objects.requireNonNull(clusterAgent);
this.localClient = new HttpLocalRpcClient(application, resourceName);
this.clusterAgent = clusterAgent;
}
@Override
protected String getNodeid() {
return localClient.getNodeid();
}
@Override
public CompletableFuture<HttpResult<byte[]>> sendMessage(
String topic, Serializable userid, String groupid, WebRequest request) {
if (topicServletMap.computeIfAbsent(topic, t -> localClient.findHttpServlet(t) != null)) {
return localClient.sendMessage(topic, userid, groupid, request);
} else {
return httpAsync(false, userid, request);
}
}
@Override
public CompletableFuture<Void> produceMessage(
String topic, Serializable userid, String groupid, WebRequest request) {
if (topicServletMap.computeIfAbsent(topic, t -> localClient.findHttpServlet(t) != null)) {
return localClient.produceMessage(topic, userid, groupid, request);
} else {
return httpAsync(true, userid, request).thenApply(v -> null);
}
}
private CompletableFuture<HttpResult<byte[]>> httpAsync(boolean produce, Serializable userid, WebRequest req) {
req.setTraceid(Traces.computeIfAbsent(req.getTraceid(), Traces.currentTraceid()));
String module = req.getPath();
module = module.substring(1, module.indexOf('/', 1));
HttpHeaders headers = req.getHeaders();
String resname = req.getHeader(Rest.REST_HEADER_RESNAME, "");
final String localModule = module;
if (logger.isLoggable(Level.FINEST)) {
logger.log(Level.FINEST, "httpAsync.queryHttpAddress: module=" + localModule + ", resname=" + resname);
}
return clusterAgent.queryHttpAddress("http", module, resname).thenCompose(addrs -> {
Traces.currentTraceid(req.getTraceid());
if (isEmpty(addrs)) {
if (logger.isLoggable(Level.WARNING)) {
logger.log(
Level.WARNING,
"httpAsync." + (produce ? "produceMessage" : "sendMessage") + " failed, module="
+ localModule + ", resname=" + resname + ", address is empty");
}
return new HttpResult<byte[]>().status(404).toFuture();
}
final HttpHeaders clientHeaders = HttpHeaders.create();
if (headers != null) {
boolean ws = headers.contains("Sec-WebSocket-Key");
headers.forEach((n, v) -> {
if (!DISALLOWED_HEADERS_SET.contains(n.toLowerCase())
&& (!ws
|| (!"Connection".equals(n)
&& !"Sec-WebSocket-Key".equals(n)
&& !"Sec-WebSocket-Version".equals(n)))) {
clientHeaders.add(n, v);
}
});
}
clientHeaders.set("Content-Type", "x-www-form-urlencoded");
if (req.isRpc()) {
clientHeaders.set(Rest.REST_HEADER_RPC, "true");
}
if (isNotEmpty(req.getTraceid())) {
clientHeaders.set(Rest.REST_HEADER_TRACEID, req.getTraceid());
}
if (userid != null) {
clientHeaders.set(Rest.REST_HEADER_CURRUSERID, String.valueOf(userid));
}
if (req.getReqConvertType() != null) {
clientHeaders.set(
Rest.REST_HEADER_REQ_CONVERT, req.getReqConvertType().toString());
}
if (req.getRespConvertType() != null) {
clientHeaders.set(
Rest.REST_HEADER_RESP_CONVERT, req.getRespConvertType().toString());
}
if (webClient != null) {
WebRequest newReq = req.copy().headers(clientHeaders);
InetSocketAddress addr = randomAddress(newReq, addrs);
if (logger.isLoggable(Level.FINEST)) {
logger.log(
Level.FINEST,
"httpAsync: module=" + localModule + ", resname=" + resname + ", addr=" + addr);
}
return (CompletableFuture) webClient.sendAsync(addr, newReq);
}
byte[] clientBody = null;
if (isNotEmpty(req.getBody())) {
String paramstr = req.getParametersToString();
if (paramstr != null) {
if (req.getPath().indexOf('?') > 0) {
req.setPath(req.getPath() + "&" + paramstr);
} else {
req.setPath(req.getPath() + "?" + paramstr);
}
}
clientBody = req.getBody();
} else {
String paramstr = req.getParametersToString();
if (paramstr != null) {
clientBody = paramstr.getBytes(StandardCharsets.UTF_8);
}
}
if (logger.isLoggable(Level.FINEST)) {
logger.log(
Level.FINEST,
"httpAsync: module=" + localModule + ", resname=" + resname + ", enter sendEachAddressAsync");
}
return sendEachAddressAsync(req, req.requestPath(), clientHeaders, clientBody, addrs.iterator());
});
}
protected InetSocketAddress randomAddress(WebRequest req, Set<InetSocketAddress> addrs) {
InetSocketAddress[] array = addrs.toArray(new InetSocketAddress[addrs.size()]);
return array[ThreadLocalRandom.current().nextInt(array.length)];
}
protected CompletableFuture<HttpResult<byte[]>> sendEachAddressAsync(
WebRequest req,
String requestPath,
final HttpHeaders clientHeaders,
byte[] clientBody,
Iterator<InetSocketAddress> it) {
if (!it.hasNext()) {
return new HttpResult<byte[]>().status(404).toFuture();
}
InetSocketAddress addr = it.next();
String host = addr.getPort() > 0 && addr.getPort() != 80
? (addr.getHostString() + ":" + addr.getPort())
: addr.getHostString();
String url = "http://" + host + requestPath;
if (logger.isLoggable(Level.FINER)) {
logger.log(
Level.FINER,
"sendEachAddressAsync: url: " + url + ", body: "
+ (clientBody != null ? new String(clientBody, StandardCharsets.UTF_8) : "") + ", headers: "
+ clientHeaders);
}
java.net.http.HttpRequest.Builder builder = java.net.http.HttpRequest.newBuilder()
.uri(URI.create(url))
.timeout(Duration.ofMillis(10_000))
// 存在sendHeader后不发送body数据的问题 java.net.http.HttpRequest的bug?
.method("POST", createBodyPublisher(clientBody));
clientHeaders.forEach(builder::header);
return httpClient
.sendAsync(builder.build(), java.net.http.HttpResponse.BodyHandlers.ofByteArray())
.thenApply((java.net.http.HttpResponse<byte[]> resp) -> {
Traces.currentTraceid(req.getTraceid());
final int rs = resp.statusCode();
if (rs != 200) {
return new HttpResult<byte[]>().status(rs);
}
return new HttpResult<>(resp.body());
});
}
private static java.net.http.HttpRequest.BodyPublisher createBodyPublisher(byte[] clientBody) {
return clientBody == null
? java.net.http.HttpRequest.BodyPublishers.noBody()
: java.net.http.HttpRequest.BodyPublishers.ofByteArray(clientBody);
}
}
package org.redkale.cluster.spi;
import static org.redkale.util.Utility.isEmpty;
import static org.redkale.util.Utility.isNotEmpty;
import java.io.Serializable;
import java.net.*;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.*;
import java.util.concurrent.*;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.redkale.annotation.Resource;
import org.redkale.boot.Application;
import org.redkale.cluster.HttpRpcClient;
import org.redkale.net.http.*;
import org.redkale.util.Traces;
import org.redkale.util.Utility;
/**
* 没有配置MQ的情况下依赖ClusterAgent实现的默认HttpRpcClient实例
*
* <p>详情见: https://redkale.org
*
* @author zhangjx
* @since 2.1.0
*/
public class HttpClusterRpcClient extends HttpRpcClient {
// jdk.internal.net.http.common.Utils.DISALLOWED_HEADERS_SET
private static final Set<String> DISALLOWED_HEADERS_SET = Utility.ofSet(
"connection",
"content-length",
"date",
"expect",
"from",
"host",
"origin",
"referer",
"upgrade",
"via",
"warning");
protected final Logger logger = Logger.getLogger(this.getClass().getSimpleName());
protected final HttpLocalRpcClient localClient;
protected final ConcurrentHashMap<String, Boolean> topicServletMap = new ConcurrentHashMap<>();
protected ClusterAgent clusterAgent;
@Resource(name = "cluster.httpClient", required = false)
protected WebClient webClient;
@Resource(name = "cluster.httpClient", required = false)
protected java.net.http.HttpClient httpClient;
public HttpClusterRpcClient(Application application, String resourceName, ClusterAgent clusterAgent) {
Objects.requireNonNull(clusterAgent);
this.localClient = new HttpLocalRpcClient(application, resourceName);
this.clusterAgent = clusterAgent;
}
@Override
protected String getNodeid() {
return localClient.getNodeid();
}
@Override
public CompletableFuture<HttpResult<byte[]>> sendMessage(
String topic, Serializable userid, String groupid, WebRequest request) {
if (topicServletMap.computeIfAbsent(topic, t -> localClient.findHttpServlet(t) != null)) {
return localClient.sendMessage(topic, userid, groupid, request);
} else {
return httpAsync(false, userid, request);
}
}
@Override
public CompletableFuture<Void> produceMessage(
String topic, Serializable userid, String groupid, WebRequest request) {
if (topicServletMap.computeIfAbsent(topic, t -> localClient.findHttpServlet(t) != null)) {
return localClient.produceMessage(topic, userid, groupid, request);
} else {
return httpAsync(true, userid, request).thenApply(v -> null);
}
}
private CompletableFuture<HttpResult<byte[]>> httpAsync(boolean produce, Serializable userid, WebRequest req) {
req.setTraceid(Traces.computeIfAbsent(req.getTraceid(), Traces.currentTraceid()));
String module = req.getPath();
module = module.substring(1, module.indexOf('/', 1));
HttpHeaders headers = req.getHeaders();
String resname = req.getHeader(Rest.REST_HEADER_RESNAME, "");
final String localModule = module;
if (logger.isLoggable(Level.FINEST)) {
logger.log(Level.FINEST, "httpAsync.queryHttpAddress: module=" + localModule + ", resname=" + resname);
}
return clusterAgent.queryHttpAddress("http", module, resname).thenCompose(addrs -> {
Traces.currentTraceid(req.getTraceid());
if (isEmpty(addrs)) {
if (logger.isLoggable(Level.WARNING)) {
logger.log(
Level.WARNING,
"httpAsync." + (produce ? "produceMessage" : "sendMessage") + " failed, module="
+ localModule + ", resname=" + resname + ", address is empty");
}
return new HttpResult<byte[]>().status(404).toFuture();
}
final HttpHeaders clientHeaders = HttpHeaders.create();
if (headers != null) {
boolean ws = headers.contains("Sec-WebSocket-Key");
headers.forEach((n, v) -> {
if (!DISALLOWED_HEADERS_SET.contains(n.toLowerCase())
&& (!ws
|| (!"Connection".equals(n)
&& !"Sec-WebSocket-Key".equals(n)
&& !"Sec-WebSocket-Version".equals(n)))) {
clientHeaders.add(n, v);
}
});
}
clientHeaders.set("Content-Type", "x-www-form-urlencoded");
if (req.isRpc()) {
clientHeaders.set(Rest.REST_HEADER_RPC, "true");
}
if (isNotEmpty(req.getTraceid())) {
clientHeaders.set(Rest.REST_HEADER_TRACEID, req.getTraceid());
}
if (userid != null) {
clientHeaders.set(Rest.REST_HEADER_CURRUSERID, String.valueOf(userid));
}
if (req.getReqConvertType() != null) {
clientHeaders.set(
Rest.REST_HEADER_REQ_CONVERT, req.getReqConvertType().toString());
}
if (req.getRespConvertType() != null) {
clientHeaders.set(
Rest.REST_HEADER_RESP_CONVERT, req.getRespConvertType().toString());
}
if (webClient != null) {
WebRequest newReq = req.copy().headers(clientHeaders);
InetSocketAddress addr = randomAddress(newReq, addrs);
if (logger.isLoggable(Level.FINEST)) {
logger.log(
Level.FINEST,
"httpAsync: module=" + localModule + ", resname=" + resname + ", addr=" + addr);
}
return (CompletableFuture) webClient.sendAsync(addr, newReq);
}
byte[] clientBody = null;
if (isNotEmpty(req.getBody())) {
String paramstr = req.getParametersToString();
if (paramstr != null) {
if (req.getPath().indexOf('?') > 0) {
req.setPath(req.getPath() + "&" + paramstr);
} else {
req.setPath(req.getPath() + "?" + paramstr);
}
}
clientBody = req.getBody();
} else {
String paramstr = req.getParametersToString();
if (paramstr != null) {
clientBody = paramstr.getBytes(StandardCharsets.UTF_8);
}
}
if (logger.isLoggable(Level.FINEST)) {
logger.log(
Level.FINEST,
"httpAsync: module=" + localModule + ", resname=" + resname + ", enter sendEachAddressAsync");
}
return sendEachAddressAsync(req, req.requestPath(), clientHeaders, clientBody, addrs.iterator());
});
}
protected InetSocketAddress randomAddress(WebRequest req, Set<InetSocketAddress> addrs) {
InetSocketAddress[] array = addrs.toArray(new InetSocketAddress[addrs.size()]);
return array[ThreadLocalRandom.current().nextInt(array.length)];
}
protected CompletableFuture<HttpResult<byte[]>> sendEachAddressAsync(
WebRequest req,
String requestPath,
final HttpHeaders clientHeaders,
byte[] clientBody,
Iterator<InetSocketAddress> it) {
if (!it.hasNext()) {
return new HttpResult<byte[]>().status(404).toFuture();
}
InetSocketAddress addr = it.next();
String host = addr.getPort() > 0 && addr.getPort() != 80
? (addr.getHostString() + ":" + addr.getPort())
: addr.getHostString();
String url = "http://" + host + requestPath;
if (logger.isLoggable(Level.FINER)) {
logger.log(
Level.FINER,
"sendEachAddressAsync: url: " + url + ", body: "
+ (clientBody != null ? new String(clientBody, StandardCharsets.UTF_8) : "") + ", headers: "
+ clientHeaders);
}
java.net.http.HttpRequest.Builder builder = java.net.http.HttpRequest.newBuilder()
.uri(URI.create(url))
.timeout(Duration.ofMillis(10_000))
// 存在sendHeader后不发送body数据的问题 java.net.http.HttpRequest的bug?
.method("POST", createBodyPublisher(clientBody));
clientHeaders.forEach(builder::header);
return httpClient
.sendAsync(builder.build(), java.net.http.HttpResponse.BodyHandlers.ofByteArray())
.thenApply((java.net.http.HttpResponse<byte[]> resp) -> {
Traces.currentTraceid(req.getTraceid());
final int rs = resp.statusCode();
if (rs != 200) {
return new HttpResult<byte[]>().status(rs);
}
return new HttpResult<>(resp.body());
});
}
private static java.net.http.HttpRequest.BodyPublisher createBodyPublisher(byte[] clientBody) {
return clientBody == null
? java.net.http.HttpRequest.BodyPublishers.noBody()
: java.net.http.HttpRequest.BodyPublishers.ofByteArray(clientBody);
}
}

View File

@@ -1,65 +1,65 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package org.redkale.convert;
import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.*;
/**
* 用于序列化时接口或抽象类的默认实现类, 被标记的类必须是接口或抽象类 <br>
* 使用场景: <br>
*
* <blockquote>
*
* <pre>
* &#64;ConvertImpl(OneImpl.class)
* public interface OneEntity {
* public String getName();
* }
*
*
* public class OneImpl implements OneEntity {
* private String name;
* public String getName(){return name;}
* public void setName(String name){this.name=name;}
* }
*
*
* String json = "{'name':'hello'}";
* OneEntity one = JsonConvert.root().convertFrom(OneEntity.class, json);
* //one instanceof OneImpl
*
* </pre>
*
* </blockquote>
*
* <p>详情见: https://redkale.org
*
* @author zhangjx
* @since 2.5.0
*/
// 一定不能标记Inherited
@Documented
@Target({TYPE})
@Retention(RUNTIME)
public @interface ConvertImpl {
/**
* 默认的实现类
*
* @return String
*/
Class value() default Object.class;
/**
* 实现类的集合
*
* @return Class[]
*/
Class[] types() default {};
}
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package org.redkale.convert;
import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.*;
/**
* 用于序列化时接口或抽象类的默认实现类, 被标记的类必须是接口或抽象类 <br>
* 使用场景: <br>
*
* <blockquote>
*
* <pre>
* &#64;ConvertImpl(OneImpl.class)
* public interface OneEntity {
* public String getName();
* }
*
*
* public class OneImpl implements OneEntity {
* private String name;
* public String getName(){return name;}
* public void setName(String name){this.name=name;}
* }
*
*
* String json = "{'name':'hello'}";
* OneEntity one = JsonConvert.root().convertFrom(OneEntity.class, json);
* //one instanceof OneImpl
*
* </pre>
*
* </blockquote>
*
* <p>详情见: https://redkale.org
*
* @author zhangjx
* @since 2.5.0
*/
// 一定不能标记Inherited
@Documented
@Target({TYPE})
@Retention(RUNTIME)
public @interface ConvertImpl {
/**
* 默认的实现类
*
* @return String
*/
Class value() default Object.class;
/**
* 实现类的集合
*
* @return Class[]
*/
Class[] types() default {};
}

View File

@@ -1,137 +1,137 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package org.redkale.convert;
import java.lang.reflect.*;
import java.util.*;
import java.util.concurrent.locks.*;
import java.util.stream.Stream;
/**
* Stream的反序列化操作类 <br>
* 支持一定程度的泛型。 <br>
*
* <p>详情见: https://redkale.org
*
* @author zhangjx
* @param <T> 反解析的集合元素类型
*/
@SuppressWarnings("unchecked")
public class StreamDecoder<T> implements Decodeable<Reader, Stream<T>> {
protected final Type type;
protected final Type componentType;
protected final Decodeable<Reader, T> componentDecoder;
protected volatile boolean inited = false;
private final ReentrantLock lock = new ReentrantLock();
private final Condition condition = lock.newCondition();
public StreamDecoder(final ConvertFactory factory, final Type type) {
this.type = type;
try {
if (type instanceof ParameterizedType) {
final ParameterizedType pt = (ParameterizedType) type;
this.componentType = pt.getActualTypeArguments()[0];
factory.register(type, this);
this.componentDecoder = factory.loadDecoder(this.componentType);
} else {
throw new ConvertException("StreamDecoder not support the type (" + type + ")");
}
} finally {
inited = true;
lock.lock();
try {
condition.signalAll();
} finally {
lock.unlock();
}
}
}
@Override
public Stream<T> convertFrom(Reader in) {
return convertFrom(in, null);
}
public Stream<T> convertFrom(Reader in, DeMember member) {
byte[] typevals = new byte[1];
int len = in.readArrayB(member, typevals, this.componentDecoder);
int contentLength = -1;
if (len == Reader.SIGN_NULL) {
return null;
}
if (len == Reader.SIGN_NOLENBUTBYTES) {
contentLength = in.readMemberContentLength(member, this.componentDecoder);
len = Reader.SIGN_NOLENGTH;
}
if (this.componentDecoder == null) {
if (!this.inited) {
lock.lock();
try {
condition.await();
} catch (Exception e) {
// do nothing
} finally {
lock.unlock();
}
}
}
final Decodeable<Reader, T> localdecoder = getComponentDecoder(this.componentDecoder, typevals);
final List<T> result = new ArrayList();
boolean first = true;
if (len == Reader.SIGN_NOLENGTH) {
int startPosition = in.position();
while (hasNext(in, member, startPosition, contentLength, first)) {
Reader itemReader = getItemReader(in, member, first);
if (itemReader == null) {
break;
}
result.add(readMemberValue(itemReader, member, localdecoder, first));
first = false;
}
} else {
for (int i = 0; i < len; i++) {
result.add(localdecoder.convertFrom(in));
}
}
in.readArrayE();
return result.stream();
}
protected boolean hasNext(Reader in, DeMember member, int startPosition, int contentLength, boolean first) {
return in.hasNext(startPosition, contentLength);
}
protected Decodeable<Reader, T> getComponentDecoder(Decodeable<Reader, T> decoder, byte[] typevals) {
return decoder;
}
protected Reader getItemReader(Reader in, DeMember member, boolean first) {
return in;
}
protected T readMemberValue(Reader in, DeMember member, Decodeable<Reader, T> decoder, boolean first) {
return decoder.convertFrom(in);
}
@Override
public Type getType() {
return type;
}
public Type getComponentType() {
return componentType;
}
public Decodeable<Reader, T> getComponentDecoder() {
return componentDecoder;
}
}
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package org.redkale.convert;
import java.lang.reflect.*;
import java.util.*;
import java.util.concurrent.locks.*;
import java.util.stream.Stream;
/**
* Stream的反序列化操作类 <br>
* 支持一定程度的泛型。 <br>
*
* <p>详情见: https://redkale.org
*
* @author zhangjx
* @param <T> 反解析的集合元素类型
*/
@SuppressWarnings("unchecked")
public class StreamDecoder<T> implements Decodeable<Reader, Stream<T>> {
protected final Type type;
protected final Type componentType;
protected final Decodeable<Reader, T> componentDecoder;
protected volatile boolean inited = false;
private final ReentrantLock lock = new ReentrantLock();
private final Condition condition = lock.newCondition();
public StreamDecoder(final ConvertFactory factory, final Type type) {
this.type = type;
try {
if (type instanceof ParameterizedType) {
final ParameterizedType pt = (ParameterizedType) type;
this.componentType = pt.getActualTypeArguments()[0];
factory.register(type, this);
this.componentDecoder = factory.loadDecoder(this.componentType);
} else {
throw new ConvertException("StreamDecoder not support the type (" + type + ")");
}
} finally {
inited = true;
lock.lock();
try {
condition.signalAll();
} finally {
lock.unlock();
}
}
}
@Override
public Stream<T> convertFrom(Reader in) {
return convertFrom(in, null);
}
public Stream<T> convertFrom(Reader in, DeMember member) {
byte[] typevals = new byte[1];
int len = in.readArrayB(member, typevals, this.componentDecoder);
int contentLength = -1;
if (len == Reader.SIGN_NULL) {
return null;
}
if (len == Reader.SIGN_NOLENBUTBYTES) {
contentLength = in.readMemberContentLength(member, this.componentDecoder);
len = Reader.SIGN_NOLENGTH;
}
if (this.componentDecoder == null) {
if (!this.inited) {
lock.lock();
try {
condition.await();
} catch (Exception e) {
// do nothing
} finally {
lock.unlock();
}
}
}
final Decodeable<Reader, T> localdecoder = getComponentDecoder(this.componentDecoder, typevals);
final List<T> result = new ArrayList();
boolean first = true;
if (len == Reader.SIGN_NOLENGTH) {
int startPosition = in.position();
while (hasNext(in, member, startPosition, contentLength, first)) {
Reader itemReader = getItemReader(in, member, first);
if (itemReader == null) {
break;
}
result.add(readMemberValue(itemReader, member, localdecoder, first));
first = false;
}
} else {
for (int i = 0; i < len; i++) {
result.add(localdecoder.convertFrom(in));
}
}
in.readArrayE();
return result.stream();
}
protected boolean hasNext(Reader in, DeMember member, int startPosition, int contentLength, boolean first) {
return in.hasNext(startPosition, contentLength);
}
protected Decodeable<Reader, T> getComponentDecoder(Decodeable<Reader, T> decoder, byte[] typevals) {
return decoder;
}
protected Reader getItemReader(Reader in, DeMember member, boolean first) {
return in;
}
protected T readMemberValue(Reader in, DeMember member, Decodeable<Reader, T> decoder, boolean first) {
return decoder.convertFrom(in);
}
@Override
public Type getType() {
return type;
}
public Type getComponentType() {
return componentType;
}
public Decodeable<Reader, T> getComponentDecoder() {
return componentDecoder;
}
}

View File

@@ -1,98 +1,98 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package org.redkale.convert.ext;
import java.lang.reflect.*;
import java.util.*;
import org.redkale.convert.*;
import org.redkale.util.RedkaleClassLoader;
/**
* 枚举 的SimpledCoder实现
*
* <p>详情见: https://redkale.org
*
* @author zhangjx
* @param <R> Reader输入的子类型
* @param <W> Writer输出的子类型
* @param <E> Enum的子类
*/
public final class EnumSimpledCoder<R extends Reader, W extends Writer, E extends Enum> extends SimpledCoder<R, W, E> {
private final Encodeable valueEncoder;
private final Map<E, Object> enumToValues;
private final Map<String, E> valueToEnums;
public EnumSimpledCoder(final ConvertFactory factory, Class<E> type) {
this.type = type;
ConvertEnumValue cev = type.getAnnotation(ConvertEnumValue.class);
if (cev == null) {
this.valueEncoder = null;
this.enumToValues = null;
this.valueToEnums = null;
} else {
try {
String fieldName = cev.value();
Field field = type.getDeclaredField(fieldName);
RedkaleClassLoader.putReflectionField(fieldName, field);
char[] chs = fieldName.toCharArray();
chs[0] = Character.toUpperCase(chs[0]);
String methodName = "get" + new String(chs);
Method method = null;
try {
method = type.getMethod(methodName);
} catch (NoSuchMethodException | SecurityException me) {
method = type.getMethod(fieldName);
methodName = fieldName;
}
RedkaleClassLoader.putReflectionMethod(methodName, method);
Map<E, Object> map1 = new HashMap<>();
Map<String, E> map2 = new HashMap<>();
for (E e : type.getEnumConstants()) {
map1.put(e, method.invoke(e));
map2.put(method.invoke(e).toString(), e);
}
this.valueEncoder = factory.loadEncoder(field.getType());
this.enumToValues = map1;
this.valueToEnums = map2;
} catch (Exception e) {
throw new ConvertException(e);
}
}
}
@Override
public void convertTo(final W out, final E value) {
if (value == null) {
out.writeNull();
} else if (valueEncoder != null) {
valueEncoder.convertTo(out, enumToValues.get(value));
} else {
out.writeSmallString(value.toString());
}
}
@Override
@SuppressWarnings("unchecked")
public E convertFrom(final R in) {
String value = in.readSmallString();
if (value == null) {
return null;
}
if (valueToEnums != null) {
return valueToEnums.get(value);
} else {
return (E) Enum.valueOf((Class<E>) type, value);
}
}
@Override
public Class<E> getType() {
return (Class<E>) type;
}
}
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package org.redkale.convert.ext;
import java.lang.reflect.*;
import java.util.*;
import org.redkale.convert.*;
import org.redkale.util.RedkaleClassLoader;
/**
* 枚举 的SimpledCoder实现
*
* <p>详情见: https://redkale.org
*
* @author zhangjx
* @param <R> Reader输入的子类型
* @param <W> Writer输出的子类型
* @param <E> Enum的子类
*/
public final class EnumSimpledCoder<R extends Reader, W extends Writer, E extends Enum> extends SimpledCoder<R, W, E> {
private final Encodeable valueEncoder;
private final Map<E, Object> enumToValues;
private final Map<String, E> valueToEnums;
public EnumSimpledCoder(final ConvertFactory factory, Class<E> type) {
this.type = type;
ConvertEnumValue cev = type.getAnnotation(ConvertEnumValue.class);
if (cev == null) {
this.valueEncoder = null;
this.enumToValues = null;
this.valueToEnums = null;
} else {
try {
String fieldName = cev.value();
Field field = type.getDeclaredField(fieldName);
RedkaleClassLoader.putReflectionField(fieldName, field);
char[] chs = fieldName.toCharArray();
chs[0] = Character.toUpperCase(chs[0]);
String methodName = "get" + new String(chs);
Method method = null;
try {
method = type.getMethod(methodName);
} catch (NoSuchMethodException | SecurityException me) {
method = type.getMethod(fieldName);
methodName = fieldName;
}
RedkaleClassLoader.putReflectionMethod(methodName, method);
Map<E, Object> map1 = new HashMap<>();
Map<String, E> map2 = new HashMap<>();
for (E e : type.getEnumConstants()) {
map1.put(e, method.invoke(e));
map2.put(method.invoke(e).toString(), e);
}
this.valueEncoder = factory.loadEncoder(field.getType());
this.enumToValues = map1;
this.valueToEnums = map2;
} catch (Exception e) {
throw new ConvertException(e);
}
}
}
@Override
public void convertTo(final W out, final E value) {
if (value == null) {
out.writeNull();
} else if (valueEncoder != null) {
valueEncoder.convertTo(out, enumToValues.get(value));
} else {
out.writeSmallString(value.toString());
}
}
@Override
@SuppressWarnings("unchecked")
public E convertFrom(final R in) {
String value = in.readSmallString();
if (value == null) {
return null;
}
if (valueToEnums != null) {
return valueToEnums.get(value);
} else {
return (E) Enum.valueOf((Class<E>) type, value);
}
}
@Override
public Class<E> getType() {
return (Class<E>) type;
}
}

View File

@@ -1,59 +1,59 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package org.redkale.convert.ext;
import java.time.Instant;
import org.redkale.convert.*;
import org.redkale.convert.json.*;
/**
* java.time.Instant 的SimpledCoder实现
*
* <p>详情见: https://redkale.org
*
* @author zhangjx
* @param <R> Reader输入的子类型
* @param <W> Writer输出的子类型
*/
public class InstantSimpledCoder<R extends Reader, W extends Writer> extends SimpledCoder<R, W, Instant> {
public static final InstantSimpledCoder instance = new InstantSimpledCoder();
@Override
public void convertTo(W out, Instant value) {
out.writeLong(value == null ? -1L : value.toEpochMilli());
}
@Override
public Instant convertFrom(R in) {
long t = in.readLong();
return t == -1 ? null : Instant.ofEpochMilli(t);
}
public static final class InstantJsonSimpledCoder<R extends JsonReader, W extends JsonWriter>
extends SimpledCoder<R, W, Instant> {
public static final InstantJsonSimpledCoder instance = new InstantJsonSimpledCoder();
@Override
public void convertTo(final W out, final Instant value) {
if (value == null) {
out.writeNull();
} else {
out.writeSmallString(value.toString());
}
}
@Override
public Instant convertFrom(R in) {
final String str = in.readSmallString();
if (str == null) {
return null;
}
return Instant.parse(str);
}
}
}
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package org.redkale.convert.ext;
import java.time.Instant;
import org.redkale.convert.*;
import org.redkale.convert.json.*;
/**
* java.time.Instant 的SimpledCoder实现
*
* <p>详情见: https://redkale.org
*
* @author zhangjx
* @param <R> Reader输入的子类型
* @param <W> Writer输出的子类型
*/
public class InstantSimpledCoder<R extends Reader, W extends Writer> extends SimpledCoder<R, W, Instant> {
public static final InstantSimpledCoder instance = new InstantSimpledCoder();
@Override
public void convertTo(W out, Instant value) {
out.writeLong(value == null ? -1L : value.toEpochMilli());
}
@Override
public Instant convertFrom(R in) {
long t = in.readLong();
return t == -1 ? null : Instant.ofEpochMilli(t);
}
public static final class InstantJsonSimpledCoder<R extends JsonReader, W extends JsonWriter>
extends SimpledCoder<R, W, Instant> {
public static final InstantJsonSimpledCoder instance = new InstantJsonSimpledCoder();
@Override
public void convertTo(final W out, final Instant value) {
if (value == null) {
out.writeNull();
} else {
out.writeSmallString(value.toString());
}
}
@Override
public Instant convertFrom(R in) {
final String str = in.readSmallString();
if (str == null) {
return null;
}
return Instant.parse(str);
}
}
}

View File

@@ -1,75 +1,75 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package org.redkale.convert.ext;
import java.time.LocalDate;
import org.redkale.convert.*;
import org.redkale.convert.json.*;
/**
* java.time.LocalDate 的SimpledCoder实现
*
* <p>详情见: https://redkale.org
*
* @author zhangjx
* @param <R> Reader输入的子类型
* @param <W> Writer输出的子类型
*/
public final class LocalDateSimpledCoder<R extends Reader, W extends Writer> extends SimpledCoder<R, W, LocalDate> {
public static final LocalDateSimpledCoder instance = new LocalDateSimpledCoder();
@Override
public void convertTo(W out, LocalDate value) {
out.writeInt(
value == null ? -1 : value.getYear() * 100_00 + value.getMonthValue() * 100 + value.getDayOfMonth());
}
@Override
public LocalDate convertFrom(R in) {
int t = in.readInt();
return t == -1 ? null : LocalDate.of(t / 100_00, t % 100_00 / 100, t % 100);
}
// public static void main(String[] args) throws Throwable {
// LocalDate now = LocalDate.now();
// System.out.println(now);
// BsonWriter writer = new BsonWriter();
// LocalDateSimpledCoder.instance.convertTo(writer, now);
// System.out.println(new ByteArray(writer).getInt(0));
// BsonReader reader = new BsonReader(writer.toArray());
// System.out.println(LocalDateSimpledCoder.instance.convertFrom(reader));
// }
/**
* java.time.LocalDate 的JsonSimpledCoder实现
*
* @param <R> Reader输入的子类型
* @param <W> Writer输出的子类型
*/
public static final class LocalDateJsonSimpledCoder<R extends JsonReader, W extends JsonWriter>
extends SimpledCoder<R, W, LocalDate> {
public static final LocalDateJsonSimpledCoder instance = new LocalDateJsonSimpledCoder();
@Override
public void convertTo(final W out, final LocalDate value) {
if (value == null) {
out.writeNull();
} else {
out.writeSmallString(value.toString());
}
}
@Override
public LocalDate convertFrom(R in) {
final String str = in.readSmallString();
if (str == null) {
return null;
}
return LocalDate.parse(str);
}
}
}
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package org.redkale.convert.ext;
import java.time.LocalDate;
import org.redkale.convert.*;
import org.redkale.convert.json.*;
/**
* java.time.LocalDate 的SimpledCoder实现
*
* <p>详情见: https://redkale.org
*
* @author zhangjx
* @param <R> Reader输入的子类型
* @param <W> Writer输出的子类型
*/
public final class LocalDateSimpledCoder<R extends Reader, W extends Writer> extends SimpledCoder<R, W, LocalDate> {
public static final LocalDateSimpledCoder instance = new LocalDateSimpledCoder();
@Override
public void convertTo(W out, LocalDate value) {
out.writeInt(
value == null ? -1 : value.getYear() * 100_00 + value.getMonthValue() * 100 + value.getDayOfMonth());
}
@Override
public LocalDate convertFrom(R in) {
int t = in.readInt();
return t == -1 ? null : LocalDate.of(t / 100_00, t % 100_00 / 100, t % 100);
}
// public static void main(String[] args) throws Throwable {
// LocalDate now = LocalDate.now();
// System.out.println(now);
// BsonWriter writer = new BsonWriter();
// LocalDateSimpledCoder.instance.convertTo(writer, now);
// System.out.println(new ByteArray(writer).getInt(0));
// BsonReader reader = new BsonReader(writer.toArray());
// System.out.println(LocalDateSimpledCoder.instance.convertFrom(reader));
// }
/**
* java.time.LocalDate 的JsonSimpledCoder实现
*
* @param <R> Reader输入的子类型
* @param <W> Writer输出的子类型
*/
public static final class LocalDateJsonSimpledCoder<R extends JsonReader, W extends JsonWriter>
extends SimpledCoder<R, W, LocalDate> {
public static final LocalDateJsonSimpledCoder instance = new LocalDateJsonSimpledCoder();
@Override
public void convertTo(final W out, final LocalDate value) {
if (value == null) {
out.writeNull();
} else {
out.writeSmallString(value.toString());
}
}
@Override
public LocalDate convertFrom(R in) {
final String str = in.readSmallString();
if (str == null) {
return null;
}
return LocalDate.parse(str);
}
}
}

View File

@@ -1,108 +1,108 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package org.redkale.convert.ext;
import java.time.*;
import org.redkale.convert.*;
import org.redkale.convert.json.*;
/**
* java.time.LocalDateTime 的SimpledCoder实现
*
* <p>详情见: https://redkale.org
*
* @author zhangjx
* @param <R> Reader输入的子类型
* @param <W> Writer输出的子类型
*/
public final class LocalDateTimeSimpledCoder<R extends Reader, W extends Writer>
extends SimpledCoder<R, W, LocalDateTime> {
private static final ByteArraySimpledCoder bsSimpledCoder = ByteArraySimpledCoder.instance;
public static final LocalDateTimeSimpledCoder instance = new LocalDateTimeSimpledCoder();
@Override
public void convertTo(W out, LocalDateTime value) {
if (value == null) {
bsSimpledCoder.convertTo(out, null);
} else {
long v1 = value.toEpochSecond(ZoneOffset.UTC);
int v2 = value.getNano();
byte[] bs = new byte[] {
(byte) (v1 >> 56),
(byte) (v1 >> 48),
(byte) (v1 >> 40),
(byte) (v1 >> 32),
(byte) (v1 >> 24),
(byte) (v1 >> 16),
(byte) (v1 >> 8),
(byte) v1,
(byte) (v2 >> 24),
(byte) (v2 >> 16),
(byte) (v2 >> 8),
(byte) v2
};
bsSimpledCoder.convertTo(out, bs);
}
}
@Override
public LocalDateTime convertFrom(R in) {
byte[] bs = bsSimpledCoder.convertFrom(in);
if (bs == null) {
return null;
}
long v1 = (((long) bs[0] & 0xff) << 56)
| (((long) bs[1] & 0xff) << 48)
| (((long) bs[2] & 0xff) << 40)
| (((long) bs[3] & 0xff) << 32)
| (((long) bs[4] & 0xff) << 24)
| (((long) bs[5] & 0xff) << 16)
| (((long) bs[6] & 0xff) << 8)
| ((long) bs[7] & 0xff);
int v2 = ((bs[8] & 0xff) << 24) | ((bs[9] & 0xff) << 16) | ((bs[10] & 0xff) << 8) | (bs[11] & 0xff);
return LocalDateTime.ofEpochSecond(v1, v2, ZoneOffset.UTC);
}
// public static void main(String[] args) throws Throwable {
// LocalDateTime now = LocalDateTime.now();
// System.out.println(now);
// BsonWriter writer = new BsonWriter();
// LocalDateTimeSimpledCoder.instance.convertTo(writer, now);
// BsonReader reader = new BsonReader(writer.toArray());
// System.out.println(LocalDateTimeSimpledCoder.instance.convertFrom(reader));
// }
/**
* java.time.LocalDateTime 的JsonSimpledCoder实现
*
* @param <R> Reader输入的子类型
* @param <W> Writer输出的子类型
*/
public static final class LocalDateTimeJsonSimpledCoder<R extends JsonReader, W extends JsonWriter>
extends SimpledCoder<R, W, LocalDateTime> {
public static final LocalDateTimeJsonSimpledCoder instance = new LocalDateTimeJsonSimpledCoder();
@Override
public void convertTo(final W out, final LocalDateTime value) {
if (value == null) {
out.writeNull();
} else {
out.writeSmallString(value.toString());
}
}
@Override
public LocalDateTime convertFrom(R in) {
final String str = in.readSmallString();
if (str == null) {
return null;
}
return LocalDateTime.parse(str);
}
}
}
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package org.redkale.convert.ext;
import java.time.*;
import org.redkale.convert.*;
import org.redkale.convert.json.*;
/**
* java.time.LocalDateTime 的SimpledCoder实现
*
* <p>详情见: https://redkale.org
*
* @author zhangjx
* @param <R> Reader输入的子类型
* @param <W> Writer输出的子类型
*/
public final class LocalDateTimeSimpledCoder<R extends Reader, W extends Writer>
extends SimpledCoder<R, W, LocalDateTime> {
private static final ByteArraySimpledCoder bsSimpledCoder = ByteArraySimpledCoder.instance;
public static final LocalDateTimeSimpledCoder instance = new LocalDateTimeSimpledCoder();
@Override
public void convertTo(W out, LocalDateTime value) {
if (value == null) {
bsSimpledCoder.convertTo(out, null);
} else {
long v1 = value.toEpochSecond(ZoneOffset.UTC);
int v2 = value.getNano();
byte[] bs = new byte[] {
(byte) (v1 >> 56),
(byte) (v1 >> 48),
(byte) (v1 >> 40),
(byte) (v1 >> 32),
(byte) (v1 >> 24),
(byte) (v1 >> 16),
(byte) (v1 >> 8),
(byte) v1,
(byte) (v2 >> 24),
(byte) (v2 >> 16),
(byte) (v2 >> 8),
(byte) v2
};
bsSimpledCoder.convertTo(out, bs);
}
}
@Override
public LocalDateTime convertFrom(R in) {
byte[] bs = bsSimpledCoder.convertFrom(in);
if (bs == null) {
return null;
}
long v1 = (((long) bs[0] & 0xff) << 56)
| (((long) bs[1] & 0xff) << 48)
| (((long) bs[2] & 0xff) << 40)
| (((long) bs[3] & 0xff) << 32)
| (((long) bs[4] & 0xff) << 24)
| (((long) bs[5] & 0xff) << 16)
| (((long) bs[6] & 0xff) << 8)
| ((long) bs[7] & 0xff);
int v2 = ((bs[8] & 0xff) << 24) | ((bs[9] & 0xff) << 16) | ((bs[10] & 0xff) << 8) | (bs[11] & 0xff);
return LocalDateTime.ofEpochSecond(v1, v2, ZoneOffset.UTC);
}
// public static void main(String[] args) throws Throwable {
// LocalDateTime now = LocalDateTime.now();
// System.out.println(now);
// BsonWriter writer = new BsonWriter();
// LocalDateTimeSimpledCoder.instance.convertTo(writer, now);
// BsonReader reader = new BsonReader(writer.toArray());
// System.out.println(LocalDateTimeSimpledCoder.instance.convertFrom(reader));
// }
/**
* java.time.LocalDateTime 的JsonSimpledCoder实现
*
* @param <R> Reader输入的子类型
* @param <W> Writer输出的子类型
*/
public static final class LocalDateTimeJsonSimpledCoder<R extends JsonReader, W extends JsonWriter>
extends SimpledCoder<R, W, LocalDateTime> {
public static final LocalDateTimeJsonSimpledCoder instance = new LocalDateTimeJsonSimpledCoder();
@Override
public void convertTo(final W out, final LocalDateTime value) {
if (value == null) {
out.writeNull();
} else {
out.writeSmallString(value.toString());
}
}
@Override
public LocalDateTime convertFrom(R in) {
final String str = in.readSmallString();
if (str == null) {
return null;
}
return LocalDateTime.parse(str);
}
}
}

View File

@@ -1,73 +1,73 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package org.redkale.convert.ext;
import java.time.LocalTime;
import org.redkale.convert.*;
import org.redkale.convert.json.*;
/**
* java.time.LocalTime 的SimpledCoder实现
*
* <p>详情见: https://redkale.org
*
* @author zhangjx
* @param <R> Reader输入的子类型
* @param <W> Writer输出的子类型
*/
public final class LocalTimeSimpledCoder<R extends Reader, W extends Writer> extends SimpledCoder<R, W, LocalTime> {
public static final LocalTimeSimpledCoder instance = new LocalTimeSimpledCoder();
@Override
public void convertTo(W out, LocalTime value) {
out.writeLong(value == null ? -1L : value.toNanoOfDay());
}
@Override
public LocalTime convertFrom(R in) {
long t = in.readLong();
return t == -1 ? null : LocalTime.ofNanoOfDay(t);
}
// public static void main(String[] args) throws Throwable {
// LocalTime now = LocalTime.now();
// System.out.println(now);
// BsonWriter writer = new BsonWriter();
// LocalTimeSimpledCoder.instance.convertTo(writer, now);
// BsonReader reader = new BsonReader(writer.toArray());
// System.out.println(LocalTimeSimpledCoder.instance.convertFrom(reader));
// }
/**
* java.time.LocalTime 的JsonSimpledCoder实现
*
* @param <R> Reader输入的子类型
* @param <W> Writer输出的子类型
*/
public static final class LocalTimeJsonSimpledCoder<R extends JsonReader, W extends JsonWriter>
extends SimpledCoder<R, W, LocalTime> {
public static final LocalTimeJsonSimpledCoder instance = new LocalTimeJsonSimpledCoder();
@Override
public void convertTo(final W out, final LocalTime value) {
if (value == null) {
out.writeNull();
} else {
out.writeSmallString(value.toString());
}
}
@Override
public LocalTime convertFrom(R in) {
final String str = in.readSmallString();
if (str == null) {
return null;
}
return LocalTime.parse(str);
}
}
}
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package org.redkale.convert.ext;
import java.time.LocalTime;
import org.redkale.convert.*;
import org.redkale.convert.json.*;
/**
* java.time.LocalTime 的SimpledCoder实现
*
* <p>详情见: https://redkale.org
*
* @author zhangjx
* @param <R> Reader输入的子类型
* @param <W> Writer输出的子类型
*/
public final class LocalTimeSimpledCoder<R extends Reader, W extends Writer> extends SimpledCoder<R, W, LocalTime> {
public static final LocalTimeSimpledCoder instance = new LocalTimeSimpledCoder();
@Override
public void convertTo(W out, LocalTime value) {
out.writeLong(value == null ? -1L : value.toNanoOfDay());
}
@Override
public LocalTime convertFrom(R in) {
long t = in.readLong();
return t == -1 ? null : LocalTime.ofNanoOfDay(t);
}
// public static void main(String[] args) throws Throwable {
// LocalTime now = LocalTime.now();
// System.out.println(now);
// BsonWriter writer = new BsonWriter();
// LocalTimeSimpledCoder.instance.convertTo(writer, now);
// BsonReader reader = new BsonReader(writer.toArray());
// System.out.println(LocalTimeSimpledCoder.instance.convertFrom(reader));
// }
/**
* java.time.LocalTime 的JsonSimpledCoder实现
*
* @param <R> Reader输入的子类型
* @param <W> Writer输出的子类型
*/
public static final class LocalTimeJsonSimpledCoder<R extends JsonReader, W extends JsonWriter>
extends SimpledCoder<R, W, LocalTime> {
public static final LocalTimeJsonSimpledCoder instance = new LocalTimeJsonSimpledCoder();
@Override
public void convertTo(final W out, final LocalTime value) {
if (value == null) {
out.writeNull();
} else {
out.writeSmallString(value.toString());
}
}
@Override
public LocalTime convertFrom(R in) {
final String str = in.readSmallString();
if (str == null) {
return null;
}
return LocalTime.parse(str);
}
}
}

View File

@@ -1,35 +1,35 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package org.redkale.convert.ext;
import java.util.concurrent.atomic.LongAdder;
import org.redkale.convert.*;
/**
* LongAdder 的SimpledCoder实现
*
* <p>详情见: https://redkale.org
*
* @author zhangjx
* @param <R> Reader输入的子类型
* @param <W> Writer输出的子类型
*/
public final class LongAdderSimpledCoder<R extends Reader, W extends Writer> extends SimpledCoder<R, W, LongAdder> {
public static final LongAdderSimpledCoder instance = new LongAdderSimpledCoder();
@Override
public void convertTo(W out, LongAdder value) {
out.writeLong(value == null ? 0L : value.longValue());
}
@Override
public LongAdder convertFrom(R in) {
LongAdder la = new LongAdder();
la.add(in.readLong());
return la;
}
}
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package org.redkale.convert.ext;
import java.util.concurrent.atomic.LongAdder;
import org.redkale.convert.*;
/**
* LongAdder 的SimpledCoder实现
*
* <p>详情见: https://redkale.org
*
* @author zhangjx
* @param <R> Reader输入的子类型
* @param <W> Writer输出的子类型
*/
public final class LongAdderSimpledCoder<R extends Reader, W extends Writer> extends SimpledCoder<R, W, LongAdder> {
public static final LongAdderSimpledCoder instance = new LongAdderSimpledCoder();
@Override
public void convertTo(W out, LongAdder value) {
out.writeLong(value == null ? 0L : value.longValue());
}
@Override
public LongAdder convertFrom(R in) {
LongAdder la = new LongAdder();
la.add(in.readLong());
return la;
}
}

View File

@@ -1,388 +1,388 @@
/*
*
*/
package org.redkale.convert.json;
import java.lang.reflect.Type;
import java.math.*;
import java.util.*;
import org.redkale.annotation.Nullable;
import org.redkale.convert.ConvertDisabled;
import org.redkale.util.*;
/**
* 常规json数组
*
* <p>详情见: https://redkale.org
*
* @author zhangjx
* @since 2.8.0
*/
public class JsonArray extends ArrayList<Object> implements JsonElement {
public JsonArray() {}
public JsonArray(Collection collection) {
super(collection);
}
public JsonArray(Object... array) {
super(Arrays.asList(array));
}
public static JsonArray convertFrom(String text) {
return convertFrom(Utility.charArray(text));
}
public static JsonArray convertFrom(char[] text) {
return convertFrom(text, 0, text.length);
}
public static JsonArray convertFrom(char[] text, int offset, int length) {
return JsonConvert.root().convertFrom(JsonArray.class, text, offset, length);
}
public static JsonArray create() {
return new JsonArray();
}
public <T> List<T> toList(Type componentType) {
Type listType = TypeToken.createParameterizedType(null, ArrayList.class, componentType);
return (List)
JsonConvert.root().convertFrom(listType, JsonConvert.root().convertTo(this));
}
public JsonArray append(Object value) {
super.add(value);
return this;
}
public JsonArray append(int index, Object value) {
super.set(index, value);
return this;
}
public boolean isNull(int index) {
return get(index) == null;
}
public boolean isJsonObject(int index) {
return get(index) instanceof JsonObject;
}
public boolean isJsonArray(int index) {
return get(index) instanceof JsonArray;
}
public JsonObject getJsonObject(int index) {
Object val = get(index);
if (val instanceof JsonObject) {
return (JsonObject) val;
}
if (val instanceof Map) {
return new JsonObject((Map) val);
}
throw new RedkaleException("val [" + val + "] is not a valid JsonObject.");
}
public JsonArray getJsonArray(int index) {
Object val = get(index);
if (val instanceof JsonArray) {
return (JsonArray) val;
}
if (val instanceof Collection) {
return new JsonArray((Collection) val);
}
throw new RedkaleException("val [" + val + "] is not a valid JsonArray.");
}
public String getString(int index) {
final Object val = get(index);
if (val == null) {
return null;
}
return val.toString();
}
public String getString(int index, String defValue) {
final Object val = get(index);
if (val == null) {
return defValue;
}
return val.toString();
}
public BigDecimal getBigDecimal(int index) {
final Object val = get(index);
if (val == null) {
return null;
}
if (val instanceof BigDecimal) {
return (BigDecimal) val;
}
return new BigDecimal(val.toString());
}
public BigDecimal getBigDecimal(int index, BigDecimal defValue) {
final Object val = get(index);
if (val == null) {
return defValue;
}
if (val instanceof BigDecimal) {
return (BigDecimal) val;
}
try {
return new BigDecimal(val.toString());
} catch (Exception e) {
return defValue;
}
}
public BigInteger getBigInteger(int index) {
final Object val = get(index);
if (val == null) {
return null;
}
if (val instanceof BigInteger) {
return (BigInteger) val;
}
return new BigInteger(val.toString());
}
public BigInteger getBigInteger(int index, BigInteger defValue) {
final Object val = get(index);
if (val == null) {
return defValue;
}
if (val instanceof BigInteger) {
return (BigInteger) val;
}
try {
return new BigInteger(val.toString());
} catch (Exception e) {
return defValue;
}
}
public Number getNumber(int index) {
Object val = get(index);
if (val == null) {
return null;
}
if (val instanceof Number) {
return (Number) val;
}
return JsonObject.stringToNumber(val.toString());
}
public Number getNumber(int index, Number defValue) {
Object val = get(index);
if (val == null) {
return defValue;
}
if (val instanceof Number) {
return (Number) val;
}
try {
return JsonObject.stringToNumber(val.toString());
} catch (Exception e) {
return defValue;
}
}
public Double getDouble(int index) {
final Object val = get(index);
if (val == null) {
return null;
}
if (val instanceof Number) {
return ((Number) val).doubleValue();
}
return Double.parseDouble(val.toString());
}
public double getDouble(int index, double defValue) {
final Object val = get(index);
if (val == null) {
return defValue;
}
if (val instanceof Number) {
return ((Number) val).doubleValue();
}
try {
return Double.parseDouble(val.toString());
} catch (Exception e) {
return defValue;
}
}
public Long getLong(int index) {
final Object val = get(index);
if (val == null) {
return null;
}
if (val instanceof Number) {
return ((Number) val).longValue();
}
return Long.parseLong(val.toString());
}
public long getLong(int index, long defValue) {
final Object val = get(index);
if (val == null) {
return defValue;
}
if (val instanceof Number) {
return ((Number) val).longValue();
}
try {
return Long.parseLong(val.toString());
} catch (Exception e) {
return defValue;
}
}
public Float getFloat(int index) {
final Object val = get(index);
if (val == null) {
return null;
}
if (val instanceof Number) {
return ((Number) val).floatValue();
}
return Float.parseFloat(val.toString());
}
public float getFloat(int index, float defValue) {
final Object val = get(index);
if (val == null) {
return defValue;
}
if (val instanceof Number) {
return ((Number) val).floatValue();
}
try {
return Float.parseFloat(val.toString());
} catch (Exception e) {
return defValue;
}
}
public Integer getInt(int index) {
final Object val = get(index);
if (val == null) {
return null;
}
if (val instanceof Number) {
return ((Number) val).intValue();
}
return Integer.parseInt(val.toString());
}
public int getInt(int index, int defValue) {
final Object val = get(index);
if (val == null) {
return defValue;
}
if (val instanceof Number) {
return ((Number) val).intValue();
}
try {
return Integer.parseInt(val.toString());
} catch (Exception e) {
return defValue;
}
}
public Short getShort(int index) {
final Object val = get(index);
if (val == null) {
return null;
}
if (val instanceof Number) {
return ((Number) val).shortValue();
}
return Short.parseShort(val.toString());
}
public short getShort(int index, short defValue) {
final Object val = get(index);
if (val == null) {
return defValue;
}
if (val instanceof Number) {
return ((Number) val).shortValue();
}
try {
return Short.parseShort(val.toString());
} catch (Exception e) {
return defValue;
}
}
public Byte getByte(int index) {
final Object val = get(index);
if (val == null) {
return null;
}
if (val instanceof Number) {
return ((Number) val).byteValue();
}
return Byte.parseByte(val.toString());
}
public byte getByte(int index, byte defValue) {
final Object val = get(index);
if (val == null) {
return defValue;
}
if (val instanceof Number) {
return ((Number) val).byteValue();
}
try {
return Byte.parseByte(val.toString());
} catch (Exception e) {
return defValue;
}
}
@Nullable
public Boolean getBoolean(int index) {
final Object val = get(index);
if (val == null) {
return null;
}
return "true".equalsIgnoreCase(val.toString());
}
public boolean getBoolean(int index, boolean defValue) {
final Object val = get(index);
if (val == null) {
return defValue;
}
return "true".equalsIgnoreCase(val.toString());
}
@Override
@ConvertDisabled
public final boolean isObject() {
return false;
}
@Override
@ConvertDisabled
public final boolean isArray() {
return true;
}
@Override
@ConvertDisabled
public final boolean isString() {
return false;
}
@Override
public String toString() {
return JsonConvert.root().convertTo(this);
}
}
/*
*
*/
package org.redkale.convert.json;
import java.lang.reflect.Type;
import java.math.*;
import java.util.*;
import org.redkale.annotation.Nullable;
import org.redkale.convert.ConvertDisabled;
import org.redkale.util.*;
/**
* 常规json数组
*
* <p>详情见: https://redkale.org
*
* @author zhangjx
* @since 2.8.0
*/
public class JsonArray extends ArrayList<Object> implements JsonElement {
public JsonArray() {}
public JsonArray(Collection collection) {
super(collection);
}
public JsonArray(Object... array) {
super(Arrays.asList(array));
}
public static JsonArray convertFrom(String text) {
return convertFrom(Utility.charArray(text));
}
public static JsonArray convertFrom(char[] text) {
return convertFrom(text, 0, text.length);
}
public static JsonArray convertFrom(char[] text, int offset, int length) {
return JsonConvert.root().convertFrom(JsonArray.class, text, offset, length);
}
public static JsonArray create() {
return new JsonArray();
}
public <T> List<T> toList(Type componentType) {
Type listType = TypeToken.createParameterizedType(null, ArrayList.class, componentType);
return (List)
JsonConvert.root().convertFrom(listType, JsonConvert.root().convertTo(this));
}
public JsonArray append(Object value) {
super.add(value);
return this;
}
public JsonArray append(int index, Object value) {
super.set(index, value);
return this;
}
public boolean isNull(int index) {
return get(index) == null;
}
public boolean isJsonObject(int index) {
return get(index) instanceof JsonObject;
}
public boolean isJsonArray(int index) {
return get(index) instanceof JsonArray;
}
public JsonObject getJsonObject(int index) {
Object val = get(index);
if (val instanceof JsonObject) {
return (JsonObject) val;
}
if (val instanceof Map) {
return new JsonObject((Map) val);
}
throw new RedkaleException("val [" + val + "] is not a valid JsonObject.");
}
public JsonArray getJsonArray(int index) {
Object val = get(index);
if (val instanceof JsonArray) {
return (JsonArray) val;
}
if (val instanceof Collection) {
return new JsonArray((Collection) val);
}
throw new RedkaleException("val [" + val + "] is not a valid JsonArray.");
}
public String getString(int index) {
final Object val = get(index);
if (val == null) {
return null;
}
return val.toString();
}
public String getString(int index, String defValue) {
final Object val = get(index);
if (val == null) {
return defValue;
}
return val.toString();
}
public BigDecimal getBigDecimal(int index) {
final Object val = get(index);
if (val == null) {
return null;
}
if (val instanceof BigDecimal) {
return (BigDecimal) val;
}
return new BigDecimal(val.toString());
}
public BigDecimal getBigDecimal(int index, BigDecimal defValue) {
final Object val = get(index);
if (val == null) {
return defValue;
}
if (val instanceof BigDecimal) {
return (BigDecimal) val;
}
try {
return new BigDecimal(val.toString());
} catch (Exception e) {
return defValue;
}
}
public BigInteger getBigInteger(int index) {
final Object val = get(index);
if (val == null) {
return null;
}
if (val instanceof BigInteger) {
return (BigInteger) val;
}
return new BigInteger(val.toString());
}
public BigInteger getBigInteger(int index, BigInteger defValue) {
final Object val = get(index);
if (val == null) {
return defValue;
}
if (val instanceof BigInteger) {
return (BigInteger) val;
}
try {
return new BigInteger(val.toString());
} catch (Exception e) {
return defValue;
}
}
public Number getNumber(int index) {
Object val = get(index);
if (val == null) {
return null;
}
if (val instanceof Number) {
return (Number) val;
}
return JsonObject.stringToNumber(val.toString());
}
public Number getNumber(int index, Number defValue) {
Object val = get(index);
if (val == null) {
return defValue;
}
if (val instanceof Number) {
return (Number) val;
}
try {
return JsonObject.stringToNumber(val.toString());
} catch (Exception e) {
return defValue;
}
}
public Double getDouble(int index) {
final Object val = get(index);
if (val == null) {
return null;
}
if (val instanceof Number) {
return ((Number) val).doubleValue();
}
return Double.parseDouble(val.toString());
}
public double getDouble(int index, double defValue) {
final Object val = get(index);
if (val == null) {
return defValue;
}
if (val instanceof Number) {
return ((Number) val).doubleValue();
}
try {
return Double.parseDouble(val.toString());
} catch (Exception e) {
return defValue;
}
}
public Long getLong(int index) {
final Object val = get(index);
if (val == null) {
return null;
}
if (val instanceof Number) {
return ((Number) val).longValue();
}
return Long.parseLong(val.toString());
}
public long getLong(int index, long defValue) {
final Object val = get(index);
if (val == null) {
return defValue;
}
if (val instanceof Number) {
return ((Number) val).longValue();
}
try {
return Long.parseLong(val.toString());
} catch (Exception e) {
return defValue;
}
}
public Float getFloat(int index) {
final Object val = get(index);
if (val == null) {
return null;
}
if (val instanceof Number) {
return ((Number) val).floatValue();
}
return Float.parseFloat(val.toString());
}
public float getFloat(int index, float defValue) {
final Object val = get(index);
if (val == null) {
return defValue;
}
if (val instanceof Number) {
return ((Number) val).floatValue();
}
try {
return Float.parseFloat(val.toString());
} catch (Exception e) {
return defValue;
}
}
public Integer getInt(int index) {
final Object val = get(index);
if (val == null) {
return null;
}
if (val instanceof Number) {
return ((Number) val).intValue();
}
return Integer.parseInt(val.toString());
}
public int getInt(int index, int defValue) {
final Object val = get(index);
if (val == null) {
return defValue;
}
if (val instanceof Number) {
return ((Number) val).intValue();
}
try {
return Integer.parseInt(val.toString());
} catch (Exception e) {
return defValue;
}
}
public Short getShort(int index) {
final Object val = get(index);
if (val == null) {
return null;
}
if (val instanceof Number) {
return ((Number) val).shortValue();
}
return Short.parseShort(val.toString());
}
public short getShort(int index, short defValue) {
final Object val = get(index);
if (val == null) {
return defValue;
}
if (val instanceof Number) {
return ((Number) val).shortValue();
}
try {
return Short.parseShort(val.toString());
} catch (Exception e) {
return defValue;
}
}
public Byte getByte(int index) {
final Object val = get(index);
if (val == null) {
return null;
}
if (val instanceof Number) {
return ((Number) val).byteValue();
}
return Byte.parseByte(val.toString());
}
public byte getByte(int index, byte defValue) {
final Object val = get(index);
if (val == null) {
return defValue;
}
if (val instanceof Number) {
return ((Number) val).byteValue();
}
try {
return Byte.parseByte(val.toString());
} catch (Exception e) {
return defValue;
}
}
@Nullable
public Boolean getBoolean(int index) {
final Object val = get(index);
if (val == null) {
return null;
}
return "true".equalsIgnoreCase(val.toString());
}
public boolean getBoolean(int index, boolean defValue) {
final Object val = get(index);
if (val == null) {
return defValue;
}
return "true".equalsIgnoreCase(val.toString());
}
@Override
@ConvertDisabled
public final boolean isObject() {
return false;
}
@Override
@ConvertDisabled
public final boolean isArray() {
return true;
}
@Override
@ConvertDisabled
public final boolean isString() {
return false;
}
@Override
public String toString() {
return JsonConvert.root().convertTo(this);
}
}

View File

@@ -1,39 +1,39 @@
/*
*
*/
package org.redkale.convert.json;
import org.redkale.util.Utility;
/**
* 常规json实体
*
* <p>详情见: https://redkale.org
*
* @author zhangjx
* @since 2.8.0
*/
public interface JsonElement extends java.io.Serializable {
public boolean isObject();
public boolean isArray();
public boolean isString();
public static JsonElement convertFrom(String text) {
return convertFrom(Utility.charArray(text));
}
public static JsonElement convertFrom(char[] text) {
return convertFrom(text, 0, text.length);
}
public static JsonElement convertFrom(char[] text, final int offset, final int length) {
Object val = JsonConvert.root().convertFrom(JsonElement.class, text, offset, length);
if (val instanceof CharSequence) {
return new JsonString(val.toString());
}
return (JsonElement) val;
}
}
/*
*
*/
package org.redkale.convert.json;
import org.redkale.util.Utility;
/**
* 常规json实体
*
* <p>详情见: https://redkale.org
*
* @author zhangjx
* @since 2.8.0
*/
public interface JsonElement extends java.io.Serializable {
public boolean isObject();
public boolean isArray();
public boolean isString();
public static JsonElement convertFrom(String text) {
return convertFrom(Utility.charArray(text));
}
public static JsonElement convertFrom(char[] text) {
return convertFrom(text, 0, text.length);
}
public static JsonElement convertFrom(char[] text, final int offset, final int length) {
Object val = JsonConvert.root().convertFrom(JsonElement.class, text, offset, length);
if (val instanceof CharSequence) {
return new JsonString(val.toString());
}
return (JsonElement) val;
}
}

View File

@@ -1,40 +1,40 @@
/*
*
*/
package org.redkale.convert.json;
import java.lang.reflect.Type;
import java.util.*;
import org.redkale.convert.AnyDecoder;
import org.redkale.convert.ext.StringSimpledCoder;
import org.redkale.util.*;
/**
* 常规json
*
* <p>详情见: https://redkale.org
*
* @author zhangjx
* @since 2.8.0
*/
class JsonElementDecoder extends AnyDecoder<JsonElement> {
private static final Type arrayType = new TypeToken<Collection<JsonElement>>() {}.getType();
private static final Type objectType = new TypeToken<Map<String, JsonElement>>() {}.getType();
private static final Creator<JsonArray> arrayCreator = t -> new JsonArray();
private static final Creator<JsonObject> objectCreator = t -> new JsonObject();
public static final JsonElementDecoder instance = new JsonElementDecoder();
public JsonElementDecoder() {
super(objectCreator, objectType, arrayCreator, arrayType, StringSimpledCoder.instance);
}
@Override
public Type getType() {
return JsonElement.class;
}
}
/*
*
*/
package org.redkale.convert.json;
import java.lang.reflect.Type;
import java.util.*;
import org.redkale.convert.AnyDecoder;
import org.redkale.convert.ext.StringSimpledCoder;
import org.redkale.util.*;
/**
* 常规json
*
* <p>详情见: https://redkale.org
*
* @author zhangjx
* @since 2.8.0
*/
class JsonElementDecoder extends AnyDecoder<JsonElement> {
private static final Type arrayType = new TypeToken<Collection<JsonElement>>() {}.getType();
private static final Type objectType = new TypeToken<Map<String, JsonElement>>() {}.getType();
private static final Creator<JsonArray> arrayCreator = t -> new JsonArray();
private static final Creator<JsonObject> objectCreator = t -> new JsonObject();
public static final JsonElementDecoder instance = new JsonElementDecoder();
public JsonElementDecoder() {
super(objectCreator, objectType, arrayCreator, arrayType, StringSimpledCoder.instance);
}
@Override
public Type getType() {
return JsonElement.class;
}
}

View File

@@ -1,471 +1,471 @@
/*
*
*/
package org.redkale.convert.json;
import java.lang.reflect.Type;
import java.math.*;
import java.util.*;
import org.redkale.annotation.Nullable;
import org.redkale.convert.ConvertDisabled;
import org.redkale.util.*;
/**
* 常规json对象
*
* <p>详情见: https://redkale.org
*
* @author zhangjx
* @since 2.8.0
*/
public class JsonObject extends LinkedHashMap<String, Object> implements JsonElement {
public JsonObject() {}
public JsonObject(Map map) {
super(map);
}
public static JsonObject convertFrom(String text) {
return convertFrom(Utility.charArray(text));
}
public static JsonObject convertFrom(char[] text) {
return convertFrom(text, 0, text.length);
}
public static JsonObject convertFrom(char[] text, int offset, int length) {
return JsonConvert.root().convertFrom(JsonObject.class, text, offset, length);
}
public static JsonObject create() {
return new JsonObject();
}
public static JsonObject of(Object bean) {
if (bean instanceof CharSequence) {
return convertFrom(bean.toString());
}
if (bean instanceof JsonObject) {
return (JsonObject) bean;
}
if (bean instanceof Map) {
return new JsonObject((Map) bean);
}
return convertFrom(JsonConvert.root().convertTo(bean));
}
public <T> T toObject(Type type) {
return (T) JsonConvert.root().convertFrom(type, JsonConvert.root().convertTo(this));
}
public JsonObject append(String key, Object value) {
super.put(key, value);
return this;
}
public JsonObject append(String key, Collection value) {
super.put(key, value == null || value instanceof JsonArray ? value : new JsonArray(value));
return this;
}
public JsonObject putObject(String key) {
JsonObject val = new JsonObject();
super.put(key, val);
return val;
}
public JsonArray putArray(String key) {
JsonArray val = new JsonArray();
super.put(key, val);
return val;
}
public boolean has(String key) {
return containsKey(key);
}
public boolean isNull(String key) {
return get(key) == null;
}
public boolean isJsonObject(String key) {
return get(key) instanceof JsonObject;
}
public boolean isJsonArray(String key) {
return get(key) instanceof JsonArray;
}
public JsonObject getJsonObject(String key) {
Object val = get(key);
if (val instanceof JsonObject) {
return (JsonObject) val;
}
if (val instanceof Map) {
return new JsonObject((Map) val);
}
throw new RedkaleException("val [" + val + "] is not a valid JsonObject.");
}
public JsonArray getJsonArray(String key) {
Object val = get(key);
if (val instanceof JsonArray) {
return (JsonArray) val;
}
if (val instanceof Collection) {
return new JsonArray((Collection) val);
}
throw new RedkaleException("val [" + val + "] is not a valid JsonArray.");
}
public String getString(String key) {
final Object val = get(key);
if (val == null) {
return null;
}
return val.toString();
}
public String getString(String key, String defValue) {
final Object val = get(key);
if (val == null) {
return defValue;
}
return val.toString();
}
public BigDecimal getBigDecimal(String key) {
final Object val = get(key);
if (val == null) {
return null;
}
if (val instanceof BigDecimal) {
return (BigDecimal) val;
}
return new BigDecimal(val.toString());
}
public BigDecimal getBigDecimal(String key, BigDecimal defValue) {
final Object val = get(key);
if (val == null) {
return defValue;
}
if (val instanceof BigDecimal) {
return (BigDecimal) val;
}
try {
return new BigDecimal(val.toString());
} catch (Exception e) {
return defValue;
}
}
public BigInteger getBigInteger(String key) {
final Object val = get(key);
if (val == null) {
return null;
}
if (val instanceof BigInteger) {
return (BigInteger) val;
}
return new BigInteger(val.toString());
}
public BigInteger getBigInteger(String key, BigInteger defValue) {
final Object val = get(key);
if (val == null) {
return defValue;
}
if (val instanceof BigInteger) {
return (BigInteger) val;
}
try {
return new BigInteger(val.toString());
} catch (Exception e) {
return defValue;
}
}
public Number getNumber(String key) {
Object val = get(key);
if (val == null) {
return null;
}
if (val instanceof Number) {
return (Number) val;
}
return stringToNumber(val.toString());
}
public Number getNumber(String key, Number defValue) {
Object val = get(key);
if (val == null) {
return defValue;
}
if (val instanceof Number) {
return (Number) val;
}
try {
return stringToNumber(val.toString());
} catch (Exception e) {
return defValue;
}
}
public Double getDouble(String key) {
final Object val = get(key);
if (val == null) {
return null;
}
if (val instanceof Number) {
return ((Number) val).doubleValue();
}
return Double.parseDouble(val.toString());
}
public double getDouble(String key, double defValue) {
final Object val = get(key);
if (val == null) {
return defValue;
}
if (val instanceof Number) {
return ((Number) val).doubleValue();
}
try {
return Double.parseDouble(val.toString());
} catch (Exception e) {
return defValue;
}
}
public Long getLong(String key) {
final Object val = get(key);
if (val == null) {
return null;
}
if (val instanceof Number) {
return ((Number) val).longValue();
}
return Long.parseLong(val.toString());
}
public long getLong(String key, long defValue) {
final Object val = get(key);
if (val == null) {
return defValue;
}
if (val instanceof Number) {
return ((Number) val).longValue();
}
try {
return Long.parseLong(val.toString());
} catch (Exception e) {
return defValue;
}
}
public Float getFloat(String key) {
final Object val = get(key);
if (val == null) {
return null;
}
if (val instanceof Number) {
return ((Number) val).floatValue();
}
return Float.parseFloat(val.toString());
}
public float getFloat(String key, float defValue) {
final Object val = get(key);
if (val == null) {
return defValue;
}
if (val instanceof Number) {
return ((Number) val).floatValue();
}
try {
return Float.parseFloat(val.toString());
} catch (Exception e) {
return defValue;
}
}
public Integer getInt(String key) {
final Object val = get(key);
if (val == null) {
return null;
}
if (val instanceof Number) {
return ((Number) val).intValue();
}
return Integer.parseInt(val.toString());
}
public int getInt(String key, int defValue) {
final Object val = get(key);
if (val == null) {
return defValue;
}
if (val instanceof Number) {
return ((Number) val).intValue();
}
try {
return Integer.parseInt(val.toString());
} catch (Exception e) {
return defValue;
}
}
public Short getShort(String key) {
final Object val = get(key);
if (val == null) {
return null;
}
if (val instanceof Number) {
return ((Number) val).shortValue();
}
return Short.parseShort(val.toString());
}
public short getShort(String key, short defValue) {
final Object val = get(key);
if (val == null) {
return defValue;
}
if (val instanceof Number) {
return ((Number) val).shortValue();
}
try {
return Short.parseShort(val.toString());
} catch (Exception e) {
return defValue;
}
}
public Byte getByte(String key) {
final Object val = get(key);
if (val == null) {
return null;
}
if (val instanceof Number) {
return ((Number) val).byteValue();
}
return Byte.parseByte(val.toString());
}
public byte getByte(String key, byte defValue) {
final Object val = get(key);
if (val == null) {
return defValue;
}
if (val instanceof Number) {
return ((Number) val).byteValue();
}
try {
return Byte.parseByte(val.toString());
} catch (Exception e) {
return defValue;
}
}
@Nullable
public Boolean getBoolean(String key) {
final Object val = get(key);
if (val == null) {
return null;
}
return "true".equalsIgnoreCase(val.toString());
}
public boolean getBoolean(String key, boolean defValue) {
final Object val = get(key);
if (val == null) {
return defValue;
}
return "true".equalsIgnoreCase(val.toString());
}
protected static Number stringToNumber(String val) {
char initial = val.charAt(0);
if ((initial >= '0' && initial <= '9') || initial == '-') {
// decimal representation
if (val.indexOf('.') > -1 || val.indexOf('e') > -1 || val.indexOf('E') > -1 || "-0".equals(val)) {
// Use a BigDecimal all the time so we keep the original
// representation. BigDecimal doesn't support -0.0, ensure we
// keep that by forcing a decimal.
try {
BigDecimal bd = new BigDecimal(val);
if (initial == '-' && BigDecimal.ZERO.compareTo(bd) == 0) {
return -0.0;
}
return bd;
} catch (NumberFormatException retryAsDouble) {
// this is to support "Hex Floats" like this: 0x1.0P-1074
try {
Double d = Double.valueOf(val);
if (d.isNaN() || d.isInfinite()) {
throw new NumberFormatException("val [" + val + "] is not a valid number.");
}
return d;
} catch (NumberFormatException ignore) {
throw new NumberFormatException("val [" + val + "] is not a valid number.");
}
}
}
// block items like 00 01 etc. Java number parsers treat these as Octal.
if (initial == '0' && val.length() > 1) {
char at1 = val.charAt(1);
if (at1 >= '0' && at1 <= '9') {
throw new NumberFormatException("val [" + val + "] is not a valid number.");
}
} else if (initial == '-' && val.length() > 2) {
char at1 = val.charAt(1);
char at2 = val.charAt(2);
if (at1 == '0' && at2 >= '0' && at2 <= '9') {
throw new NumberFormatException("val [" + val + "] is not a valid number.");
}
}
// integer representation.
// This will narrow any values to the smallest reasonable Object representation
// (Integer, Long, or BigInteger)
// BigInteger down conversion: We use a similar bitLength compare as
// BigInteger#intValueExact uses. Increases GC, but objects hold
// only what they need. i.e. Less runtime overhead if the value is
// long lived.
BigInteger bi = new BigInteger(val);
if (bi.bitLength() <= 31) {
return bi.intValue();
}
if (bi.bitLength() <= 63) {
return bi.longValue();
}
return bi;
}
return null;
}
@Override
@ConvertDisabled
public final boolean isObject() {
return true;
}
@Override
@ConvertDisabled
public final boolean isArray() {
return false;
}
@Override
@ConvertDisabled
public final boolean isString() {
return false;
}
@Override
public String toString() {
return JsonConvert.root().convertTo(this);
}
}
/*
*
*/
package org.redkale.convert.json;
import java.lang.reflect.Type;
import java.math.*;
import java.util.*;
import org.redkale.annotation.Nullable;
import org.redkale.convert.ConvertDisabled;
import org.redkale.util.*;
/**
* 常规json对象
*
* <p>详情见: https://redkale.org
*
* @author zhangjx
* @since 2.8.0
*/
public class JsonObject extends LinkedHashMap<String, Object> implements JsonElement {
public JsonObject() {}
public JsonObject(Map map) {
super(map);
}
public static JsonObject convertFrom(String text) {
return convertFrom(Utility.charArray(text));
}
public static JsonObject convertFrom(char[] text) {
return convertFrom(text, 0, text.length);
}
public static JsonObject convertFrom(char[] text, int offset, int length) {
return JsonConvert.root().convertFrom(JsonObject.class, text, offset, length);
}
public static JsonObject create() {
return new JsonObject();
}
public static JsonObject of(Object bean) {
if (bean instanceof CharSequence) {
return convertFrom(bean.toString());
}
if (bean instanceof JsonObject) {
return (JsonObject) bean;
}
if (bean instanceof Map) {
return new JsonObject((Map) bean);
}
return convertFrom(JsonConvert.root().convertTo(bean));
}
public <T> T toObject(Type type) {
return (T) JsonConvert.root().convertFrom(type, JsonConvert.root().convertTo(this));
}
public JsonObject append(String key, Object value) {
super.put(key, value);
return this;
}
public JsonObject append(String key, Collection value) {
super.put(key, value == null || value instanceof JsonArray ? value : new JsonArray(value));
return this;
}
public JsonObject putObject(String key) {
JsonObject val = new JsonObject();
super.put(key, val);
return val;
}
public JsonArray putArray(String key) {
JsonArray val = new JsonArray();
super.put(key, val);
return val;
}
public boolean has(String key) {
return containsKey(key);
}
public boolean isNull(String key) {
return get(key) == null;
}
public boolean isJsonObject(String key) {
return get(key) instanceof JsonObject;
}
public boolean isJsonArray(String key) {
return get(key) instanceof JsonArray;
}
public JsonObject getJsonObject(String key) {
Object val = get(key);
if (val instanceof JsonObject) {
return (JsonObject) val;
}
if (val instanceof Map) {
return new JsonObject((Map) val);
}
throw new RedkaleException("val [" + val + "] is not a valid JsonObject.");
}
public JsonArray getJsonArray(String key) {
Object val = get(key);
if (val instanceof JsonArray) {
return (JsonArray) val;
}
if (val instanceof Collection) {
return new JsonArray((Collection) val);
}
throw new RedkaleException("val [" + val + "] is not a valid JsonArray.");
}
public String getString(String key) {
final Object val = get(key);
if (val == null) {
return null;
}
return val.toString();
}
public String getString(String key, String defValue) {
final Object val = get(key);
if (val == null) {
return defValue;
}
return val.toString();
}
public BigDecimal getBigDecimal(String key) {
final Object val = get(key);
if (val == null) {
return null;
}
if (val instanceof BigDecimal) {
return (BigDecimal) val;
}
return new BigDecimal(val.toString());
}
public BigDecimal getBigDecimal(String key, BigDecimal defValue) {
final Object val = get(key);
if (val == null) {
return defValue;
}
if (val instanceof BigDecimal) {
return (BigDecimal) val;
}
try {
return new BigDecimal(val.toString());
} catch (Exception e) {
return defValue;
}
}
public BigInteger getBigInteger(String key) {
final Object val = get(key);
if (val == null) {
return null;
}
if (val instanceof BigInteger) {
return (BigInteger) val;
}
return new BigInteger(val.toString());
}
public BigInteger getBigInteger(String key, BigInteger defValue) {
final Object val = get(key);
if (val == null) {
return defValue;
}
if (val instanceof BigInteger) {
return (BigInteger) val;
}
try {
return new BigInteger(val.toString());
} catch (Exception e) {
return defValue;
}
}
public Number getNumber(String key) {
Object val = get(key);
if (val == null) {
return null;
}
if (val instanceof Number) {
return (Number) val;
}
return stringToNumber(val.toString());
}
public Number getNumber(String key, Number defValue) {
Object val = get(key);
if (val == null) {
return defValue;
}
if (val instanceof Number) {
return (Number) val;
}
try {
return stringToNumber(val.toString());
} catch (Exception e) {
return defValue;
}
}
public Double getDouble(String key) {
final Object val = get(key);
if (val == null) {
return null;
}
if (val instanceof Number) {
return ((Number) val).doubleValue();
}
return Double.parseDouble(val.toString());
}
public double getDouble(String key, double defValue) {
final Object val = get(key);
if (val == null) {
return defValue;
}
if (val instanceof Number) {
return ((Number) val).doubleValue();
}
try {
return Double.parseDouble(val.toString());
} catch (Exception e) {
return defValue;
}
}
public Long getLong(String key) {
final Object val = get(key);
if (val == null) {
return null;
}
if (val instanceof Number) {
return ((Number) val).longValue();
}
return Long.parseLong(val.toString());
}
public long getLong(String key, long defValue) {
final Object val = get(key);
if (val == null) {
return defValue;
}
if (val instanceof Number) {
return ((Number) val).longValue();
}
try {
return Long.parseLong(val.toString());
} catch (Exception e) {
return defValue;
}
}
public Float getFloat(String key) {
final Object val = get(key);
if (val == null) {
return null;
}
if (val instanceof Number) {
return ((Number) val).floatValue();
}
return Float.parseFloat(val.toString());
}
public float getFloat(String key, float defValue) {
final Object val = get(key);
if (val == null) {
return defValue;
}
if (val instanceof Number) {
return ((Number) val).floatValue();
}
try {
return Float.parseFloat(val.toString());
} catch (Exception e) {
return defValue;
}
}
public Integer getInt(String key) {
final Object val = get(key);
if (val == null) {
return null;
}
if (val instanceof Number) {
return ((Number) val).intValue();
}
return Integer.parseInt(val.toString());
}
public int getInt(String key, int defValue) {
final Object val = get(key);
if (val == null) {
return defValue;
}
if (val instanceof Number) {
return ((Number) val).intValue();
}
try {
return Integer.parseInt(val.toString());
} catch (Exception e) {
return defValue;
}
}
public Short getShort(String key) {
final Object val = get(key);
if (val == null) {
return null;
}
if (val instanceof Number) {
return ((Number) val).shortValue();
}
return Short.parseShort(val.toString());
}
public short getShort(String key, short defValue) {
final Object val = get(key);
if (val == null) {
return defValue;
}
if (val instanceof Number) {
return ((Number) val).shortValue();
}
try {
return Short.parseShort(val.toString());
} catch (Exception e) {
return defValue;
}
}
public Byte getByte(String key) {
final Object val = get(key);
if (val == null) {
return null;
}
if (val instanceof Number) {
return ((Number) val).byteValue();
}
return Byte.parseByte(val.toString());
}
public byte getByte(String key, byte defValue) {
final Object val = get(key);
if (val == null) {
return defValue;
}
if (val instanceof Number) {
return ((Number) val).byteValue();
}
try {
return Byte.parseByte(val.toString());
} catch (Exception e) {
return defValue;
}
}
@Nullable
public Boolean getBoolean(String key) {
final Object val = get(key);
if (val == null) {
return null;
}
return "true".equalsIgnoreCase(val.toString());
}
public boolean getBoolean(String key, boolean defValue) {
final Object val = get(key);
if (val == null) {
return defValue;
}
return "true".equalsIgnoreCase(val.toString());
}
protected static Number stringToNumber(String val) {
char initial = val.charAt(0);
if ((initial >= '0' && initial <= '9') || initial == '-') {
// decimal representation
if (val.indexOf('.') > -1 || val.indexOf('e') > -1 || val.indexOf('E') > -1 || "-0".equals(val)) {
// Use a BigDecimal all the time so we keep the original
// representation. BigDecimal doesn't support -0.0, ensure we
// keep that by forcing a decimal.
try {
BigDecimal bd = new BigDecimal(val);
if (initial == '-' && BigDecimal.ZERO.compareTo(bd) == 0) {
return -0.0;
}
return bd;
} catch (NumberFormatException retryAsDouble) {
// this is to support "Hex Floats" like this: 0x1.0P-1074
try {
Double d = Double.valueOf(val);
if (d.isNaN() || d.isInfinite()) {
throw new NumberFormatException("val [" + val + "] is not a valid number.");
}
return d;
} catch (NumberFormatException ignore) {
throw new NumberFormatException("val [" + val + "] is not a valid number.");
}
}
}
// block items like 00 01 etc. Java number parsers treat these as Octal.
if (initial == '0' && val.length() > 1) {
char at1 = val.charAt(1);
if (at1 >= '0' && at1 <= '9') {
throw new NumberFormatException("val [" + val + "] is not a valid number.");
}
} else if (initial == '-' && val.length() > 2) {
char at1 = val.charAt(1);
char at2 = val.charAt(2);
if (at1 == '0' && at2 >= '0' && at2 <= '9') {
throw new NumberFormatException("val [" + val + "] is not a valid number.");
}
}
// integer representation.
// This will narrow any values to the smallest reasonable Object representation
// (Integer, Long, or BigInteger)
// BigInteger down conversion: We use a similar bitLength compare as
// BigInteger#intValueExact uses. Increases GC, but objects hold
// only what they need. i.e. Less runtime overhead if the value is
// long lived.
BigInteger bi = new BigInteger(val);
if (bi.bitLength() <= 31) {
return bi.intValue();
}
if (bi.bitLength() <= 63) {
return bi.longValue();
}
return bi;
}
return null;
}
@Override
@ConvertDisabled
public final boolean isObject() {
return true;
}
@Override
@ConvertDisabled
public final boolean isArray() {
return false;
}
@Override
@ConvertDisabled
public final boolean isString() {
return false;
}
@Override
public String toString() {
return JsonConvert.root().convertTo(this);
}
}

View File

@@ -1,83 +1,83 @@
/*
*
*/
package org.redkale.convert.json;
import org.redkale.convert.ConvertDisabled;
/**
* 常规json字符串
*
* <p>详情见: https://redkale.org
*
* @author zhangjx
* @since 2.8.0
*/
public class JsonString implements CharSequence, JsonElement, Comparable<JsonString> {
private String value;
public JsonString() {}
public JsonString(String value) {
this.value = value;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
@ConvertDisabled
public boolean isNull() {
return value == null;
}
@Override
public int length() {
return value.length();
}
@Override
public char charAt(int index) {
return value.charAt(index);
}
@Override
public CharSequence subSequence(int start, int end) {
return value.substring(end, end);
}
@Override
public int compareTo(JsonString o) {
return o == null || o.value == null
? (value == null ? 0 : 1)
: (this.value == null ? -1 : this.value.compareTo(o.value));
}
@Override
@ConvertDisabled
public final boolean isObject() {
return false;
}
@Override
@ConvertDisabled
public final boolean isArray() {
return false;
}
@Override
@ConvertDisabled
public final boolean isString() {
return true;
}
@Override
public String toString() {
return value;
}
}
/*
*
*/
package org.redkale.convert.json;
import org.redkale.convert.ConvertDisabled;
/**
* 常规json字符串
*
* <p>详情见: https://redkale.org
*
* @author zhangjx
* @since 2.8.0
*/
public class JsonString implements CharSequence, JsonElement, Comparable<JsonString> {
private String value;
public JsonString() {}
public JsonString(String value) {
this.value = value;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
@ConvertDisabled
public boolean isNull() {
return value == null;
}
@Override
public int length() {
return value.length();
}
@Override
public char charAt(int index) {
return value.charAt(index);
}
@Override
public CharSequence subSequence(int start, int end) {
return value.substring(end, end);
}
@Override
public int compareTo(JsonString o) {
return o == null || o.value == null
? (value == null ? 0 : 1)
: (this.value == null ? -1 : this.value.compareTo(o.value));
}
@Override
@ConvertDisabled
public final boolean isObject() {
return false;
}
@Override
@ConvertDisabled
public final boolean isArray() {
return false;
}
@Override
@ConvertDisabled
public final boolean isString() {
return true;
}
@Override
public String toString() {
return value;
}
}

View File

@@ -1,45 +1,45 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package org.redkale.convert.proto;
import java.lang.reflect.Type;
import java.util.concurrent.atomic.*;
import org.redkale.convert.*;
/**
* @author zhangjx
* @param <T> T
*/
public class ProtobufArrayDecoder<T> extends ArrayDecoder<T> {
protected final boolean simple;
private final boolean string;
private final boolean enumtostring;
public ProtobufArrayDecoder(ConvertFactory factory, Type type) {
super(factory, type);
this.enumtostring = ((ProtobufFactory) factory).enumtostring;
Type comtype = this.getComponentType();
this.string = String.class == comtype;
this.simple = Boolean.class == comtype
|| Short.class == comtype
|| Character.class == comtype
|| Integer.class == comtype
|| Float.class == comtype
|| Long.class == comtype
|| Double.class == comtype
|| AtomicInteger.class == comtype
|| AtomicLong.class == comtype;
}
@Override
protected Reader getItemReader(Reader in, DeMember member, boolean first) {
if (simple) return in;
return ProtobufFactory.getItemReader(string, simple, in, member, enumtostring, first);
}
}
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package org.redkale.convert.proto;
import java.lang.reflect.Type;
import java.util.concurrent.atomic.*;
import org.redkale.convert.*;
/**
* @author zhangjx
* @param <T> T
*/
public class ProtobufArrayDecoder<T> extends ArrayDecoder<T> {
protected final boolean simple;
private final boolean string;
private final boolean enumtostring;
public ProtobufArrayDecoder(ConvertFactory factory, Type type) {
super(factory, type);
this.enumtostring = ((ProtobufFactory) factory).enumtostring;
Type comtype = this.getComponentType();
this.string = String.class == comtype;
this.simple = Boolean.class == comtype
|| Short.class == comtype
|| Character.class == comtype
|| Integer.class == comtype
|| Float.class == comtype
|| Long.class == comtype
|| Double.class == comtype
|| AtomicInteger.class == comtype
|| AtomicLong.class == comtype;
}
@Override
protected Reader getItemReader(Reader in, DeMember member, boolean first) {
if (simple) return in;
return ProtobufFactory.getItemReader(string, simple, in, member, enumtostring, first);
}
}

View File

@@ -1,58 +1,58 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package org.redkale.convert.proto;
import java.lang.reflect.Type;
import java.util.concurrent.atomic.*;
import org.redkale.convert.*;
/**
* @author zhangjx
* @param <T> T
*/
public class ProtobufArrayEncoder<T> extends ArrayEncoder<T> {
protected final boolean simple;
public ProtobufArrayEncoder(ConvertFactory factory, Type type) {
super(factory, type);
Type comtype = this.getComponentType();
this.simple = Boolean.class == comtype
|| Short.class == comtype
|| Character.class == comtype
|| Integer.class == comtype
|| Float.class == comtype
|| Long.class == comtype
|| Double.class == comtype
|| AtomicInteger.class == comtype
|| AtomicLong.class == comtype;
}
@Override
protected void writeMemberValue(
Writer out, EnMember member, Encodeable<Writer, Object> encoder, Object item, int index) {
if (simple) {
if (item == null) {
((ProtobufWriter) out).writeUInt32(0);
} else {
componentEncoder.convertTo(out, item);
}
return;
}
if (member != null) out.writeFieldName(member);
if (item == null) {
((ProtobufWriter) out).writeUInt32(0);
} else if (item instanceof CharSequence) {
encoder.convertTo(out, item);
} else {
ProtobufWriter tmp = new ProtobufWriter().configFieldFunc(out);
encoder.convertTo(tmp, item);
int length = tmp.count();
((ProtobufWriter) out).writeUInt32(length);
((ProtobufWriter) out).writeTo(tmp.toArray());
}
}
}
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package org.redkale.convert.proto;
import java.lang.reflect.Type;
import java.util.concurrent.atomic.*;
import org.redkale.convert.*;
/**
* @author zhangjx
* @param <T> T
*/
public class ProtobufArrayEncoder<T> extends ArrayEncoder<T> {
protected final boolean simple;
public ProtobufArrayEncoder(ConvertFactory factory, Type type) {
super(factory, type);
Type comtype = this.getComponentType();
this.simple = Boolean.class == comtype
|| Short.class == comtype
|| Character.class == comtype
|| Integer.class == comtype
|| Float.class == comtype
|| Long.class == comtype
|| Double.class == comtype
|| AtomicInteger.class == comtype
|| AtomicLong.class == comtype;
}
@Override
protected void writeMemberValue(
Writer out, EnMember member, Encodeable<Writer, Object> encoder, Object item, int index) {
if (simple) {
if (item == null) {
((ProtobufWriter) out).writeUInt32(0);
} else {
componentEncoder.convertTo(out, item);
}
return;
}
if (member != null) out.writeFieldName(member);
if (item == null) {
((ProtobufWriter) out).writeUInt32(0);
} else if (item instanceof CharSequence) {
encoder.convertTo(out, item);
} else {
ProtobufWriter tmp = new ProtobufWriter().configFieldFunc(out);
encoder.convertTo(tmp, item);
int length = tmp.count();
((ProtobufWriter) out).writeUInt32(length);
((ProtobufWriter) out).writeTo(tmp.toArray());
}
}
}

View File

@@ -1,198 +1,198 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package org.redkale.convert.proto;
import java.nio.ByteBuffer;
/** @author zhangjx */
public class ProtobufByteBufferReader extends ProtobufReader {
private ByteBuffer[] buffers;
private int currentIndex = 0;
private ByteBuffer currentBuffer;
protected ProtobufByteBufferReader(ByteBuffer... buffers) {
this.buffers = buffers;
if (buffers != null && buffers.length > 0) this.currentBuffer = buffers[currentIndex];
}
@Override
protected boolean recycle() {
super.recycle(); // this.position 初始化值为-1
this.currentIndex = 0;
this.currentBuffer = null;
this.buffers = null;
return false;
}
@Override
protected byte currentByte() {
return currentBuffer.get(currentBuffer.position());
}
protected byte nextByte() {
if (this.currentBuffer.hasRemaining()) {
this.position++;
return this.currentBuffer.get();
}
for (; ; ) {
this.currentBuffer = this.buffers[++this.currentIndex];
if (this.currentBuffer.hasRemaining()) {
this.position++;
return this.currentBuffer.get();
}
}
}
//
// //------------------------------------------------------------
// /**
// * 判断对象是否存在下一个属性或者数组是否存在下一个元素
// *
// * @param startPosition 起始位置
// * @param contentLength 内容大小, 不确定的传-1
// *
// * @return 是否存在
// */
// @Override
// public boolean hasNext(int startPosition, int contentLength) {
// //("-------------: " + startPosition + ", " + contentLength + ", " + this.position);
// if (startPosition >= 0 && contentLength >= 0) {
// return (this.position) < (startPosition + contentLength);
// }
// return (this.position + 1) < this.content.length;
// }
//
// @Override
// public byte[] readByteArray() {
// final int size = readRawVarint32();
// byte[] bs = new byte[size];
// System.arraycopy(content, position + 1, bs, 0, size);
// position += size;
// return bs;
// }
//
// protected int readRawVarint32() { //readUInt32
// fastpath:
// {
// int tempPos = this.position;
// if ((tempPos + 1) == content.length) break fastpath;
//
// int x;
// if ((x = content[++tempPos]) >= 0) {
// this.position = tempPos;
// return x;
// } else if (content.length - (tempPos + 1) < 9) {
// break fastpath;
// } else if ((x ^= (content[++tempPos] << 7)) < 0) {
// x ^= (~0 << 7);
// } else if ((x ^= (content[++tempPos] << 14)) >= 0) {
// x ^= (~0 << 7) ^ (~0 << 14);
// } else if ((x ^= (content[++tempPos] << 21)) < 0) {
// x ^= (~0 << 7) ^ (~0 << 14) ^ (~0 << 21);
// } else {
// int y = content[++tempPos];
// x ^= y << 28;
// x ^= (~0 << 7) ^ (~0 << 14) ^ (~0 << 21) ^ (~0 << 28);
// if (y < 0
// && content[++tempPos] < 0
// && content[++tempPos] < 0
// && content[++tempPos] < 0
// && content[++tempPos] < 0
// && content[++tempPos] < 0) {
// break fastpath; // Will throw malformedVarint()
// }
// }
// this.position = tempPos;
// return x;
// }
// return (int) readRawVarint64SlowPath();
// }
//
// protected long readRawVarint64() {
// fastpath:
// {
// int tempPos = this.position;
// if ((tempPos + 1) == content.length) break fastpath;
//
// long x;
// int y;
// if ((y = content[++tempPos]) >= 0) {
// this.position = tempPos;
// return y;
// } else if (content.length - (tempPos + 1) < 9) {
// break fastpath;
// } else if ((y ^= (content[++tempPos] << 7)) < 0) {
// x = y ^ (~0 << 7);
// } else if ((y ^= (content[++tempPos] << 14)) >= 0) {
// x = y ^ ((~0 << 7) ^ (~0 << 14));
// } else if ((y ^= (content[++tempPos] << 21)) < 0) {
// x = y ^ ((~0 << 7) ^ (~0 << 14) ^ (~0 << 21));
// } else if ((x = y ^ ((long) content[++tempPos] << 28)) >= 0L) {
// x ^= (~0L << 7) ^ (~0L << 14) ^ (~0L << 21) ^ (~0L << 28);
// } else if ((x ^= ((long) content[++tempPos] << 35)) < 0L) {
// x ^= (~0L << 7) ^ (~0L << 14) ^ (~0L << 21) ^ (~0L << 28) ^ (~0L << 35);
// } else if ((x ^= ((long) content[++tempPos] << 42)) >= 0L) {
// x ^= (~0L << 7) ^ (~0L << 14) ^ (~0L << 21) ^ (~0L << 28) ^ (~0L << 35) ^ (~0L << 42);
// } else if ((x ^= ((long) content[++tempPos] << 49)) < 0L) {
// x ^= (~0L << 7)
// ^ (~0L << 14)
// ^ (~0L << 21)
// ^ (~0L << 28)
// ^ (~0L << 35)
// ^ (~0L << 42)
// ^ (~0L << 49);
// } else {
// x ^= ((long) content[++tempPos] << 56);
// x ^= (~0L << 7)
// ^ (~0L << 14)
// ^ (~0L << 21)
// ^ (~0L << 28)
// ^ (~0L << 35)
// ^ (~0L << 42)
// ^ (~0L << 49)
// ^ (~0L << 56);
// if (x < 0L) {
// if (content[++tempPos] < 0L) {
// break fastpath; // Will throw malformedVarint()
// }
// }
// }
// this.position = tempPos;
// return x;
// }
// return readRawVarint64SlowPath();
// }
//
// protected long readRawVarint64SlowPath() {
// long result = 0;
// for (int shift = 0; shift < 64; shift += 7) {
// final byte b = content[++this.position];
// result |= (long) (b & 0x7F) << shift;
// if ((b & 0x80) == 0) return result;
// }
// throw new ConvertException("readRawVarint64SlowPath error");
// }
//
// protected int readRawLittleEndian32() {
// return ((content[++this.position] & 0xff)
// | ((content[++this.position] & 0xff) << 8)
// | ((content[++this.position] & 0xff) << 16)
// | ((content[++this.position] & 0xff) << 24));
// }
//
// protected long readRawLittleEndian64() {
// return ((content[++this.position] & 0xffL)
// | ((content[++this.position] & 0xffL) << 8)
// | ((content[++this.position] & 0xffL) << 16)
// | ((content[++this.position] & 0xffL) << 24)
// | ((content[++this.position] & 0xffL) << 32)
// | ((content[++this.position] & 0xffL) << 40)
// | ((content[++this.position] & 0xffL) << 48)
// | ((content[++this.position] & 0xffL) << 56));
// }
}
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package org.redkale.convert.proto;
import java.nio.ByteBuffer;
/** @author zhangjx */
public class ProtobufByteBufferReader extends ProtobufReader {
private ByteBuffer[] buffers;
private int currentIndex = 0;
private ByteBuffer currentBuffer;
protected ProtobufByteBufferReader(ByteBuffer... buffers) {
this.buffers = buffers;
if (buffers != null && buffers.length > 0) this.currentBuffer = buffers[currentIndex];
}
@Override
protected boolean recycle() {
super.recycle(); // this.position 初始化值为-1
this.currentIndex = 0;
this.currentBuffer = null;
this.buffers = null;
return false;
}
@Override
protected byte currentByte() {
return currentBuffer.get(currentBuffer.position());
}
protected byte nextByte() {
if (this.currentBuffer.hasRemaining()) {
this.position++;
return this.currentBuffer.get();
}
for (; ; ) {
this.currentBuffer = this.buffers[++this.currentIndex];
if (this.currentBuffer.hasRemaining()) {
this.position++;
return this.currentBuffer.get();
}
}
}
//
// //------------------------------------------------------------
// /**
// * 判断对象是否存在下一个属性或者数组是否存在下一个元素
// *
// * @param startPosition 起始位置
// * @param contentLength 内容大小, 不确定的传-1
// *
// * @return 是否存在
// */
// @Override
// public boolean hasNext(int startPosition, int contentLength) {
// //("-------------: " + startPosition + ", " + contentLength + ", " + this.position);
// if (startPosition >= 0 && contentLength >= 0) {
// return (this.position) < (startPosition + contentLength);
// }
// return (this.position + 1) < this.content.length;
// }
//
// @Override
// public byte[] readByteArray() {
// final int size = readRawVarint32();
// byte[] bs = new byte[size];
// System.arraycopy(content, position + 1, bs, 0, size);
// position += size;
// return bs;
// }
//
// protected int readRawVarint32() { //readUInt32
// fastpath:
// {
// int tempPos = this.position;
// if ((tempPos + 1) == content.length) break fastpath;
//
// int x;
// if ((x = content[++tempPos]) >= 0) {
// this.position = tempPos;
// return x;
// } else if (content.length - (tempPos + 1) < 9) {
// break fastpath;
// } else if ((x ^= (content[++tempPos] << 7)) < 0) {
// x ^= (~0 << 7);
// } else if ((x ^= (content[++tempPos] << 14)) >= 0) {
// x ^= (~0 << 7) ^ (~0 << 14);
// } else if ((x ^= (content[++tempPos] << 21)) < 0) {
// x ^= (~0 << 7) ^ (~0 << 14) ^ (~0 << 21);
// } else {
// int y = content[++tempPos];
// x ^= y << 28;
// x ^= (~0 << 7) ^ (~0 << 14) ^ (~0 << 21) ^ (~0 << 28);
// if (y < 0
// && content[++tempPos] < 0
// && content[++tempPos] < 0
// && content[++tempPos] < 0
// && content[++tempPos] < 0
// && content[++tempPos] < 0) {
// break fastpath; // Will throw malformedVarint()
// }
// }
// this.position = tempPos;
// return x;
// }
// return (int) readRawVarint64SlowPath();
// }
//
// protected long readRawVarint64() {
// fastpath:
// {
// int tempPos = this.position;
// if ((tempPos + 1) == content.length) break fastpath;
//
// long x;
// int y;
// if ((y = content[++tempPos]) >= 0) {
// this.position = tempPos;
// return y;
// } else if (content.length - (tempPos + 1) < 9) {
// break fastpath;
// } else if ((y ^= (content[++tempPos] << 7)) < 0) {
// x = y ^ (~0 << 7);
// } else if ((y ^= (content[++tempPos] << 14)) >= 0) {
// x = y ^ ((~0 << 7) ^ (~0 << 14));
// } else if ((y ^= (content[++tempPos] << 21)) < 0) {
// x = y ^ ((~0 << 7) ^ (~0 << 14) ^ (~0 << 21));
// } else if ((x = y ^ ((long) content[++tempPos] << 28)) >= 0L) {
// x ^= (~0L << 7) ^ (~0L << 14) ^ (~0L << 21) ^ (~0L << 28);
// } else if ((x ^= ((long) content[++tempPos] << 35)) < 0L) {
// x ^= (~0L << 7) ^ (~0L << 14) ^ (~0L << 21) ^ (~0L << 28) ^ (~0L << 35);
// } else if ((x ^= ((long) content[++tempPos] << 42)) >= 0L) {
// x ^= (~0L << 7) ^ (~0L << 14) ^ (~0L << 21) ^ (~0L << 28) ^ (~0L << 35) ^ (~0L << 42);
// } else if ((x ^= ((long) content[++tempPos] << 49)) < 0L) {
// x ^= (~0L << 7)
// ^ (~0L << 14)
// ^ (~0L << 21)
// ^ (~0L << 28)
// ^ (~0L << 35)
// ^ (~0L << 42)
// ^ (~0L << 49);
// } else {
// x ^= ((long) content[++tempPos] << 56);
// x ^= (~0L << 7)
// ^ (~0L << 14)
// ^ (~0L << 21)
// ^ (~0L << 28)
// ^ (~0L << 35)
// ^ (~0L << 42)
// ^ (~0L << 49)
// ^ (~0L << 56);
// if (x < 0L) {
// if (content[++tempPos] < 0L) {
// break fastpath; // Will throw malformedVarint()
// }
// }
// }
// this.position = tempPos;
// return x;
// }
// return readRawVarint64SlowPath();
// }
//
// protected long readRawVarint64SlowPath() {
// long result = 0;
// for (int shift = 0; shift < 64; shift += 7) {
// final byte b = content[++this.position];
// result |= (long) (b & 0x7F) << shift;
// if ((b & 0x80) == 0) return result;
// }
// throw new ConvertException("readRawVarint64SlowPath error");
// }
//
// protected int readRawLittleEndian32() {
// return ((content[++this.position] & 0xff)
// | ((content[++this.position] & 0xff) << 8)
// | ((content[++this.position] & 0xff) << 16)
// | ((content[++this.position] & 0xff) << 24));
// }
//
// protected long readRawLittleEndian64() {
// return ((content[++this.position] & 0xffL)
// | ((content[++this.position] & 0xffL) << 8)
// | ((content[++this.position] & 0xffL) << 16)
// | ((content[++this.position] & 0xffL) << 24)
// | ((content[++this.position] & 0xffL) << 32)
// | ((content[++this.position] & 0xffL) << 40)
// | ((content[++this.position] & 0xffL) << 48)
// | ((content[++this.position] & 0xffL) << 56));
// }
}

View File

@@ -1,144 +1,144 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package org.redkale.convert.proto;
import java.nio.ByteBuffer;
import java.util.function.Supplier;
import org.redkale.util.Utility;
/** @author zhangjx */
public class ProtobufByteBufferWriter extends ProtobufWriter {
private final Supplier<ByteBuffer> supplier;
private ByteBuffer[] buffers;
private int index;
public ProtobufByteBufferWriter(int features, boolean enumtostring, Supplier<ByteBuffer> supplier) {
super((byte[]) null);
this.features = features;
this.enumtostring = enumtostring;
this.supplier = supplier;
}
@Override
protected boolean recycle() {
super.recycle();
this.buffers = null;
this.index = 0;
return false;
}
@Override
public ByteBuffer[] toBuffers() {
if (buffers == null) {
return new ByteBuffer[0];
}
for (int i = index; i < this.buffers.length; i++) {
ByteBuffer buf = this.buffers[i];
if (buf.position() != 0) {
buf.flip();
}
}
return this.buffers;
}
@Override
public byte[] toArray() {
if (buffers == null) {
return new byte[0];
}
int pos = 0;
byte[] bytes = new byte[this.count];
for (ByteBuffer buf : toBuffers()) {
int r = buf.remaining();
buf.get(bytes, pos, r);
buf.flip();
pos += r;
}
return bytes;
}
@Override
public String toString() {
return this.getClass().getSimpleName() + "[count=" + this.count + "]";
}
@Override
protected int expand(final int byteLength) {
if (this.buffers == null) {
this.index = 0;
this.buffers = new ByteBuffer[] {supplier.get()};
}
ByteBuffer buffer = this.buffers[index];
if (!buffer.hasRemaining()) {
buffer.flip();
buffer = supplier.get();
this.buffers = Utility.append(this.buffers, buffer);
this.index++;
}
int len = buffer.remaining();
int size = 0;
while (len < byteLength) {
buffer = supplier.get();
this.buffers = Utility.append(this.buffers, buffer);
len += buffer.remaining();
size++;
}
return size;
}
@Override
public void writeTo(final byte[] chs, final int start, final int len) {
if (expand(len) == 0) {
this.buffers[index].put(chs, start, len);
} else {
ByteBuffer buffer = this.buffers[index];
final int end = start + len;
int remain = len; // 还剩多少没有写
while (remain > 0) {
final int br = buffer.remaining();
if (remain > br) { // 一个buffer写不完
buffer.put(chs, end - remain, br);
buffer = nextByteBuffer();
remain -= br;
} else {
buffer.put(chs, end - remain, remain);
remain = 0;
}
}
}
this.count += len;
}
private ByteBuffer nextByteBuffer() {
this.buffers[this.index].flip();
return this.buffers[++this.index];
}
@Override
public void writeTo(final byte ch) {
expand(1);
this.buffers[index].put(ch);
count++;
}
@Override
public byte[] content() {
throw new UnsupportedOperationException("Not supported yet."); // 无需实现
}
@Override
public int offset() {
throw new UnsupportedOperationException("Not supported yet."); // 无需实现
}
@Override
public int length() {
throw new UnsupportedOperationException("Not supported yet."); // 无需实现
}
}
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package org.redkale.convert.proto;
import java.nio.ByteBuffer;
import java.util.function.Supplier;
import org.redkale.util.Utility;
/** @author zhangjx */
public class ProtobufByteBufferWriter extends ProtobufWriter {
private final Supplier<ByteBuffer> supplier;
private ByteBuffer[] buffers;
private int index;
public ProtobufByteBufferWriter(int features, boolean enumtostring, Supplier<ByteBuffer> supplier) {
super((byte[]) null);
this.features = features;
this.enumtostring = enumtostring;
this.supplier = supplier;
}
@Override
protected boolean recycle() {
super.recycle();
this.buffers = null;
this.index = 0;
return false;
}
@Override
public ByteBuffer[] toBuffers() {
if (buffers == null) {
return new ByteBuffer[0];
}
for (int i = index; i < this.buffers.length; i++) {
ByteBuffer buf = this.buffers[i];
if (buf.position() != 0) {
buf.flip();
}
}
return this.buffers;
}
@Override
public byte[] toArray() {
if (buffers == null) {
return new byte[0];
}
int pos = 0;
byte[] bytes = new byte[this.count];
for (ByteBuffer buf : toBuffers()) {
int r = buf.remaining();
buf.get(bytes, pos, r);
buf.flip();
pos += r;
}
return bytes;
}
@Override
public String toString() {
return this.getClass().getSimpleName() + "[count=" + this.count + "]";
}
@Override
protected int expand(final int byteLength) {
if (this.buffers == null) {
this.index = 0;
this.buffers = new ByteBuffer[] {supplier.get()};
}
ByteBuffer buffer = this.buffers[index];
if (!buffer.hasRemaining()) {
buffer.flip();
buffer = supplier.get();
this.buffers = Utility.append(this.buffers, buffer);
this.index++;
}
int len = buffer.remaining();
int size = 0;
while (len < byteLength) {
buffer = supplier.get();
this.buffers = Utility.append(this.buffers, buffer);
len += buffer.remaining();
size++;
}
return size;
}
@Override
public void writeTo(final byte[] chs, final int start, final int len) {
if (expand(len) == 0) {
this.buffers[index].put(chs, start, len);
} else {
ByteBuffer buffer = this.buffers[index];
final int end = start + len;
int remain = len; // 还剩多少没有写
while (remain > 0) {
final int br = buffer.remaining();
if (remain > br) { // 一个buffer写不完
buffer.put(chs, end - remain, br);
buffer = nextByteBuffer();
remain -= br;
} else {
buffer.put(chs, end - remain, remain);
remain = 0;
}
}
}
this.count += len;
}
private ByteBuffer nextByteBuffer() {
this.buffers[this.index].flip();
return this.buffers[++this.index];
}
@Override
public void writeTo(final byte ch) {
expand(1);
this.buffers[index].put(ch);
count++;
}
@Override
public byte[] content() {
throw new UnsupportedOperationException("Not supported yet."); // 无需实现
}
@Override
public int offset() {
throw new UnsupportedOperationException("Not supported yet."); // 无需实现
}
@Override
public int length() {
throw new UnsupportedOperationException("Not supported yet."); // 无需实现
}
}

View File

@@ -1,45 +1,45 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package org.redkale.convert.proto;
import java.lang.reflect.Type;
import java.util.concurrent.atomic.*;
import org.redkale.convert.*;
/**
* @author zhangjx
* @param <T> T
*/
public class ProtobufCollectionDecoder<T> extends CollectionDecoder<T> {
protected final boolean simple;
private final boolean string;
private final boolean enumtostring;
public ProtobufCollectionDecoder(ConvertFactory factory, Type type) {
super(factory, type);
this.enumtostring = ((ProtobufFactory) factory).enumtostring;
Type comtype = this.getComponentType();
this.string = String.class == comtype;
this.simple = Boolean.class == comtype
|| Short.class == comtype
|| Character.class == comtype
|| Integer.class == comtype
|| Float.class == comtype
|| Long.class == comtype
|| Double.class == comtype
|| AtomicInteger.class == comtype
|| AtomicLong.class == comtype;
}
@Override
protected Reader getItemReader(Reader in, DeMember member, boolean first) {
if (simple) return in;
return ProtobufFactory.getItemReader(string, simple, in, member, enumtostring, first);
}
}
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package org.redkale.convert.proto;
import java.lang.reflect.Type;
import java.util.concurrent.atomic.*;
import org.redkale.convert.*;
/**
* @author zhangjx
* @param <T> T
*/
public class ProtobufCollectionDecoder<T> extends CollectionDecoder<T> {
protected final boolean simple;
private final boolean string;
private final boolean enumtostring;
public ProtobufCollectionDecoder(ConvertFactory factory, Type type) {
super(factory, type);
this.enumtostring = ((ProtobufFactory) factory).enumtostring;
Type comtype = this.getComponentType();
this.string = String.class == comtype;
this.simple = Boolean.class == comtype
|| Short.class == comtype
|| Character.class == comtype
|| Integer.class == comtype
|| Float.class == comtype
|| Long.class == comtype
|| Double.class == comtype
|| AtomicInteger.class == comtype
|| AtomicLong.class == comtype;
}
@Override
protected Reader getItemReader(Reader in, DeMember member, boolean first) {
if (simple) return in;
return ProtobufFactory.getItemReader(string, simple, in, member, enumtostring, first);
}
}

View File

@@ -1,57 +1,57 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package org.redkale.convert.proto;
import java.lang.reflect.Type;
import java.util.concurrent.atomic.*;
import org.redkale.convert.*;
/**
* @author zhangjx
* @param <T> T
*/
public class ProtobufCollectionEncoder<T> extends CollectionEncoder<T> {
protected final boolean simple;
public ProtobufCollectionEncoder(ConvertFactory factory, Type type) {
super(factory, type);
Type comtype = this.getComponentType();
this.simple = Boolean.class == comtype
|| Short.class == comtype
|| Character.class == comtype
|| Integer.class == comtype
|| Float.class == comtype
|| Long.class == comtype
|| Double.class == comtype
|| AtomicInteger.class == comtype
|| AtomicLong.class == comtype;
}
@Override
protected void writeMemberValue(Writer out, EnMember member, Object item, boolean first) {
if (simple) {
if (item == null) {
((ProtobufWriter) out).writeUInt32(0);
} else {
componentEncoder.convertTo(out, item);
}
return;
}
if (member != null) out.writeFieldName(member);
if (item == null) {
((ProtobufWriter) out).writeUInt32(0);
} else if (item instanceof CharSequence) {
componentEncoder.convertTo(out, item);
} else {
ProtobufWriter tmp = new ProtobufWriter().configFieldFunc(out);
componentEncoder.convertTo(tmp, item);
int length = tmp.count();
((ProtobufWriter) out).writeUInt32(length);
((ProtobufWriter) out).writeTo(tmp.toArray());
}
}
}
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package org.redkale.convert.proto;
import java.lang.reflect.Type;
import java.util.concurrent.atomic.*;
import org.redkale.convert.*;
/**
* @author zhangjx
* @param <T> T
*/
public class ProtobufCollectionEncoder<T> extends CollectionEncoder<T> {
protected final boolean simple;
public ProtobufCollectionEncoder(ConvertFactory factory, Type type) {
super(factory, type);
Type comtype = this.getComponentType();
this.simple = Boolean.class == comtype
|| Short.class == comtype
|| Character.class == comtype
|| Integer.class == comtype
|| Float.class == comtype
|| Long.class == comtype
|| Double.class == comtype
|| AtomicInteger.class == comtype
|| AtomicLong.class == comtype;
}
@Override
protected void writeMemberValue(Writer out, EnMember member, Object item, boolean first) {
if (simple) {
if (item == null) {
((ProtobufWriter) out).writeUInt32(0);
} else {
componentEncoder.convertTo(out, item);
}
return;
}
if (member != null) out.writeFieldName(member);
if (item == null) {
((ProtobufWriter) out).writeUInt32(0);
} else if (item instanceof CharSequence) {
componentEncoder.convertTo(out, item);
} else {
ProtobufWriter tmp = new ProtobufWriter().configFieldFunc(out);
componentEncoder.convertTo(tmp, item);
int length = tmp.count();
((ProtobufWriter) out).writeUInt32(length);
((ProtobufWriter) out).writeTo(tmp.toArray());
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,71 +1,71 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package org.redkale.convert.proto;
import java.lang.reflect.Method;
import java.util.*;
import org.redkale.convert.*;
import org.redkale.util.RedkaleClassLoader;
/**
* 枚举 的SimpledCoder实现
*
* <p>详情见: https://redkale.org
*
* @author zhangjx
* @param <R> Reader输入的子类型
* @param <W> Writer输出的子类型
* @param <E> Enum的子类
*/
public class ProtobufEnumSimpledCoder<R extends Reader, W extends Writer, E extends Enum>
extends SimpledCoder<R, W, E> {
private final Map<Integer, E> values = new HashMap<>();
private final boolean enumtostring;
public ProtobufEnumSimpledCoder(Class<E> type, boolean enumtostring) {
this.type = type;
this.enumtostring = enumtostring;
try {
final Method method = type.getMethod("values");
RedkaleClassLoader.putReflectionMethod(type.getName(), method);
for (E item : (E[]) method.invoke(null)) {
values.put(item.ordinal(), item);
}
} catch (Exception e) {
throw new ConvertException(e);
}
}
@Override
public void convertTo(final W out, final E value) {
if (value == null) {
out.writeNull();
} else if (enumtostring) {
out.writeSmallString(value.toString());
} else {
((ProtobufWriter) out).writeUInt32(value.ordinal());
}
}
@Override
@SuppressWarnings("unchecked")
public E convertFrom(final R in) {
if (enumtostring) {
String value = in.readSmallString();
if (value == null) return null;
return (E) Enum.valueOf((Class<E>) type, value);
}
int value = ((ProtobufReader) in).readRawVarint32();
return values.get(value);
}
@Override
public Class<E> getType() {
return (Class) type;
}
}
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package org.redkale.convert.proto;
import java.lang.reflect.Method;
import java.util.*;
import org.redkale.convert.*;
import org.redkale.util.RedkaleClassLoader;
/**
* 枚举 的SimpledCoder实现
*
* <p>详情见: https://redkale.org
*
* @author zhangjx
* @param <R> Reader输入的子类型
* @param <W> Writer输出的子类型
* @param <E> Enum的子类
*/
public class ProtobufEnumSimpledCoder<R extends Reader, W extends Writer, E extends Enum>
extends SimpledCoder<R, W, E> {
private final Map<Integer, E> values = new HashMap<>();
private final boolean enumtostring;
public ProtobufEnumSimpledCoder(Class<E> type, boolean enumtostring) {
this.type = type;
this.enumtostring = enumtostring;
try {
final Method method = type.getMethod("values");
RedkaleClassLoader.putReflectionMethod(type.getName(), method);
for (E item : (E[]) method.invoke(null)) {
values.put(item.ordinal(), item);
}
} catch (Exception e) {
throw new ConvertException(e);
}
}
@Override
public void convertTo(final W out, final E value) {
if (value == null) {
out.writeNull();
} else if (enumtostring) {
out.writeSmallString(value.toString());
} else {
((ProtobufWriter) out).writeUInt32(value.ordinal());
}
}
@Override
@SuppressWarnings("unchecked")
public E convertFrom(final R in) {
if (enumtostring) {
String value = in.readSmallString();
if (value == null) return null;
return (E) Enum.valueOf((Class<E>) type, value);
}
int value = ((ProtobufReader) in).readRawVarint32();
return values.get(value);
}
@Override
public Class<E> getType() {
return (Class) type;
}
}

View File

@@ -1,345 +1,345 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package org.redkale.convert.proto;
import java.io.Serializable;
import java.lang.reflect.*;
import java.util.*;
import java.util.concurrent.atomic.*;
import java.util.stream.Stream;
import org.redkale.convert.*;
import org.redkale.util.AnyValue;
import org.redkale.util.AnyValueWriter;
/** @author zhangjx */
public class ProtobufFactory extends ConvertFactory<ProtobufReader, ProtobufWriter> {
private static final ProtobufFactory instance = new ProtobufFactory(
null,
getSystemPropertyInt("redkale.convert.protobuf.tiny", "redkale.convert.tiny", true, Convert.FEATURE_TINY)
| getSystemPropertyInt(
"redkale.convert.protobuf.nullable",
"redkale.convert.nullable",
false,
Convert.FEATURE_NULLABLE),
Boolean.parseBoolean(System.getProperty("redkale.convert.protobuf.enumtostring", "true")));
static final Decodeable objectDecoder = instance.loadDecoder(Object.class);
static final Encodeable objectEncoder = instance.loadEncoder(Object.class);
protected final boolean enumtostring;
protected boolean reversible = false;
static {
instance.register(Serializable.class, objectDecoder);
instance.register(Serializable.class, objectEncoder);
instance.register(AnyValue.class, instance.loadDecoder(AnyValueWriter.class));
instance.register(AnyValue.class, instance.loadEncoder(AnyValueWriter.class));
}
@SuppressWarnings("OverridableMethodCallInConstructor")
private ProtobufFactory(ProtobufFactory parent, int features, boolean enumtostring) {
super(parent, features);
this.enumtostring = enumtostring;
if (parent == null) { // root
this.register(String[].class, this.createArrayDecoder(String[].class));
this.register(String[].class, this.createArrayEncoder(String[].class));
}
}
public static ProtobufFactory root() {
return instance;
}
@Override
public ProtobufFactory withFeatures(int features) {
return super.withFeatures(features);
}
@Override
public ProtobufFactory addFeature(int feature) {
return super.addFeature(feature);
}
@Override
public ProtobufFactory removeFeature(int feature) {
return super.removeFeature(feature);
}
@Override
public ProtobufFactory withTinyFeature(boolean tiny) {
return super.withTinyFeature(tiny);
}
@Override
public ProtobufFactory withNullableFeature(boolean nullable) {
return super.withNullableFeature(nullable);
}
public static ProtobufFactory create() {
return new ProtobufFactory(null, instance.features, instance.enumtostring);
}
@Override
protected SimpledCoder createEnumSimpledCoder(Class enumClass) {
return new ProtobufEnumSimpledCoder(enumClass, this.enumtostring);
}
@Override
protected ObjectDecoder createObjectDecoder(Type type) {
return new ProtobufObjectDecoder(type);
}
@Override
protected ObjectEncoder createObjectEncoder(Type type) {
return new ProtobufObjectEncoder(type);
}
@Override
protected <E> Decodeable<ProtobufReader, E> createMapDecoder(Type type) {
return new ProtobufMapDecoder(this, type);
}
@Override
protected <E> Encodeable<ProtobufWriter, E> createMapEncoder(Type type) {
return new ProtobufMapEncoder(this, type);
}
@Override
protected <E> Decodeable<ProtobufReader, E> createArrayDecoder(Type type) {
return new ProtobufArrayDecoder(this, type);
}
@Override
protected <E> Encodeable<ProtobufWriter, E> createArrayEncoder(Type type) {
return new ProtobufArrayEncoder(this, type);
}
@Override
protected <E> Decodeable<ProtobufReader, E> createCollectionDecoder(Type type) {
return new ProtobufCollectionDecoder(this, type);
}
@Override
protected <E> Encodeable<ProtobufWriter, E> createCollectionEncoder(Type type) {
return new ProtobufCollectionEncoder(this, type);
}
@Override
protected <E> Decodeable<ProtobufReader, E> createStreamDecoder(Type type) {
return new ProtobufStreamDecoder(this, type);
}
@Override
protected <E> Encodeable<ProtobufWriter, E> createStreamEncoder(Type type) {
return new ProtobufStreamEncoder(this, type);
}
@Override
public final ProtobufConvert getConvert() {
if (convert == null) {
convert = new ProtobufConvert(this, features);
}
return (ProtobufConvert) convert;
}
@Override
public ProtobufFactory createChild() {
return new ProtobufFactory(this, features, this.enumtostring);
}
@Override
public ProtobufFactory createChild(int features) {
return new ProtobufFactory(this, features, this.enumtostring);
}
@Override
public ConvertType getConvertType() {
return ConvertType.PROTOBUF;
}
public ProtobufFactory reversible(boolean reversible) {
this.reversible = reversible;
return this;
}
@Override
public boolean isReversible() {
return reversible;
}
@Override
public boolean isFieldSort() {
return true;
}
protected static Reader getItemReader(
boolean string, boolean simple, Reader in, DeMember member, boolean enumtostring, boolean first) {
if (string) {
if (member == null || first) {
return in;
}
ProtobufReader reader = (ProtobufReader) in;
int tag = reader.readTag();
if (tag != member.getTag()) {
reader.backTag(tag);
return null;
}
return in;
} else {
ProtobufReader reader = (ProtobufReader) in;
if (!first && member != null) {
int tag = reader.readTag();
if (tag != member.getTag()) {
reader.backTag(tag);
return null;
}
}
byte[] bs = reader.readByteArray();
return new ProtobufReader(bs);
}
}
public static int getTag(String fieldName, Type fieldType, int fieldPos, boolean enumtostring) {
int wiretype = ProtobufFactory.wireType(fieldType, enumtostring);
return (fieldPos << 3 | wiretype);
}
public static int getTag(DeMember member, boolean enumtostring) {
int wiretype = ProtobufFactory.wireType(member.getAttribute().type(), enumtostring);
return (member.getPosition() << 3 | wiretype);
}
public static int wireType(Type javaType, boolean enumtostring) {
if (javaType == double.class || javaType == Double.class) {
return 1;
}
if (javaType == float.class || javaType == Float.class) {
return 5;
}
if (javaType == boolean.class || javaType == Boolean.class) {
return 0;
}
if (javaType instanceof Class) {
Class javaClazz = (Class) javaType;
if (javaClazz.isEnum()) {
return enumtostring ? 2 : 0;
}
if (javaClazz.isPrimitive() || Number.class.isAssignableFrom(javaClazz)) {
return 0;
}
}
return 2;
}
public static String wireTypeString(Type javaType, boolean enumtostring) {
if (javaType == double.class || javaType == Double.class) {
return "double";
}
if (javaType == long.class || javaType == Long.class) {
return "sint64";
}
if (javaType == float.class || javaType == Float.class) {
return "float";
}
if (javaType == int.class || javaType == Integer.class) {
return "sint32";
}
if (javaType == short.class || javaType == Short.class) {
return "sint32";
}
if (javaType == char.class || javaType == Character.class) {
return "sint32";
}
if (javaType == byte.class || javaType == Byte.class) {
return "sint32";
}
if (javaType == boolean.class || javaType == Boolean.class) {
return "bool";
}
if (javaType == AtomicLong.class) {
return "sint64";
}
if (javaType == AtomicInteger.class) {
return "sint32";
}
if (javaType == AtomicBoolean.class) {
return "bool";
}
if (javaType == double[].class || javaType == Double[].class) {
return "repeated double";
}
if (javaType == long[].class || javaType == Long[].class) {
return "repeated sint64";
}
if (javaType == float[].class || javaType == Float[].class) {
return "repeated float";
}
if (javaType == int[].class || javaType == Integer[].class) {
return "repeated sint32";
}
if (javaType == short[].class || javaType == Short[].class) {
return "repeated sint32";
}
if (javaType == char[].class || javaType == Character[].class) {
return "repeated sint32";
}
if (javaType == byte[].class || javaType == Byte[].class) {
return "bytes";
}
if (javaType == boolean[].class || javaType == Boolean[].class) {
return "repeated bool";
}
if (javaType == AtomicLong[].class) {
return "repeated sint64";
}
if (javaType == AtomicInteger[].class) {
return "repeated sint32";
}
if (javaType == AtomicBoolean[].class) {
return "repeated bool";
}
if (javaType == java.util.Properties.class) {
return "map<string,string>";
}
if (javaType instanceof Class) {
Class javaClazz = (Class) javaType;
if (javaClazz.isArray()) {
return "repeated " + wireTypeString(javaClazz.getComponentType(), enumtostring);
}
if (javaClazz.isEnum()) {
return enumtostring ? "string" : javaClazz.getSimpleName();
}
if (CharSequence.class.isAssignableFrom(javaClazz)) {
return "string";
}
return javaClazz == Object.class ? "Any" : javaClazz.getSimpleName();
} else if (javaType instanceof ParameterizedType) { // Collection、Stream、Map 必须是泛型
final ParameterizedType pt = (ParameterizedType) javaType;
final Class rawType = (Class) pt.getRawType();
if (Map.class.isAssignableFrom(rawType)) {
Type keyType = pt.getActualTypeArguments()[0];
Type valueType = pt.getActualTypeArguments()[1];
return "map<" + wireTypeString(keyType, enumtostring) + "," + wireTypeString(valueType, enumtostring)
+ ">";
} else if (Collection.class.isAssignableFrom(rawType)
|| Stream.class.isAssignableFrom(rawType)
|| rawType.isArray()) {
return "repeated " + wireTypeString(pt.getActualTypeArguments()[0], enumtostring);
} else if (pt.getActualTypeArguments().length == 1 && (pt.getActualTypeArguments()[0] instanceof Class)) {
return rawType.getSimpleName() + "_" + ((Class) pt.getActualTypeArguments()[0]).getSimpleName();
}
} else if (javaType instanceof GenericArrayType) {
return "repeated " + wireTypeString(((GenericArrayType) javaType).getGenericComponentType(), enumtostring);
}
throw new UnsupportedOperationException("ProtobufConvert not supported type(" + javaType + ")");
}
}
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package org.redkale.convert.proto;
import java.io.Serializable;
import java.lang.reflect.*;
import java.util.*;
import java.util.concurrent.atomic.*;
import java.util.stream.Stream;
import org.redkale.convert.*;
import org.redkale.util.AnyValue;
import org.redkale.util.AnyValueWriter;
/** @author zhangjx */
public class ProtobufFactory extends ConvertFactory<ProtobufReader, ProtobufWriter> {
private static final ProtobufFactory instance = new ProtobufFactory(
null,
getSystemPropertyInt("redkale.convert.protobuf.tiny", "redkale.convert.tiny", true, Convert.FEATURE_TINY)
| getSystemPropertyInt(
"redkale.convert.protobuf.nullable",
"redkale.convert.nullable",
false,
Convert.FEATURE_NULLABLE),
Boolean.parseBoolean(System.getProperty("redkale.convert.protobuf.enumtostring", "true")));
static final Decodeable objectDecoder = instance.loadDecoder(Object.class);
static final Encodeable objectEncoder = instance.loadEncoder(Object.class);
protected final boolean enumtostring;
protected boolean reversible = false;
static {
instance.register(Serializable.class, objectDecoder);
instance.register(Serializable.class, objectEncoder);
instance.register(AnyValue.class, instance.loadDecoder(AnyValueWriter.class));
instance.register(AnyValue.class, instance.loadEncoder(AnyValueWriter.class));
}
@SuppressWarnings("OverridableMethodCallInConstructor")
private ProtobufFactory(ProtobufFactory parent, int features, boolean enumtostring) {
super(parent, features);
this.enumtostring = enumtostring;
if (parent == null) { // root
this.register(String[].class, this.createArrayDecoder(String[].class));
this.register(String[].class, this.createArrayEncoder(String[].class));
}
}
public static ProtobufFactory root() {
return instance;
}
@Override
public ProtobufFactory withFeatures(int features) {
return super.withFeatures(features);
}
@Override
public ProtobufFactory addFeature(int feature) {
return super.addFeature(feature);
}
@Override
public ProtobufFactory removeFeature(int feature) {
return super.removeFeature(feature);
}
@Override
public ProtobufFactory withTinyFeature(boolean tiny) {
return super.withTinyFeature(tiny);
}
@Override
public ProtobufFactory withNullableFeature(boolean nullable) {
return super.withNullableFeature(nullable);
}
public static ProtobufFactory create() {
return new ProtobufFactory(null, instance.features, instance.enumtostring);
}
@Override
protected SimpledCoder createEnumSimpledCoder(Class enumClass) {
return new ProtobufEnumSimpledCoder(enumClass, this.enumtostring);
}
@Override
protected ObjectDecoder createObjectDecoder(Type type) {
return new ProtobufObjectDecoder(type);
}
@Override
protected ObjectEncoder createObjectEncoder(Type type) {
return new ProtobufObjectEncoder(type);
}
@Override
protected <E> Decodeable<ProtobufReader, E> createMapDecoder(Type type) {
return new ProtobufMapDecoder(this, type);
}
@Override
protected <E> Encodeable<ProtobufWriter, E> createMapEncoder(Type type) {
return new ProtobufMapEncoder(this, type);
}
@Override
protected <E> Decodeable<ProtobufReader, E> createArrayDecoder(Type type) {
return new ProtobufArrayDecoder(this, type);
}
@Override
protected <E> Encodeable<ProtobufWriter, E> createArrayEncoder(Type type) {
return new ProtobufArrayEncoder(this, type);
}
@Override
protected <E> Decodeable<ProtobufReader, E> createCollectionDecoder(Type type) {
return new ProtobufCollectionDecoder(this, type);
}
@Override
protected <E> Encodeable<ProtobufWriter, E> createCollectionEncoder(Type type) {
return new ProtobufCollectionEncoder(this, type);
}
@Override
protected <E> Decodeable<ProtobufReader, E> createStreamDecoder(Type type) {
return new ProtobufStreamDecoder(this, type);
}
@Override
protected <E> Encodeable<ProtobufWriter, E> createStreamEncoder(Type type) {
return new ProtobufStreamEncoder(this, type);
}
@Override
public final ProtobufConvert getConvert() {
if (convert == null) {
convert = new ProtobufConvert(this, features);
}
return (ProtobufConvert) convert;
}
@Override
public ProtobufFactory createChild() {
return new ProtobufFactory(this, features, this.enumtostring);
}
@Override
public ProtobufFactory createChild(int features) {
return new ProtobufFactory(this, features, this.enumtostring);
}
@Override
public ConvertType getConvertType() {
return ConvertType.PROTOBUF;
}
public ProtobufFactory reversible(boolean reversible) {
this.reversible = reversible;
return this;
}
@Override
public boolean isReversible() {
return reversible;
}
@Override
public boolean isFieldSort() {
return true;
}
protected static Reader getItemReader(
boolean string, boolean simple, Reader in, DeMember member, boolean enumtostring, boolean first) {
if (string) {
if (member == null || first) {
return in;
}
ProtobufReader reader = (ProtobufReader) in;
int tag = reader.readTag();
if (tag != member.getTag()) {
reader.backTag(tag);
return null;
}
return in;
} else {
ProtobufReader reader = (ProtobufReader) in;
if (!first && member != null) {
int tag = reader.readTag();
if (tag != member.getTag()) {
reader.backTag(tag);
return null;
}
}
byte[] bs = reader.readByteArray();
return new ProtobufReader(bs);
}
}
public static int getTag(String fieldName, Type fieldType, int fieldPos, boolean enumtostring) {
int wiretype = ProtobufFactory.wireType(fieldType, enumtostring);
return (fieldPos << 3 | wiretype);
}
public static int getTag(DeMember member, boolean enumtostring) {
int wiretype = ProtobufFactory.wireType(member.getAttribute().type(), enumtostring);
return (member.getPosition() << 3 | wiretype);
}
public static int wireType(Type javaType, boolean enumtostring) {
if (javaType == double.class || javaType == Double.class) {
return 1;
}
if (javaType == float.class || javaType == Float.class) {
return 5;
}
if (javaType == boolean.class || javaType == Boolean.class) {
return 0;
}
if (javaType instanceof Class) {
Class javaClazz = (Class) javaType;
if (javaClazz.isEnum()) {
return enumtostring ? 2 : 0;
}
if (javaClazz.isPrimitive() || Number.class.isAssignableFrom(javaClazz)) {
return 0;
}
}
return 2;
}
public static String wireTypeString(Type javaType, boolean enumtostring) {
if (javaType == double.class || javaType == Double.class) {
return "double";
}
if (javaType == long.class || javaType == Long.class) {
return "sint64";
}
if (javaType == float.class || javaType == Float.class) {
return "float";
}
if (javaType == int.class || javaType == Integer.class) {
return "sint32";
}
if (javaType == short.class || javaType == Short.class) {
return "sint32";
}
if (javaType == char.class || javaType == Character.class) {
return "sint32";
}
if (javaType == byte.class || javaType == Byte.class) {
return "sint32";
}
if (javaType == boolean.class || javaType == Boolean.class) {
return "bool";
}
if (javaType == AtomicLong.class) {
return "sint64";
}
if (javaType == AtomicInteger.class) {
return "sint32";
}
if (javaType == AtomicBoolean.class) {
return "bool";
}
if (javaType == double[].class || javaType == Double[].class) {
return "repeated double";
}
if (javaType == long[].class || javaType == Long[].class) {
return "repeated sint64";
}
if (javaType == float[].class || javaType == Float[].class) {
return "repeated float";
}
if (javaType == int[].class || javaType == Integer[].class) {
return "repeated sint32";
}
if (javaType == short[].class || javaType == Short[].class) {
return "repeated sint32";
}
if (javaType == char[].class || javaType == Character[].class) {
return "repeated sint32";
}
if (javaType == byte[].class || javaType == Byte[].class) {
return "bytes";
}
if (javaType == boolean[].class || javaType == Boolean[].class) {
return "repeated bool";
}
if (javaType == AtomicLong[].class) {
return "repeated sint64";
}
if (javaType == AtomicInteger[].class) {
return "repeated sint32";
}
if (javaType == AtomicBoolean[].class) {
return "repeated bool";
}
if (javaType == java.util.Properties.class) {
return "map<string,string>";
}
if (javaType instanceof Class) {
Class javaClazz = (Class) javaType;
if (javaClazz.isArray()) {
return "repeated " + wireTypeString(javaClazz.getComponentType(), enumtostring);
}
if (javaClazz.isEnum()) {
return enumtostring ? "string" : javaClazz.getSimpleName();
}
if (CharSequence.class.isAssignableFrom(javaClazz)) {
return "string";
}
return javaClazz == Object.class ? "Any" : javaClazz.getSimpleName();
} else if (javaType instanceof ParameterizedType) { // Collection、Stream、Map 必须是泛型
final ParameterizedType pt = (ParameterizedType) javaType;
final Class rawType = (Class) pt.getRawType();
if (Map.class.isAssignableFrom(rawType)) {
Type keyType = pt.getActualTypeArguments()[0];
Type valueType = pt.getActualTypeArguments()[1];
return "map<" + wireTypeString(keyType, enumtostring) + "," + wireTypeString(valueType, enumtostring)
+ ">";
} else if (Collection.class.isAssignableFrom(rawType)
|| Stream.class.isAssignableFrom(rawType)
|| rawType.isArray()) {
return "repeated " + wireTypeString(pt.getActualTypeArguments()[0], enumtostring);
} else if (pt.getActualTypeArguments().length == 1 && (pt.getActualTypeArguments()[0] instanceof Class)) {
return rawType.getSimpleName() + "_" + ((Class) pt.getActualTypeArguments()[0]).getSimpleName();
}
} else if (javaType instanceof GenericArrayType) {
return "repeated " + wireTypeString(((GenericArrayType) javaType).getGenericComponentType(), enumtostring);
}
throw new UnsupportedOperationException("ProtobufConvert not supported type(" + javaType + ")");
}
}

View File

@@ -1,52 +1,52 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package org.redkale.convert.proto;
import java.lang.reflect.Type;
import org.redkale.convert.*;
/**
* @author zhangjx
* @param <K> K
* @param <V> V
*/
public class ProtobufMapDecoder<K, V> extends MapDecoder<K, V> {
private final boolean enumtostring;
public ProtobufMapDecoder(ConvertFactory factory, Type type) {
super(factory, type);
this.enumtostring = ((ProtobufFactory) factory).enumtostring;
}
@Override
protected Reader getEntryReader(Reader in, DeMember member, boolean first) {
ProtobufReader reader = (ProtobufReader) in;
if (!first && member != null) {
int tag = reader.readTag();
if (tag != member.getTag()) {
reader.backTag(tag);
return null;
}
}
byte[] bs = reader.readByteArray();
return new ProtobufReader(bs);
}
@Override
protected K readKeyMember(Reader in, DeMember member, Decodeable<Reader, K> decoder, boolean first) {
ProtobufReader reader = (ProtobufReader) in;
reader.readTag();
return decoder.convertFrom(in);
}
@Override
protected V readValueMember(Reader in, DeMember member, Decodeable<Reader, V> decoder, boolean first) {
ProtobufReader reader = (ProtobufReader) in;
reader.readTag();
return decoder.convertFrom(in);
}
}
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package org.redkale.convert.proto;
import java.lang.reflect.Type;
import org.redkale.convert.*;
/**
* @author zhangjx
* @param <K> K
* @param <V> V
*/
public class ProtobufMapDecoder<K, V> extends MapDecoder<K, V> {
private final boolean enumtostring;
public ProtobufMapDecoder(ConvertFactory factory, Type type) {
super(factory, type);
this.enumtostring = ((ProtobufFactory) factory).enumtostring;
}
@Override
protected Reader getEntryReader(Reader in, DeMember member, boolean first) {
ProtobufReader reader = (ProtobufReader) in;
if (!first && member != null) {
int tag = reader.readTag();
if (tag != member.getTag()) {
reader.backTag(tag);
return null;
}
}
byte[] bs = reader.readByteArray();
return new ProtobufReader(bs);
}
@Override
protected K readKeyMember(Reader in, DeMember member, Decodeable<Reader, K> decoder, boolean first) {
ProtobufReader reader = (ProtobufReader) in;
reader.readTag();
return decoder.convertFrom(in);
}
@Override
protected V readValueMember(Reader in, DeMember member, Decodeable<Reader, V> decoder, boolean first) {
ProtobufReader reader = (ProtobufReader) in;
reader.readTag();
return decoder.convertFrom(in);
}
}

View File

@@ -1,37 +1,37 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package org.redkale.convert.proto;
import java.lang.reflect.Type;
import org.redkale.convert.*;
/**
* @author zhangjx
* @param <K> K
* @param <V> V
*/
public class ProtobufMapEncoder<K, V> extends MapEncoder<K, V> {
private final boolean enumtostring;
public ProtobufMapEncoder(ConvertFactory factory, Type type) {
super(factory, type);
this.enumtostring = ((ProtobufFactory) factory).enumtostring;
}
@Override
protected void writeMemberValue(Writer out, EnMember member, K key, V value, boolean first) {
ProtobufWriter tmp = new ProtobufWriter().configFieldFunc(out);
if (member != null) out.writeFieldName(member);
tmp.writeUInt32(1 << 3 | ProtobufFactory.wireType(keyEncoder.getType(), enumtostring));
keyEncoder.convertTo(tmp, key);
tmp.writeUInt32(2 << 3 | ProtobufFactory.wireType(valueEncoder.getType(), enumtostring));
valueEncoder.convertTo(tmp, value);
int length = tmp.count();
((ProtobufWriter) out).writeUInt32(length);
((ProtobufWriter) out).writeTo(tmp.toArray());
}
}
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package org.redkale.convert.proto;
import java.lang.reflect.Type;
import org.redkale.convert.*;
/**
* @author zhangjx
* @param <K> K
* @param <V> V
*/
public class ProtobufMapEncoder<K, V> extends MapEncoder<K, V> {
private final boolean enumtostring;
public ProtobufMapEncoder(ConvertFactory factory, Type type) {
super(factory, type);
this.enumtostring = ((ProtobufFactory) factory).enumtostring;
}
@Override
protected void writeMemberValue(Writer out, EnMember member, K key, V value, boolean first) {
ProtobufWriter tmp = new ProtobufWriter().configFieldFunc(out);
if (member != null) out.writeFieldName(member);
tmp.writeUInt32(1 << 3 | ProtobufFactory.wireType(keyEncoder.getType(), enumtostring));
keyEncoder.convertTo(tmp, key);
tmp.writeUInt32(2 << 3 | ProtobufFactory.wireType(valueEncoder.getType(), enumtostring));
valueEncoder.convertTo(tmp, value);
int length = tmp.count();
((ProtobufWriter) out).writeUInt32(length);
((ProtobufWriter) out).writeTo(tmp.toArray());
}
}

View File

@@ -1,81 +1,81 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package org.redkale.convert.proto;
import java.lang.reflect.Type;
import org.redkale.convert.*;
import org.redkale.util.Attribute;
import org.redkale.util.Utility;
/**
* @author zhangjx
* @param <T> T
*/
public class ProtobufObjectDecoder<T> extends ObjectDecoder<ProtobufReader, T> {
protected ProtobufObjectDecoder(Type type) {
super(type);
}
@Override
protected void initForEachDeMember(ConvertFactory factory, DeMember member) {
if (member.getIndex() < 1) {
throw new ConvertException(Utility.orElse(member.getField(), member.getMethod()) + " not found @"
+ ConvertColumn.class.getSimpleName() + ".index");
}
Attribute attr = member.getAttribute();
setTag(
member,
ProtobufFactory.getTag(
attr.field(),
attr.genericType(),
member.getPosition(),
((ProtobufFactory) factory).enumtostring));
}
@Override
protected ProtobufReader objectReader(ProtobufReader in) {
if (in.position() > in.initoffset) return new ProtobufReader(in.readByteArray());
return in;
}
@Override
protected boolean hasNext(ProtobufReader in, boolean first) {
return in.hasNext();
}
@Override
protected Object readDeMemberValue(ProtobufReader in, DeMember member, boolean first) {
Decodeable decoder = member.getDecoder();
if (decoder instanceof ProtobufArrayDecoder) {
return ((ProtobufArrayDecoder) decoder).convertFrom(in, member);
} else if (decoder instanceof ProtobufCollectionDecoder) {
return ((ProtobufCollectionDecoder) decoder).convertFrom(in, member);
} else if (decoder instanceof ProtobufStreamDecoder) {
return ((ProtobufStreamDecoder) decoder).convertFrom(in, member);
} else if (decoder instanceof ProtobufMapDecoder) {
return ((ProtobufMapDecoder) decoder).convertFrom(in, member);
} else {
return member.read(in);
}
}
@Override
protected void readDeMemberValue(ProtobufReader in, DeMember member, T result, boolean first) {
Decodeable decoder = member.getDecoder();
if (decoder instanceof ProtobufArrayDecoder) {
member.getAttribute().set(result, ((ProtobufArrayDecoder) decoder).convertFrom(in, member));
} else if (decoder instanceof ProtobufCollectionDecoder) {
member.getAttribute().set(result, ((ProtobufCollectionDecoder) decoder).convertFrom(in, member));
} else if (decoder instanceof ProtobufStreamDecoder) {
member.getAttribute().set(result, ((ProtobufStreamDecoder) decoder).convertFrom(in, member));
} else if (decoder instanceof ProtobufMapDecoder) {
member.getAttribute().set(result, ((ProtobufMapDecoder) decoder).convertFrom(in, member));
} else {
member.read(in, result);
}
}
}
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package org.redkale.convert.proto;
import java.lang.reflect.Type;
import org.redkale.convert.*;
import org.redkale.util.Attribute;
import org.redkale.util.Utility;
/**
* @author zhangjx
* @param <T> T
*/
public class ProtobufObjectDecoder<T> extends ObjectDecoder<ProtobufReader, T> {
protected ProtobufObjectDecoder(Type type) {
super(type);
}
@Override
protected void initForEachDeMember(ConvertFactory factory, DeMember member) {
if (member.getIndex() < 1) {
throw new ConvertException(Utility.orElse(member.getField(), member.getMethod()) + " not found @"
+ ConvertColumn.class.getSimpleName() + ".index");
}
Attribute attr = member.getAttribute();
setTag(
member,
ProtobufFactory.getTag(
attr.field(),
attr.genericType(),
member.getPosition(),
((ProtobufFactory) factory).enumtostring));
}
@Override
protected ProtobufReader objectReader(ProtobufReader in) {
if (in.position() > in.initoffset) return new ProtobufReader(in.readByteArray());
return in;
}
@Override
protected boolean hasNext(ProtobufReader in, boolean first) {
return in.hasNext();
}
@Override
protected Object readDeMemberValue(ProtobufReader in, DeMember member, boolean first) {
Decodeable decoder = member.getDecoder();
if (decoder instanceof ProtobufArrayDecoder) {
return ((ProtobufArrayDecoder) decoder).convertFrom(in, member);
} else if (decoder instanceof ProtobufCollectionDecoder) {
return ((ProtobufCollectionDecoder) decoder).convertFrom(in, member);
} else if (decoder instanceof ProtobufStreamDecoder) {
return ((ProtobufStreamDecoder) decoder).convertFrom(in, member);
} else if (decoder instanceof ProtobufMapDecoder) {
return ((ProtobufMapDecoder) decoder).convertFrom(in, member);
} else {
return member.read(in);
}
}
@Override
protected void readDeMemberValue(ProtobufReader in, DeMember member, T result, boolean first) {
Decodeable decoder = member.getDecoder();
if (decoder instanceof ProtobufArrayDecoder) {
member.getAttribute().set(result, ((ProtobufArrayDecoder) decoder).convertFrom(in, member));
} else if (decoder instanceof ProtobufCollectionDecoder) {
member.getAttribute().set(result, ((ProtobufCollectionDecoder) decoder).convertFrom(in, member));
} else if (decoder instanceof ProtobufStreamDecoder) {
member.getAttribute().set(result, ((ProtobufStreamDecoder) decoder).convertFrom(in, member));
} else if (decoder instanceof ProtobufMapDecoder) {
member.getAttribute().set(result, ((ProtobufMapDecoder) decoder).convertFrom(in, member));
} else {
member.read(in, result);
}
}
}

View File

@@ -1,43 +1,43 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package org.redkale.convert.proto;
import java.lang.reflect.Type;
import org.redkale.convert.*;
import org.redkale.util.Attribute;
import org.redkale.util.Utility;
/** @author zhangjx */
public class ProtobufObjectEncoder<T> extends ObjectEncoder<ProtobufWriter, T> {
protected ProtobufObjectEncoder(Type type) {
super(type);
}
@Override
protected void initForEachEnMember(ConvertFactory factory, EnMember member) {
if (member.getIndex() < 1) {
throw new ConvertException(Utility.orElse(member.getField(), member.getMethod()) + " not found @"
+ ConvertColumn.class.getSimpleName() + ".index");
}
Attribute attr = member.getAttribute();
setTag(
member,
ProtobufFactory.getTag(
attr.field(),
attr.genericType(),
member.getPosition(),
((ProtobufFactory) factory).enumtostring));
}
@Override
protected ProtobufWriter objectWriter(ProtobufWriter out, T value) {
if (out.count() > out.initOffset) {
return new ProtobufWriter(out, out.getFeatures()).configFieldFunc(out);
}
return out;
}
}
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package org.redkale.convert.proto;
import java.lang.reflect.Type;
import org.redkale.convert.*;
import org.redkale.util.Attribute;
import org.redkale.util.Utility;
/** @author zhangjx */
public class ProtobufObjectEncoder<T> extends ObjectEncoder<ProtobufWriter, T> {
protected ProtobufObjectEncoder(Type type) {
super(type);
}
@Override
protected void initForEachEnMember(ConvertFactory factory, EnMember member) {
if (member.getIndex() < 1) {
throw new ConvertException(Utility.orElse(member.getField(), member.getMethod()) + " not found @"
+ ConvertColumn.class.getSimpleName() + ".index");
}
Attribute attr = member.getAttribute();
setTag(
member,
ProtobufFactory.getTag(
attr.field(),
attr.genericType(),
member.getPosition(),
((ProtobufFactory) factory).enumtostring));
}
@Override
protected ProtobufWriter objectWriter(ProtobufWriter out, T value) {
if (out.count() > out.initOffset) {
return new ProtobufWriter(out, out.getFeatures()).configFieldFunc(out);
}
return out;
}
}

View File

@@ -1,449 +1,449 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package org.redkale.convert.proto;
import java.lang.reflect.Type;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.concurrent.atomic.*;
import org.redkale.convert.*;
import org.redkale.util.ObjectPool;
/** @author zhangjx */
public class ProtobufReader extends Reader {
protected int position = -1;
protected int initoffset;
private byte[] content;
protected int cachetag = Integer.MIN_VALUE;
protected boolean enumtostring;
public static ObjectPool<ProtobufReader> createPool(int max) {
return ObjectPool.createSafePool(max, (Object... params) -> new ProtobufReader(), null, (t) -> t.recycle());
}
public ProtobufReader() {}
public ProtobufReader(byte[] bytes) {
setBytes(bytes, 0, bytes.length);
}
public ProtobufReader(byte[] bytes, int start, int len) {
setBytes(bytes, start, len);
}
public ProtobufReader enumtostring(boolean enumtostring) {
this.enumtostring = enumtostring;
return this;
}
@Override
public void prepare(byte[] bytes) {
setBytes(bytes);
}
public final void setBytes(byte[] bytes) {
if (bytes == null) {
this.position = 0;
this.initoffset = 0;
} else {
setBytes(bytes, 0, bytes.length);
}
}
public final void setBytes(byte[] bytes, int start, int len) {
if (bytes == null) {
this.position = 0;
this.initoffset = 0;
} else {
this.content = bytes;
this.position = start - 1;
this.initoffset = this.position;
}
}
protected boolean recycle() {
this.position = -1;
this.initoffset = -1;
this.content = null;
return true;
}
public ProtobufReader clear() {
this.recycle();
return this;
}
public byte[] remainBytes() {
if (this.position >= this.content.length) {
return new byte[0];
}
return Arrays.copyOfRange(this.content, this.position + 1, this.content.length);
}
/** 跳过属性的值 */
@Override
@SuppressWarnings("unchecked")
public final void skipValue() {
int tag = readTag();
if (tag == 0) {
return;
}
switch (tag & 0x7) {
case 0:
readRawVarint32();
break;
case 1:
readRawLittleEndian64();
break;
case 2:
readByteArray();
break;
case 5:
readRawLittleEndian32();
break;
}
}
@Override
public final String readObjectB(final Class clazz) {
return (this.position + 1) < this.content.length ? "" : null;
}
@Override
public final void readObjectE(final Class clazz) {
// do nothing
}
@Override
public final int readMapB(DeMember member, byte[] typevals, Decodeable keyDecoder, Decodeable valueDecoder) {
return Reader.SIGN_NOLENGTH;
}
@Override
public final void readMapE() {
// do nothing
}
/**
* 判断下一个非空白字符是否为[
*
* @param member DeMember
* @param typevals byte[]
* @param componentDecoder Decodeable
* @return SIGN_NOLENGTH 或 SIGN_NULL
*/
@Override
public final int readArrayB(DeMember member, byte[] typevals, Decodeable componentDecoder) {
if (member == null || componentDecoder == null) {
return Reader.SIGN_NOLENBUTBYTES;
}
Type type = componentDecoder.getType();
if (!(type instanceof Class)) {
return Reader.SIGN_NOLENBUTBYTES;
}
Class clazz = (Class) type;
if (clazz.isPrimitive()
|| clazz == Boolean.class
|| clazz == Byte.class
|| clazz == Short.class
|| clazz == Character.class
|| clazz == Integer.class
|| clazz == Float.class
|| clazz == Long.class
|| clazz == Double.class
|| clazz == AtomicInteger.class
|| clazz == AtomicLong.class) {
return Reader.SIGN_NOLENBUTBYTES;
}
return Reader.SIGN_NOLENGTH;
}
@Override
public final void readArrayE() {
// do nothing
}
/** 判断下一个非空白字节是否: */
@Override
public final void readBlank() {
// do nothing
}
@Override
public final int position() {
return this.position;
}
@Override
public final int readMemberContentLength(DeMember member, Decodeable decoder) {
if (member == null && decoder == null) {
return -1; // 为byte[]
}
if (member != null) {
if (member.getDecoder() instanceof ProtobufArrayDecoder) {
ProtobufArrayDecoder pdecoder = (ProtobufArrayDecoder) member.getDecoder();
if (pdecoder.simple) {
return readRawVarint32();
}
} else if (member.getDecoder() instanceof ProtobufCollectionDecoder) {
ProtobufCollectionDecoder pdecoder = (ProtobufCollectionDecoder) member.getDecoder();
if (pdecoder.simple) {
return readRawVarint32();
}
} else if (member.getDecoder() instanceof ProtobufStreamDecoder) {
ProtobufStreamDecoder pdecoder = (ProtobufStreamDecoder) member.getDecoder();
if (pdecoder.simple) {
return readRawVarint32();
}
}
return -1;
}
return readRawVarint32(); // readUInt32
}
@Override
public final DeMember readFieldName(
final DeMember[] members, Map<String, DeMember> memberFieldMap, Map<Integer, DeMember> memberTagMap) {
int tag = readTag();
for (DeMember member : members) {
if (member.getTag() == tag) {
return member;
}
}
backTag(tag);
return null;
}
// ------------------------------------------------------------
@Override
public final boolean readBoolean() {
return readRawVarint64() != 0;
}
@Override
public final byte readByte() {
return (byte) readInt();
}
@Override
public final char readChar() {
return (char) readInt();
}
@Override
public final short readShort() {
return (short) readInt();
}
@Override
public final int readInt() { // readSInt32
int n = readRawVarint32();
return (n >>> 1) ^ -(n & 1);
}
@Override
public final long readLong() { // readSInt64
long n = readRawVarint64();
return (n >>> 1) ^ -(n & 1);
}
@Override
public final float readFloat() {
return Float.intBitsToFloat(readRawLittleEndian32());
}
@Override
public final double readDouble() {
return Double.longBitsToDouble(readRawLittleEndian64());
}
@Override
public final String readClassName() {
return "";
}
@Override
public final String readSmallString() {
return readString();
}
@Override
public final String readString() {
return new String(readByteArray(), StandardCharsets.UTF_8);
}
protected final int readTag() {
if (cachetag != Integer.MIN_VALUE) {
int tag = cachetag;
cachetag = Integer.MIN_VALUE;
return tag;
}
return readRawVarint32();
}
protected final void backTag(int tag) {
this.cachetag = tag;
}
protected byte currentByte() {
return this.content[this.position];
}
/**
* 判断对象是否存在下一个属性或者数组是否存在下一个元素
*
* @param startPosition 起始位置
* @param contentLength 内容大小, 不确定的传-1
* @return 是否存在
*/
@Override
public boolean hasNext(int startPosition, int contentLength) {
// ("-------------: " + startPosition + ", " + contentLength + ", " + this.position);
if (startPosition >= 0 && contentLength >= 0) {
return (this.position) < (startPosition + contentLength);
}
return (this.position + 1) < this.content.length;
}
@Override
public byte[] readByteArray() {
final int size = readRawVarint32();
byte[] bs = new byte[size];
System.arraycopy(content, position + 1, bs, 0, size);
position += size;
return bs;
}
protected int readRawVarint32() { // readUInt32
fastpath:
{
int tempPos = this.position;
if ((tempPos + 1) == content.length) {
break fastpath;
}
int x;
if ((x = content[++tempPos]) >= 0) {
this.position = tempPos;
return x;
} else if (content.length - (tempPos + 1) < 9) {
break fastpath;
} else if ((x ^= (content[++tempPos] << 7)) < 0) {
x ^= (~0 << 7);
} else if ((x ^= (content[++tempPos] << 14)) >= 0) {
x ^= (~0 << 7) ^ (~0 << 14);
} else if ((x ^= (content[++tempPos] << 21)) < 0) {
x ^= (~0 << 7) ^ (~0 << 14) ^ (~0 << 21);
} else {
int y = content[++tempPos];
x ^= y << 28;
x ^= (~0 << 7) ^ (~0 << 14) ^ (~0 << 21) ^ (~0 << 28);
if (y < 0
&& content[++tempPos] < 0
&& content[++tempPos] < 0
&& content[++tempPos] < 0
&& content[++tempPos] < 0
&& content[++tempPos] < 0) {
break fastpath; // Will throw malformedVarint()
}
}
this.position = tempPos;
return x;
}
return (int) readRawVarint64SlowPath();
}
protected long readRawVarint64() {
fastpath:
{
int tempPos = this.position;
if ((tempPos + 1) == content.length) {
break fastpath;
}
long x;
int y;
if ((y = content[++tempPos]) >= 0) {
this.position = tempPos;
return y;
} else if (content.length - (tempPos + 1) < 9) {
break fastpath;
} else if ((y ^= (content[++tempPos] << 7)) < 0) {
x = y ^ (~0 << 7);
} else if ((y ^= (content[++tempPos] << 14)) >= 0) {
x = y ^ ((~0 << 7) ^ (~0 << 14));
} else if ((y ^= (content[++tempPos] << 21)) < 0) {
x = y ^ ((~0 << 7) ^ (~0 << 14) ^ (~0 << 21));
} else if ((x = y ^ ((long) content[++tempPos] << 28)) >= 0L) {
x ^= (~0L << 7) ^ (~0L << 14) ^ (~0L << 21) ^ (~0L << 28);
} else if ((x ^= ((long) content[++tempPos] << 35)) < 0L) {
x ^= (~0L << 7) ^ (~0L << 14) ^ (~0L << 21) ^ (~0L << 28) ^ (~0L << 35);
} else if ((x ^= ((long) content[++tempPos] << 42)) >= 0L) {
x ^= (~0L << 7) ^ (~0L << 14) ^ (~0L << 21) ^ (~0L << 28) ^ (~0L << 35) ^ (~0L << 42);
} else if ((x ^= ((long) content[++tempPos] << 49)) < 0L) {
x ^= (~0L << 7) ^ (~0L << 14) ^ (~0L << 21) ^ (~0L << 28) ^ (~0L << 35) ^ (~0L << 42) ^ (~0L << 49);
} else {
x ^= ((long) content[++tempPos] << 56);
x ^= (~0L << 7)
^ (~0L << 14)
^ (~0L << 21)
^ (~0L << 28)
^ (~0L << 35)
^ (~0L << 42)
^ (~0L << 49)
^ (~0L << 56);
if (x < 0L) {
if (content[++tempPos] < 0L) {
break fastpath; // Will throw malformedVarint()
}
}
}
this.position = tempPos;
return x;
}
return readRawVarint64SlowPath();
}
protected long readRawVarint64SlowPath() {
long result = 0;
for (int shift = 0; shift < 64; shift += 7) {
final byte b = content[++this.position];
result |= (long) (b & 0x7F) << shift;
if ((b & 0x80) == 0) {
return result;
}
}
throw new ConvertException("readRawVarint64SlowPath error");
}
protected int readRawLittleEndian32() {
return ((content[++this.position] & 0xff)
| ((content[++this.position] & 0xff) << 8)
| ((content[++this.position] & 0xff) << 16)
| ((content[++this.position] & 0xff) << 24));
}
protected long readRawLittleEndian64() {
return ((content[++this.position] & 0xffL)
| ((content[++this.position] & 0xffL) << 8)
| ((content[++this.position] & 0xffL) << 16)
| ((content[++this.position] & 0xffL) << 24)
| ((content[++this.position] & 0xffL) << 32)
| ((content[++this.position] & 0xffL) << 40)
| ((content[++this.position] & 0xffL) << 48)
| ((content[++this.position] & 0xffL) << 56));
}
@Override
public ValueType readType() {
throw new UnsupportedOperationException("Not supported yet.");
}
}
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package org.redkale.convert.proto;
import java.lang.reflect.Type;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.concurrent.atomic.*;
import org.redkale.convert.*;
import org.redkale.util.ObjectPool;
/** @author zhangjx */
public class ProtobufReader extends Reader {
protected int position = -1;
protected int initoffset;
private byte[] content;
protected int cachetag = Integer.MIN_VALUE;
protected boolean enumtostring;
public static ObjectPool<ProtobufReader> createPool(int max) {
return ObjectPool.createSafePool(max, (Object... params) -> new ProtobufReader(), null, (t) -> t.recycle());
}
public ProtobufReader() {}
public ProtobufReader(byte[] bytes) {
setBytes(bytes, 0, bytes.length);
}
public ProtobufReader(byte[] bytes, int start, int len) {
setBytes(bytes, start, len);
}
public ProtobufReader enumtostring(boolean enumtostring) {
this.enumtostring = enumtostring;
return this;
}
@Override
public void prepare(byte[] bytes) {
setBytes(bytes);
}
public final void setBytes(byte[] bytes) {
if (bytes == null) {
this.position = 0;
this.initoffset = 0;
} else {
setBytes(bytes, 0, bytes.length);
}
}
public final void setBytes(byte[] bytes, int start, int len) {
if (bytes == null) {
this.position = 0;
this.initoffset = 0;
} else {
this.content = bytes;
this.position = start - 1;
this.initoffset = this.position;
}
}
protected boolean recycle() {
this.position = -1;
this.initoffset = -1;
this.content = null;
return true;
}
public ProtobufReader clear() {
this.recycle();
return this;
}
public byte[] remainBytes() {
if (this.position >= this.content.length) {
return new byte[0];
}
return Arrays.copyOfRange(this.content, this.position + 1, this.content.length);
}
/** 跳过属性的值 */
@Override
@SuppressWarnings("unchecked")
public final void skipValue() {
int tag = readTag();
if (tag == 0) {
return;
}
switch (tag & 0x7) {
case 0:
readRawVarint32();
break;
case 1:
readRawLittleEndian64();
break;
case 2:
readByteArray();
break;
case 5:
readRawLittleEndian32();
break;
}
}
@Override
public final String readObjectB(final Class clazz) {
return (this.position + 1) < this.content.length ? "" : null;
}
@Override
public final void readObjectE(final Class clazz) {
// do nothing
}
@Override
public final int readMapB(DeMember member, byte[] typevals, Decodeable keyDecoder, Decodeable valueDecoder) {
return Reader.SIGN_NOLENGTH;
}
@Override
public final void readMapE() {
// do nothing
}
/**
* 判断下一个非空白字符是否为[
*
* @param member DeMember
* @param typevals byte[]
* @param componentDecoder Decodeable
* @return SIGN_NOLENGTH 或 SIGN_NULL
*/
@Override
public final int readArrayB(DeMember member, byte[] typevals, Decodeable componentDecoder) {
if (member == null || componentDecoder == null) {
return Reader.SIGN_NOLENBUTBYTES;
}
Type type = componentDecoder.getType();
if (!(type instanceof Class)) {
return Reader.SIGN_NOLENBUTBYTES;
}
Class clazz = (Class) type;
if (clazz.isPrimitive()
|| clazz == Boolean.class
|| clazz == Byte.class
|| clazz == Short.class
|| clazz == Character.class
|| clazz == Integer.class
|| clazz == Float.class
|| clazz == Long.class
|| clazz == Double.class
|| clazz == AtomicInteger.class
|| clazz == AtomicLong.class) {
return Reader.SIGN_NOLENBUTBYTES;
}
return Reader.SIGN_NOLENGTH;
}
@Override
public final void readArrayE() {
// do nothing
}
/** 判断下一个非空白字节是否: */
@Override
public final void readBlank() {
// do nothing
}
@Override
public final int position() {
return this.position;
}
@Override
public final int readMemberContentLength(DeMember member, Decodeable decoder) {
if (member == null && decoder == null) {
return -1; // 为byte[]
}
if (member != null) {
if (member.getDecoder() instanceof ProtobufArrayDecoder) {
ProtobufArrayDecoder pdecoder = (ProtobufArrayDecoder) member.getDecoder();
if (pdecoder.simple) {
return readRawVarint32();
}
} else if (member.getDecoder() instanceof ProtobufCollectionDecoder) {
ProtobufCollectionDecoder pdecoder = (ProtobufCollectionDecoder) member.getDecoder();
if (pdecoder.simple) {
return readRawVarint32();
}
} else if (member.getDecoder() instanceof ProtobufStreamDecoder) {
ProtobufStreamDecoder pdecoder = (ProtobufStreamDecoder) member.getDecoder();
if (pdecoder.simple) {
return readRawVarint32();
}
}
return -1;
}
return readRawVarint32(); // readUInt32
}
@Override
public final DeMember readFieldName(
final DeMember[] members, Map<String, DeMember> memberFieldMap, Map<Integer, DeMember> memberTagMap) {
int tag = readTag();
for (DeMember member : members) {
if (member.getTag() == tag) {
return member;
}
}
backTag(tag);
return null;
}
// ------------------------------------------------------------
@Override
public final boolean readBoolean() {
return readRawVarint64() != 0;
}
@Override
public final byte readByte() {
return (byte) readInt();
}
@Override
public final char readChar() {
return (char) readInt();
}
@Override
public final short readShort() {
return (short) readInt();
}
@Override
public final int readInt() { // readSInt32
int n = readRawVarint32();
return (n >>> 1) ^ -(n & 1);
}
@Override
public final long readLong() { // readSInt64
long n = readRawVarint64();
return (n >>> 1) ^ -(n & 1);
}
@Override
public final float readFloat() {
return Float.intBitsToFloat(readRawLittleEndian32());
}
@Override
public final double readDouble() {
return Double.longBitsToDouble(readRawLittleEndian64());
}
@Override
public final String readClassName() {
return "";
}
@Override
public final String readSmallString() {
return readString();
}
@Override
public final String readString() {
return new String(readByteArray(), StandardCharsets.UTF_8);
}
protected final int readTag() {
if (cachetag != Integer.MIN_VALUE) {
int tag = cachetag;
cachetag = Integer.MIN_VALUE;
return tag;
}
return readRawVarint32();
}
protected final void backTag(int tag) {
this.cachetag = tag;
}
protected byte currentByte() {
return this.content[this.position];
}
/**
* 判断对象是否存在下一个属性或者数组是否存在下一个元素
*
* @param startPosition 起始位置
* @param contentLength 内容大小, 不确定的传-1
* @return 是否存在
*/
@Override
public boolean hasNext(int startPosition, int contentLength) {
// ("-------------: " + startPosition + ", " + contentLength + ", " + this.position);
if (startPosition >= 0 && contentLength >= 0) {
return (this.position) < (startPosition + contentLength);
}
return (this.position + 1) < this.content.length;
}
@Override
public byte[] readByteArray() {
final int size = readRawVarint32();
byte[] bs = new byte[size];
System.arraycopy(content, position + 1, bs, 0, size);
position += size;
return bs;
}
protected int readRawVarint32() { // readUInt32
fastpath:
{
int tempPos = this.position;
if ((tempPos + 1) == content.length) {
break fastpath;
}
int x;
if ((x = content[++tempPos]) >= 0) {
this.position = tempPos;
return x;
} else if (content.length - (tempPos + 1) < 9) {
break fastpath;
} else if ((x ^= (content[++tempPos] << 7)) < 0) {
x ^= (~0 << 7);
} else if ((x ^= (content[++tempPos] << 14)) >= 0) {
x ^= (~0 << 7) ^ (~0 << 14);
} else if ((x ^= (content[++tempPos] << 21)) < 0) {
x ^= (~0 << 7) ^ (~0 << 14) ^ (~0 << 21);
} else {
int y = content[++tempPos];
x ^= y << 28;
x ^= (~0 << 7) ^ (~0 << 14) ^ (~0 << 21) ^ (~0 << 28);
if (y < 0
&& content[++tempPos] < 0
&& content[++tempPos] < 0
&& content[++tempPos] < 0
&& content[++tempPos] < 0
&& content[++tempPos] < 0) {
break fastpath; // Will throw malformedVarint()
}
}
this.position = tempPos;
return x;
}
return (int) readRawVarint64SlowPath();
}
protected long readRawVarint64() {
fastpath:
{
int tempPos = this.position;
if ((tempPos + 1) == content.length) {
break fastpath;
}
long x;
int y;
if ((y = content[++tempPos]) >= 0) {
this.position = tempPos;
return y;
} else if (content.length - (tempPos + 1) < 9) {
break fastpath;
} else if ((y ^= (content[++tempPos] << 7)) < 0) {
x = y ^ (~0 << 7);
} else if ((y ^= (content[++tempPos] << 14)) >= 0) {
x = y ^ ((~0 << 7) ^ (~0 << 14));
} else if ((y ^= (content[++tempPos] << 21)) < 0) {
x = y ^ ((~0 << 7) ^ (~0 << 14) ^ (~0 << 21));
} else if ((x = y ^ ((long) content[++tempPos] << 28)) >= 0L) {
x ^= (~0L << 7) ^ (~0L << 14) ^ (~0L << 21) ^ (~0L << 28);
} else if ((x ^= ((long) content[++tempPos] << 35)) < 0L) {
x ^= (~0L << 7) ^ (~0L << 14) ^ (~0L << 21) ^ (~0L << 28) ^ (~0L << 35);
} else if ((x ^= ((long) content[++tempPos] << 42)) >= 0L) {
x ^= (~0L << 7) ^ (~0L << 14) ^ (~0L << 21) ^ (~0L << 28) ^ (~0L << 35) ^ (~0L << 42);
} else if ((x ^= ((long) content[++tempPos] << 49)) < 0L) {
x ^= (~0L << 7) ^ (~0L << 14) ^ (~0L << 21) ^ (~0L << 28) ^ (~0L << 35) ^ (~0L << 42) ^ (~0L << 49);
} else {
x ^= ((long) content[++tempPos] << 56);
x ^= (~0L << 7)
^ (~0L << 14)
^ (~0L << 21)
^ (~0L << 28)
^ (~0L << 35)
^ (~0L << 42)
^ (~0L << 49)
^ (~0L << 56);
if (x < 0L) {
if (content[++tempPos] < 0L) {
break fastpath; // Will throw malformedVarint()
}
}
}
this.position = tempPos;
return x;
}
return readRawVarint64SlowPath();
}
protected long readRawVarint64SlowPath() {
long result = 0;
for (int shift = 0; shift < 64; shift += 7) {
final byte b = content[++this.position];
result |= (long) (b & 0x7F) << shift;
if ((b & 0x80) == 0) {
return result;
}
}
throw new ConvertException("readRawVarint64SlowPath error");
}
protected int readRawLittleEndian32() {
return ((content[++this.position] & 0xff)
| ((content[++this.position] & 0xff) << 8)
| ((content[++this.position] & 0xff) << 16)
| ((content[++this.position] & 0xff) << 24));
}
protected long readRawLittleEndian64() {
return ((content[++this.position] & 0xffL)
| ((content[++this.position] & 0xffL) << 8)
| ((content[++this.position] & 0xffL) << 16)
| ((content[++this.position] & 0xffL) << 24)
| ((content[++this.position] & 0xffL) << 32)
| ((content[++this.position] & 0xffL) << 40)
| ((content[++this.position] & 0xffL) << 48)
| ((content[++this.position] & 0xffL) << 56));
}
@Override
public ValueType readType() {
throw new UnsupportedOperationException("Not supported yet.");
}
}

View File

@@ -1,45 +1,45 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package org.redkale.convert.proto;
import java.lang.reflect.Type;
import java.util.concurrent.atomic.*;
import org.redkale.convert.*;
/**
* @author zhangjx
* @param <T> 泛型
*/
public class ProtobufStreamDecoder<T> extends StreamDecoder<T> {
protected final boolean simple;
private final boolean string;
private final boolean enumtostring;
public ProtobufStreamDecoder(ConvertFactory factory, Type type) {
super(factory, type);
this.enumtostring = ((ProtobufFactory) factory).enumtostring;
Type comtype = this.getComponentType();
this.string = String.class == comtype;
this.simple = Boolean.class == comtype
|| Short.class == comtype
|| Character.class == comtype
|| Integer.class == comtype
|| Float.class == comtype
|| Long.class == comtype
|| Double.class == comtype
|| AtomicInteger.class == comtype
|| AtomicLong.class == comtype;
}
@Override
protected Reader getItemReader(Reader in, DeMember member, boolean first) {
if (simple) return in;
return ProtobufFactory.getItemReader(string, simple, in, member, enumtostring, first);
}
}
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package org.redkale.convert.proto;
import java.lang.reflect.Type;
import java.util.concurrent.atomic.*;
import org.redkale.convert.*;
/**
* @author zhangjx
* @param <T> 泛型
*/
public class ProtobufStreamDecoder<T> extends StreamDecoder<T> {
protected final boolean simple;
private final boolean string;
private final boolean enumtostring;
public ProtobufStreamDecoder(ConvertFactory factory, Type type) {
super(factory, type);
this.enumtostring = ((ProtobufFactory) factory).enumtostring;
Type comtype = this.getComponentType();
this.string = String.class == comtype;
this.simple = Boolean.class == comtype
|| Short.class == comtype
|| Character.class == comtype
|| Integer.class == comtype
|| Float.class == comtype
|| Long.class == comtype
|| Double.class == comtype
|| AtomicInteger.class == comtype
|| AtomicLong.class == comtype;
}
@Override
protected Reader getItemReader(Reader in, DeMember member, boolean first) {
if (simple) return in;
return ProtobufFactory.getItemReader(string, simple, in, member, enumtostring, first);
}
}

View File

@@ -1,55 +1,55 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package org.redkale.convert.proto;
import java.lang.reflect.Type;
import java.util.concurrent.atomic.*;
import org.redkale.convert.*;
/**
* @author zhangjx
* @param <T> T
*/
public class ProtobufStreamEncoder<T> extends StreamEncoder<T> {
protected final boolean simple;
public ProtobufStreamEncoder(ConvertFactory factory, Type type) {
super(factory, type);
Type comtype = this.getComponentType();
this.simple = Boolean.class == comtype
|| Short.class == comtype
|| Character.class == comtype
|| Integer.class == comtype
|| Float.class == comtype
|| Long.class == comtype
|| Double.class == comtype
|| AtomicInteger.class == comtype
|| AtomicLong.class == comtype;
}
@Override
protected void writeMemberValue(Writer out, EnMember member, Object item, boolean first) {
if (simple) {
if (item == null) {
((ProtobufWriter) out).writeUInt32(0);
} else {
componentEncoder.convertTo(out, item);
}
return;
}
if (member != null) out.writeFieldName(member);
if (item instanceof CharSequence) {
componentEncoder.convertTo(out, item);
} else {
ProtobufWriter tmp = new ProtobufWriter().configFieldFunc(out);
componentEncoder.convertTo(tmp, item);
int length = tmp.count();
((ProtobufWriter) out).writeUInt32(length);
((ProtobufWriter) out).writeTo(tmp.toArray());
}
}
}
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package org.redkale.convert.proto;
import java.lang.reflect.Type;
import java.util.concurrent.atomic.*;
import org.redkale.convert.*;
/**
* @author zhangjx
* @param <T> T
*/
public class ProtobufStreamEncoder<T> extends StreamEncoder<T> {
protected final boolean simple;
public ProtobufStreamEncoder(ConvertFactory factory, Type type) {
super(factory, type);
Type comtype = this.getComponentType();
this.simple = Boolean.class == comtype
|| Short.class == comtype
|| Character.class == comtype
|| Integer.class == comtype
|| Float.class == comtype
|| Long.class == comtype
|| Double.class == comtype
|| AtomicInteger.class == comtype
|| AtomicLong.class == comtype;
}
@Override
protected void writeMemberValue(Writer out, EnMember member, Object item, boolean first) {
if (simple) {
if (item == null) {
((ProtobufWriter) out).writeUInt32(0);
} else {
componentEncoder.convertTo(out, item);
}
return;
}
if (member != null) out.writeFieldName(member);
if (item instanceof CharSequence) {
componentEncoder.convertTo(out, item);
} else {
ProtobufWriter tmp = new ProtobufWriter().configFieldFunc(out);
componentEncoder.convertTo(tmp, item);
int length = tmp.count();
((ProtobufWriter) out).writeUInt32(length);
((ProtobufWriter) out).writeTo(tmp.toArray());
}
}
}

View File

@@ -1,50 +1,50 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package org.redkale.convert.proto;
import java.io.*;
import org.redkale.convert.*;
/**
* 详情见: https://redkale.org
*
* @author zhangjx
*/
class ProtobufStreamReader extends ProtobufByteBufferReader {
private InputStream in;
private byte currByte;
protected ProtobufStreamReader(InputStream in) {
super();
this.in = in;
}
@Override
protected boolean recycle() {
super.recycle(); // this.position 初始化值为-1
this.in = null;
this.currByte = 0;
return false;
}
@Override
public byte nextByte() {
try {
byte b = (currByte = (byte) in.read());
this.position++;
return b;
} catch (IOException e) {
throw new ConvertException(e);
}
}
@Override
protected byte currentByte() {
return currByte;
}
}
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package org.redkale.convert.proto;
import java.io.*;
import org.redkale.convert.*;
/**
* 详情见: https://redkale.org
*
* @author zhangjx
*/
class ProtobufStreamReader extends ProtobufByteBufferReader {
private InputStream in;
private byte currByte;
protected ProtobufStreamReader(InputStream in) {
super();
this.in = in;
}
@Override
protected boolean recycle() {
super.recycle(); // this.position 初始化值为-1
this.in = null;
this.currByte = 0;
return false;
}
@Override
public byte nextByte() {
try {
byte b = (currByte = (byte) in.read());
this.position++;
return b;
} catch (IOException e) {
throw new ConvertException(e);
}
}
@Override
protected byte currentByte() {
return currByte;
}
}

View File

@@ -1,49 +1,49 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package org.redkale.convert.proto;
import java.io.*;
import org.redkale.convert.ConvertException;
/**
* 详情见: https://redkale.org
*
* @author zhangjx
*/
class ProtobufStreamWriter extends ProtobufByteBufferWriter {
private OutputStream out;
protected ProtobufStreamWriter(int features, boolean enumtostring, OutputStream out) {
super(features, enumtostring, null);
this.out = out;
}
@Override
protected boolean recycle() {
super.recycle();
this.out = null;
return false;
}
@Override
public void writeTo(final byte[] chs, final int start, final int len) {
try {
out.write(chs, start, len);
} catch (IOException e) {
throw new ConvertException(e);
}
}
@Override
public void writeTo(final byte ch) {
try {
out.write((byte) ch);
} catch (IOException e) {
throw new ConvertException(e);
}
}
}
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package org.redkale.convert.proto;
import java.io.*;
import org.redkale.convert.ConvertException;
/**
* 详情见: https://redkale.org
*
* @author zhangjx
*/
class ProtobufStreamWriter extends ProtobufByteBufferWriter {
private OutputStream out;
protected ProtobufStreamWriter(int features, boolean enumtostring, OutputStream out) {
super(features, enumtostring, null);
this.out = out;
}
@Override
protected boolean recycle() {
super.recycle();
this.out = null;
return false;
}
@Override
public void writeTo(final byte[] chs, final int start, final int len) {
try {
out.write(chs, start, len);
} catch (IOException e) {
throw new ConvertException(e);
}
}
@Override
public void writeTo(final byte ch) {
try {
out.write((byte) ch);
} catch (IOException e) {
throw new ConvertException(e);
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,29 +1,29 @@
/*
*
*/
package org.redkale.inject;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
/**
* 自定义注入加载器
*
* <p>详情见: https://redkale.org
*
* @since 2.8.0
* @author zhangjx
* @param <T> Annotation
*/
public interface ResourceAnnotationLoader<T extends Annotation> {
public void load(
ResourceFactory factory,
String srcResourceName,
Object srcObj,
T annotation,
Field field,
Object attachment);
public Class<T> annotationType();
}
/*
*
*/
package org.redkale.inject;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
/**
* 自定义注入加载器
*
* <p>详情见: https://redkale.org
*
* @since 2.8.0
* @author zhangjx
* @param <T> Annotation
*/
public interface ResourceAnnotationLoader<T extends Annotation> {
public void load(
ResourceFactory factory,
String srcResourceName,
Object srcObj,
T annotation,
Field field,
Object attachment);
public Class<T> annotationType();
}

View File

@@ -1,16 +1,16 @@
/*
*
*/
package org.redkale.lock;
/**
* //TODO 待实现
*
* <p>锁管理器
*
* <p>详情见: https://redkale.org
*
* @author zhangjx
* @since 2.8.0
*/
public interface LockManager {}
/*
*
*/
package org.redkale.lock;
/**
* //TODO 待实现
*
* <p>锁管理器
*
* <p>详情见: https://redkale.org
*
* @author zhangjx
* @since 2.8.0
*/
public interface LockManager {}

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