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 * ***************************************************************************** Copyright (c) 2008 - 2013 Oracle
* Corporation. All rights reserved. * Corporation. All rights reserved.
* *
* <p>This program and the accompanying materials are made available under the terms of the Eclipse Public License v1.0 * <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 * 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 * at http://www.eclipse.org/legal/epl-v10.html and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php. * http://www.eclipse.org/org/documents/edl-v10.php.
* *
* <p>Contributors: Linda DeMichiel - Java Persistence 2.1 Linda DeMichiel - Java Persistence 2.0 * <p>Contributors: Linda DeMichiel - Java Persistence 2.1 Linda DeMichiel - Java Persistence 2.0
* *
* <p>**************************************************************************** * <p>****************************************************************************
*/ */
package javax.persistence; package javax.persistence;
import static java.lang.annotation.ElementType.*; import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.RUNTIME; import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.*; import java.lang.annotation.*;
/** /**
* Specifies the mapped column for a persistent property or field. If no <code>Column</code> annotation is specified, * Specifies the mapped column for a persistent property or field. If no <code>Column</code> annotation is specified,
* the default values apply. * the default values apply.
* *
* <blockquote> * <blockquote>
* *
* <pre> * <pre>
* Example 1: * Example 1:
* *
* &#064;Column(name="DESC", nullable=false, length=512) * &#064;Column(name="DESC", nullable=false, length=512)
* public String getDescription() { return description; } * public String getDescription() { return description; }
* *
* Example 2: * Example 2:
* *
* &#064;Column(name="DESC", * &#064;Column(name="DESC",
* columnDefinition="CLOB NOT NULL", * columnDefinition="CLOB NOT NULL",
* table="EMP_DETAIL") * table="EMP_DETAIL")
* &#064;Lob * &#064;Lob
* public String getDescription() { return description; } * public String getDescription() { return description; }
* *
* Example 3: * Example 3:
* *
* &#064;Column(name="ORDER_COST", updatable=false, precision=12, scale=2) * &#064;Column(name="ORDER_COST", updatable=false, precision=12, scale=2)
* public BigDecimal getCost() { return cost; } * public BigDecimal getCost() { return cost; }
* *
* </pre> * </pre>
* *
* </blockquote> * </blockquote>
* *
* @since Java Persistence 1.0 * @since Java Persistence 1.0
* @deprecated replace by {@link org.redkale.persistence.Column} * @deprecated replace by {@link org.redkale.persistence.Column}
* @see org.redkale.persistence.Column * @see org.redkale.persistence.Column
*/ */
@Deprecated(since = "2.8.0") @Deprecated(since = "2.8.0")
@Target({METHOD, FIELD}) @Target({METHOD, FIELD})
@Retention(RUNTIME) @Retention(RUNTIME)
public @interface Column { public @interface Column {
/** /**
* (Optional) The name of the column. Defaults to the property or field name. * (Optional) The name of the column. Defaults to the property or field name.
* *
* @return String * @return String
*/ */
String name() default ""; String name() default "";
/** /**
* (Optional) The comment of the column. * (Optional) The comment of the column.
* *
* @return String * @return String
*/ */
String comment() default ""; String comment() default "";
/** /**
* (Optional) Whether the column is a unique key. This is a shortcut for the <code>UniqueConstraint</code> * (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 * 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 * column. This constraint applies in addition to any constraint entailed by primary key mapping and to constraints
* specified at the table level. * specified at the table level.
* *
* @return boolean * @return boolean
*/ */
boolean unique() default false; boolean unique() default false;
/** /**
* (Optional) Whether the database column is required. * (Optional) Whether the database column is required.
* *
* @return boolean * @return boolean
*/ */
boolean nullable() default true; boolean nullable() default true;
/** /**
* for OpenAPI Specification 3 * for OpenAPI Specification 3
* *
* @return String * @return String
*/ */
String example() default ""; String example() default "";
/** /**
* (Optional) Whether the column is included in SQL INSERT statements generated by the persistence provider. * (Optional) Whether the column is included in SQL INSERT statements generated by the persistence provider.
* *
* @return boolean * @return boolean
*/ */
boolean insertable() default true; boolean insertable() default true;
/** /**
* (Optional) Whether the column is included in SQL UPDATE statements generated by the persistence provider. * (Optional) Whether the column is included in SQL UPDATE statements generated by the persistence provider.
* *
* @return boolean * @return boolean
*/ */
boolean updatable() default true; 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 * (Optional) The name of the table that contains the column. If absent the column is assumed to be in the primary
* table. * table.
* *
* @return String * @return String
*/ */
@Deprecated @Deprecated
String table() default ""; String table() default "";
/** /**
* (Optional) The column length. (Applies only if a string-valued column is used.) if type==String and length == * (Optional) The column length. (Applies only if a string-valued column is used.) if type==String and length ==
* 65535 then sqltype is TEXT <br> * 65535 then sqltype is TEXT <br>
* if type==String and length &#60;= 16777215 then sqltype is MEDIUMTEXT <br> * if type==String and length &#60;= 16777215 then sqltype is MEDIUMTEXT <br>
* if type==String and length &#62; 16777215 then sqltype is LONGTEXT <br> * if type==String and length &#62; 16777215 then sqltype is LONGTEXT <br>
* if type==byte[] and length &#60;= 65535 then sqltype is BLOB <br> * if type==byte[] and length &#60;= 65535 then sqltype is BLOB <br>
* if type==byte[] and length &#60;= 16777215 then sqltype is MEDIUMBLOB <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> * if type==byte[] and length &#62; 16777215 then sqltype is LONGBLOB <br>
* *
* @return int * @return int
*/ */
int length() default 255; int length() default 255;
/** /**
* (Optional) The precision for a decimal (exact numeric) column. (Applies only if a decimal column is used.) Value * (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. * must be set by developer if used when generating the DDL for the column.
* *
* @return int * @return int
*/ */
int precision() default 0; int precision() default 0;
/** /**
* (Optional) The scale for a decimal (exact numeric) column. (Applies only if a decimal column is used.) * (Optional) The scale for a decimal (exact numeric) column. (Applies only if a decimal column is used.)
* *
* @return int * @return int
*/ */
int scale() default 0; int scale() default 0;
} }

View File

@@ -1,49 +1,49 @@
/** /**
* ***************************************************************************** Copyright (c) 2008 - 2013 Oracle * ***************************************************************************** Copyright (c) 2008 - 2013 Oracle
* Corporation. All rights reserved. * Corporation. All rights reserved.
* *
* <p>This program and the accompanying materials are made available under the terms of the Eclipse Public License v1.0 * <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 * 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 * at http://www.eclipse.org/legal/epl-v10.html and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php. * http://www.eclipse.org/org/documents/edl-v10.php.
* *
* <p>Contributors: Linda DeMichiel - Java Persistence 2.1 Linda DeMichiel - Java Persistence 2.0 * <p>Contributors: Linda DeMichiel - Java Persistence 2.1 Linda DeMichiel - Java Persistence 2.0
* *
* <p>**************************************************************************** * <p>****************************************************************************
*/ */
package javax.persistence; package javax.persistence;
import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.RetentionPolicy.RUNTIME; import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.*; import java.lang.annotation.*;
/** /**
* Specifies that the class is an entity. This annotation is applied to the entity class. * Specifies that the class is an entity. This annotation is applied to the entity class.
* *
* @since Java Persistence 1.0 * @since Java Persistence 1.0
* @deprecated replace by {@link org.redkale.persistence.Entity} * @deprecated replace by {@link org.redkale.persistence.Entity}
* @see org.redkale.persistence.Entity * @see org.redkale.persistence.Entity
*/ */
@Deprecated(since = "2.8.0") @Deprecated(since = "2.8.0")
@Inherited @Inherited
@Documented @Documented
@Target(TYPE) @Target(TYPE)
@Retention(RUNTIME) @Retention(RUNTIME)
public @interface Entity { public @interface Entity {
/** /**
* (Optional) The entity name. Defaults to the unqualified name of the entity class. This name is used to refer to * (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. * the entity in queries. The name must not be a reserved literal in the Java Persistence query language.
* *
* @return String * @return String
*/ */
String name() default ""; String name() default "";
/** /**
* (Optional) The comment of the entity. * (Optional) The comment of the entity.
* *
* @return String * @return String
*/ */
String comment() default ""; String comment() default "";
} }

View File

@@ -1,46 +1,46 @@
/** /**
* ***************************************************************************** Copyright (c) 2008 - 2013 Oracle * ***************************************************************************** Copyright (c) 2008 - 2013 Oracle
* Corporation. All rights reserved. * Corporation. All rights reserved.
* *
* <p>This program and the accompanying materials are made available under the terms of the Eclipse Public License v1.0 * <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 * 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 * at http://www.eclipse.org/legal/epl-v10.html and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php. * http://www.eclipse.org/org/documents/edl-v10.php.
* *
* <p>Contributors: Linda DeMichiel - Java Persistence 2.1 Linda DeMichiel - Java Persistence 2.0 * <p>Contributors: Linda DeMichiel - Java Persistence 2.1 Linda DeMichiel - Java Persistence 2.0
* *
* <p>**************************************************************************** * <p>****************************************************************************
*/ */
package javax.persistence; package javax.persistence;
import static java.lang.annotation.ElementType.*; import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.RUNTIME; import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.*; import java.lang.annotation.*;
/** /**
* Specifies the primary key of an entity. The field or property to which the <code>Id</code> annotation is applied * 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>; * 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> * <code>java.util.Date</code>; <code>java.sql.Date</code>; <code>java.math.BigDecimal</code>; <code>
* java.math.BigInteger</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 * <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 * <code>Column</code> annotation is specified, the primary key column name is assumed to be the name of the primary key
* property or field. * property or field.
* *
* <pre> * <pre>
* Example: * Example:
* *
* &#064;Id * &#064;Id
* public Long getId() { return id; } * public Long getId() { return id; }
* </pre> * </pre>
* *
* @see Column see GeneratedValue * @see Column see GeneratedValue
* @since Java Persistence 1.0 * @since Java Persistence 1.0
* @deprecated replace by {@link org.redkale.persistence.Id} * @deprecated replace by {@link org.redkale.persistence.Id}
* @see org.redkale.persistence.Id * @see org.redkale.persistence.Id
*/ */
@Deprecated(since = "2.8.0") @Deprecated(since = "2.8.0")
@Target({METHOD, FIELD}) @Target({METHOD, FIELD})
@Retention(RUNTIME) @Retention(RUNTIME)
public @interface Id {} public @interface Id {}

View File

@@ -1,64 +1,64 @@
/** /**
* ***************************************************************************** Copyright (c) 2011 - 2013 Oracle * ***************************************************************************** Copyright (c) 2011 - 2013 Oracle
* Corporation. All rights reserved. * Corporation. All rights reserved.
* *
* <p>This program and the accompanying materials are made available under the terms of the Eclipse Public License v1.0 * <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 * 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 * at http://www.eclipse.org/legal/epl-v10.html and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php. * http://www.eclipse.org/org/documents/edl-v10.php.
* *
* <p>Contributors: Linda DeMichiel - Java Persistence 2.1 * <p>Contributors: Linda DeMichiel - Java Persistence 2.1
* *
* <p>**************************************************************************** * <p>****************************************************************************
*/ */
package javax.persistence; package javax.persistence;
import static java.lang.annotation.RetentionPolicy.RUNTIME; import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.*; import java.lang.annotation.*;
/** /**
* Used in schema generation to specify creation of an index. * Used in schema generation to specify creation of an index.
* *
* <p>Note that it is not necessary to specify an index for a primary key, as the primary key index will be created * <p>Note that it is not necessary to specify an index for a primary key, as the primary key index will be created
* automatically. * automatically.
* *
* <p>The syntax of the <code>columnList</code> element is a <code>column_list</code>, as follows: * <p>The syntax of the <code>columnList</code> element is a <code>column_list</code>, as follows:
* *
* <pre> * <pre>
* column::= index_column [,index_column]* * column::= index_column [,index_column]*
* index_column::= column_name [ASC | DESC] * index_column::= column_name [ASC | DESC]
* </pre> * </pre>
* *
* <p>If <code>ASC</code> or <code>DESC</code> is not specified, <code>ASC</code> (ascending order) is assumed. * <p>If <code>ASC</code> or <code>DESC</code> is not specified, <code>ASC</code> (ascending order) is assumed.
* *
* @since Java Persistence 2.1 * @since Java Persistence 2.1
* @deprecated replace by {@link org.redkale.persistence.Index} * @deprecated replace by {@link org.redkale.persistence.Index}
* @see org.redkale.persistence.Index * @see org.redkale.persistence.Index
*/ */
@Deprecated(since = "2.8.0") @Deprecated(since = "2.8.0")
@Target({}) @Target({})
@Retention(RUNTIME) @Retention(RUNTIME)
public @interface Index { public @interface Index {
/** /**
* (Optional) The name of the index; defaults to a provider-generated name. * (Optional) The name of the index; defaults to a provider-generated name.
* *
* @return String * @return String
*/ */
String name() default ""; String name() default "";
/** /**
* (Required) The names of the columns to be included in the index, in order. * (Required) The names of the columns to be included in the index, in order.
* *
* @return String * @return String
*/ */
String columnList(); String columnList();
/** /**
* (Optional) Whether the index is unique. * (Optional) Whether the index is unique.
* *
* @return boolean * @return boolean
*/ */
boolean unique() default false; boolean unique() default false;
} }

View File

@@ -1,88 +1,88 @@
/** /**
* ***************************************************************************** Copyright (c) 2008 - 2013 Oracle * ***************************************************************************** Copyright (c) 2008 - 2013 Oracle
* Corporation. All rights reserved. * Corporation. All rights reserved.
* *
* <p>This program and the accompanying materials are made available under the terms of the Eclipse Public License v1.0 * <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 * 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 * at http://www.eclipse.org/legal/epl-v10.html and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php. * http://www.eclipse.org/org/documents/edl-v10.php.
* *
* <p>Contributors: Linda DeMichiel - Java Persistence 2.1 Linda DeMichiel - Java Persistence 2.0 * <p>Contributors: Linda DeMichiel - Java Persistence 2.1 Linda DeMichiel - Java Persistence 2.0
* *
* <p>**************************************************************************** * <p>****************************************************************************
*/ */
package javax.persistence; package javax.persistence;
import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.RetentionPolicy.RUNTIME; import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.*; import java.lang.annotation.*;
/** /**
* Specifies the primary table for the annotated entity. Additional tables may be specified using SecondaryTable or * Specifies the primary table for the annotated entity. Additional tables may be specified using SecondaryTable or
* SecondaryTables annotation. * SecondaryTables annotation.
* *
* <p>If no <code>Table</code> annotation is specified for an entity class, the default values apply. * <p>If no <code>Table</code> annotation is specified for an entity class, the default values apply.
* *
* <pre> * <pre>
* Example: * Example:
* *
* &#064;Entity * &#064;Entity
* &#064;Table(name="CUST", schema="RECORDS") * &#064;Table(name="CUST", schema="RECORDS")
* public class Customer { ... } * public class Customer { ... }
* </pre> * </pre>
* *
* @since Java Persistence 1.0 * @since Java Persistence 1.0
* @deprecated replace by {@link org.redkale.persistence.Table} * @deprecated replace by {@link org.redkale.persistence.Table}
* @see org.redkale.persistence.Table * @see org.redkale.persistence.Table
*/ */
@Deprecated(since = "2.8.0") @Deprecated(since = "2.8.0")
@Target(TYPE) @Target(TYPE)
@Retention(RUNTIME) @Retention(RUNTIME)
public @interface Table { public @interface Table {
/** /**
* (Optional) The name of the table. * (Optional) The name of the table.
* *
* <p>Defaults to the entity name. * <p>Defaults to the entity name.
* *
* @return String * @return String
*/ */
String name() default ""; String name() default "";
/** /**
* (Optional) The catalog of the table. * (Optional) The catalog of the table.
* *
* <p>Defaults to the default catalog. * <p>Defaults to the default catalog.
* *
* @return String * @return String
*/ */
String catalog() default ""; String catalog() default "";
/** /**
* (Optional) Unique constraints that are to be placed on the table. These are only used if table generation is in * (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> * 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. * JoinColumn</code> annotations and constraints entailed by primary key mappings.
* *
* <p>Defaults to no additional constraints. * <p>Defaults to no additional constraints.
* *
* @return UniqueConstraint[] * @return UniqueConstraint[]
*/ */
UniqueConstraint[] uniqueConstraints() default {}; UniqueConstraint[] uniqueConstraints() default {};
/** /**
* (Optional) Indexes for the table. These are only used if table generation is in effect. Note that it is not * (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. * necessary to specify an index for a primary key, as the primary key index will be created automatically.
* *
* @return indexes * @return indexes
* @since Java Persistence 2.1 * @since Java Persistence 2.1
*/ */
Index[] indexes() default {}; Index[] indexes() default {};
/** /**
* comment * comment
* *
* @return String * @return String
*/ */
String comment() default ""; String comment() default "";
} }

View File

@@ -1,43 +1,43 @@
/** /**
* ***************************************************************************** Copyright (c) 2008 - 2013 Oracle * ***************************************************************************** Copyright (c) 2008 - 2013 Oracle
* Corporation. All rights reserved. * Corporation. All rights reserved.
* *
* <p>This program and the accompanying materials are made available under the terms of the Eclipse Public License v1.0 * <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 * 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 * at http://www.eclipse.org/legal/epl-v10.html and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php. * http://www.eclipse.org/org/documents/edl-v10.php.
* *
* <p>Contributors: Linda DeMichiel - Java Persistence 2.1 Linda DeMichiel - Java Persistence 2.0 * <p>Contributors: Linda DeMichiel - Java Persistence 2.1 Linda DeMichiel - Java Persistence 2.0
* *
* <p>**************************************************************************** * <p>****************************************************************************
*/ */
package javax.persistence; package javax.persistence;
import static java.lang.annotation.ElementType.*; import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.RUNTIME; import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.*; 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 * 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. * class, mapped superclass, or embeddable class.
* *
* <pre> * <pre>
* Example: * Example:
* *
* &#064;Entity * &#064;Entity
* public class Employee { * public class Employee {
* &#064;Id int id; * &#064;Id int id;
* &#064;Transient User currentUser; * &#064;Transient User currentUser;
* ... * ...
* } * }
* </pre> * </pre>
* *
* @since Java Persistence 1.0 * @since Java Persistence 1.0
* @deprecated replace by {@link org.redkale.persistence.Transient} * @deprecated replace by {@link org.redkale.persistence.Transient}
* @see org.redkale.persistence.Transient * @see org.redkale.persistence.Transient
*/ */
@Deprecated(since = "2.8.0") @Deprecated(since = "2.8.0")
@Target({METHOD, FIELD}) @Target({METHOD, FIELD})
@Retention(RUNTIME) @Retention(RUNTIME)
public @interface Transient {} public @interface Transient {}

View File

@@ -1,57 +1,57 @@
/** /**
* ***************************************************************************** Copyright (c) 2008 - 2013 Oracle * ***************************************************************************** Copyright (c) 2008 - 2013 Oracle
* Corporation. All rights reserved. * Corporation. All rights reserved.
* *
* <p>This program and the accompanying materials are made available under the terms of the Eclipse Public License v1.0 * <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 * 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 * at http://www.eclipse.org/legal/epl-v10.html and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php. * http://www.eclipse.org/org/documents/edl-v10.php.
* *
* <p>Contributors: Linda DeMichiel - Java Persistence 2.1 Linda DeMichiel - Java Persistence 2.0 * <p>Contributors: Linda DeMichiel - Java Persistence 2.1 Linda DeMichiel - Java Persistence 2.0
* *
* <p>**************************************************************************** * <p>****************************************************************************
*/ */
package javax.persistence; package javax.persistence;
import static java.lang.annotation.RetentionPolicy.RUNTIME; import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.*; import java.lang.annotation.*;
/** /**
* Specifies that a unique constraint is to be included in the generated DDL for a primary or secondary table. * Specifies that a unique constraint is to be included in the generated DDL for a primary or secondary table.
* *
* <pre> * <pre>
* Example: * Example:
* &#064;Entity * &#064;Entity
* &#064;Table( * &#064;Table(
* name="EMPLOYEE", * name="EMPLOYEE",
* uniqueConstraints= * uniqueConstraints=
* &#064;UniqueConstraint(columnNames={"EMP_ID", "EMP_NAME"}) * &#064;UniqueConstraint(columnNames={"EMP_ID", "EMP_NAME"})
* ) * )
* public class Employee { ... } * public class Employee { ... }
* </pre> * </pre>
* *
* @since Java Persistence 1.0 * @since Java Persistence 1.0
* @deprecated replace by {@link org.redkale.persistence.UniqueConstraint} * @deprecated replace by {@link org.redkale.persistence.UniqueConstraint}
* @see org.redkale.persistence.UniqueConstraint * @see org.redkale.persistence.UniqueConstraint
*/ */
@Deprecated(since = "2.8.0") @Deprecated(since = "2.8.0")
@Target({}) @Target({})
@Retention(RUNTIME) @Retention(RUNTIME)
public @interface UniqueConstraint { public @interface UniqueConstraint {
/** /**
* (Optional) Constraint name. A provider-chosen name will be chosen if a name is not specified. * (Optional) Constraint name. A provider-chosen name will be chosen if a name is not specified.
* *
* @return String * @return String
* @since Java Persistence 2.0 * @since Java Persistence 2.0
*/ */
String name() default ""; String name() default "";
/** /**
* (Required) An array of the column names that make up the constraint. * (Required) An array of the column names that make up the constraint.
* *
* @return String[] * @return String[]
*/ */
String[] columnNames(); String[] columnNames();
} }

View File

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

View File

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

View File

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

View File

@@ -1,25 +1,25 @@
/* /*
* *
*/ */
package org.redkale.annotation; package org.redkale.annotation;
import java.lang.annotation.*; import java.lang.annotation.*;
/** /**
* 非阻塞模式标记, 标记在Service类和方法、Filter类、HttpServlet类上 <br> * 非阻塞模式标记, 标记在Service类和方法、Filter类、HttpServlet类上 <br>
* 一般情况下,没有显注此注解的方法视为阻塞时, 以下两种情况除外: <br> * 一般情况下,没有显注此注解的方法视为阻塞时, 以下两种情况除外: <br>
* 1、返回类型是CompletionStage <br> * 1、返回类型是CompletionStage <br>
* 2、返回类型是void且参数存在CompletionHandler类型 <br> * 2、返回类型是void且参数存在CompletionHandler类型 <br>
* 阻塞模式的方法会在work线程池中运行 非阻塞在IO线程中运行。 * 阻塞模式的方法会在work线程池中运行 非阻塞在IO线程中运行。
* *
* <p>详情见: https://redkale.org * <p>详情见: https://redkale.org
* *
* @author zhangjx * @author zhangjx
* @since 2.8.0 * @since 2.8.0
*/ */
@Target({ElementType.TYPE, ElementType.METHOD}) @Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME) @Retention(RetentionPolicy.RUNTIME)
public @interface NonBlocking { // 不可使用@Inherited防止被继承, 见HttpServlet.preExecute/authenticate/execute public @interface NonBlocking { // 不可使用@Inherited防止被继承, 见HttpServlet.preExecute/authenticate/execute
boolean value() default true; boolean value() default true;
} }

View File

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

View File

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

View File

@@ -1,29 +1,29 @@
/* /*
* *
*/ */
package org.redkale.annotation; package org.redkale.annotation;
import static java.lang.annotation.ElementType.PARAMETER; import static java.lang.annotation.ElementType.PARAMETER;
import static java.lang.annotation.RetentionPolicy.RUNTIME; import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.Documented; import java.lang.annotation.Documented;
import java.lang.annotation.Retention; import java.lang.annotation.Retention;
import java.lang.annotation.Target; import java.lang.annotation.Target;
/** /**
* 参数名注解,编译时加上 <b>-parameters</b> 参数可以不用此注解 * 参数名注解,编译时加上 <b>-parameters</b> 参数可以不用此注解
* *
* <p>详情见: https://redkale.org * <p>详情见: https://redkale.org
* *
* @author zhangjx * @author zhangjx
* @since 2.8.0 * @since 2.8.0
*/ */
@Documented @Documented
@Target({PARAMETER}) @Target({PARAMETER})
@Retention(RUNTIME) @Retention(RUNTIME)
public @interface Param { public @interface Param {
String value(); String value();
String comment() default ""; String comment() default "";
} }

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,331 +1,331 @@
/* /*
* ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
* *
* *
* *
* *
* *
* *
* *
* *
* *
* *
* *
* *
* *
* *
* *
* *
* *
* *
* *
* *
*/ */
/* /*
* *
* *
* *
* *
* *
* ASM: a very small and fast Java bytecode manipulation framework * ASM: a very small and fast Java bytecode manipulation framework
* Copyright (c) 2000-2011 INRIA, France Telecom * Copyright (c) 2000-2011 INRIA, France Telecom
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
* are met: * are met:
* 1. Redistributions of source code must retain the above copyright * 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright * 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders nor the names of its * 3. Neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from * contributors may be used to endorse or promote products derived from
* this software without specific prior written permission. * this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE. * THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package org.redkale.asm; package org.redkale.asm;
/** /**
* A dynamically extensible vector of bytes. This class is roughly equivalent to a DataOutputStream on top of a * A dynamically extensible vector of bytes. This class is roughly equivalent to a DataOutputStream on top of a
* ByteArrayOutputStream, but is more efficient. * ByteArrayOutputStream, but is more efficient.
* *
* @author Eric Bruneton * @author Eric Bruneton
*/ */
public class ByteVector { public class ByteVector {
/** The content of this vector. */ /** The content of this vector. */
byte[] data; byte[] data;
/** Actual number of bytes in this vector. */ /** Actual number of bytes in this vector. */
int length; int length;
/** Constructs a new {@link ByteVector ByteVector} with a default initial size. */ /** Constructs a new {@link ByteVector ByteVector} with a default initial size. */
public ByteVector() { public ByteVector() {
data = new byte[64]; data = new byte[64];
} }
/** /**
* Constructs a new {@link ByteVector ByteVector} with the given initial size. * Constructs a new {@link ByteVector ByteVector} with the given initial size.
* *
* @param initialSize the initial size of the byte vector to be constructed. * @param initialSize the initial size of the byte vector to be constructed.
*/ */
public ByteVector(final int initialSize) { public ByteVector(final int initialSize) {
data = new byte[initialSize]; data = new byte[initialSize];
} }
/** /**
* Puts a byte into this byte vector. The byte vector is automatically enlarged if necessary. * Puts a byte into this byte vector. The byte vector is automatically enlarged if necessary.
* *
* @param b a byte. * @param b a byte.
* @return this byte vector. * @return this byte vector.
*/ */
public ByteVector putByte(final int b) { public ByteVector putByte(final int b) {
int length = this.length; int length = this.length;
if (length + 1 > data.length) { if (length + 1 > data.length) {
enlarge(1); enlarge(1);
} }
data[length++] = (byte) b; data[length++] = (byte) b;
this.length = length; this.length = length;
return this; return this;
} }
/** /**
* Puts two bytes into this byte vector. The byte vector is automatically enlarged if necessary. * Puts two bytes into this byte vector. The byte vector is automatically enlarged if necessary.
* *
* @param b1 a byte. * @param b1 a byte.
* @param b2 another byte. * @param b2 another byte.
* @return this byte vector. * @return this byte vector.
*/ */
ByteVector put11(final int b1, final int b2) { ByteVector put11(final int b1, final int b2) {
int length = this.length; int length = this.length;
if (length + 2 > data.length) { if (length + 2 > data.length) {
enlarge(2); enlarge(2);
} }
byte[] data = this.data; byte[] data = this.data;
data[length++] = (byte) b1; data[length++] = (byte) b1;
data[length++] = (byte) b2; data[length++] = (byte) b2;
this.length = length; this.length = length;
return this; return this;
} }
/** /**
* Puts a short into this byte vector. The byte vector is automatically enlarged if necessary. * Puts a short into this byte vector. The byte vector is automatically enlarged if necessary.
* *
* @param s a short. * @param s a short.
* @return this byte vector. * @return this byte vector.
*/ */
public ByteVector putShort(final int s) { public ByteVector putShort(final int s) {
int length = this.length; int length = this.length;
if (length + 2 > data.length) { if (length + 2 > data.length) {
enlarge(2); enlarge(2);
} }
byte[] data = this.data; byte[] data = this.data;
data[length++] = (byte) (s >>> 8); data[length++] = (byte) (s >>> 8);
data[length++] = (byte) s; data[length++] = (byte) s;
this.length = length; this.length = length;
return this; return this;
} }
/** /**
* Puts a byte and a short into this byte vector. The byte vector is automatically enlarged if necessary. * Puts a byte and a short into this byte vector. The byte vector is automatically enlarged if necessary.
* *
* @param b a byte. * @param b a byte.
* @param s a short. * @param s a short.
* @return this byte vector. * @return this byte vector.
*/ */
ByteVector put12(final int b, final int s) { ByteVector put12(final int b, final int s) {
int length = this.length; int length = this.length;
if (length + 3 > data.length) { if (length + 3 > data.length) {
enlarge(3); enlarge(3);
} }
byte[] data = this.data; byte[] data = this.data;
data[length++] = (byte) b; data[length++] = (byte) b;
data[length++] = (byte) (s >>> 8); data[length++] = (byte) (s >>> 8);
data[length++] = (byte) s; data[length++] = (byte) s;
this.length = length; this.length = length;
return this; return this;
} }
/** /**
* Puts an int into this byte vector. The byte vector is automatically enlarged if necessary. * Puts an int into this byte vector. The byte vector is automatically enlarged if necessary.
* *
* @param i an int. * @param i an int.
* @return this byte vector. * @return this byte vector.
*/ */
public ByteVector putInt(final int i) { public ByteVector putInt(final int i) {
int length = this.length; int length = this.length;
if (length + 4 > data.length) { if (length + 4 > data.length) {
enlarge(4); enlarge(4);
} }
byte[] data = this.data; byte[] data = this.data;
data[length++] = (byte) (i >>> 24); data[length++] = (byte) (i >>> 24);
data[length++] = (byte) (i >>> 16); data[length++] = (byte) (i >>> 16);
data[length++] = (byte) (i >>> 8); data[length++] = (byte) (i >>> 8);
data[length++] = (byte) i; data[length++] = (byte) i;
this.length = length; this.length = length;
return this; return this;
} }
/** /**
* Puts a long into this byte vector. The byte vector is automatically enlarged if necessary. * Puts a long into this byte vector. The byte vector is automatically enlarged if necessary.
* *
* @param l a long. * @param l a long.
* @return this byte vector. * @return this byte vector.
*/ */
public ByteVector putLong(final long l) { public ByteVector putLong(final long l) {
int length = this.length; int length = this.length;
if (length + 8 > data.length) { if (length + 8 > data.length) {
enlarge(8); enlarge(8);
} }
byte[] data = this.data; byte[] data = this.data;
int i = (int) (l >>> 32); int i = (int) (l >>> 32);
data[length++] = (byte) (i >>> 24); data[length++] = (byte) (i >>> 24);
data[length++] = (byte) (i >>> 16); data[length++] = (byte) (i >>> 16);
data[length++] = (byte) (i >>> 8); data[length++] = (byte) (i >>> 8);
data[length++] = (byte) i; data[length++] = (byte) i;
i = (int) l; i = (int) l;
data[length++] = (byte) (i >>> 24); data[length++] = (byte) (i >>> 24);
data[length++] = (byte) (i >>> 16); data[length++] = (byte) (i >>> 16);
data[length++] = (byte) (i >>> 8); data[length++] = (byte) (i >>> 8);
data[length++] = (byte) i; data[length++] = (byte) i;
this.length = length; this.length = length;
return this; return this;
} }
/** /**
* Puts an UTF8 string into this byte vector. The byte vector is automatically enlarged if necessary. * Puts an UTF8 string into this byte vector. The byte vector is automatically enlarged if necessary.
* *
* @param s a String whose UTF8 encoded length must be less than 65536. * @param s a String whose UTF8 encoded length must be less than 65536.
* @return this byte vector. * @return this byte vector.
*/ */
public ByteVector putUTF8(final String s) { public ByteVector putUTF8(final String s) {
int charLength = s.length(); int charLength = s.length();
if (charLength > 65535) { if (charLength > 65535) {
throw new IllegalArgumentException(); throw new IllegalArgumentException();
} }
int len = length; int len = length;
if (len + 2 + charLength > data.length) { if (len + 2 + charLength > data.length) {
enlarge(2 + charLength); enlarge(2 + charLength);
} }
byte[] data = this.data; byte[] data = this.data;
// optimistic algorithm: instead of computing the byte length and then // optimistic algorithm: instead of computing the byte length and then
// serializing the string (which requires two loops), we assume the byte // serializing the string (which requires two loops), we assume the byte
// length is equal to char length (which is the most frequent case), and // length is equal to char length (which is the most frequent case), and
// we start serializing the string right away. During the serialization, // we start serializing the string right away. During the serialization,
// if we find that this assumption is wrong, we continue with the // if we find that this assumption is wrong, we continue with the
// general method. // general method.
data[len++] = (byte) (charLength >>> 8); data[len++] = (byte) (charLength >>> 8);
data[len++] = (byte) charLength; data[len++] = (byte) charLength;
for (int i = 0; i < charLength; ++i) { for (int i = 0; i < charLength; ++i) {
char c = s.charAt(i); char c = s.charAt(i);
if (c >= '\001' && c <= '\177') { if (c >= '\001' && c <= '\177') {
data[len++] = (byte) c; data[len++] = (byte) c;
} else { } else {
length = len; length = len;
return encodeUTF8(s, i, 65535); return encodeUTF8(s, i, 65535);
} }
} }
length = len; length = len;
return this; return this;
} }
/** /**
* Puts an UTF8 string into this byte vector. The byte vector is automatically enlarged if necessary. The string * 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 * length is encoded in two bytes before the encoded characters, if there is space for that (i.e. if this.length - i
* - 2 >= 0). * - 2 >= 0).
* *
* @param s the String to encode. * @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 * @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. * encoded, using only one byte per character.
* @param maxByteLength the maximum byte length of the encoded string, including the already encoded characters. * @param maxByteLength the maximum byte length of the encoded string, including the already encoded characters.
* @return this byte vector. * @return this byte vector.
*/ */
ByteVector encodeUTF8(final String s, int i, int maxByteLength) { ByteVector encodeUTF8(final String s, int i, int maxByteLength) {
int charLength = s.length(); int charLength = s.length();
int byteLength = i; int byteLength = i;
char c; char c;
for (int j = i; j < charLength; ++j) { for (int j = i; j < charLength; ++j) {
c = s.charAt(j); c = s.charAt(j);
if (c >= '\001' && c <= '\177') { if (c >= '\001' && c <= '\177') {
byteLength++; byteLength++;
} else if (c > '\u07FF') { } else if (c > '\u07FF') {
byteLength += 3; byteLength += 3;
} else { } else {
byteLength += 2; byteLength += 2;
} }
} }
if (byteLength > maxByteLength) { if (byteLength > maxByteLength) {
throw new IllegalArgumentException(); throw new IllegalArgumentException();
} }
int start = length - i - 2; int start = length - i - 2;
if (start >= 0) { if (start >= 0) {
data[start] = (byte) (byteLength >>> 8); data[start] = (byte) (byteLength >>> 8);
data[start + 1] = (byte) byteLength; data[start + 1] = (byte) byteLength;
} }
if (length + byteLength - i > data.length) { if (length + byteLength - i > data.length) {
enlarge(byteLength - i); enlarge(byteLength - i);
} }
int len = length; int len = length;
for (int j = i; j < charLength; ++j) { for (int j = i; j < charLength; ++j) {
c = s.charAt(j); c = s.charAt(j);
if (c >= '\001' && c <= '\177') { if (c >= '\001' && c <= '\177') {
data[len++] = (byte) c; data[len++] = (byte) c;
} else if (c > '\u07FF') { } else if (c > '\u07FF') {
data[len++] = (byte) (0xE0 | c >> 12 & 0xF); data[len++] = (byte) (0xE0 | c >> 12 & 0xF);
data[len++] = (byte) (0x80 | c >> 6 & 0x3F); data[len++] = (byte) (0x80 | c >> 6 & 0x3F);
data[len++] = (byte) (0x80 | c & 0x3F); data[len++] = (byte) (0x80 | c & 0x3F);
} else { } else {
data[len++] = (byte) (0xC0 | c >> 6 & 0x1F); data[len++] = (byte) (0xC0 | c >> 6 & 0x1F);
data[len++] = (byte) (0x80 | c & 0x3F); data[len++] = (byte) (0x80 | c & 0x3F);
} }
} }
length = len; length = len;
return this; return this;
} }
/** /**
* Puts an array of bytes into this byte vector. The byte vector is automatically enlarged if necessary. * Puts an array of bytes into this byte vector. The byte vector is automatically enlarged if necessary.
* *
* @param b an array of bytes. May be &#60;tt&#62;null&#60;/tt&#62; to put &#60;tt&#62;len&#60;/tt&#62; null bytes * @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. * into this byte vector.
* @param off index of the fist byte of b that must be copied. * @param off index of the fist byte of b that must be copied.
* @param len number of bytes of b that must be copied. * @param len number of bytes of b that must be copied.
* @return this byte vector. * @return this byte vector.
*/ */
public ByteVector putByteArray(final byte[] b, final int off, final int len) { public ByteVector putByteArray(final byte[] b, final int off, final int len) {
if (length + len > data.length) { if (length + len > data.length) {
enlarge(len); enlarge(len);
} }
if (b != null) { if (b != null) {
System.arraycopy(b, off, data, length, len); System.arraycopy(b, off, data, length, len);
} }
length += len; length += len;
return this; return this;
} }
/** /**
* Enlarge this byte vector so that it can receive n more bytes. * Enlarge this byte vector so that it can receive n more bytes.
* *
* @param size number of additional bytes that this byte vector should be able to receive. * @param size number of additional bytes that this byte vector should be able to receive.
*/ */
private void enlarge(final int size) { private void enlarge(final int size) {
int length1 = 2 * data.length; int length1 = 2 * data.length;
int length2 = length + size; int length2 = length + size;
byte[] newData = new byte[length1 > length2 ? length1 : length2]; byte[] newData = new byte[length1 > length2 ? length1 : length2];
System.arraycopy(data, 0, newData, 0, length); System.arraycopy(data, 0, newData, 0, length);
data = newData; 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. * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
* *
* *
* *
* *
* *
* *
* *
* *
* *
* *
* *
* *
* *
* *
* *
* *
* *
* *
* *
* *
*/ */
/* /*
* *
* *
* *
* *
* *
* ASM: a very small and fast Java bytecode manipulation framework * ASM: a very small and fast Java bytecode manipulation framework
* Copyright (c) 2000-2011 INRIA, France Telecom * Copyright (c) 2000-2011 INRIA, France Telecom
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
* are met: * are met:
* 1. Redistributions of source code must retain the above copyright * 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright * 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders nor the names of its * 3. Neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from * contributors may be used to endorse or promote products derived from
* this software without specific prior written permission. * this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE. * THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package org.redkale.asm; package org.redkale.asm;
/** /**
* A visitor to visit a Java class. The methods of this class must be called in the following order: * 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;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;visitOuterClass&#60;/tt&#62; ] ( &#60;tt&#62;visitAnnotation&#60;/tt&#62; |
* &#60;tt&#62;visitTypeAnnotation&#60;/tt&#62; | &#60;tt&#62;visitAttribute&#60;/tt&#62; )* ( * &#60;tt&#62;visitTypeAnnotation&#60;/tt&#62; | &#60;tt&#62;visitAttribute&#60;/tt&#62; )* (
* &#60;tt&#62;visitInnerClass&#60;/tt&#62; | &#60;tt&#62;visitField&#60;/tt&#62; | &#60;tt&#62;visitMethod&#60;/tt&#62; * &#60;tt&#62;visitInnerClass&#60;/tt&#62; | &#60;tt&#62;visitField&#60;/tt&#62; | &#60;tt&#62;visitMethod&#60;/tt&#62;
* )* &#60;tt&#62;visitEnd&#60;/tt&#62;. * )* &#60;tt&#62;visitEnd&#60;/tt&#62;.
* *
* @author Eric Bruneton * @author Eric Bruneton
*/ */
public abstract class ClassVisitor { public abstract class ClassVisitor {
/** /**
* The ASM API version implemented by this visitor. The value of this field must be one of {@link Opcodes#ASM4}, * 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}. * {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
*/ */
protected final int api; protected final int api;
/** The class visitor to which this visitor must delegate method calls. May be null. */ /** The class visitor to which this visitor must delegate method calls. May be null. */
protected ClassVisitor cv; protected ClassVisitor cv;
/** /**
* Constructs a new {@link ClassVisitor}. * Constructs a new {@link ClassVisitor}.
* *
* @param api the ASM API version implemented by this visitor. Must be one of {@link Opcodes#ASM4}, * @param api the ASM API version implemented by this visitor. Must be one of {@link Opcodes#ASM4},
* {@link Opcodes#ASM5} or {@link Opcodes#ASM6}. * {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
*/ */
public ClassVisitor(final int api) { public ClassVisitor(final int api) {
this(api, null); this(api, null);
} }
/** /**
* Constructs a new {@link ClassVisitor}. * Constructs a new {@link ClassVisitor}.
* *
* @param api the ASM API version implemented by this visitor. Must be one of {@link Opcodes#ASM4}, * @param api the ASM API version implemented by this visitor. Must be one of {@link Opcodes#ASM4},
* {@link Opcodes#ASM5} or {@link Opcodes#ASM6}. * {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
* @param cv the class visitor to which this visitor must delegate method calls. May be null. * @param cv the class visitor to which this visitor must delegate method calls. May be null.
*/ */
public ClassVisitor(final int api, final ClassVisitor cv) { public ClassVisitor(final int api, final ClassVisitor cv) {
this.api = api; this.api = api;
this.cv = cv; this.cv = cv;
} }
/** /**
* Visits the header of the class. * Visits the header of the class.
* *
* @param version the class version. * @param version the class version.
* @param access the class's access flags (see {@link Opcodes}). This parameter also indicates if the class is * @param access the class's access flags (see {@link Opcodes}). This parameter also indicates if the class is
* deprecated. * deprecated.
* @param name the internal name of the class (see {@link Type#getInternalName() getInternalName}). * @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 * @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. * 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}). * @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 * For interfaces, the super class is {@link Object}. May be &#60;tt&#62;null&#60;/tt&#62;, but only for the
* {@link Object} class. * {@link Object} class.
* @param interfaces the internal names of the class's interfaces (see {@link Type#getInternalName() * @param interfaces the internal names of the class's interfaces (see {@link Type#getInternalName()
* getInternalName}). May be &#60;tt&#62;null&#60;/tt&#62;. * getInternalName}). May be &#60;tt&#62;null&#60;/tt&#62;.
*/ */
public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) { public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) {
if (cv != null) { if (cv != null) {
cv.visit(version, access, name, signature, superName, interfaces); cv.visit(version, access, name, signature, superName, interfaces);
} }
} }
/** /**
* Visits the source of the class. * Visits the source of the class.
* *
* @param source the name of the source file from which the class was compiled. May be * @param source the name of the source file from which the class was compiled. May be
* &#60;tt&#62;null&#60;/tt&#62;. * &#60;tt&#62;null&#60;/tt&#62;.
* @param debug additional debug information to compute the correspondance between source and compiled elements of * @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;. * the class. May be &#60;tt&#62;null&#60;/tt&#62;.
*/ */
public void visitSource(String source, String debug) { public void visitSource(String source, String debug) {
if (cv != null) { if (cv != null) {
cv.visitSource(source, debug); cv.visitSource(source, debug);
} }
} }
/** /**
* Visit the module corresponding to the class. * Visit the module corresponding to the class.
* *
* @param name module name * @param name module name
* @param access module flags, among {@code ACC_OPEN}, {@code ACC_SYNTHETIC} and {@code ACC_MANDATED}. * @param access module flags, among {@code ACC_OPEN}, {@code ACC_SYNTHETIC} and {@code ACC_MANDATED}.
* @param version module version or null. * @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 * @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. * in visiting this module.
*/ */
public ModuleVisitor visitModule(String name, int access, String version) { public ModuleVisitor visitModule(String name, int access, String version) {
if (api < Opcodes.ASM6) { if (api < Opcodes.ASM6) {
throw new RuntimeException(); throw new RuntimeException();
} }
if (cv != null) { if (cv != null) {
return cv.visitModule(name, access, version); return cv.visitModule(name, access, version);
} }
return null; return null;
} }
/** /**
* Visits the enclosing class of the class. This method must be called only if the class has an enclosing class. * Visits the enclosing class of the class. This method must be called only if the class has an enclosing class.
* *
* @param owner internal name of the enclosing class of the class. * @param 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 * @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. * 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 * @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. * is not enclosed in a method of its enclosing class.
*/ */
public void visitOuterClass(String owner, String name, String desc) { public void visitOuterClass(String owner, String name, String desc) {
if (cv != null) { if (cv != null) {
cv.visitOuterClass(owner, name, desc); cv.visitOuterClass(owner, name, desc);
} }
} }
/** /**
* Visits an annotation of the class. * Visits an annotation of the class.
* *
* @param desc the class descriptor of the annotation 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. * @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 * @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. * interested in visiting this annotation.
*/ */
public AnnotationVisitor visitAnnotation(String desc, boolean visible) { public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
if (cv != null) { if (cv != null) {
return cv.visitAnnotation(desc, visible); return cv.visitAnnotation(desc, visible);
} }
return null; return null;
} }
/** /**
* Visits an annotation on a type in the class signature. * 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 * @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 CLASS_TYPE_PARAMETER},
* {@link TypeReference#CLASS_TYPE_PARAMETER_BOUND CLASS_TYPE_PARAMETER_BOUND} or * {@link TypeReference#CLASS_TYPE_PARAMETER_BOUND CLASS_TYPE_PARAMETER_BOUND} or
* {@link TypeReference#CLASS_EXTENDS CLASS_EXTENDS}. See {@link TypeReference}. * {@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 * @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. * 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 desc the class descriptor of the annotation class.
* @param visible &#60;tt&#62;true&#60;/tt&#62; if the annotation is visible at runtime. * @param visible &#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 * @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. * interested in visiting this annotation.
*/ */
public AnnotationVisitor visitTypeAnnotation(int typeRef, TypePath typePath, String desc, boolean visible) { public AnnotationVisitor visitTypeAnnotation(int typeRef, TypePath typePath, String desc, boolean visible) {
if (cv != null) { if (cv != null) {
return cv.visitTypeAnnotation(typeRef, typePath, desc, visible); return cv.visitTypeAnnotation(typeRef, typePath, desc, visible);
} }
return null; return null;
} }
/** /**
* Visits a non standard attribute of the class. * Visits a non standard attribute of the class.
* *
* @param attr an attribute. * @param attr an attribute.
*/ */
public void visitAttribute(Attribute attr) { public void visitAttribute(Attribute attr) {
if (cv != null) { if (cv != null) {
cv.visitAttribute(attr); cv.visitAttribute(attr);
} }
} }
/** /**
* Visits information about an inner class. This inner class is not necessarily a member of the class being visited. * Visits information about an inner class. This inner class is not necessarily a member of the class being visited.
* *
* @param name the internal name of an inner class (see {@link Type#getInternalName() getInternalName}). * @param 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 * @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. * {@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 * @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. * &#60;tt&#62;null&#60;/tt&#62; for anonymous inner classes.
* @param access the access flags of the inner class as originally declared in the enclosing class. * @param access the access flags of the inner class as originally declared in the enclosing class.
*/ */
public void visitInnerClass(String name, String outerName, String innerName, int access) { public void visitInnerClass(String name, String outerName, String innerName, int access) {
if (cv != null) { if (cv != null) {
cv.visitInnerClass(name, outerName, innerName, access); cv.visitInnerClass(name, outerName, innerName, access);
} }
} }
/** /**
* Visits a field of the class. * Visits a field of the class.
* *
* @param access the field's access flags (see {@link Opcodes}). This parameter also indicates if the field is * @param access the field's access flags (see {@link Opcodes}). This parameter also indicates if the field is
* synthetic and/or deprecated. * synthetic and/or deprecated.
* @param name the field's name. * @param name the field's name.
* @param desc the field's descriptor (see {@link Type Type}). * @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 * @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. * generic types.
* @param value the field's initial value. This parameter, which may be &#60;tt&#62;null&#60;/tt&#62; if the field * @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} * 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;, * 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 * &#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 * 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. * 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 * @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. * visitor is not interested in visiting these annotations and attributes.
*/ */
public FieldVisitor visitField(int access, String name, String desc, String signature, Object value) { public FieldVisitor visitField(int access, String name, String desc, String signature, Object value) {
if (cv != null) { if (cv != null) {
return cv.visitField(access, name, desc, signature, value); return cv.visitField(access, name, desc, signature, value);
} }
return null; return null;
} }
/** /**
* Visits a method of the class. This method <i>must</i> return a new {@link MethodVisitor} instance (or * 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. * &#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 * @param access the method's access flags (see {@link Opcodes}). This parameter also indicates if the method is
* synthetic and/or deprecated. * synthetic and/or deprecated.
* @param name the method's name. * @param name the method's name.
* @param desc the method's descriptor (see {@link Type Type}). * @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 * @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. * type and exceptions do not use generic types.
* @param exceptions the internal names of the method's exception classes (see {@link Type#getInternalName() * @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;. * 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 * @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. * not interested in visiting the code of this method.
*/ */
public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) { public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
if (cv != null) { if (cv != null) {
return cv.visitMethod(access, name, desc, signature, exceptions); return cv.visitMethod(access, name, desc, signature, exceptions);
} }
return null; 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 * 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. * all the fields and methods of the class have been visited.
*/ */
public void visitEnd() { public void visitEnd() {
if (cv != null) { if (cv != null) {
cv.visitEnd(); 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. * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
* *
* *
* *
* *
* *
* *
* *
* *
* *
* *
* *
* *
* *
* *
* *
* *
* *
* *
* *
* *
*/ */
/* /*
* *
* *
* *
* *
* *
* ASM: a very small and fast Java bytecode manipulation framework * ASM: a very small and fast Java bytecode manipulation framework
* Copyright (c) 2000-2011 INRIA, France Telecom * Copyright (c) 2000-2011 INRIA, France Telecom
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
* are met: * are met:
* 1. Redistributions of source code must retain the above copyright * 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright * 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders nor the names of its * 3. Neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from * contributors may be used to endorse or promote products derived from
* this software without specific prior written permission. * this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE. * THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package org.redkale.asm; package org.redkale.asm;
/** /**
* Information about a class being parsed in a {@link ClassReader}. * Information about a class being parsed in a {@link ClassReader}.
* *
* @author Eric Bruneton * @author Eric Bruneton
*/ */
class Context { class Context {
/** Prototypes of the attributes that must be parsed for this class. */ /** Prototypes of the attributes that must be parsed for this class. */
Attribute[] attrs; Attribute[] attrs;
/** The {@link ClassReader} option flags for the parsing of this class. */ /** The {@link ClassReader} option flags for the parsing of this class. */
int flags; int flags;
/** The buffer used to read strings. */ /** The buffer used to read strings. */
char[] buffer; char[] buffer;
/** The start index of each bootstrap method. */ /** The start index of each bootstrap method. */
int[] bootstrapMethods; int[] bootstrapMethods;
/** The access flags of the method currently being parsed. */ /** The access flags of the method currently being parsed. */
int access; int access;
/** The name of the method currently being parsed. */ /** The name of the method currently being parsed. */
String name; String name;
/** The descriptor of the method currently being parsed. */ /** The descriptor of the method currently being parsed. */
String desc; String desc;
/** /**
* The label objects, indexed by bytecode offset, of the method currently being parsed (only bytecode offsets for * 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). * which a label is needed have a non null associated Label object).
*/ */
Label[] labels; Label[] labels;
/** The target of the type annotation currently being parsed. */ /** The target of the type annotation currently being parsed. */
int typeRef; int typeRef;
/** The path of the type annotation currently being parsed. */ /** The path of the type annotation currently being parsed. */
TypePath typePath; TypePath typePath;
/** The offset of the latest stack map frame that has been parsed. */ /** The offset of the latest stack map frame that has been parsed. */
int offset; int offset;
/** /**
* The labels corresponding to the start of the local variable ranges in the local variable type annotation * The labels corresponding to the start of the local variable ranges in the local variable type annotation
* currently being parsed. * currently being parsed.
*/ */
Label[] start; Label[] start;
/** /**
* The labels corresponding to the end of the local variable ranges in the local variable type annotation currently * The labels corresponding to the end of the local variable ranges in the local variable type annotation currently
* being parsed. * being parsed.
*/ */
Label[] end; Label[] end;
/** /**
* The local variable indices for each local variable range in the local variable type annotation currently being * The local variable indices for each local variable range in the local variable type annotation currently being
* parsed. * parsed.
*/ */
int[] index; int[] index;
/** The encoding of the latest stack map frame that has been parsed. */ /** The encoding of the latest stack map frame that has been parsed. */
int mode; int mode;
/** The number of locals in the latest stack map frame that has been parsed. */ /** The number of locals in the latest stack map frame that has been parsed. */
int localCount; int localCount;
/** /**
* The number locals in the latest stack map frame that has been parsed, minus the number of locals in the previous * The number locals in the latest stack map frame that has been parsed, minus the number of locals in the previous
* frame. * frame.
*/ */
int localDiff; int localDiff;
/** The local values of the latest stack map frame that has been parsed. */ /** The local values of the latest stack map frame that has been parsed. */
Object[] local; Object[] local;
/** The stack size of the latest stack map frame that has been parsed. */ /** The stack size of the latest stack map frame that has been parsed. */
int stackCount; int stackCount;
/** The stack values of the latest stack map frame that has been parsed. */ /** The stack values of the latest stack map frame that has been parsed. */
Object[] stack; Object[] stack;
} }

View File

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

View File

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

View File

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

View File

@@ -1,320 +1,320 @@
/* /*
* ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
* *
* *
* *
* *
* *
* *
* *
* *
* *
* *
* *
* *
* *
* *
* *
* *
* *
* *
* *
* *
*/ */
/* /*
* *
* *
* *
* *
* *
* ASM: a very small and fast Java bytecode manipulation framework * ASM: a very small and fast Java bytecode manipulation framework
* Copyright (c) 2000-2011 INRIA, France Telecom * Copyright (c) 2000-2011 INRIA, France Telecom
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
* are met: * are met:
* 1. Redistributions of source code must retain the above copyright * 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright * 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders nor the names of its * 3. Neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from * contributors may be used to endorse or promote products derived from
* this software without specific prior written permission. * this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE. * THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package org.redkale.asm; package org.redkale.asm;
/** /**
* An {@link FieldVisitor} that generates Java fields in bytecode form. * An {@link FieldVisitor} that generates Java fields in bytecode form.
* *
* @author Eric Bruneton * @author Eric Bruneton
*/ */
final class FieldWriter extends FieldVisitor { final class FieldWriter extends FieldVisitor {
/** The class writer to which this field must be added. */ /** The class writer to which this field must be added. */
private final ClassWriter cw; private final ClassWriter cw;
/** Access flags of this field. */ /** Access flags of this field. */
private final int access; private final int access;
/** The index of the constant pool item that contains the name of this method. */ /** The index of the constant pool item that contains the name of this method. */
private final int name; private final int name;
/** The index of the constant pool item that contains the descriptor of this field. */ /** The index of the constant pool item that contains the descriptor of this field. */
private final int desc; private final int desc;
/** The index of the constant pool item that contains the signature of this field. */ /** The index of the constant pool item that contains the signature of this field. */
private int signature; private int signature;
/** The index of the constant pool item that contains the constant value of this field. */ /** The index of the constant pool item that contains the constant value of this field. */
private int value; private int value;
/** The runtime visible annotations of this field. May be &#60;tt&#62;null&#60;/tt&#62;. */ /** The runtime visible annotations of this field. May be &#60;tt&#62;null&#60;/tt&#62;. */
private AnnotationWriter anns; private AnnotationWriter anns;
/** The runtime invisible annotations of this field. May be &#60;tt&#62;null&#60;/tt&#62;. */ /** The runtime invisible annotations of this field. May be &#60;tt&#62;null&#60;/tt&#62;. */
private AnnotationWriter ianns; private AnnotationWriter ianns;
/** The runtime visible type annotations of this field. May be &#60;tt&#62;null&#60;/tt&#62;. */ /** The runtime visible type annotations of this field. May be &#60;tt&#62;null&#60;/tt&#62;. */
private AnnotationWriter tanns; private AnnotationWriter tanns;
/** The runtime invisible type annotations of this field. May be &#60;tt&#62;null&#60;/tt&#62;. */ /** The runtime invisible type annotations of this field. May be &#60;tt&#62;null&#60;/tt&#62;. */
private AnnotationWriter itanns; private AnnotationWriter itanns;
/** The non standard attributes of this field. May be &#60;tt&#62;null&#60;/tt&#62;. */ /** The non standard attributes of this field. May be &#60;tt&#62;null&#60;/tt&#62;. */
private Attribute attrs; private Attribute attrs;
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
// Constructor // Constructor
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
/** /**
* Constructs a new {@link FieldWriter}. * Constructs a new {@link FieldWriter}.
* *
* @param cw the class writer to which this field must be added. * @param cw the class writer to which this field must be added.
* @param access the field's access flags (see {@link Opcodes}). * @param access the field's access flags (see {@link Opcodes}).
* @param name the field's name. * @param name the field's name.
* @param desc the field's descriptor (see {@link Type}). * @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 signature the field's signature. May be &#60;tt&#62;null&#60;/tt&#62;.
* @param value the field's constant value. May be &#60;tt&#62;null&#60;/tt&#62;. * @param value the field's constant value. May be &#60;tt&#62;null&#60;/tt&#62;.
*/ */
FieldWriter( FieldWriter(
final ClassWriter cw, final ClassWriter cw,
final int access, final int access,
final String name, final String name,
final String desc, final String desc,
final String signature, final String signature,
final Object value) { final Object value) {
super(Opcodes.ASM6); super(Opcodes.ASM6);
if (cw.firstField == null) { if (cw.firstField == null) {
cw.firstField = this; cw.firstField = this;
} else { } else {
cw.lastField.fv = this; cw.lastField.fv = this;
} }
cw.lastField = this; cw.lastField = this;
this.cw = cw; this.cw = cw;
this.access = access; this.access = access;
this.name = cw.newUTF8(name); this.name = cw.newUTF8(name);
this.desc = cw.newUTF8(desc); this.desc = cw.newUTF8(desc);
if (signature != null) { if (signature != null) {
this.signature = cw.newUTF8(signature); this.signature = cw.newUTF8(signature);
} }
if (value != null) { if (value != null) {
this.value = cw.newConstItem(value).index; this.value = cw.newConstItem(value).index;
} }
} }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
// Implementation of the FieldVisitor abstract class // Implementation of the FieldVisitor abstract class
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
@Override @Override
public AnnotationVisitor visitAnnotation(final String desc, final boolean visible) { public AnnotationVisitor visitAnnotation(final String desc, final boolean visible) {
ByteVector bv = new ByteVector(); ByteVector bv = new ByteVector();
// write type, and reserve space for values count // write type, and reserve space for values count
bv.putShort(cw.newUTF8(desc)).putShort(0); bv.putShort(cw.newUTF8(desc)).putShort(0);
AnnotationWriter aw = new AnnotationWriter(cw, true, bv, bv, 2); AnnotationWriter aw = new AnnotationWriter(cw, true, bv, bv, 2);
if (visible) { if (visible) {
aw.next = anns; aw.next = anns;
anns = aw; anns = aw;
} else { } else {
aw.next = ianns; aw.next = ianns;
ianns = aw; ianns = aw;
} }
return aw; return aw;
} }
@Override @Override
public AnnotationVisitor visitTypeAnnotation( public AnnotationVisitor visitTypeAnnotation(
final int typeRef, final TypePath typePath, final String desc, final boolean visible) { final int typeRef, final TypePath typePath, final String desc, final boolean visible) {
ByteVector bv = new ByteVector(); ByteVector bv = new ByteVector();
// write target_type and target_info // write target_type and target_info
AnnotationWriter.putTarget(typeRef, typePath, bv); AnnotationWriter.putTarget(typeRef, typePath, bv);
// write type, and reserve space for values count // write type, and reserve space for values count
bv.putShort(cw.newUTF8(desc)).putShort(0); bv.putShort(cw.newUTF8(desc)).putShort(0);
AnnotationWriter aw = new AnnotationWriter(cw, true, bv, bv, bv.length - 2); AnnotationWriter aw = new AnnotationWriter(cw, true, bv, bv, bv.length - 2);
if (visible) { if (visible) {
aw.next = tanns; aw.next = tanns;
tanns = aw; tanns = aw;
} else { } else {
aw.next = itanns; aw.next = itanns;
itanns = aw; itanns = aw;
} }
return aw; return aw;
} }
@Override @Override
public void visitAttribute(final Attribute attr) { public void visitAttribute(final Attribute attr) {
attr.next = attrs; attr.next = attrs;
attrs = attr; attrs = attr;
} }
@Override @Override
public void visitEnd() { public void visitEnd() {
// do nothing // do nothing
} }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
// Utility methods // Utility methods
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
/** /**
* Returns the size of this field. * Returns the size of this field.
* *
* @return the size of this field. * @return the size of this field.
*/ */
int getSize() { int getSize() {
int size = 8; int size = 8;
if (value != 0) { if (value != 0) {
cw.newUTF8("ConstantValue"); cw.newUTF8("ConstantValue");
size += 8; size += 8;
} }
if ((access & Opcodes.ACC_SYNTHETIC) != 0) { if ((access & Opcodes.ACC_SYNTHETIC) != 0) {
if ((cw.version & 0xFFFF) < Opcodes.V1_5 || (access & ClassWriter.ACC_SYNTHETIC_ATTRIBUTE) != 0) { if ((cw.version & 0xFFFF) < Opcodes.V1_5 || (access & ClassWriter.ACC_SYNTHETIC_ATTRIBUTE) != 0) {
cw.newUTF8("Synthetic"); cw.newUTF8("Synthetic");
size += 6; size += 6;
} }
} }
if ((access & Opcodes.ACC_DEPRECATED) != 0) { if ((access & Opcodes.ACC_DEPRECATED) != 0) {
cw.newUTF8("Deprecated"); cw.newUTF8("Deprecated");
size += 6; size += 6;
} }
if (signature != 0) { if (signature != 0) {
cw.newUTF8("Signature"); cw.newUTF8("Signature");
size += 8; size += 8;
} }
if (anns != null) { if (anns != null) {
cw.newUTF8("RuntimeVisibleAnnotations"); cw.newUTF8("RuntimeVisibleAnnotations");
size += 8 + anns.getSize(); size += 8 + anns.getSize();
} }
if (ianns != null) { if (ianns != null) {
cw.newUTF8("RuntimeInvisibleAnnotations"); cw.newUTF8("RuntimeInvisibleAnnotations");
size += 8 + ianns.getSize(); size += 8 + ianns.getSize();
} }
if (tanns != null) { if (tanns != null) {
cw.newUTF8("RuntimeVisibleTypeAnnotations"); cw.newUTF8("RuntimeVisibleTypeAnnotations");
size += 8 + tanns.getSize(); size += 8 + tanns.getSize();
} }
if (itanns != null) { if (itanns != null) {
cw.newUTF8("RuntimeInvisibleTypeAnnotations"); cw.newUTF8("RuntimeInvisibleTypeAnnotations");
size += 8 + itanns.getSize(); size += 8 + itanns.getSize();
} }
if (attrs != null) { if (attrs != null) {
size += attrs.getSize(cw, null, 0, -1, -1); size += attrs.getSize(cw, null, 0, -1, -1);
} }
return size; return size;
} }
/** /**
* Puts the content of this field into the given byte vector. * Puts the content of this field into the given byte vector.
* *
* @param out where the content of this field must be put. * @param out where the content of this field must be put.
*/ */
void put(final ByteVector out) { void put(final ByteVector out) {
final int FACTOR = ClassWriter.TO_ACC_SYNTHETIC; final int FACTOR = ClassWriter.TO_ACC_SYNTHETIC;
int mask = Opcodes.ACC_DEPRECATED int mask = Opcodes.ACC_DEPRECATED
| ClassWriter.ACC_SYNTHETIC_ATTRIBUTE | ClassWriter.ACC_SYNTHETIC_ATTRIBUTE
| ((access & ClassWriter.ACC_SYNTHETIC_ATTRIBUTE) / FACTOR); | ((access & ClassWriter.ACC_SYNTHETIC_ATTRIBUTE) / FACTOR);
out.putShort(access & ~mask).putShort(name).putShort(desc); out.putShort(access & ~mask).putShort(name).putShort(desc);
int attributeCount = 0; int attributeCount = 0;
if (value != 0) { if (value != 0) {
++attributeCount; ++attributeCount;
} }
if ((access & Opcodes.ACC_SYNTHETIC) != 0) { if ((access & Opcodes.ACC_SYNTHETIC) != 0) {
if ((cw.version & 0xFFFF) < Opcodes.V1_5 || (access & ClassWriter.ACC_SYNTHETIC_ATTRIBUTE) != 0) { if ((cw.version & 0xFFFF) < Opcodes.V1_5 || (access & ClassWriter.ACC_SYNTHETIC_ATTRIBUTE) != 0) {
++attributeCount; ++attributeCount;
} }
} }
if ((access & Opcodes.ACC_DEPRECATED) != 0) { if ((access & Opcodes.ACC_DEPRECATED) != 0) {
++attributeCount; ++attributeCount;
} }
if (signature != 0) { if (signature != 0) {
++attributeCount; ++attributeCount;
} }
if (anns != null) { if (anns != null) {
++attributeCount; ++attributeCount;
} }
if (ianns != null) { if (ianns != null) {
++attributeCount; ++attributeCount;
} }
if (tanns != null) { if (tanns != null) {
++attributeCount; ++attributeCount;
} }
if (itanns != null) { if (itanns != null) {
++attributeCount; ++attributeCount;
} }
if (attrs != null) { if (attrs != null) {
attributeCount += attrs.getCount(); attributeCount += attrs.getCount();
} }
out.putShort(attributeCount); out.putShort(attributeCount);
if (value != 0) { if (value != 0) {
out.putShort(cw.newUTF8("ConstantValue")); out.putShort(cw.newUTF8("ConstantValue"));
out.putInt(2).putShort(value); out.putInt(2).putShort(value);
} }
if ((access & Opcodes.ACC_SYNTHETIC) != 0) { if ((access & Opcodes.ACC_SYNTHETIC) != 0) {
if ((cw.version & 0xFFFF) < Opcodes.V1_5 || (access & ClassWriter.ACC_SYNTHETIC_ATTRIBUTE) != 0) { if ((cw.version & 0xFFFF) < Opcodes.V1_5 || (access & ClassWriter.ACC_SYNTHETIC_ATTRIBUTE) != 0) {
out.putShort(cw.newUTF8("Synthetic")).putInt(0); out.putShort(cw.newUTF8("Synthetic")).putInt(0);
} }
} }
if ((access & Opcodes.ACC_DEPRECATED) != 0) { if ((access & Opcodes.ACC_DEPRECATED) != 0) {
out.putShort(cw.newUTF8("Deprecated")).putInt(0); out.putShort(cw.newUTF8("Deprecated")).putInt(0);
} }
if (signature != 0) { if (signature != 0) {
out.putShort(cw.newUTF8("Signature")); out.putShort(cw.newUTF8("Signature"));
out.putInt(2).putShort(signature); out.putInt(2).putShort(signature);
} }
if (anns != null) { if (anns != null) {
out.putShort(cw.newUTF8("RuntimeVisibleAnnotations")); out.putShort(cw.newUTF8("RuntimeVisibleAnnotations"));
anns.put(out); anns.put(out);
} }
if (ianns != null) { if (ianns != null) {
out.putShort(cw.newUTF8("RuntimeInvisibleAnnotations")); out.putShort(cw.newUTF8("RuntimeInvisibleAnnotations"));
ianns.put(out); ianns.put(out);
} }
if (tanns != null) { if (tanns != null) {
out.putShort(cw.newUTF8("RuntimeVisibleTypeAnnotations")); out.putShort(cw.newUTF8("RuntimeVisibleTypeAnnotations"));
tanns.put(out); tanns.put(out);
} }
if (itanns != null) { if (itanns != null) {
out.putShort(cw.newUTF8("RuntimeInvisibleTypeAnnotations")); out.putShort(cw.newUTF8("RuntimeInvisibleTypeAnnotations"));
itanns.put(out); itanns.put(out);
} }
if (attrs != null) { if (attrs != null) {
attrs.put(cw, null, 0, -1, -1, out); 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. * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
* *
* *
* *
* *
* *
* *
* *
* *
* *
* *
* *
* *
* *
* *
* *
* *
* *
* *
* *
* *
*/ */
/* /*
* *
* *
* *
* *
* *
* ASM: a very small and fast Java bytecode manipulation framework * ASM: a very small and fast Java bytecode manipulation framework
* Copyright (c) 2000-2011 INRIA, France Telecom * Copyright (c) 2000-2011 INRIA, France Telecom
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
* are met: * are met:
* 1. Redistributions of source code must retain the above copyright * 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright * 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders nor the names of its * 3. Neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from * contributors may be used to endorse or promote products derived from
* this software without specific prior written permission. * this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE. * THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package org.redkale.asm; package org.redkale.asm;
/** /**
* A reference to a field or a method. * A reference to a field or a method.
* *
* @author Remi Forax * @author Remi Forax
* @author Eric Bruneton * @author Eric Bruneton
*/ */
public final class Handle { public final class Handle {
/** /**
* The kind of field or method designated by this Handle. Should be {@link Opcodes#H_GETFIELD}, * 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_GETSTATIC}, {@link Opcodes#H_PUTFIELD}, {@link Opcodes#H_PUTSTATIC},
* {@link Opcodes#H_INVOKEVIRTUAL}, {@link Opcodes#H_INVOKESTATIC}, {@link Opcodes#H_INVOKESPECIAL}, * {@link Opcodes#H_INVOKEVIRTUAL}, {@link Opcodes#H_INVOKESTATIC}, {@link Opcodes#H_INVOKESPECIAL},
* {@link Opcodes#H_NEWINVOKESPECIAL} or {@link Opcodes#H_INVOKEINTERFACE}. * {@link Opcodes#H_NEWINVOKESPECIAL} or {@link Opcodes#H_INVOKEINTERFACE}.
*/ */
final int tag; final int tag;
/** The internal name of the class that owns the field or method designated by this handle. */ /** The internal name of the class that owns the field or method designated by this handle. */
final String owner; final String owner;
/** The name of the field or method designated by this handle. */ /** The name of the field or method designated by this handle. */
final String name; final String name;
/** The descriptor of the field or method designated by this handle. */ /** The descriptor of the field or method designated by this handle. */
final String desc; final String desc;
/** Indicate if the owner is an interface or not. */ /** Indicate if the owner is an interface or not. */
final boolean itf; final boolean itf;
/** /**
* Constructs a new field or method handle. * Constructs a new field or method handle.
* *
* @param tag the kind of field or method designated by this Handle. Must be {@link Opcodes#H_GETFIELD}, * @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_GETSTATIC}, {@link Opcodes#H_PUTFIELD}, {@link Opcodes#H_PUTSTATIC},
* {@link Opcodes#H_INVOKEVIRTUAL}, {@link Opcodes#H_INVOKESTATIC}, {@link Opcodes#H_INVOKESPECIAL}, * {@link Opcodes#H_INVOKEVIRTUAL}, {@link Opcodes#H_INVOKESTATIC}, {@link Opcodes#H_INVOKESPECIAL},
* {@link Opcodes#H_NEWINVOKESPECIAL} or {@link Opcodes#H_INVOKEINTERFACE}. * {@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 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 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 desc the descriptor of the field or method designated by this handle.
* @param itf true if the owner is an interface. * @param itf true if the owner is an interface.
*/ */
public Handle(int tag, String owner, String name, String desc, boolean itf) { public Handle(int tag, String owner, String name, String desc, boolean itf) {
this.tag = tag; this.tag = tag;
this.owner = owner; this.owner = owner;
this.name = name; this.name = name;
this.desc = desc; this.desc = desc;
this.itf = itf; this.itf = itf;
} }
/** /**
* Returns the kind of field or method designated by this handle. * Returns the kind of field or method designated by this handle.
* *
* @return {@link Opcodes#H_GETFIELD}, {@link Opcodes#H_GETSTATIC}, {@link Opcodes#H_PUTFIELD}, * @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_PUTSTATIC}, {@link Opcodes#H_INVOKEVIRTUAL}, {@link Opcodes#H_INVOKESTATIC},
* {@link Opcodes#H_INVOKESPECIAL}, {@link Opcodes#H_NEWINVOKESPECIAL} or {@link Opcodes#H_INVOKEINTERFACE}. * {@link Opcodes#H_INVOKESPECIAL}, {@link Opcodes#H_NEWINVOKESPECIAL} or {@link Opcodes#H_INVOKEINTERFACE}.
*/ */
public int getTag() { public int getTag() {
return tag; return tag;
} }
/** /**
* Returns the internal name of the class that owns the field or method designated by this handle. * Returns the internal name of the class that owns the field or method designated by this handle.
* *
* @return the internal name of the class that owns the field or method designated by this handle. * @return the internal name of the class that owns the field or method designated by this handle.
*/ */
public String getOwner() { public String getOwner() {
return owner; return owner;
} }
/** /**
* Returns the name of the field or method designated by this handle. * Returns the name of the field or method designated by this handle.
* *
* @return 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() { public String getName() {
return name; return name;
} }
/** /**
* Returns the descriptor of the field or method designated by this handle. * Returns the descriptor of the field or method designated by this handle.
* *
* @return 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() { public String getDesc() {
return desc; return desc;
} }
/** /**
* Returns true if the owner of the field or method designated by this handle is an interface. * Returns true if the owner of the field or method designated by this handle is an interface.
* *
* @return true if the owner of the field or method designated by this handle is an interface. * @return true if the owner of the field or method designated by this handle is an interface.
*/ */
public boolean isInterface() { public boolean isInterface() {
return itf; return itf;
} }
@Override @Override
public boolean equals(Object obj) { public boolean equals(Object obj) {
if (obj == this) { if (obj == this) {
return true; return true;
} }
if (!(obj instanceof Handle)) { if (!(obj instanceof Handle)) {
return false; return false;
} }
Handle h = (Handle) obj; Handle h = (Handle) obj;
return tag == h.tag && itf == h.itf && owner.equals(h.owner) && name.equals(h.name) && desc.equals(h.desc); return tag == h.tag && itf == h.itf && owner.equals(h.owner) && name.equals(h.name) && desc.equals(h.desc);
} }
@Override @Override
public int hashCode() { public int hashCode() {
return tag + (itf ? 64 : 0) + owner.hashCode() * name.hashCode() * desc.hashCode(); return tag + (itf ? 64 : 0) + owner.hashCode() * name.hashCode() * desc.hashCode();
} }
/** /**
* Returns the textual representation of this handle. The textual representation is: * Returns the textual representation of this handle. The textual representation is:
* *
* <pre> * <pre>
* for a reference to a class: * for a reference to a class:
* owner '.' name desc ' ' '(' tag ')' * owner '.' name desc ' ' '(' tag ')'
* for a reference to an interface: * for a reference to an interface:
* owner '.' name desc ' ' '(' tag ' ' itf ')' * owner '.' name desc ' ' '(' tag ' ' itf ')'
* </pre> * </pre>
* *
* . As this format is unambiguous, it can be parsed if necessary. * . As this format is unambiguous, it can be parsed if necessary.
*/ */
@Override @Override
public String toString() { public String toString() {
return owner + '.' + name + desc + " (" + tag + (itf ? " itf" : "") + ')'; return owner + '.' + name + desc + " (" + tag + (itf ? " itf" : "") + ')';
} }
} }

View File

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

View File

@@ -1,289 +1,289 @@
/* /*
* ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
* *
* *
* *
* *
* *
* *
* *
* *
* *
* *
* *
* *
* *
* *
* *
* *
* *
* *
* *
* *
*/ */
/* /*
* *
* *
* *
* *
* *
* ASM: a very small and fast Java bytecode manipulation framework * ASM: a very small and fast Java bytecode manipulation framework
* Copyright (c) 2000-2011 INRIA, France Telecom * Copyright (c) 2000-2011 INRIA, France Telecom
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
* are met: * are met:
* 1. Redistributions of source code must retain the above copyright * 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright * 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders nor the names of its * 3. Neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from * contributors may be used to endorse or promote products derived from
* this software without specific prior written permission. * this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE. * THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package org.redkale.asm; package org.redkale.asm;
/** /**
* A constant pool item. Constant pool items can be created with the 'newXXX' methods in the {@link ClassWriter} class. * A constant pool item. Constant pool items can be created with the 'newXXX' methods in the {@link ClassWriter} class.
* *
* @author Eric Bruneton * @author Eric Bruneton
*/ */
final class Item { final class Item {
/** Index of this item in the constant pool. */ /** Index of this item in the constant pool. */
int index; int index;
/** /**
* Type of this constant pool item. A single class is used to represent all constant pool item types, in order to * 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}, * 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#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#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#METH}, {@link ClassWriter#IMETH}, {@link ClassWriter#MODULE}, {@link ClassWriter#PACKAGE},
* {@link ClassWriter#MTYPE}, {@link ClassWriter#INDY}. * {@link ClassWriter#MTYPE}, {@link ClassWriter#INDY}.
* *
* <p>MethodHandle constant 9 variations are stored using a range of 9 values from {@link ClassWriter#HANDLE_BASE} + * <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. * 1 to {@link ClassWriter#HANDLE_BASE} + 9.
* *
* <p>Special Item types are used for Items that are stored in the ClassWriter {@link ClassWriter#typeTable}, * <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 * 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}, * constant pool's hash table. These special item types are {@link ClassWriter#TYPE_NORMAL},
* {@link ClassWriter#TYPE_UNINIT} and {@link ClassWriter#TYPE_MERGED}. * {@link ClassWriter#TYPE_UNINIT} and {@link ClassWriter#TYPE_MERGED}.
*/ */
int type; int type;
/** Value of this item, for an integer item. */ /** Value of this item, for an integer item. */
int intVal; int intVal;
/** Value of this item, for a long item. */ /** Value of this item, for a long item. */
long longVal; long longVal;
/** First part of the value of this item, for items that do not hold a primitive value. */ /** First part of the value of this item, for items that do not hold a primitive value. */
String strVal1; String strVal1;
/** Second part of the value of this item, for items that do not hold a primitive value. */ /** Second part of the value of this item, for items that do not hold a primitive value. */
String strVal2; String strVal2;
/** Third part of the value of this item, for items that do not hold a primitive value. */ /** Third part of the value of this item, for items that do not hold a primitive value. */
String strVal3; String strVal3;
/** The hash code value of this constant pool item. */ /** The hash code value of this constant pool item. */
int hashCode; int hashCode;
/** Link to another constant pool item, used for collision lists in the constant pool's hash table. */ /** Link to another constant pool item, used for collision lists in the constant pool's hash table. */
Item next; Item next;
/** Constructs an uninitialized {@link Item}. */ /** Constructs an uninitialized {@link Item}. */
Item() {} Item() {}
/** /**
* Constructs an uninitialized {@link Item} for constant pool element at given position. * Constructs an uninitialized {@link Item} for constant pool element at given position.
* *
* @param index index of the item to be constructed. * @param index index of the item to be constructed.
*/ */
Item(final int index) { Item(final int index) {
this.index = index; this.index = index;
} }
/** /**
* Constructs a copy of the given item. * Constructs a copy of the given item.
* *
* @param index index of the item to be constructed. * @param index index of the item to be constructed.
* @param i the item that must be copied into the item to be constructed. * @param i the item that must be copied into the item to be constructed.
*/ */
Item(final int index, final Item i) { Item(final int index, final Item i) {
this.index = index; this.index = index;
type = i.type; type = i.type;
intVal = i.intVal; intVal = i.intVal;
longVal = i.longVal; longVal = i.longVal;
strVal1 = i.strVal1; strVal1 = i.strVal1;
strVal2 = i.strVal2; strVal2 = i.strVal2;
strVal3 = i.strVal3; strVal3 = i.strVal3;
hashCode = i.hashCode; hashCode = i.hashCode;
} }
/** /**
* Sets this item to an integer item. * Sets this item to an integer item.
* *
* @param intVal the value of this item. * @param intVal the value of this item.
*/ */
void set(final int intVal) { void set(final int intVal) {
this.type = ClassWriter.INT; this.type = ClassWriter.INT;
this.intVal = intVal; this.intVal = intVal;
this.hashCode = 0x7FFFFFFF & (type + intVal); this.hashCode = 0x7FFFFFFF & (type + intVal);
} }
/** /**
* Sets this item to a long item. * Sets this item to a long item.
* *
* @param longVal the value of this item. * @param longVal the value of this item.
*/ */
void set(final long longVal) { void set(final long longVal) {
this.type = ClassWriter.LONG; this.type = ClassWriter.LONG;
this.longVal = longVal; this.longVal = longVal;
this.hashCode = 0x7FFFFFFF & (type + (int) longVal); this.hashCode = 0x7FFFFFFF & (type + (int) longVal);
} }
/** /**
* Sets this item to a float item. * Sets this item to a float item.
* *
* @param floatVal the value of this item. * @param floatVal the value of this item.
*/ */
void set(final float floatVal) { void set(final float floatVal) {
this.type = ClassWriter.FLOAT; this.type = ClassWriter.FLOAT;
this.intVal = Float.floatToRawIntBits(floatVal); this.intVal = Float.floatToRawIntBits(floatVal);
this.hashCode = 0x7FFFFFFF & (type + (int) floatVal); this.hashCode = 0x7FFFFFFF & (type + (int) floatVal);
} }
/** /**
* Sets this item to a double item. * Sets this item to a double item.
* *
* @param doubleVal the value of this item. * @param doubleVal the value of this item.
*/ */
void set(final double doubleVal) { void set(final double doubleVal) {
this.type = ClassWriter.DOUBLE; this.type = ClassWriter.DOUBLE;
this.longVal = Double.doubleToRawLongBits(doubleVal); this.longVal = Double.doubleToRawLongBits(doubleVal);
this.hashCode = 0x7FFFFFFF & (type + (int) doubleVal); this.hashCode = 0x7FFFFFFF & (type + (int) doubleVal);
} }
/** /**
* Sets this item to an item that do not hold a primitive value. * Sets this item to an item that do not hold a primitive value.
* *
* @param type the type of this item. * @param type the type of this item.
* @param strVal1 first part of the value of this item. * @param strVal1 first part of the value of this item.
* @param strVal2 second part of the value of this item. * @param strVal2 second part of the value of this item.
* @param strVal3 third part of the value of this item. * @param strVal3 third part of the value of this item.
*/ */
@SuppressWarnings("fallthrough") @SuppressWarnings("fallthrough")
void set(final int type, final String strVal1, final String strVal2, final String strVal3) { void set(final int type, final String strVal1, final String strVal2, final String strVal3) {
this.type = type; this.type = type;
this.strVal1 = strVal1; this.strVal1 = strVal1;
this.strVal2 = strVal2; this.strVal2 = strVal2;
this.strVal3 = strVal3; this.strVal3 = strVal3;
switch (type) { switch (type) {
case ClassWriter.CLASS: case ClassWriter.CLASS:
this.intVal = 0; // intVal of a class must be zero, see visitInnerClass this.intVal = 0; // intVal of a class must be zero, see visitInnerClass
case ClassWriter.UTF8: case ClassWriter.UTF8:
case ClassWriter.STR: case ClassWriter.STR:
case ClassWriter.MTYPE: case ClassWriter.MTYPE:
case ClassWriter.MODULE: case ClassWriter.MODULE:
case ClassWriter.PACKAGE: case ClassWriter.PACKAGE:
case ClassWriter.TYPE_NORMAL: case ClassWriter.TYPE_NORMAL:
hashCode = 0x7FFFFFFF & (type + strVal1.hashCode()); hashCode = 0x7FFFFFFF & (type + strVal1.hashCode());
return; return;
case ClassWriter.NAME_TYPE: { case ClassWriter.NAME_TYPE: {
hashCode = 0x7FFFFFFF & (type + strVal1.hashCode() * strVal2.hashCode()); hashCode = 0x7FFFFFFF & (type + strVal1.hashCode() * strVal2.hashCode());
return; return;
} }
// ClassWriter.FIELD: // ClassWriter.FIELD:
// ClassWriter.METH: // ClassWriter.METH:
// ClassWriter.IMETH: // ClassWriter.IMETH:
// ClassWriter.HANDLE_BASE + 1..9 // ClassWriter.HANDLE_BASE + 1..9
default: default:
hashCode = 0x7FFFFFFF & (type + strVal1.hashCode() * strVal2.hashCode() * strVal3.hashCode()); hashCode = 0x7FFFFFFF & (type + strVal1.hashCode() * strVal2.hashCode() * strVal3.hashCode());
} }
} }
/** /**
* Sets the item to an InvokeDynamic item. * Sets the item to an InvokeDynamic item.
* *
* @param name invokedynamic's name. * @param name invokedynamic's name.
* @param desc invokedynamic's desc. * @param desc invokedynamic's desc.
* @param bsmIndex zero based index into the class attribute BootrapMethods. * @param bsmIndex zero based index into the class attribute BootrapMethods.
*/ */
void set(String name, String desc, int bsmIndex) { void set(String name, String desc, int bsmIndex) {
this.type = ClassWriter.INDY; this.type = ClassWriter.INDY;
this.longVal = bsmIndex; this.longVal = bsmIndex;
this.strVal1 = name; this.strVal1 = name;
this.strVal2 = desc; this.strVal2 = desc;
this.hashCode = 0x7FFFFFFF & (ClassWriter.INDY + bsmIndex * strVal1.hashCode() * strVal2.hashCode()); this.hashCode = 0x7FFFFFFF & (ClassWriter.INDY + bsmIndex * strVal1.hashCode() * strVal2.hashCode());
} }
/** /**
* Sets the item to a BootstrapMethod item. * Sets the item to a BootstrapMethod item.
* *
* @param position position in byte in the class attribute BootrapMethods. * @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 * @param hashCode hashcode of the item. This hashcode is processed from the hashcode of the bootstrap method and
* the hashcode of all bootstrap arguments. * the hashcode of all bootstrap arguments.
*/ */
void set(int position, int hashCode) { void set(int position, int hashCode) {
this.type = ClassWriter.BSM; this.type = ClassWriter.BSM;
this.intVal = position; this.intVal = position;
this.hashCode = hashCode; this.hashCode = hashCode;
} }
/** /**
* Indicates if the given item is equal to this one. <i>This method assumes that the two items have the same * Indicates if the given item is equal to this one. <i>This method assumes that the two items have the same
* {@link #type}</i>. * {@link #type}</i>.
* *
* @param i the item to be compared to this one. Both items must have the same {@link #type}. * @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; * @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. * otherwise.
*/ */
boolean isEqualTo(final Item i) { boolean isEqualTo(final Item i) {
switch (type) { switch (type) {
case ClassWriter.UTF8: case ClassWriter.UTF8:
case ClassWriter.STR: case ClassWriter.STR:
case ClassWriter.CLASS: case ClassWriter.CLASS:
case ClassWriter.MODULE: case ClassWriter.MODULE:
case ClassWriter.PACKAGE: case ClassWriter.PACKAGE:
case ClassWriter.MTYPE: case ClassWriter.MTYPE:
case ClassWriter.TYPE_NORMAL: case ClassWriter.TYPE_NORMAL:
return i.strVal1.equals(strVal1); return i.strVal1.equals(strVal1);
case ClassWriter.TYPE_MERGED: case ClassWriter.TYPE_MERGED:
case ClassWriter.LONG: case ClassWriter.LONG:
case ClassWriter.DOUBLE: case ClassWriter.DOUBLE:
return i.longVal == longVal; return i.longVal == longVal;
case ClassWriter.INT: case ClassWriter.INT:
case ClassWriter.FLOAT: case ClassWriter.FLOAT:
return i.intVal == intVal; return i.intVal == intVal;
case ClassWriter.TYPE_UNINIT: case ClassWriter.TYPE_UNINIT:
return i.intVal == intVal && i.strVal1.equals(strVal1); return i.intVal == intVal && i.strVal1.equals(strVal1);
case ClassWriter.NAME_TYPE: case ClassWriter.NAME_TYPE:
return i.strVal1.equals(strVal1) && i.strVal2.equals(strVal2); return i.strVal1.equals(strVal1) && i.strVal2.equals(strVal2);
case ClassWriter.INDY: { case ClassWriter.INDY: {
return i.longVal == longVal && i.strVal1.equals(strVal1) && i.strVal2.equals(strVal2); return i.longVal == longVal && i.strVal1.equals(strVal1) && i.strVal2.equals(strVal2);
} }
// case ClassWriter.FIELD: // case ClassWriter.FIELD:
// case ClassWriter.METH: // case ClassWriter.METH:
// case ClassWriter.IMETH: // case ClassWriter.IMETH:
// case ClassWriter.HANDLE_BASE + 1..9 // case ClassWriter.HANDLE_BASE + 1..9
default: default:
return i.strVal1.equals(strVal1) && i.strVal2.equals(strVal2) && i.strVal3.equals(strVal3); 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. * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
* *
* *
* *
* *
* *
* *
* *
* *
* *
* *
* *
* *
* *
* *
* *
* *
* *
* *
* *
* *
*/ */
/* /*
* *
* *
* *
* *
* *
* ASM: a very small and fast Java bytecode manipulation framework * ASM: a very small and fast Java bytecode manipulation framework
* Copyright (c) 2000-2011 INRIA, France Telecom * Copyright (c) 2000-2011 INRIA, France Telecom
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
* are met: * are met:
* 1. Redistributions of source code must retain the above copyright * 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright * 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders nor the names of its * 3. Neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from * contributors may be used to endorse or promote products derived from
* this software without specific prior written permission. * this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE. * THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package org.redkale.asm; package org.redkale.asm;
/** /**
* A visitor to visit a Java module. The methods of this class must be called in the following order: * 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;visitMainClass&#60;/tt&#62; | ( &#60;tt&#62;visitPackage&#60;/tt&#62; |
* &#60;tt&#62;visitRequire&#60;/tt&#62; | &#60;tt&#62;visitExport&#60;/tt&#62; | &#60;tt&#62;visitOpen&#60;/tt&#62; | * &#60;tt&#62;visitRequire&#60;/tt&#62; | &#60;tt&#62;visitExport&#60;/tt&#62; | &#60;tt&#62;visitOpen&#60;/tt&#62; |
* &#60;tt&#62;visitUse&#60;/tt&#62; | &#60;tt&#62;visitProvide&#60;/tt&#62; )* &#60;tt&#62;visitEnd&#60;/tt&#62;. * &#60;tt&#62;visitUse&#60;/tt&#62; | &#60;tt&#62;visitProvide&#60;/tt&#62; )* &#60;tt&#62;visitEnd&#60;/tt&#62;.
* *
* <p>The methods {@link #visitRequire(String, int, String)}, {@link #visitExport(String, int, String...)}, * <p>The methods {@link #visitRequire(String, int, String)}, {@link #visitExport(String, int, String...)},
* {@link #visitOpen(String, int, String...)} and {@link #visitPackage(String)} take as parameter a package name or a * {@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 * 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). * qualified names (names separated by dot).
* *
* @author Remi Forax * @author Remi Forax
*/ */
public abstract class ModuleVisitor { public abstract class ModuleVisitor {
/** The ASM API version implemented by this visitor. The value of this field must be {@link Opcodes#ASM6}. */ /** The ASM API version implemented by this visitor. The value of this field must be {@link Opcodes#ASM6}. */
protected final int api; protected final int api;
/** The module visitor to which this visitor must delegate method calls. May be null. */ /** The module visitor to which this visitor must delegate method calls. May be null. */
protected ModuleVisitor mv; protected ModuleVisitor mv;
/** /**
* Constructs a new {@link ModuleVisitor}. * Constructs a new {@link ModuleVisitor}.
* *
* @param api the ASM API version implemented by this visitor. Must be {@link Opcodes#ASM6}. * @param api the ASM API version implemented by this visitor. Must be {@link Opcodes#ASM6}.
*/ */
public ModuleVisitor(final int api) { public ModuleVisitor(final int api) {
this(api, null); this(api, null);
} }
/** /**
* Constructs a new {@link ModuleVisitor}. * Constructs a new {@link ModuleVisitor}.
* *
* @param api the ASM API version implemented by this visitor. Must be {@link Opcodes#ASM6}. * @param api the ASM API version implemented by this visitor. Must be {@link Opcodes#ASM6}.
* @param mv the module visitor to which this visitor must delegate method calls. May be null. * @param mv the module visitor to which this visitor must delegate method calls. May be null.
*/ */
public ModuleVisitor(final int api, final ModuleVisitor mv) { public ModuleVisitor(final int api, final ModuleVisitor mv) {
if (api != Opcodes.ASM6) { if (api != Opcodes.ASM6) {
throw new IllegalArgumentException(); throw new IllegalArgumentException();
} }
this.api = api; this.api = api;
this.mv = mv; this.mv = mv;
} }
/** /**
* Visit the main class of the current module. * Visit the main class of the current module.
* *
* @param mainClass the internal name of 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) { public void visitMainClass(String mainClass) {
if (mv != null) { if (mv != null) {
mv.visitMainClass(mainClass); mv.visitMainClass(mainClass);
} }
} }
/** /**
* Visit a package of the current module. * Visit a package of the current module.
* *
* @param packaze the qualified name of a package. * @param packaze the qualified name of a package.
*/ */
public void visitPackage(String packaze) { public void visitPackage(String packaze) {
if (mv != null) { if (mv != null) {
mv.visitPackage(packaze); mv.visitPackage(packaze);
} }
} }
/** /**
* Visits a dependence of the current module. * Visits a dependence of the current module.
* *
* @param module the qualified name of the dependence. * @param module the qualified name of the dependence.
* @param access the access flag of the dependence among ACC_TRANSITIVE, ACC_STATIC_PHASE, ACC_SYNTHETIC and * @param access the access flag of the dependence among ACC_TRANSITIVE, ACC_STATIC_PHASE, ACC_SYNTHETIC and
* ACC_MANDATED. * ACC_MANDATED.
* @param version the module version at compile time or null. * @param version the module version at compile time or null.
*/ */
public void visitRequire(String module, int access, String version) { public void visitRequire(String module, int access, String version) {
if (mv != null) { if (mv != null) {
mv.visitRequire(module, access, version); mv.visitRequire(module, access, version);
} }
} }
/** /**
* Visit an exported package of the current module. * Visit an exported package of the current module.
* *
* @param packaze the qualified name of the exported package. * @param packaze the qualified name of the exported package.
* @param access the access flag of the exported package, valid values are among {@code ACC_SYNTHETIC} and * @param access the access flag of the exported package, valid values are among {@code ACC_SYNTHETIC} and
* {@code ACC_MANDATED}. * {@code ACC_MANDATED}.
* @param modules the qualified names of the modules that can access to the public classes of the exported package * @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;. * or &#60;tt&#62;null&#60;/tt&#62;.
*/ */
public void visitExport(String packaze, int access, String... modules) { public void visitExport(String packaze, int access, String... modules) {
if (mv != null) { if (mv != null) {
mv.visitExport(packaze, access, modules); mv.visitExport(packaze, access, modules);
} }
} }
/** /**
* Visit an open package of the current module. * Visit an open package of the current module.
* *
* @param packaze the qualified name of the opened package. * @param packaze the qualified name of the opened package.
* @param access the access flag of the opened package, valid values are among {@code ACC_SYNTHETIC} and * @param access the access flag of the opened package, valid values are among {@code ACC_SYNTHETIC} and
* {@code ACC_MANDATED}. * {@code ACC_MANDATED}.
* @param modules the qualified names of the modules that can use deep reflection to the classes of the open package * @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;. * or &#60;tt&#62;null&#60;/tt&#62;.
*/ */
public void visitOpen(String packaze, int access, String... modules) { public void visitOpen(String packaze, int access, String... modules) {
if (mv != null) { if (mv != null) {
mv.visitOpen(packaze, access, modules); 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. * 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. * @param service the internal name of the service.
*/ */
public void visitUse(String service) { public void visitUse(String service) {
if (mv != null) { if (mv != null) {
mv.visitUse(service); mv.visitUse(service);
} }
} }
/** /**
* Visit an implementation of a service. * Visit an implementation of a service.
* *
* @param service the internal name of the service * @param service the internal name of the service
* @param providers the internal names of the implementations of the service (there is at least one provider). * @param providers the internal names of the implementations of the service (there is at least one provider).
*/ */
public void visitProvide(String service, String... providers) { public void visitProvide(String service, String... providers) {
if (mv != null) { if (mv != null) {
mv.visitProvide(service, providers); 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 * 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. * everything have been visited.
*/ */
public void visitEnd() { public void visitEnd() {
if (mv != null) { if (mv != null) {
mv.visitEnd(); mv.visitEnd();
} }
} }
} }

View File

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

View File

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

View File

@@ -1,402 +1,402 @@
/* /*
* ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
* *
* *
* *
* *
* *
* *
* *
* *
* *
* *
* *
* *
* *
* *
* *
* *
* *
* *
* *
* *
*/ */
/* /*
* *
* *
* *
* *
* *
* ASM: a very small and fast Java bytecode manipulation framework * ASM: a very small and fast Java bytecode manipulation framework
* Copyright (c) 2000-2013 INRIA, France Telecom * Copyright (c) 2000-2013 INRIA, France Telecom
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
* are met: * are met:
* 1. Redistributions of source code must retain the above copyright * 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright * 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders nor the names of its * 3. Neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from * contributors may be used to endorse or promote products derived from
* this software without specific prior written permission. * this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE. * THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package org.redkale.asm; package org.redkale.asm;
/** /**
* A reference to a type appearing in a class, field or method declaration, or on an instruction. Such a reference * 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' * 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). * clause, a 'new' instruction, a 'catch' clause, a type cast, a local variable declaration, etc).
* *
* @author Eric Bruneton * @author Eric Bruneton
*/ */
public class TypeReference { public class TypeReference {
/** The sort of type references that target a type parameter of a generic class. See {@link #getSort getSort}. */ /** The sort of type references that target a type parameter of a generic class. See {@link #getSort getSort}. */
public static final int CLASS_TYPE_PARAMETER = 0x00; 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}. */ /** 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; 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 * The sort of type references that target the super class of a class or one of the interfaces it implements. See
* {@link #getSort getSort}. * {@link #getSort getSort}.
*/ */
public static final int CLASS_EXTENDS = 0x10; 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 * The sort of type references that target a bound of a type parameter of a generic class. See {@link #getSort
* getSort}. * getSort}.
*/ */
public static final int CLASS_TYPE_PARAMETER_BOUND = 0x11; 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 * The sort of type references that target a bound of a type parameter of a generic method. See {@link #getSort
* getSort}. * getSort}.
*/ */
public static final int METHOD_TYPE_PARAMETER_BOUND = 0x12; 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}. */ /** The sort of type references that target the type of a field. See {@link #getSort getSort}. */
public static final int FIELD = 0x13; public static final int FIELD = 0x13;
/** The sort of type references that target the return type of a method. See {@link #getSort getSort}. */ /** The sort of type references that target the return type of a method. See {@link #getSort getSort}. */
public static final int METHOD_RETURN = 0x14; public static final int METHOD_RETURN = 0x14;
/** The sort of type references that target the receiver type of a method. See {@link #getSort getSort}. */ /** The sort of type references that target the receiver type of a method. See {@link #getSort getSort}. */
public static final int METHOD_RECEIVER = 0x15; 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}. * 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; 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 * The sort of type references that target the type of an exception declared in the throws clause of a method. See
* {@link #getSort getSort}. * {@link #getSort getSort}.
*/ */
public static final int THROWS = 0x17; 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}. * 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; 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 * The sort of type references that target the type of a resource variable in a method. See {@link #getSort
* getSort}. * getSort}.
*/ */
public static final int RESOURCE_VARIABLE = 0x41; 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 * The sort of type references that target the type of the exception of a 'catch' clause in a method. See
* {@link #getSort getSort}. * {@link #getSort getSort}.
*/ */
public static final int EXCEPTION_PARAMETER = 0x42; public static final int EXCEPTION_PARAMETER = 0x42;
/** /**
* The sort of type references that target the type declared in an 'instanceof' instruction. See {@link #getSort * The sort of type references that target the type declared in an 'instanceof' instruction. See {@link #getSort
* getSort}. * getSort}.
*/ */
public static final int INSTANCEOF = 0x43; public static final int INSTANCEOF = 0x43;
/** /**
* The sort of type references that target the type of the object created by a 'new' instruction. See * The sort of type references that target the type of the object created by a 'new' instruction. See
* {@link #getSort getSort}. * {@link #getSort getSort}.
*/ */
public static final int NEW = 0x44; public static final int NEW = 0x44;
/** /**
* The sort of type references that target the receiver type of a constructor reference. See {@link #getSort * The sort of type references that target the receiver type of a constructor reference. See {@link #getSort
* getSort}. * getSort}.
*/ */
public static final int CONSTRUCTOR_REFERENCE = 0x45; 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}. * 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; 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 * The sort of type references that target the type declared in an explicit or implicit cast instruction. See
* {@link #getSort getSort}. * {@link #getSort getSort}.
*/ */
public static final int CAST = 0x47; 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 * The sort of type references that target a type parameter of a generic constructor in a constructor call. See
* {@link #getSort getSort}. * {@link #getSort getSort}.
*/ */
public static final int CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT = 0x48; 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 * The sort of type references that target a type parameter of a generic method in a method call. See
* {@link #getSort getSort}. * {@link #getSort getSort}.
*/ */
public static final int METHOD_INVOCATION_TYPE_ARGUMENT = 0x49; 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 * The sort of type references that target a type parameter of a generic constructor in a constructor reference. See
* {@link #getSort getSort}. * {@link #getSort getSort}.
*/ */
public static final int CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT = 0x4A; 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 * The sort of type references that target a type parameter of a generic method in a method reference. See
* {@link #getSort getSort}. * {@link #getSort getSort}.
*/ */
public static final int METHOD_REFERENCE_TYPE_ARGUMENT = 0x4B; public static final int METHOD_REFERENCE_TYPE_ARGUMENT = 0x4B;
/** The type reference value in Java class file format. */ /** The type reference value in Java class file format. */
private int value; private int value;
/** /**
* Creates a new TypeReference. * Creates a new TypeReference.
* *
* @param typeRef the int encoded value of the type reference, as received in a visit method related to type * @param typeRef the int encoded value of the type reference, as received in a visit method related to type
* annotations, like visitTypeAnnotation. * annotations, like visitTypeAnnotation.
*/ */
public TypeReference(int typeRef) { public TypeReference(int typeRef) {
this.value = typeRef; this.value = typeRef;
} }
/** /**
* Returns a type reference of the given sort. * Returns a type reference of the given sort.
* *
* @param sort {@link #FIELD FIELD}, {@link #METHOD_RETURN METHOD_RETURN}, {@link #METHOD_RECEIVER METHOD_RECEIVER}, * @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 * {@link #LOCAL_VARIABLE LOCAL_VARIABLE}, {@link #RESOURCE_VARIABLE RESOURCE_VARIABLE}, {@link #INSTANCEOF
* INSTANCEOF}, {@link #NEW NEW}, {@link #CONSTRUCTOR_REFERENCE CONSTRUCTOR_REFERENCE}, or * INSTANCEOF}, {@link #NEW NEW}, {@link #CONSTRUCTOR_REFERENCE CONSTRUCTOR_REFERENCE}, or
* {@link #METHOD_REFERENCE METHOD_REFERENCE}. * {@link #METHOD_REFERENCE METHOD_REFERENCE}.
* @return a type reference of the given sort. * @return a type reference of the given sort.
*/ */
public static TypeReference newTypeReference(int sort) { public static TypeReference newTypeReference(int sort) {
return new TypeReference(sort << 24); return new TypeReference(sort << 24);
} }
/** /**
* Returns a reference to a type parameter of a generic class or method. * Returns a reference to a type parameter of a generic class or method.
* *
* @param sort {@link #CLASS_TYPE_PARAMETER CLASS_TYPE_PARAMETER} or {@link #METHOD_TYPE_PARAMETER * @param sort {@link #CLASS_TYPE_PARAMETER CLASS_TYPE_PARAMETER} or {@link #METHOD_TYPE_PARAMETER
* METHOD_TYPE_PARAMETER}. * METHOD_TYPE_PARAMETER}.
* @param paramIndex the type parameter index. * @param paramIndex the type parameter index.
* @return a reference to the given generic class or method type parameter. * @return a reference to the given generic class or method type parameter.
*/ */
public static TypeReference newTypeParameterReference(int sort, int paramIndex) { public static TypeReference newTypeParameterReference(int sort, int paramIndex) {
return new TypeReference((sort << 24) | (paramIndex << 16)); return new TypeReference((sort << 24) | (paramIndex << 16));
} }
/** /**
* Returns a reference to a type parameter bound of a generic class or method. * Returns a reference to a type parameter bound of a generic class or method.
* *
* @param sort {@link #CLASS_TYPE_PARAMETER CLASS_TYPE_PARAMETER} or {@link #METHOD_TYPE_PARAMETER * @param sort {@link #CLASS_TYPE_PARAMETER CLASS_TYPE_PARAMETER} or {@link #METHOD_TYPE_PARAMETER
* METHOD_TYPE_PARAMETER}. * METHOD_TYPE_PARAMETER}.
* @param paramIndex the type parameter index. * @param paramIndex the type parameter index.
* @param boundIndex the type bound index within the above type parameters. * @param boundIndex the type bound index within the above type parameters.
* @return a reference to the given generic class or method type parameter bound. * @return a reference to the given generic class or method type parameter bound.
*/ */
public static TypeReference newTypeParameterBoundReference(int sort, int paramIndex, int boundIndex) { public static TypeReference newTypeParameterBoundReference(int sort, int paramIndex, int boundIndex) {
return new TypeReference((sort << 24) | (paramIndex << 16) | (boundIndex << 8)); return new TypeReference((sort << 24) | (paramIndex << 16) | (boundIndex << 8));
} }
/** /**
* Returns a reference to the super class or to an interface of the 'implements' clause of a class. * Returns a reference to the super class or to an interface of the 'implements' clause of a class.
* *
* @param itfIndex the index of an interface in the 'implements' clause of a class, or -1 to reference the super * @param itfIndex the index of an interface in the 'implements' clause of a class, or -1 to reference the super
* class of the class. * class of the class.
* @return a reference to the given super type of a class. * @return a reference to the given super type of a class.
*/ */
public static TypeReference newSuperTypeReference(int itfIndex) { public static TypeReference newSuperTypeReference(int itfIndex) {
itfIndex &= 0xFFFF; itfIndex &= 0xFFFF;
return new TypeReference((CLASS_EXTENDS << 24) | (itfIndex << 8)); return new TypeReference((CLASS_EXTENDS << 24) | (itfIndex << 8));
} }
/** /**
* Returns a reference to the type of a formal parameter of a method. * Returns a reference to the type of a formal parameter of a method.
* *
* @param paramIndex the formal parameter index. * @param paramIndex the formal parameter index.
* @return a reference to the type of the given method formal parameter. * @return a reference to the type of the given method formal parameter.
*/ */
public static TypeReference newFormalParameterReference(int paramIndex) { public static TypeReference newFormalParameterReference(int paramIndex) {
return new TypeReference((METHOD_FORMAL_PARAMETER << 24) | (paramIndex << 16)); return new TypeReference((METHOD_FORMAL_PARAMETER << 24) | (paramIndex << 16));
} }
/** /**
* Returns a reference to the type of an exception, in a 'throws' clause of a method. * 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. * @param exceptionIndex the index of an exception in a 'throws' clause of a method.
* @return a reference to the type of the given exception. * @return a reference to the type of the given exception.
*/ */
public static TypeReference newExceptionReference(int exceptionIndex) { public static TypeReference newExceptionReference(int exceptionIndex) {
return new TypeReference((THROWS << 24) | (exceptionIndex << 8)); return new TypeReference((THROWS << 24) | (exceptionIndex << 8));
} }
/** /**
* Returns a reference to the type of the exception declared in a 'catch' clause of a method. * 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 * @param tryCatchBlockIndex the index of a try catch block (using the order in which they are visited with
* visitTryCatchBlock). * visitTryCatchBlock).
* @return a reference to the type of the given exception. * @return a reference to the type of the given exception.
*/ */
public static TypeReference newTryCatchReference(int tryCatchBlockIndex) { public static TypeReference newTryCatchReference(int tryCatchBlockIndex) {
return new TypeReference((EXCEPTION_PARAMETER << 24) | (tryCatchBlockIndex << 8)); return new TypeReference((EXCEPTION_PARAMETER << 24) | (tryCatchBlockIndex << 8));
} }
/** /**
* Returns a reference to the type of a type argument in a constructor or method call or reference. * Returns a reference to the type of a type argument in a constructor or method call or reference.
* *
* @param sort {@link #CAST CAST}, {@link #CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT * @param sort {@link #CAST CAST}, {@link #CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT
* CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT}, {@link #METHOD_INVOCATION_TYPE_ARGUMENT * CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT}, {@link #METHOD_INVOCATION_TYPE_ARGUMENT
* METHOD_INVOCATION_TYPE_ARGUMENT}, {@link #CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT * METHOD_INVOCATION_TYPE_ARGUMENT}, {@link #CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT
* CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT}, or {@link #METHOD_REFERENCE_TYPE_ARGUMENT * CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT}, or {@link #METHOD_REFERENCE_TYPE_ARGUMENT
* METHOD_REFERENCE_TYPE_ARGUMENT}. * METHOD_REFERENCE_TYPE_ARGUMENT}.
* @param argIndex the type argument index. * @param argIndex the type argument index.
* @return a reference to the type of the given type argument. * @return a reference to the type of the given type argument.
*/ */
public static TypeReference newTypeArgumentReference(int sort, int argIndex) { public static TypeReference newTypeArgumentReference(int sort, int argIndex) {
return new TypeReference((sort << 24) | argIndex); return new TypeReference((sort << 24) | argIndex);
} }
/** /**
* Returns the sort of this type reference. * Returns the sort of this type reference.
* *
* @return {@link #CLASS_TYPE_PARAMETER CLASS_TYPE_PARAMETER}, {@link #METHOD_TYPE_PARAMETER METHOD_TYPE_PARAMETER}, * @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 #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 * {@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_RETURN}, {@link #METHOD_RECEIVER METHOD_RECEIVER}, {@link #METHOD_FORMAL_PARAMETER
* METHOD_FORMAL_PARAMETER}, {@link #THROWS THROWS}, {@link #LOCAL_VARIABLE LOCAL_VARIABLE}, * METHOD_FORMAL_PARAMETER}, {@link #THROWS THROWS}, {@link #LOCAL_VARIABLE LOCAL_VARIABLE},
* {@link #RESOURCE_VARIABLE RESOURCE_VARIABLE}, {@link #EXCEPTION_PARAMETER EXCEPTION_PARAMETER}, * {@link #RESOURCE_VARIABLE RESOURCE_VARIABLE}, {@link #EXCEPTION_PARAMETER EXCEPTION_PARAMETER},
* {@link #INSTANCEOF INSTANCEOF}, {@link #NEW NEW}, {@link #CONSTRUCTOR_REFERENCE CONSTRUCTOR_REFERENCE}, * {@link #INSTANCEOF INSTANCEOF}, {@link #NEW NEW}, {@link #CONSTRUCTOR_REFERENCE CONSTRUCTOR_REFERENCE},
* {@link #METHOD_REFERENCE METHOD_REFERENCE}, {@link #CAST CAST}, {@link #CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT * {@link #METHOD_REFERENCE METHOD_REFERENCE}, {@link #CAST CAST}, {@link #CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT
* CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT}, {@link #METHOD_INVOCATION_TYPE_ARGUMENT * CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT}, {@link #METHOD_INVOCATION_TYPE_ARGUMENT
* METHOD_INVOCATION_TYPE_ARGUMENT}, {@link #CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT * METHOD_INVOCATION_TYPE_ARGUMENT}, {@link #CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT
* CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT}, or {@link #METHOD_REFERENCE_TYPE_ARGUMENT * CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT}, or {@link #METHOD_REFERENCE_TYPE_ARGUMENT
* METHOD_REFERENCE_TYPE_ARGUMENT}. * METHOD_REFERENCE_TYPE_ARGUMENT}.
*/ */
public int getSort() { public int getSort() {
return value >>> 24; return value >>> 24;
} }
/** /**
* Returns the index of the type parameter referenced by this type reference. This method must only be used for type * 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 * 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 * METHOD_TYPE_PARAMETER}, {@link #CLASS_TYPE_PARAMETER_BOUND CLASS_TYPE_PARAMETER_BOUND} or
* {@link #METHOD_TYPE_PARAMETER_BOUND METHOD_TYPE_PARAMETER_BOUND}. * {@link #METHOD_TYPE_PARAMETER_BOUND METHOD_TYPE_PARAMETER_BOUND}.
* *
* @return a type parameter index. * @return a type parameter index.
*/ */
public int getTypeParameterIndex() { public int getTypeParameterIndex() {
return (value & 0x00FF0000) >> 16; return (value & 0x00FF0000) >> 16;
} }
/** /**
* Returns the index of the type parameter bound, within the type parameter {@link #getTypeParameterIndex}, * 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 * 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 * {@link #CLASS_TYPE_PARAMETER_BOUND CLASS_TYPE_PARAMETER_BOUND} or {@link #METHOD_TYPE_PARAMETER_BOUND
* METHOD_TYPE_PARAMETER_BOUND}. * METHOD_TYPE_PARAMETER_BOUND}.
* *
* @return a type parameter bound index. * @return a type parameter bound index.
*/ */
public int getTypeParameterBoundIndex() { public int getTypeParameterBoundIndex() {
return (value & 0x0000FF00) >> 8; 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 * 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}. * 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 * @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. * the type of the super class.
*/ */
public int getSuperTypeIndex() { public int getSuperTypeIndex() {
return (short) ((value & 0x00FFFF00) >> 8); return (short) ((value & 0x00FFFF00) >> 8);
} }
/** /**
* Returns the index of the formal parameter whose type is referenced by this type reference. This method must only * 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}. * be used for type references whose sort is {@link #METHOD_FORMAL_PARAMETER METHOD_FORMAL_PARAMETER}.
* *
* @return a formal parameter index. * @return a formal parameter index.
*/ */
public int getFormalParameterIndex() { public int getFormalParameterIndex() {
return (value & 0x00FF0000) >> 16; return (value & 0x00FF0000) >> 16;
} }
/** /**
* Returns the index of the exception, in a 'throws' clause of a method, whose type is referenced by this type * 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}. * 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. * @return the index of an exception in the 'throws' clause of a method.
*/ */
public int getExceptionIndex() { public int getExceptionIndex() {
return (value & 0x00FFFF00) >> 8; return (value & 0x00FFFF00) >> 8;
} }
/** /**
* Returns the index of the try catch block (using the order in which they are visited with visitTryCatchBlock), * 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 * 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} . * sort is {@link #EXCEPTION_PARAMETER EXCEPTION_PARAMETER} .
* *
* @return the index of an exception in the 'throws' clause of a method. * @return the index of an exception in the 'throws' clause of a method.
*/ */
public int getTryCatchBlockIndex() { public int getTryCatchBlockIndex() {
return (value & 0x00FFFF00) >> 8; return (value & 0x00FFFF00) >> 8;
} }
/** /**
* Returns the index of the type argument referenced by this type reference. This method must only be used for type * 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 * 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}, * CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT}, {@link #METHOD_INVOCATION_TYPE_ARGUMENT METHOD_INVOCATION_TYPE_ARGUMENT},
* {@link #CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT}, or * {@link #CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT}, or
* {@link #METHOD_REFERENCE_TYPE_ARGUMENT METHOD_REFERENCE_TYPE_ARGUMENT}. * {@link #METHOD_REFERENCE_TYPE_ARGUMENT METHOD_REFERENCE_TYPE_ARGUMENT}.
* *
* @return a type parameter index. * @return a type parameter index.
*/ */
public int getTypeArgumentIndex() { public int getTypeArgumentIndex() {
return value & 0xFF; return value & 0xFF;
} }
/** /**
* Returns the int encoded value of this type reference, suitable for use in visit methods related to type * Returns the int encoded value of this type reference, suitable for use in visit methods related to type
* annotations, like visitTypeAnnotation. * annotations, like visitTypeAnnotation.
* *
* @return the int encoded value of this type reference. * @return the int encoded value of this type reference.
*/ */
public int getValue() { public int getValue() {
return value; return value;
} }
} }

View File

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

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

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

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

View File

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

View File

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

View File

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

View File

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

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,228 +1,228 @@
package org.redkale.cluster.spi; package org.redkale.cluster.spi;
import static org.redkale.util.Utility.isEmpty; import static org.redkale.util.Utility.isEmpty;
import static org.redkale.util.Utility.isNotEmpty; import static org.redkale.util.Utility.isNotEmpty;
import java.io.Serializable; import java.io.Serializable;
import java.net.*; import java.net.*;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.time.Duration; import java.time.Duration;
import java.util.*; import java.util.*;
import java.util.concurrent.*; import java.util.concurrent.*;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
import org.redkale.annotation.Resource; import org.redkale.annotation.Resource;
import org.redkale.boot.Application; import org.redkale.boot.Application;
import org.redkale.cluster.HttpRpcClient; import org.redkale.cluster.HttpRpcClient;
import org.redkale.net.http.*; import org.redkale.net.http.*;
import org.redkale.util.Traces; import org.redkale.util.Traces;
import org.redkale.util.Utility; import org.redkale.util.Utility;
/** /**
* 没有配置MQ的情况下依赖ClusterAgent实现的默认HttpRpcClient实例 * 没有配置MQ的情况下依赖ClusterAgent实现的默认HttpRpcClient实例
* *
* <p>详情见: https://redkale.org * <p>详情见: https://redkale.org
* *
* @author zhangjx * @author zhangjx
* @since 2.1.0 * @since 2.1.0
*/ */
public class HttpClusterRpcClient extends HttpRpcClient { public class HttpClusterRpcClient extends HttpRpcClient {
// jdk.internal.net.http.common.Utils.DISALLOWED_HEADERS_SET // jdk.internal.net.http.common.Utils.DISALLOWED_HEADERS_SET
private static final Set<String> DISALLOWED_HEADERS_SET = Utility.ofSet( private static final Set<String> DISALLOWED_HEADERS_SET = Utility.ofSet(
"connection", "connection",
"content-length", "content-length",
"date", "date",
"expect", "expect",
"from", "from",
"host", "host",
"origin", "origin",
"referer", "referer",
"upgrade", "upgrade",
"via", "via",
"warning"); "warning");
protected final Logger logger = Logger.getLogger(this.getClass().getSimpleName()); protected final Logger logger = Logger.getLogger(this.getClass().getSimpleName());
protected final HttpLocalRpcClient localClient; protected final HttpLocalRpcClient localClient;
protected final ConcurrentHashMap<String, Boolean> topicServletMap = new ConcurrentHashMap<>(); protected final ConcurrentHashMap<String, Boolean> topicServletMap = new ConcurrentHashMap<>();
protected ClusterAgent clusterAgent; protected ClusterAgent clusterAgent;
@Resource(name = "cluster.httpClient", required = false) @Resource(name = "cluster.httpClient", required = false)
protected WebClient webClient; protected WebClient webClient;
@Resource(name = "cluster.httpClient", required = false) @Resource(name = "cluster.httpClient", required = false)
protected java.net.http.HttpClient httpClient; protected java.net.http.HttpClient httpClient;
public HttpClusterRpcClient(Application application, String resourceName, ClusterAgent clusterAgent) { public HttpClusterRpcClient(Application application, String resourceName, ClusterAgent clusterAgent) {
Objects.requireNonNull(clusterAgent); Objects.requireNonNull(clusterAgent);
this.localClient = new HttpLocalRpcClient(application, resourceName); this.localClient = new HttpLocalRpcClient(application, resourceName);
this.clusterAgent = clusterAgent; this.clusterAgent = clusterAgent;
} }
@Override @Override
protected String getNodeid() { protected String getNodeid() {
return localClient.getNodeid(); return localClient.getNodeid();
} }
@Override @Override
public CompletableFuture<HttpResult<byte[]>> sendMessage( public CompletableFuture<HttpResult<byte[]>> sendMessage(
String topic, Serializable userid, String groupid, WebRequest request) { String topic, Serializable userid, String groupid, WebRequest request) {
if (topicServletMap.computeIfAbsent(topic, t -> localClient.findHttpServlet(t) != null)) { if (topicServletMap.computeIfAbsent(topic, t -> localClient.findHttpServlet(t) != null)) {
return localClient.sendMessage(topic, userid, groupid, request); return localClient.sendMessage(topic, userid, groupid, request);
} else { } else {
return httpAsync(false, userid, request); return httpAsync(false, userid, request);
} }
} }
@Override @Override
public CompletableFuture<Void> produceMessage( public CompletableFuture<Void> produceMessage(
String topic, Serializable userid, String groupid, WebRequest request) { String topic, Serializable userid, String groupid, WebRequest request) {
if (topicServletMap.computeIfAbsent(topic, t -> localClient.findHttpServlet(t) != null)) { if (topicServletMap.computeIfAbsent(topic, t -> localClient.findHttpServlet(t) != null)) {
return localClient.produceMessage(topic, userid, groupid, request); return localClient.produceMessage(topic, userid, groupid, request);
} else { } else {
return httpAsync(true, userid, request).thenApply(v -> null); return httpAsync(true, userid, request).thenApply(v -> null);
} }
} }
private CompletableFuture<HttpResult<byte[]>> httpAsync(boolean produce, Serializable userid, WebRequest req) { private CompletableFuture<HttpResult<byte[]>> httpAsync(boolean produce, Serializable userid, WebRequest req) {
req.setTraceid(Traces.computeIfAbsent(req.getTraceid(), Traces.currentTraceid())); req.setTraceid(Traces.computeIfAbsent(req.getTraceid(), Traces.currentTraceid()));
String module = req.getPath(); String module = req.getPath();
module = module.substring(1, module.indexOf('/', 1)); module = module.substring(1, module.indexOf('/', 1));
HttpHeaders headers = req.getHeaders(); HttpHeaders headers = req.getHeaders();
String resname = req.getHeader(Rest.REST_HEADER_RESNAME, ""); String resname = req.getHeader(Rest.REST_HEADER_RESNAME, "");
final String localModule = module; final String localModule = module;
if (logger.isLoggable(Level.FINEST)) { if (logger.isLoggable(Level.FINEST)) {
logger.log(Level.FINEST, "httpAsync.queryHttpAddress: module=" + localModule + ", resname=" + resname); logger.log(Level.FINEST, "httpAsync.queryHttpAddress: module=" + localModule + ", resname=" + resname);
} }
return clusterAgent.queryHttpAddress("http", module, resname).thenCompose(addrs -> { return clusterAgent.queryHttpAddress("http", module, resname).thenCompose(addrs -> {
Traces.currentTraceid(req.getTraceid()); Traces.currentTraceid(req.getTraceid());
if (isEmpty(addrs)) { if (isEmpty(addrs)) {
if (logger.isLoggable(Level.WARNING)) { if (logger.isLoggable(Level.WARNING)) {
logger.log( logger.log(
Level.WARNING, Level.WARNING,
"httpAsync." + (produce ? "produceMessage" : "sendMessage") + " failed, module=" "httpAsync." + (produce ? "produceMessage" : "sendMessage") + " failed, module="
+ localModule + ", resname=" + resname + ", address is empty"); + localModule + ", resname=" + resname + ", address is empty");
} }
return new HttpResult<byte[]>().status(404).toFuture(); return new HttpResult<byte[]>().status(404).toFuture();
} }
final HttpHeaders clientHeaders = HttpHeaders.create(); final HttpHeaders clientHeaders = HttpHeaders.create();
if (headers != null) { if (headers != null) {
boolean ws = headers.contains("Sec-WebSocket-Key"); boolean ws = headers.contains("Sec-WebSocket-Key");
headers.forEach((n, v) -> { headers.forEach((n, v) -> {
if (!DISALLOWED_HEADERS_SET.contains(n.toLowerCase()) if (!DISALLOWED_HEADERS_SET.contains(n.toLowerCase())
&& (!ws && (!ws
|| (!"Connection".equals(n) || (!"Connection".equals(n)
&& !"Sec-WebSocket-Key".equals(n) && !"Sec-WebSocket-Key".equals(n)
&& !"Sec-WebSocket-Version".equals(n)))) { && !"Sec-WebSocket-Version".equals(n)))) {
clientHeaders.add(n, v); clientHeaders.add(n, v);
} }
}); });
} }
clientHeaders.set("Content-Type", "x-www-form-urlencoded"); clientHeaders.set("Content-Type", "x-www-form-urlencoded");
if (req.isRpc()) { if (req.isRpc()) {
clientHeaders.set(Rest.REST_HEADER_RPC, "true"); clientHeaders.set(Rest.REST_HEADER_RPC, "true");
} }
if (isNotEmpty(req.getTraceid())) { if (isNotEmpty(req.getTraceid())) {
clientHeaders.set(Rest.REST_HEADER_TRACEID, req.getTraceid()); clientHeaders.set(Rest.REST_HEADER_TRACEID, req.getTraceid());
} }
if (userid != null) { if (userid != null) {
clientHeaders.set(Rest.REST_HEADER_CURRUSERID, String.valueOf(userid)); clientHeaders.set(Rest.REST_HEADER_CURRUSERID, String.valueOf(userid));
} }
if (req.getReqConvertType() != null) { if (req.getReqConvertType() != null) {
clientHeaders.set( clientHeaders.set(
Rest.REST_HEADER_REQ_CONVERT, req.getReqConvertType().toString()); Rest.REST_HEADER_REQ_CONVERT, req.getReqConvertType().toString());
} }
if (req.getRespConvertType() != null) { if (req.getRespConvertType() != null) {
clientHeaders.set( clientHeaders.set(
Rest.REST_HEADER_RESP_CONVERT, req.getRespConvertType().toString()); Rest.REST_HEADER_RESP_CONVERT, req.getRespConvertType().toString());
} }
if (webClient != null) { if (webClient != null) {
WebRequest newReq = req.copy().headers(clientHeaders); WebRequest newReq = req.copy().headers(clientHeaders);
InetSocketAddress addr = randomAddress(newReq, addrs); InetSocketAddress addr = randomAddress(newReq, addrs);
if (logger.isLoggable(Level.FINEST)) { if (logger.isLoggable(Level.FINEST)) {
logger.log( logger.log(
Level.FINEST, Level.FINEST,
"httpAsync: module=" + localModule + ", resname=" + resname + ", addr=" + addr); "httpAsync: module=" + localModule + ", resname=" + resname + ", addr=" + addr);
} }
return (CompletableFuture) webClient.sendAsync(addr, newReq); return (CompletableFuture) webClient.sendAsync(addr, newReq);
} }
byte[] clientBody = null; byte[] clientBody = null;
if (isNotEmpty(req.getBody())) { if (isNotEmpty(req.getBody())) {
String paramstr = req.getParametersToString(); String paramstr = req.getParametersToString();
if (paramstr != null) { if (paramstr != null) {
if (req.getPath().indexOf('?') > 0) { if (req.getPath().indexOf('?') > 0) {
req.setPath(req.getPath() + "&" + paramstr); req.setPath(req.getPath() + "&" + paramstr);
} else { } else {
req.setPath(req.getPath() + "?" + paramstr); req.setPath(req.getPath() + "?" + paramstr);
} }
} }
clientBody = req.getBody(); clientBody = req.getBody();
} else { } else {
String paramstr = req.getParametersToString(); String paramstr = req.getParametersToString();
if (paramstr != null) { if (paramstr != null) {
clientBody = paramstr.getBytes(StandardCharsets.UTF_8); clientBody = paramstr.getBytes(StandardCharsets.UTF_8);
} }
} }
if (logger.isLoggable(Level.FINEST)) { if (logger.isLoggable(Level.FINEST)) {
logger.log( logger.log(
Level.FINEST, Level.FINEST,
"httpAsync: module=" + localModule + ", resname=" + resname + ", enter sendEachAddressAsync"); "httpAsync: module=" + localModule + ", resname=" + resname + ", enter sendEachAddressAsync");
} }
return sendEachAddressAsync(req, req.requestPath(), clientHeaders, clientBody, addrs.iterator()); return sendEachAddressAsync(req, req.requestPath(), clientHeaders, clientBody, addrs.iterator());
}); });
} }
protected InetSocketAddress randomAddress(WebRequest req, Set<InetSocketAddress> addrs) { protected InetSocketAddress randomAddress(WebRequest req, Set<InetSocketAddress> addrs) {
InetSocketAddress[] array = addrs.toArray(new InetSocketAddress[addrs.size()]); InetSocketAddress[] array = addrs.toArray(new InetSocketAddress[addrs.size()]);
return array[ThreadLocalRandom.current().nextInt(array.length)]; return array[ThreadLocalRandom.current().nextInt(array.length)];
} }
protected CompletableFuture<HttpResult<byte[]>> sendEachAddressAsync( protected CompletableFuture<HttpResult<byte[]>> sendEachAddressAsync(
WebRequest req, WebRequest req,
String requestPath, String requestPath,
final HttpHeaders clientHeaders, final HttpHeaders clientHeaders,
byte[] clientBody, byte[] clientBody,
Iterator<InetSocketAddress> it) { Iterator<InetSocketAddress> it) {
if (!it.hasNext()) { if (!it.hasNext()) {
return new HttpResult<byte[]>().status(404).toFuture(); return new HttpResult<byte[]>().status(404).toFuture();
} }
InetSocketAddress addr = it.next(); InetSocketAddress addr = it.next();
String host = addr.getPort() > 0 && addr.getPort() != 80 String host = addr.getPort() > 0 && addr.getPort() != 80
? (addr.getHostString() + ":" + addr.getPort()) ? (addr.getHostString() + ":" + addr.getPort())
: addr.getHostString(); : addr.getHostString();
String url = "http://" + host + requestPath; String url = "http://" + host + requestPath;
if (logger.isLoggable(Level.FINER)) { if (logger.isLoggable(Level.FINER)) {
logger.log( logger.log(
Level.FINER, Level.FINER,
"sendEachAddressAsync: url: " + url + ", body: " "sendEachAddressAsync: url: " + url + ", body: "
+ (clientBody != null ? new String(clientBody, StandardCharsets.UTF_8) : "") + ", headers: " + (clientBody != null ? new String(clientBody, StandardCharsets.UTF_8) : "") + ", headers: "
+ clientHeaders); + clientHeaders);
} }
java.net.http.HttpRequest.Builder builder = java.net.http.HttpRequest.newBuilder() java.net.http.HttpRequest.Builder builder = java.net.http.HttpRequest.newBuilder()
.uri(URI.create(url)) .uri(URI.create(url))
.timeout(Duration.ofMillis(10_000)) .timeout(Duration.ofMillis(10_000))
// 存在sendHeader后不发送body数据的问题 java.net.http.HttpRequest的bug? // 存在sendHeader后不发送body数据的问题 java.net.http.HttpRequest的bug?
.method("POST", createBodyPublisher(clientBody)); .method("POST", createBodyPublisher(clientBody));
clientHeaders.forEach(builder::header); clientHeaders.forEach(builder::header);
return httpClient return httpClient
.sendAsync(builder.build(), java.net.http.HttpResponse.BodyHandlers.ofByteArray()) .sendAsync(builder.build(), java.net.http.HttpResponse.BodyHandlers.ofByteArray())
.thenApply((java.net.http.HttpResponse<byte[]> resp) -> { .thenApply((java.net.http.HttpResponse<byte[]> resp) -> {
Traces.currentTraceid(req.getTraceid()); Traces.currentTraceid(req.getTraceid());
final int rs = resp.statusCode(); final int rs = resp.statusCode();
if (rs != 200) { if (rs != 200) {
return new HttpResult<byte[]>().status(rs); return new HttpResult<byte[]>().status(rs);
} }
return new HttpResult<>(resp.body()); return new HttpResult<>(resp.body());
}); });
} }
private static java.net.http.HttpRequest.BodyPublisher createBodyPublisher(byte[] clientBody) { private static java.net.http.HttpRequest.BodyPublisher createBodyPublisher(byte[] clientBody) {
return clientBody == null return clientBody == null
? java.net.http.HttpRequest.BodyPublishers.noBody() ? java.net.http.HttpRequest.BodyPublishers.noBody()
: java.net.http.HttpRequest.BodyPublishers.ofByteArray(clientBody); : 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 license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates * To change this template file, choose Tools | Templates
* and open the template in the editor. * and open the template in the editor.
*/ */
package org.redkale.convert; package org.redkale.convert;
import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.RetentionPolicy.RUNTIME; import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.*; import java.lang.annotation.*;
/** /**
* 用于序列化时接口或抽象类的默认实现类, 被标记的类必须是接口或抽象类 <br> * 用于序列化时接口或抽象类的默认实现类, 被标记的类必须是接口或抽象类 <br>
* 使用场景: <br> * 使用场景: <br>
* *
* <blockquote> * <blockquote>
* *
* <pre> * <pre>
* &#64;ConvertImpl(OneImpl.class) * &#64;ConvertImpl(OneImpl.class)
* public interface OneEntity { * public interface OneEntity {
* public String getName(); * public String getName();
* } * }
* *
* *
* public class OneImpl implements OneEntity { * public class OneImpl implements OneEntity {
* private String name; * private String name;
* public String getName(){return name;} * public String getName(){return name;}
* public void setName(String name){this.name=name;} * public void setName(String name){this.name=name;}
* } * }
* *
* *
* String json = "{'name':'hello'}"; * String json = "{'name':'hello'}";
* OneEntity one = JsonConvert.root().convertFrom(OneEntity.class, json); * OneEntity one = JsonConvert.root().convertFrom(OneEntity.class, json);
* //one instanceof OneImpl * //one instanceof OneImpl
* *
* </pre> * </pre>
* *
* </blockquote> * </blockquote>
* *
* <p>详情见: https://redkale.org * <p>详情见: https://redkale.org
* *
* @author zhangjx * @author zhangjx
* @since 2.5.0 * @since 2.5.0
*/ */
// 一定不能标记Inherited // 一定不能标记Inherited
@Documented @Documented
@Target({TYPE}) @Target({TYPE})
@Retention(RUNTIME) @Retention(RUNTIME)
public @interface ConvertImpl { public @interface ConvertImpl {
/** /**
* 默认的实现类 * 默认的实现类
* *
* @return String * @return String
*/ */
Class value() default Object.class; Class value() default Object.class;
/** /**
* 实现类的集合 * 实现类的集合
* *
* @return Class[] * @return Class[]
*/ */
Class[] types() default {}; Class[] types() default {};
} }

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,45 +1,45 @@
/* /*
* To change this license header, choose License Headers in Project Properties. * To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates * To change this template file, choose Tools | Templates
* and open the template in the editor. * and open the template in the editor.
*/ */
package org.redkale.convert.proto; package org.redkale.convert.proto;
import java.lang.reflect.Type; import java.lang.reflect.Type;
import java.util.concurrent.atomic.*; import java.util.concurrent.atomic.*;
import org.redkale.convert.*; import org.redkale.convert.*;
/** /**
* @author zhangjx * @author zhangjx
* @param <T> T * @param <T> T
*/ */
public class ProtobufArrayDecoder<T> extends ArrayDecoder<T> { public class ProtobufArrayDecoder<T> extends ArrayDecoder<T> {
protected final boolean simple; protected final boolean simple;
private final boolean string; private final boolean string;
private final boolean enumtostring; private final boolean enumtostring;
public ProtobufArrayDecoder(ConvertFactory factory, Type type) { public ProtobufArrayDecoder(ConvertFactory factory, Type type) {
super(factory, type); super(factory, type);
this.enumtostring = ((ProtobufFactory) factory).enumtostring; this.enumtostring = ((ProtobufFactory) factory).enumtostring;
Type comtype = this.getComponentType(); Type comtype = this.getComponentType();
this.string = String.class == comtype; this.string = String.class == comtype;
this.simple = Boolean.class == comtype this.simple = Boolean.class == comtype
|| Short.class == comtype || Short.class == comtype
|| Character.class == comtype || Character.class == comtype
|| Integer.class == comtype || Integer.class == comtype
|| Float.class == comtype || Float.class == comtype
|| Long.class == comtype || Long.class == comtype
|| Double.class == comtype || Double.class == comtype
|| AtomicInteger.class == comtype || AtomicInteger.class == comtype
|| AtomicLong.class == comtype; || AtomicLong.class == comtype;
} }
@Override @Override
protected Reader getItemReader(Reader in, DeMember member, boolean first) { protected Reader getItemReader(Reader in, DeMember member, boolean first) {
if (simple) return in; if (simple) return in;
return ProtobufFactory.getItemReader(string, simple, in, member, enumtostring, first); 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 license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates * To change this template file, choose Tools | Templates
* and open the template in the editor. * and open the template in the editor.
*/ */
package org.redkale.convert.proto; package org.redkale.convert.proto;
import java.lang.reflect.Type; import java.lang.reflect.Type;
import java.util.concurrent.atomic.*; import java.util.concurrent.atomic.*;
import org.redkale.convert.*; import org.redkale.convert.*;
/** /**
* @author zhangjx * @author zhangjx
* @param <T> T * @param <T> T
*/ */
public class ProtobufArrayEncoder<T> extends ArrayEncoder<T> { public class ProtobufArrayEncoder<T> extends ArrayEncoder<T> {
protected final boolean simple; protected final boolean simple;
public ProtobufArrayEncoder(ConvertFactory factory, Type type) { public ProtobufArrayEncoder(ConvertFactory factory, Type type) {
super(factory, type); super(factory, type);
Type comtype = this.getComponentType(); Type comtype = this.getComponentType();
this.simple = Boolean.class == comtype this.simple = Boolean.class == comtype
|| Short.class == comtype || Short.class == comtype
|| Character.class == comtype || Character.class == comtype
|| Integer.class == comtype || Integer.class == comtype
|| Float.class == comtype || Float.class == comtype
|| Long.class == comtype || Long.class == comtype
|| Double.class == comtype || Double.class == comtype
|| AtomicInteger.class == comtype || AtomicInteger.class == comtype
|| AtomicLong.class == comtype; || AtomicLong.class == comtype;
} }
@Override @Override
protected void writeMemberValue( protected void writeMemberValue(
Writer out, EnMember member, Encodeable<Writer, Object> encoder, Object item, int index) { Writer out, EnMember member, Encodeable<Writer, Object> encoder, Object item, int index) {
if (simple) { if (simple) {
if (item == null) { if (item == null) {
((ProtobufWriter) out).writeUInt32(0); ((ProtobufWriter) out).writeUInt32(0);
} else { } else {
componentEncoder.convertTo(out, item); componentEncoder.convertTo(out, item);
} }
return; return;
} }
if (member != null) out.writeFieldName(member); if (member != null) out.writeFieldName(member);
if (item == null) { if (item == null) {
((ProtobufWriter) out).writeUInt32(0); ((ProtobufWriter) out).writeUInt32(0);
} else if (item instanceof CharSequence) { } else if (item instanceof CharSequence) {
encoder.convertTo(out, item); encoder.convertTo(out, item);
} else { } else {
ProtobufWriter tmp = new ProtobufWriter().configFieldFunc(out); ProtobufWriter tmp = new ProtobufWriter().configFieldFunc(out);
encoder.convertTo(tmp, item); encoder.convertTo(tmp, item);
int length = tmp.count(); int length = tmp.count();
((ProtobufWriter) out).writeUInt32(length); ((ProtobufWriter) out).writeUInt32(length);
((ProtobufWriter) out).writeTo(tmp.toArray()); ((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 license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates * To change this template file, choose Tools | Templates
* and open the template in the editor. * and open the template in the editor.
*/ */
package org.redkale.convert.proto; package org.redkale.convert.proto;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
/** @author zhangjx */ /** @author zhangjx */
public class ProtobufByteBufferReader extends ProtobufReader { public class ProtobufByteBufferReader extends ProtobufReader {
private ByteBuffer[] buffers; private ByteBuffer[] buffers;
private int currentIndex = 0; private int currentIndex = 0;
private ByteBuffer currentBuffer; private ByteBuffer currentBuffer;
protected ProtobufByteBufferReader(ByteBuffer... buffers) { protected ProtobufByteBufferReader(ByteBuffer... buffers) {
this.buffers = buffers; this.buffers = buffers;
if (buffers != null && buffers.length > 0) this.currentBuffer = buffers[currentIndex]; if (buffers != null && buffers.length > 0) this.currentBuffer = buffers[currentIndex];
} }
@Override @Override
protected boolean recycle() { protected boolean recycle() {
super.recycle(); // this.position 初始化值为-1 super.recycle(); // this.position 初始化值为-1
this.currentIndex = 0; this.currentIndex = 0;
this.currentBuffer = null; this.currentBuffer = null;
this.buffers = null; this.buffers = null;
return false; return false;
} }
@Override @Override
protected byte currentByte() { protected byte currentByte() {
return currentBuffer.get(currentBuffer.position()); return currentBuffer.get(currentBuffer.position());
} }
protected byte nextByte() { protected byte nextByte() {
if (this.currentBuffer.hasRemaining()) { if (this.currentBuffer.hasRemaining()) {
this.position++; this.position++;
return this.currentBuffer.get(); return this.currentBuffer.get();
} }
for (; ; ) { for (; ; ) {
this.currentBuffer = this.buffers[++this.currentIndex]; this.currentBuffer = this.buffers[++this.currentIndex];
if (this.currentBuffer.hasRemaining()) { if (this.currentBuffer.hasRemaining()) {
this.position++; this.position++;
return this.currentBuffer.get(); return this.currentBuffer.get();
} }
} }
} }
// //
// //------------------------------------------------------------ // //------------------------------------------------------------
// /** // /**
// * 判断对象是否存在下一个属性或者数组是否存在下一个元素 // * 判断对象是否存在下一个属性或者数组是否存在下一个元素
// * // *
// * @param startPosition 起始位置 // * @param startPosition 起始位置
// * @param contentLength 内容大小, 不确定的传-1 // * @param contentLength 内容大小, 不确定的传-1
// * // *
// * @return 是否存在 // * @return 是否存在
// */ // */
// @Override // @Override
// public boolean hasNext(int startPosition, int contentLength) { // public boolean hasNext(int startPosition, int contentLength) {
// //("-------------: " + startPosition + ", " + contentLength + ", " + this.position); // //("-------------: " + startPosition + ", " + contentLength + ", " + this.position);
// if (startPosition >= 0 && contentLength >= 0) { // if (startPosition >= 0 && contentLength >= 0) {
// return (this.position) < (startPosition + contentLength); // return (this.position) < (startPosition + contentLength);
// } // }
// return (this.position + 1) < this.content.length; // return (this.position + 1) < this.content.length;
// } // }
// //
// @Override // @Override
// public byte[] readByteArray() { // public byte[] readByteArray() {
// final int size = readRawVarint32(); // final int size = readRawVarint32();
// byte[] bs = new byte[size]; // byte[] bs = new byte[size];
// System.arraycopy(content, position + 1, bs, 0, size); // System.arraycopy(content, position + 1, bs, 0, size);
// position += size; // position += size;
// return bs; // return bs;
// } // }
// //
// protected int readRawVarint32() { //readUInt32 // protected int readRawVarint32() { //readUInt32
// fastpath: // fastpath:
// { // {
// int tempPos = this.position; // int tempPos = this.position;
// if ((tempPos + 1) == content.length) break fastpath; // if ((tempPos + 1) == content.length) break fastpath;
// //
// int x; // int x;
// if ((x = content[++tempPos]) >= 0) { // if ((x = content[++tempPos]) >= 0) {
// this.position = tempPos; // this.position = tempPos;
// return x; // return x;
// } else if (content.length - (tempPos + 1) < 9) { // } else if (content.length - (tempPos + 1) < 9) {
// break fastpath; // break fastpath;
// } else if ((x ^= (content[++tempPos] << 7)) < 0) { // } else if ((x ^= (content[++tempPos] << 7)) < 0) {
// x ^= (~0 << 7); // x ^= (~0 << 7);
// } else if ((x ^= (content[++tempPos] << 14)) >= 0) { // } else if ((x ^= (content[++tempPos] << 14)) >= 0) {
// x ^= (~0 << 7) ^ (~0 << 14); // x ^= (~0 << 7) ^ (~0 << 14);
// } else if ((x ^= (content[++tempPos] << 21)) < 0) { // } else if ((x ^= (content[++tempPos] << 21)) < 0) {
// x ^= (~0 << 7) ^ (~0 << 14) ^ (~0 << 21); // x ^= (~0 << 7) ^ (~0 << 14) ^ (~0 << 21);
// } else { // } else {
// int y = content[++tempPos]; // int y = content[++tempPos];
// x ^= y << 28; // x ^= y << 28;
// x ^= (~0 << 7) ^ (~0 << 14) ^ (~0 << 21) ^ (~0 << 28); // x ^= (~0 << 7) ^ (~0 << 14) ^ (~0 << 21) ^ (~0 << 28);
// if (y < 0 // if (y < 0
// && content[++tempPos] < 0 // && content[++tempPos] < 0
// && content[++tempPos] < 0 // && content[++tempPos] < 0
// && content[++tempPos] < 0 // && content[++tempPos] < 0
// && content[++tempPos] < 0 // && content[++tempPos] < 0
// && content[++tempPos] < 0) { // && content[++tempPos] < 0) {
// break fastpath; // Will throw malformedVarint() // break fastpath; // Will throw malformedVarint()
// } // }
// } // }
// this.position = tempPos; // this.position = tempPos;
// return x; // return x;
// } // }
// return (int) readRawVarint64SlowPath(); // return (int) readRawVarint64SlowPath();
// } // }
// //
// protected long readRawVarint64() { // protected long readRawVarint64() {
// fastpath: // fastpath:
// { // {
// int tempPos = this.position; // int tempPos = this.position;
// if ((tempPos + 1) == content.length) break fastpath; // if ((tempPos + 1) == content.length) break fastpath;
// //
// long x; // long x;
// int y; // int y;
// if ((y = content[++tempPos]) >= 0) { // if ((y = content[++tempPos]) >= 0) {
// this.position = tempPos; // this.position = tempPos;
// return y; // return y;
// } else if (content.length - (tempPos + 1) < 9) { // } else if (content.length - (tempPos + 1) < 9) {
// break fastpath; // break fastpath;
// } else if ((y ^= (content[++tempPos] << 7)) < 0) { // } else if ((y ^= (content[++tempPos] << 7)) < 0) {
// x = y ^ (~0 << 7); // x = y ^ (~0 << 7);
// } else if ((y ^= (content[++tempPos] << 14)) >= 0) { // } else if ((y ^= (content[++tempPos] << 14)) >= 0) {
// x = y ^ ((~0 << 7) ^ (~0 << 14)); // x = y ^ ((~0 << 7) ^ (~0 << 14));
// } else if ((y ^= (content[++tempPos] << 21)) < 0) { // } else if ((y ^= (content[++tempPos] << 21)) < 0) {
// x = y ^ ((~0 << 7) ^ (~0 << 14) ^ (~0 << 21)); // x = y ^ ((~0 << 7) ^ (~0 << 14) ^ (~0 << 21));
// } else if ((x = y ^ ((long) content[++tempPos] << 28)) >= 0L) { // } else if ((x = y ^ ((long) content[++tempPos] << 28)) >= 0L) {
// x ^= (~0L << 7) ^ (~0L << 14) ^ (~0L << 21) ^ (~0L << 28); // x ^= (~0L << 7) ^ (~0L << 14) ^ (~0L << 21) ^ (~0L << 28);
// } else if ((x ^= ((long) content[++tempPos] << 35)) < 0L) { // } else if ((x ^= ((long) content[++tempPos] << 35)) < 0L) {
// x ^= (~0L << 7) ^ (~0L << 14) ^ (~0L << 21) ^ (~0L << 28) ^ (~0L << 35); // x ^= (~0L << 7) ^ (~0L << 14) ^ (~0L << 21) ^ (~0L << 28) ^ (~0L << 35);
// } else if ((x ^= ((long) content[++tempPos] << 42)) >= 0L) { // } else if ((x ^= ((long) content[++tempPos] << 42)) >= 0L) {
// x ^= (~0L << 7) ^ (~0L << 14) ^ (~0L << 21) ^ (~0L << 28) ^ (~0L << 35) ^ (~0L << 42); // x ^= (~0L << 7) ^ (~0L << 14) ^ (~0L << 21) ^ (~0L << 28) ^ (~0L << 35) ^ (~0L << 42);
// } else if ((x ^= ((long) content[++tempPos] << 49)) < 0L) { // } else if ((x ^= ((long) content[++tempPos] << 49)) < 0L) {
// x ^= (~0L << 7) // x ^= (~0L << 7)
// ^ (~0L << 14) // ^ (~0L << 14)
// ^ (~0L << 21) // ^ (~0L << 21)
// ^ (~0L << 28) // ^ (~0L << 28)
// ^ (~0L << 35) // ^ (~0L << 35)
// ^ (~0L << 42) // ^ (~0L << 42)
// ^ (~0L << 49); // ^ (~0L << 49);
// } else { // } else {
// x ^= ((long) content[++tempPos] << 56); // x ^= ((long) content[++tempPos] << 56);
// x ^= (~0L << 7) // x ^= (~0L << 7)
// ^ (~0L << 14) // ^ (~0L << 14)
// ^ (~0L << 21) // ^ (~0L << 21)
// ^ (~0L << 28) // ^ (~0L << 28)
// ^ (~0L << 35) // ^ (~0L << 35)
// ^ (~0L << 42) // ^ (~0L << 42)
// ^ (~0L << 49) // ^ (~0L << 49)
// ^ (~0L << 56); // ^ (~0L << 56);
// if (x < 0L) { // if (x < 0L) {
// if (content[++tempPos] < 0L) { // if (content[++tempPos] < 0L) {
// break fastpath; // Will throw malformedVarint() // break fastpath; // Will throw malformedVarint()
// } // }
// } // }
// } // }
// this.position = tempPos; // this.position = tempPos;
// return x; // return x;
// } // }
// return readRawVarint64SlowPath(); // return readRawVarint64SlowPath();
// } // }
// //
// protected long readRawVarint64SlowPath() { // protected long readRawVarint64SlowPath() {
// long result = 0; // long result = 0;
// for (int shift = 0; shift < 64; shift += 7) { // for (int shift = 0; shift < 64; shift += 7) {
// final byte b = content[++this.position]; // final byte b = content[++this.position];
// result |= (long) (b & 0x7F) << shift; // result |= (long) (b & 0x7F) << shift;
// if ((b & 0x80) == 0) return result; // if ((b & 0x80) == 0) return result;
// } // }
// throw new ConvertException("readRawVarint64SlowPath error"); // throw new ConvertException("readRawVarint64SlowPath error");
// } // }
// //
// protected int readRawLittleEndian32() { // protected int readRawLittleEndian32() {
// return ((content[++this.position] & 0xff) // return ((content[++this.position] & 0xff)
// | ((content[++this.position] & 0xff) << 8) // | ((content[++this.position] & 0xff) << 8)
// | ((content[++this.position] & 0xff) << 16) // | ((content[++this.position] & 0xff) << 16)
// | ((content[++this.position] & 0xff) << 24)); // | ((content[++this.position] & 0xff) << 24));
// } // }
// //
// protected long readRawLittleEndian64() { // protected long readRawLittleEndian64() {
// return ((content[++this.position] & 0xffL) // return ((content[++this.position] & 0xffL)
// | ((content[++this.position] & 0xffL) << 8) // | ((content[++this.position] & 0xffL) << 8)
// | ((content[++this.position] & 0xffL) << 16) // | ((content[++this.position] & 0xffL) << 16)
// | ((content[++this.position] & 0xffL) << 24) // | ((content[++this.position] & 0xffL) << 24)
// | ((content[++this.position] & 0xffL) << 32) // | ((content[++this.position] & 0xffL) << 32)
// | ((content[++this.position] & 0xffL) << 40) // | ((content[++this.position] & 0xffL) << 40)
// | ((content[++this.position] & 0xffL) << 48) // | ((content[++this.position] & 0xffL) << 48)
// | ((content[++this.position] & 0xffL) << 56)); // | ((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 license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates * To change this template file, choose Tools | Templates
* and open the template in the editor. * and open the template in the editor.
*/ */
package org.redkale.convert.proto; package org.redkale.convert.proto;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.util.function.Supplier; import java.util.function.Supplier;
import org.redkale.util.Utility; import org.redkale.util.Utility;
/** @author zhangjx */ /** @author zhangjx */
public class ProtobufByteBufferWriter extends ProtobufWriter { public class ProtobufByteBufferWriter extends ProtobufWriter {
private final Supplier<ByteBuffer> supplier; private final Supplier<ByteBuffer> supplier;
private ByteBuffer[] buffers; private ByteBuffer[] buffers;
private int index; private int index;
public ProtobufByteBufferWriter(int features, boolean enumtostring, Supplier<ByteBuffer> supplier) { public ProtobufByteBufferWriter(int features, boolean enumtostring, Supplier<ByteBuffer> supplier) {
super((byte[]) null); super((byte[]) null);
this.features = features; this.features = features;
this.enumtostring = enumtostring; this.enumtostring = enumtostring;
this.supplier = supplier; this.supplier = supplier;
} }
@Override @Override
protected boolean recycle() { protected boolean recycle() {
super.recycle(); super.recycle();
this.buffers = null; this.buffers = null;
this.index = 0; this.index = 0;
return false; return false;
} }
@Override @Override
public ByteBuffer[] toBuffers() { public ByteBuffer[] toBuffers() {
if (buffers == null) { if (buffers == null) {
return new ByteBuffer[0]; return new ByteBuffer[0];
} }
for (int i = index; i < this.buffers.length; i++) { for (int i = index; i < this.buffers.length; i++) {
ByteBuffer buf = this.buffers[i]; ByteBuffer buf = this.buffers[i];
if (buf.position() != 0) { if (buf.position() != 0) {
buf.flip(); buf.flip();
} }
} }
return this.buffers; return this.buffers;
} }
@Override @Override
public byte[] toArray() { public byte[] toArray() {
if (buffers == null) { if (buffers == null) {
return new byte[0]; return new byte[0];
} }
int pos = 0; int pos = 0;
byte[] bytes = new byte[this.count]; byte[] bytes = new byte[this.count];
for (ByteBuffer buf : toBuffers()) { for (ByteBuffer buf : toBuffers()) {
int r = buf.remaining(); int r = buf.remaining();
buf.get(bytes, pos, r); buf.get(bytes, pos, r);
buf.flip(); buf.flip();
pos += r; pos += r;
} }
return bytes; return bytes;
} }
@Override @Override
public String toString() { public String toString() {
return this.getClass().getSimpleName() + "[count=" + this.count + "]"; return this.getClass().getSimpleName() + "[count=" + this.count + "]";
} }
@Override @Override
protected int expand(final int byteLength) { protected int expand(final int byteLength) {
if (this.buffers == null) { if (this.buffers == null) {
this.index = 0; this.index = 0;
this.buffers = new ByteBuffer[] {supplier.get()}; this.buffers = new ByteBuffer[] {supplier.get()};
} }
ByteBuffer buffer = this.buffers[index]; ByteBuffer buffer = this.buffers[index];
if (!buffer.hasRemaining()) { if (!buffer.hasRemaining()) {
buffer.flip(); buffer.flip();
buffer = supplier.get(); buffer = supplier.get();
this.buffers = Utility.append(this.buffers, buffer); this.buffers = Utility.append(this.buffers, buffer);
this.index++; this.index++;
} }
int len = buffer.remaining(); int len = buffer.remaining();
int size = 0; int size = 0;
while (len < byteLength) { while (len < byteLength) {
buffer = supplier.get(); buffer = supplier.get();
this.buffers = Utility.append(this.buffers, buffer); this.buffers = Utility.append(this.buffers, buffer);
len += buffer.remaining(); len += buffer.remaining();
size++; size++;
} }
return size; return size;
} }
@Override @Override
public void writeTo(final byte[] chs, final int start, final int len) { public void writeTo(final byte[] chs, final int start, final int len) {
if (expand(len) == 0) { if (expand(len) == 0) {
this.buffers[index].put(chs, start, len); this.buffers[index].put(chs, start, len);
} else { } else {
ByteBuffer buffer = this.buffers[index]; ByteBuffer buffer = this.buffers[index];
final int end = start + len; final int end = start + len;
int remain = len; // 还剩多少没有写 int remain = len; // 还剩多少没有写
while (remain > 0) { while (remain > 0) {
final int br = buffer.remaining(); final int br = buffer.remaining();
if (remain > br) { // 一个buffer写不完 if (remain > br) { // 一个buffer写不完
buffer.put(chs, end - remain, br); buffer.put(chs, end - remain, br);
buffer = nextByteBuffer(); buffer = nextByteBuffer();
remain -= br; remain -= br;
} else { } else {
buffer.put(chs, end - remain, remain); buffer.put(chs, end - remain, remain);
remain = 0; remain = 0;
} }
} }
} }
this.count += len; this.count += len;
} }
private ByteBuffer nextByteBuffer() { private ByteBuffer nextByteBuffer() {
this.buffers[this.index].flip(); this.buffers[this.index].flip();
return this.buffers[++this.index]; return this.buffers[++this.index];
} }
@Override @Override
public void writeTo(final byte ch) { public void writeTo(final byte ch) {
expand(1); expand(1);
this.buffers[index].put(ch); this.buffers[index].put(ch);
count++; count++;
} }
@Override @Override
public byte[] content() { public byte[] content() {
throw new UnsupportedOperationException("Not supported yet."); // 无需实现 throw new UnsupportedOperationException("Not supported yet."); // 无需实现
} }
@Override @Override
public int offset() { public int offset() {
throw new UnsupportedOperationException("Not supported yet."); // 无需实现 throw new UnsupportedOperationException("Not supported yet."); // 无需实现
} }
@Override @Override
public int length() { public int length() {
throw new UnsupportedOperationException("Not supported yet."); // 无需实现 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 license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates * To change this template file, choose Tools | Templates
* and open the template in the editor. * and open the template in the editor.
*/ */
package org.redkale.convert.proto; package org.redkale.convert.proto;
import java.lang.reflect.Type; import java.lang.reflect.Type;
import java.util.concurrent.atomic.*; import java.util.concurrent.atomic.*;
import org.redkale.convert.*; import org.redkale.convert.*;
/** /**
* @author zhangjx * @author zhangjx
* @param <T> T * @param <T> T
*/ */
public class ProtobufCollectionDecoder<T> extends CollectionDecoder<T> { public class ProtobufCollectionDecoder<T> extends CollectionDecoder<T> {
protected final boolean simple; protected final boolean simple;
private final boolean string; private final boolean string;
private final boolean enumtostring; private final boolean enumtostring;
public ProtobufCollectionDecoder(ConvertFactory factory, Type type) { public ProtobufCollectionDecoder(ConvertFactory factory, Type type) {
super(factory, type); super(factory, type);
this.enumtostring = ((ProtobufFactory) factory).enumtostring; this.enumtostring = ((ProtobufFactory) factory).enumtostring;
Type comtype = this.getComponentType(); Type comtype = this.getComponentType();
this.string = String.class == comtype; this.string = String.class == comtype;
this.simple = Boolean.class == comtype this.simple = Boolean.class == comtype
|| Short.class == comtype || Short.class == comtype
|| Character.class == comtype || Character.class == comtype
|| Integer.class == comtype || Integer.class == comtype
|| Float.class == comtype || Float.class == comtype
|| Long.class == comtype || Long.class == comtype
|| Double.class == comtype || Double.class == comtype
|| AtomicInteger.class == comtype || AtomicInteger.class == comtype
|| AtomicLong.class == comtype; || AtomicLong.class == comtype;
} }
@Override @Override
protected Reader getItemReader(Reader in, DeMember member, boolean first) { protected Reader getItemReader(Reader in, DeMember member, boolean first) {
if (simple) return in; if (simple) return in;
return ProtobufFactory.getItemReader(string, simple, in, member, enumtostring, first); 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 license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates * To change this template file, choose Tools | Templates
* and open the template in the editor. * and open the template in the editor.
*/ */
package org.redkale.convert.proto; package org.redkale.convert.proto;
import java.lang.reflect.Type; import java.lang.reflect.Type;
import java.util.concurrent.atomic.*; import java.util.concurrent.atomic.*;
import org.redkale.convert.*; import org.redkale.convert.*;
/** /**
* @author zhangjx * @author zhangjx
* @param <T> T * @param <T> T
*/ */
public class ProtobufCollectionEncoder<T> extends CollectionEncoder<T> { public class ProtobufCollectionEncoder<T> extends CollectionEncoder<T> {
protected final boolean simple; protected final boolean simple;
public ProtobufCollectionEncoder(ConvertFactory factory, Type type) { public ProtobufCollectionEncoder(ConvertFactory factory, Type type) {
super(factory, type); super(factory, type);
Type comtype = this.getComponentType(); Type comtype = this.getComponentType();
this.simple = Boolean.class == comtype this.simple = Boolean.class == comtype
|| Short.class == comtype || Short.class == comtype
|| Character.class == comtype || Character.class == comtype
|| Integer.class == comtype || Integer.class == comtype
|| Float.class == comtype || Float.class == comtype
|| Long.class == comtype || Long.class == comtype
|| Double.class == comtype || Double.class == comtype
|| AtomicInteger.class == comtype || AtomicInteger.class == comtype
|| AtomicLong.class == comtype; || AtomicLong.class == comtype;
} }
@Override @Override
protected void writeMemberValue(Writer out, EnMember member, Object item, boolean first) { protected void writeMemberValue(Writer out, EnMember member, Object item, boolean first) {
if (simple) { if (simple) {
if (item == null) { if (item == null) {
((ProtobufWriter) out).writeUInt32(0); ((ProtobufWriter) out).writeUInt32(0);
} else { } else {
componentEncoder.convertTo(out, item); componentEncoder.convertTo(out, item);
} }
return; return;
} }
if (member != null) out.writeFieldName(member); if (member != null) out.writeFieldName(member);
if (item == null) { if (item == null) {
((ProtobufWriter) out).writeUInt32(0); ((ProtobufWriter) out).writeUInt32(0);
} else if (item instanceof CharSequence) { } else if (item instanceof CharSequence) {
componentEncoder.convertTo(out, item); componentEncoder.convertTo(out, item);
} else { } else {
ProtobufWriter tmp = new ProtobufWriter().configFieldFunc(out); ProtobufWriter tmp = new ProtobufWriter().configFieldFunc(out);
componentEncoder.convertTo(tmp, item); componentEncoder.convertTo(tmp, item);
int length = tmp.count(); int length = tmp.count();
((ProtobufWriter) out).writeUInt32(length); ((ProtobufWriter) out).writeUInt32(length);
((ProtobufWriter) out).writeTo(tmp.toArray()); ((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 license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates * To change this template file, choose Tools | Templates
* and open the template in the editor. * and open the template in the editor.
*/ */
package org.redkale.convert.proto; package org.redkale.convert.proto;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.*; import java.util.*;
import org.redkale.convert.*; import org.redkale.convert.*;
import org.redkale.util.RedkaleClassLoader; import org.redkale.util.RedkaleClassLoader;
/** /**
* 枚举 的SimpledCoder实现 * 枚举 的SimpledCoder实现
* *
* <p>详情见: https://redkale.org * <p>详情见: https://redkale.org
* *
* @author zhangjx * @author zhangjx
* @param <R> Reader输入的子类型 * @param <R> Reader输入的子类型
* @param <W> Writer输出的子类型 * @param <W> Writer输出的子类型
* @param <E> Enum的子类 * @param <E> Enum的子类
*/ */
public class ProtobufEnumSimpledCoder<R extends Reader, W extends Writer, E extends Enum> public class ProtobufEnumSimpledCoder<R extends Reader, W extends Writer, E extends Enum>
extends SimpledCoder<R, W, E> { extends SimpledCoder<R, W, E> {
private final Map<Integer, E> values = new HashMap<>(); private final Map<Integer, E> values = new HashMap<>();
private final boolean enumtostring; private final boolean enumtostring;
public ProtobufEnumSimpledCoder(Class<E> type, boolean enumtostring) { public ProtobufEnumSimpledCoder(Class<E> type, boolean enumtostring) {
this.type = type; this.type = type;
this.enumtostring = enumtostring; this.enumtostring = enumtostring;
try { try {
final Method method = type.getMethod("values"); final Method method = type.getMethod("values");
RedkaleClassLoader.putReflectionMethod(type.getName(), method); RedkaleClassLoader.putReflectionMethod(type.getName(), method);
for (E item : (E[]) method.invoke(null)) { for (E item : (E[]) method.invoke(null)) {
values.put(item.ordinal(), item); values.put(item.ordinal(), item);
} }
} catch (Exception e) { } catch (Exception e) {
throw new ConvertException(e); throw new ConvertException(e);
} }
} }
@Override @Override
public void convertTo(final W out, final E value) { public void convertTo(final W out, final E value) {
if (value == null) { if (value == null) {
out.writeNull(); out.writeNull();
} else if (enumtostring) { } else if (enumtostring) {
out.writeSmallString(value.toString()); out.writeSmallString(value.toString());
} else { } else {
((ProtobufWriter) out).writeUInt32(value.ordinal()); ((ProtobufWriter) out).writeUInt32(value.ordinal());
} }
} }
@Override @Override
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public E convertFrom(final R in) { public E convertFrom(final R in) {
if (enumtostring) { if (enumtostring) {
String value = in.readSmallString(); String value = in.readSmallString();
if (value == null) return null; if (value == null) return null;
return (E) Enum.valueOf((Class<E>) type, value); return (E) Enum.valueOf((Class<E>) type, value);
} }
int value = ((ProtobufReader) in).readRawVarint32(); int value = ((ProtobufReader) in).readRawVarint32();
return values.get(value); return values.get(value);
} }
@Override @Override
public Class<E> getType() { public Class<E> getType() {
return (Class) type; return (Class) type;
} }
} }

View File

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

View File

@@ -1,37 +1,37 @@
/* /*
* To change this license header, choose License Headers in Project Properties. * To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates * To change this template file, choose Tools | Templates
* and open the template in the editor. * and open the template in the editor.
*/ */
package org.redkale.convert.proto; package org.redkale.convert.proto;
import java.lang.reflect.Type; import java.lang.reflect.Type;
import org.redkale.convert.*; import org.redkale.convert.*;
/** /**
* @author zhangjx * @author zhangjx
* @param <K> K * @param <K> K
* @param <V> V * @param <V> V
*/ */
public class ProtobufMapEncoder<K, V> extends MapEncoder<K, V> { public class ProtobufMapEncoder<K, V> extends MapEncoder<K, V> {
private final boolean enumtostring; private final boolean enumtostring;
public ProtobufMapEncoder(ConvertFactory factory, Type type) { public ProtobufMapEncoder(ConvertFactory factory, Type type) {
super(factory, type); super(factory, type);
this.enumtostring = ((ProtobufFactory) factory).enumtostring; this.enumtostring = ((ProtobufFactory) factory).enumtostring;
} }
@Override @Override
protected void writeMemberValue(Writer out, EnMember member, K key, V value, boolean first) { protected void writeMemberValue(Writer out, EnMember member, K key, V value, boolean first) {
ProtobufWriter tmp = new ProtobufWriter().configFieldFunc(out); ProtobufWriter tmp = new ProtobufWriter().configFieldFunc(out);
if (member != null) out.writeFieldName(member); if (member != null) out.writeFieldName(member);
tmp.writeUInt32(1 << 3 | ProtobufFactory.wireType(keyEncoder.getType(), enumtostring)); tmp.writeUInt32(1 << 3 | ProtobufFactory.wireType(keyEncoder.getType(), enumtostring));
keyEncoder.convertTo(tmp, key); keyEncoder.convertTo(tmp, key);
tmp.writeUInt32(2 << 3 | ProtobufFactory.wireType(valueEncoder.getType(), enumtostring)); tmp.writeUInt32(2 << 3 | ProtobufFactory.wireType(valueEncoder.getType(), enumtostring));
valueEncoder.convertTo(tmp, value); valueEncoder.convertTo(tmp, value);
int length = tmp.count(); int length = tmp.count();
((ProtobufWriter) out).writeUInt32(length); ((ProtobufWriter) out).writeUInt32(length);
((ProtobufWriter) out).writeTo(tmp.toArray()); ((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 license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates * To change this template file, choose Tools | Templates
* and open the template in the editor. * and open the template in the editor.
*/ */
package org.redkale.convert.proto; package org.redkale.convert.proto;
import java.lang.reflect.Type; import java.lang.reflect.Type;
import org.redkale.convert.*; import org.redkale.convert.*;
import org.redkale.util.Attribute; import org.redkale.util.Attribute;
import org.redkale.util.Utility; import org.redkale.util.Utility;
/** /**
* @author zhangjx * @author zhangjx
* @param <T> T * @param <T> T
*/ */
public class ProtobufObjectDecoder<T> extends ObjectDecoder<ProtobufReader, T> { public class ProtobufObjectDecoder<T> extends ObjectDecoder<ProtobufReader, T> {
protected ProtobufObjectDecoder(Type type) { protected ProtobufObjectDecoder(Type type) {
super(type); super(type);
} }
@Override @Override
protected void initForEachDeMember(ConvertFactory factory, DeMember member) { protected void initForEachDeMember(ConvertFactory factory, DeMember member) {
if (member.getIndex() < 1) { if (member.getIndex() < 1) {
throw new ConvertException(Utility.orElse(member.getField(), member.getMethod()) + " not found @" throw new ConvertException(Utility.orElse(member.getField(), member.getMethod()) + " not found @"
+ ConvertColumn.class.getSimpleName() + ".index"); + ConvertColumn.class.getSimpleName() + ".index");
} }
Attribute attr = member.getAttribute(); Attribute attr = member.getAttribute();
setTag( setTag(
member, member,
ProtobufFactory.getTag( ProtobufFactory.getTag(
attr.field(), attr.field(),
attr.genericType(), attr.genericType(),
member.getPosition(), member.getPosition(),
((ProtobufFactory) factory).enumtostring)); ((ProtobufFactory) factory).enumtostring));
} }
@Override @Override
protected ProtobufReader objectReader(ProtobufReader in) { protected ProtobufReader objectReader(ProtobufReader in) {
if (in.position() > in.initoffset) return new ProtobufReader(in.readByteArray()); if (in.position() > in.initoffset) return new ProtobufReader(in.readByteArray());
return in; return in;
} }
@Override @Override
protected boolean hasNext(ProtobufReader in, boolean first) { protected boolean hasNext(ProtobufReader in, boolean first) {
return in.hasNext(); return in.hasNext();
} }
@Override @Override
protected Object readDeMemberValue(ProtobufReader in, DeMember member, boolean first) { protected Object readDeMemberValue(ProtobufReader in, DeMember member, boolean first) {
Decodeable decoder = member.getDecoder(); Decodeable decoder = member.getDecoder();
if (decoder instanceof ProtobufArrayDecoder) { if (decoder instanceof ProtobufArrayDecoder) {
return ((ProtobufArrayDecoder) decoder).convertFrom(in, member); return ((ProtobufArrayDecoder) decoder).convertFrom(in, member);
} else if (decoder instanceof ProtobufCollectionDecoder) { } else if (decoder instanceof ProtobufCollectionDecoder) {
return ((ProtobufCollectionDecoder) decoder).convertFrom(in, member); return ((ProtobufCollectionDecoder) decoder).convertFrom(in, member);
} else if (decoder instanceof ProtobufStreamDecoder) { } else if (decoder instanceof ProtobufStreamDecoder) {
return ((ProtobufStreamDecoder) decoder).convertFrom(in, member); return ((ProtobufStreamDecoder) decoder).convertFrom(in, member);
} else if (decoder instanceof ProtobufMapDecoder) { } else if (decoder instanceof ProtobufMapDecoder) {
return ((ProtobufMapDecoder) decoder).convertFrom(in, member); return ((ProtobufMapDecoder) decoder).convertFrom(in, member);
} else { } else {
return member.read(in); return member.read(in);
} }
} }
@Override @Override
protected void readDeMemberValue(ProtobufReader in, DeMember member, T result, boolean first) { protected void readDeMemberValue(ProtobufReader in, DeMember member, T result, boolean first) {
Decodeable decoder = member.getDecoder(); Decodeable decoder = member.getDecoder();
if (decoder instanceof ProtobufArrayDecoder) { if (decoder instanceof ProtobufArrayDecoder) {
member.getAttribute().set(result, ((ProtobufArrayDecoder) decoder).convertFrom(in, member)); member.getAttribute().set(result, ((ProtobufArrayDecoder) decoder).convertFrom(in, member));
} else if (decoder instanceof ProtobufCollectionDecoder) { } else if (decoder instanceof ProtobufCollectionDecoder) {
member.getAttribute().set(result, ((ProtobufCollectionDecoder) decoder).convertFrom(in, member)); member.getAttribute().set(result, ((ProtobufCollectionDecoder) decoder).convertFrom(in, member));
} else if (decoder instanceof ProtobufStreamDecoder) { } else if (decoder instanceof ProtobufStreamDecoder) {
member.getAttribute().set(result, ((ProtobufStreamDecoder) decoder).convertFrom(in, member)); member.getAttribute().set(result, ((ProtobufStreamDecoder) decoder).convertFrom(in, member));
} else if (decoder instanceof ProtobufMapDecoder) { } else if (decoder instanceof ProtobufMapDecoder) {
member.getAttribute().set(result, ((ProtobufMapDecoder) decoder).convertFrom(in, member)); member.getAttribute().set(result, ((ProtobufMapDecoder) decoder).convertFrom(in, member));
} else { } else {
member.read(in, result); member.read(in, result);
} }
} }
} }

View File

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

View File

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

View File

@@ -1,49 +1,49 @@
/* /*
* To change this license header, choose License Headers in Project Properties. * To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates * To change this template file, choose Tools | Templates
* and open the template in the editor. * and open the template in the editor.
*/ */
package org.redkale.convert.proto; package org.redkale.convert.proto;
import java.io.*; import java.io.*;
import org.redkale.convert.ConvertException; import org.redkale.convert.ConvertException;
/** /**
* 详情见: https://redkale.org * 详情见: https://redkale.org
* *
* @author zhangjx * @author zhangjx
*/ */
class ProtobufStreamWriter extends ProtobufByteBufferWriter { class ProtobufStreamWriter extends ProtobufByteBufferWriter {
private OutputStream out; private OutputStream out;
protected ProtobufStreamWriter(int features, boolean enumtostring, OutputStream out) { protected ProtobufStreamWriter(int features, boolean enumtostring, OutputStream out) {
super(features, enumtostring, null); super(features, enumtostring, null);
this.out = out; this.out = out;
} }
@Override @Override
protected boolean recycle() { protected boolean recycle() {
super.recycle(); super.recycle();
this.out = null; this.out = null;
return false; return false;
} }
@Override @Override
public void writeTo(final byte[] chs, final int start, final int len) { public void writeTo(final byte[] chs, final int start, final int len) {
try { try {
out.write(chs, start, len); out.write(chs, start, len);
} catch (IOException e) { } catch (IOException e) {
throw new ConvertException(e); throw new ConvertException(e);
} }
} }
@Override @Override
public void writeTo(final byte ch) { public void writeTo(final byte ch) {
try { try {
out.write((byte) ch); out.write((byte) ch);
} catch (IOException e) { } catch (IOException e) {
throw new ConvertException(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; package org.redkale.inject;
import java.lang.annotation.Annotation; import java.lang.annotation.Annotation;
import java.lang.reflect.Field; import java.lang.reflect.Field;
/** /**
* 自定义注入加载器 * 自定义注入加载器
* *
* <p>详情见: https://redkale.org * <p>详情见: https://redkale.org
* *
* @since 2.8.0 * @since 2.8.0
* @author zhangjx * @author zhangjx
* @param <T> Annotation * @param <T> Annotation
*/ */
public interface ResourceAnnotationLoader<T extends Annotation> { public interface ResourceAnnotationLoader<T extends Annotation> {
public void load( public void load(
ResourceFactory factory, ResourceFactory factory,
String srcResourceName, String srcResourceName,
Object srcObj, Object srcObj,
T annotation, T annotation,
Field field, Field field,
Object attachment); Object attachment);
public Class<T> annotationType(); public Class<T> annotationType();
} }

View File

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

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