spring-loaded TypeDescriptor 源码
spring-loaded TypeDescriptor 代码
文件路径:/springloaded/src/main/java/org/springsource/loaded/TypeDescriptor.java
/*
* Copyright 2010-2012 VMware and contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springsource.loaded;
import java.util.ArrayList;
import java.util.List;
/**
* Encapsulates the information about a type relevant to reloading. The TypeDescriptor for a type is sometimes extracted
* whilst performing some other operation (eg. {@link InterfaceExtractor}) but can also be retrieved directly using
* {@link TypeDescriptorExtractor}.
*
* @author Andy Clement
* @since 0.5.0
*/
public class TypeDescriptor implements Constants {
private final int modifiers;
final String typename; // slashed
final String supertypeName; // slashed
final String[] superinterfaceNames; // slashed // empty array if there are none
private final MethodMember[] constructors; // empty array if there are none (but this doesn't ever happen!)
private final MethodMember[] methods; // empty array if there are none
private final MethodMember[] nonprivateMethods; // empty array if there are none
private final FieldMember[] fields; // empty array if there are none
private final FieldMember[] fieldsRequiringAccessors; // empty array if there are none
private List<String> finalInHierarchy; // nameAndDescriptor strings for methods final in the hierarchy (e.g. ordinal()I for an enum)
private final TypeRegistry registry;
private final boolean isReloadable;
private final boolean hasClinit;
private final static int IS_GROOVY_TYPE = 0x0001;
private int bits = 0x0000;
private ReloadableType reloadableType;
private int nextId = 0;
public TypeDescriptor(String slashedTypeName, String supertypeName, String[] superinterfaceNames, int modifiers,
List<? extends MethodMember> constructors, List<MethodMember> methods, List<? extends FieldMember> fields,
List<? extends FieldMember> fieldsRequiringAccessors, boolean isReloadable, TypeRegistry registry,
boolean hasClinit,
List<String> finalInHierarchy) {
this.typename = slashedTypeName;
this.supertypeName = supertypeName;
this.superinterfaceNames = (superinterfaceNames == null ? NO_STRINGS : superinterfaceNames);
this.finalInHierarchy = finalInHierarchy;
this.modifiers = modifiers;
this.fields = fields.size() == 0 ? FieldMember.NONE : fields.toArray(new FieldMember[fields.size()]);
this.fieldsRequiringAccessors = fieldsRequiringAccessors.size() == 0 ? FieldMember.NONE
: fieldsRequiringAccessors
.toArray(new FieldMember[fieldsRequiringAccessors.size()]);
this.constructors = constructors.size() == 0 ? MethodMember.NONE
: constructors.toArray(new MethodMember[constructors
.size()]);
this.methods = methods.size() == 0 ? MethodMember.NONE : methods.toArray(new MethodMember[methods.size()]);
this.nonprivateMethods = filterNonPrivateMethods(this.methods);
this.isReloadable = isReloadable;
this.registry = registry;
this.hasClinit = hasClinit;
allocateIds();
}
private static MethodMember[] filterNonPrivateMethods(MethodMember[] allMethods) {
List<MethodMember> result = null;
for (MethodMember method : allMethods) {
if (!method.isPrivate()) {
if (result == null) {
result = new ArrayList<MethodMember>();
}
result.add(method);
}
}
if (result == null) {
return MethodMember.NONE;
}
else {
return result.toArray(new MethodMember[result.size()]);
}
}
private void allocateIds() {
// Give the methods awareness of their index
for (MethodMember method : methods) {
method.setId(nextId++);
}
}
public MethodMember[] getMethods() {
return methods;
}
public MethodMember[] getConstructors() {
return constructors;
}
public FieldMember[] getFields() {
return fields;
}
public FieldMember[] getFieldsRequiringAccessors() {
return fieldsRequiringAccessors;
}
public int getModifiers() {
return modifiers;
}
/**
* @return the (slashed) type name
*/
public String getName() {
return typename;
}
/**
* @return the (slashed) supertype name
*/
public String getSupertypeName() {
return supertypeName;
}
/**
* @return array of (slashed) superinterface names (or an empty array if none)
*/
public String[] getSuperinterfacesName() {
return superinterfaceNames;
}
/**
* Check if this descriptor defines the specified method. A strict check on all aspects of the method -
* names/exceptions/flags, etc.
*
* @param method the method to check the existence of in this type descriptor
* @return true if this descriptor defines the specified method
*/
public boolean defines(MethodMember method) {
for (MethodMember existingMethod : methods) {
// make sure it *really* defines it (i.e. it is not a catcher)
if (!MethodMember.isCatcher(existingMethod) && existingMethod.equals(method)) {
return true;
}
}
return false;
}
/**
* Check if this descriptor defines a method with the specified name and descriptor. Return the method if it is
* found. Modifiers, generic signature and exceptions are ignored in this search.
*
* @param name the member name
* @param descriptor the member descriptor (e.g. (Ljava/lang/String;)I)
* @return the MethodMember if there is one
*/
public MethodMember getByDescriptor(String name, String descriptor) {
for (MethodMember existingMethod : methods) {
if (existingMethod.getName().equals(name) && existingMethod.getDescriptor().equals(descriptor)) {
return existingMethod;
}
}
return null;
}
public MethodMember getByNameAndDescriptor(String nameAndDescriptor) {
for (MethodMember existingMethod : methods) {
if (nameAndDescriptor.startsWith(existingMethod.getName())
&& nameAndDescriptor.endsWith(existingMethod.getDescriptor())) {
return existingMethod;
}
}
return null;
}
/**
* @return true if this type descriptor has been created for a reloadable type
*/
public boolean isReloadable() {
return isReloadable;
}
public MethodMember getMethod(int methodId) {
// Should never be an AIOOBE if the woven code is behaving
return methods[methodId];
}
public MethodMember getConstructor(int ctorId) {
// Should never be an AIOOBE if the woven code is behaving
return constructors[ctorId];
}
/**
* @return true if the type is an interface
*/
public boolean isInterface() {
return (modifiers & ACC_INTERFACE) != 0;
}
/**
* @return true if the type is an annotation
*/
public boolean isAnnotation() {
return (modifiers & ACC_ANNOTATION) != 0;
}
/**
* @return true if the type is an enum
*/
public boolean isEnum() {
return (modifiers & ACC_ENUM) != 0;
}
public boolean definesNonPrivate(String nameAndDescriptor) {
for (MethodMember existingMethod : nonprivateMethods) {
if (existingMethod.nameAndDescriptor.equals(nameAndDescriptor)) {
return true;
}
}
return false;
}
public boolean isFinalInHierarchy(String nad) {
return finalInHierarchy.contains(nad);
}
/**
* Search for a field on this type descriptor - do not try supertypes. This lookup does not differentiate between
* static/instance fields.
*
* @param name the name of the field
* @return a FieldMember if the field is found, otherwise null
*/
public FieldMember getField(String name) {
for (FieldMember field : fields) {
if (field.getName().equals(name)) {
return field;
}
}
return null;
}
public ReloadableType getReloadableType() {
if (!isReloadable) {
return null;
}
if (reloadableType == null) {
reloadableType = registry.getReloadableType(this.typename);
if (reloadableType == null) {
throw new IllegalStateException("There is no ReloadableType instance for " + typename);
}
}
return reloadableType;
}
public TypeRegistry getTypeRegistry() {
return registry;
}
// could be worth caching if used for more than error messages...
public String getDottedName() {
return getName().replace('/', '.');
}
public MethodMember getConstructor(String desc) {
for (MethodMember ctor : constructors) {
String d = ctor.getDescriptor();
if (d.equals(desc)) {
return ctor;
}
}
return null;
}
public boolean isGroovyType() {
return (bits & IS_GROOVY_TYPE) != 0;
}
public void setIsGroovyType(boolean b) {
bits |= IS_GROOVY_TYPE;
}
public boolean hasClinit() {
return hasClinit;
}
public String toString() {
StringBuilder s = new StringBuilder();
s.append("TypeDescriptor: name=" + typename + " superclass=" + supertypeName + " superinterfaces="
+ interfacesToString());
s.append(" flags=0x" + Integer.toHexString(modifiers).toUpperCase()).append("\n");
s.append("Fields: #" + fields.length + "\n" + fieldsToString());
s.append("Constructors:#" + constructors.length + "\n" + methodsToString(constructors));
s.append("Methods:#" + methods.length + "\n" + methodsToString(methods));
return s.toString();
}
private String fieldsToString() {
StringBuilder s = new StringBuilder();
int count = 0;
for (FieldMember field : fields) {
s.append(" field #" + Utils.toPaddedNumber((count++), 3)).append(' ').append(field.toString()).append('\n');
}
return s.toString();
}
private String interfacesToString() {
if (superinterfaceNames == null) {
return "";
}
else {
StringBuilder s = new StringBuilder();
for (String superinterfaceName : superinterfaceNames) {
s.append(superinterfaceName);
s.append(" ");
}
return s.toString().trim();
}
}
public String methodsToString(MethodMember[] methods) {
StringBuilder s = new StringBuilder();
int count = 0;
for (MethodMember method : methods) {
s.append(" method #" + Utils.toPaddedNumber((count++), 3)).append(' ').append(method.toString()).append(
" ")
.append(method.bitsToString()).append('\n');
}
return s.toString();
}
}
相关信息
相关文章
spring-loaded AbstractMember 源码
spring-loaded AnyTypePattern 源码
spring-loaded ChildClassLoader 源码
spring-loaded ConstantPoolChecker 源码
spring-loaded ConstantPoolChecker2 源码
0
赞
热门推荐
-
2、 - 优质文章
-
3、 gate.io
-
8、 golang
-
9、 openharmony
-
10、 Vue中input框自动聚焦