Polish CGLIB fork

- primarily automated "clean up" using Eclipse IDE
This commit is contained in:
Sam Brannen
2022-12-09 00:56:38 -05:00
parent 69f47e7700
commit b0b2bbc857
89 changed files with 1229 additions and 874 deletions

View File

@@ -16,12 +16,25 @@
package org.springframework.cglib.beans; package org.springframework.cglib.beans;
import java.beans.PropertyDescriptor; import java.beans.PropertyDescriptor;
import java.lang.reflect.*; import java.lang.reflect.Modifier;
import java.security.ProtectionDomain; import java.security.ProtectionDomain;
import org.springframework.cglib.core.*; import java.util.HashMap;
import java.util.Map;
import org.springframework.asm.ClassVisitor; import org.springframework.asm.ClassVisitor;
import org.springframework.asm.Type; import org.springframework.asm.Type;
import java.util.*; import org.springframework.cglib.core.AbstractClassGenerator;
import org.springframework.cglib.core.ClassEmitter;
import org.springframework.cglib.core.CodeEmitter;
import org.springframework.cglib.core.Constants;
import org.springframework.cglib.core.Converter;
import org.springframework.cglib.core.EmitUtils;
import org.springframework.cglib.core.KeyFactory;
import org.springframework.cglib.core.Local;
import org.springframework.cglib.core.MethodInfo;
import org.springframework.cglib.core.ReflectUtils;
import org.springframework.cglib.core.Signature;
import org.springframework.cglib.core.TypeUtils;
/** /**
* @author Chris Nokleberg * @author Chris Nokleberg
@@ -39,7 +52,7 @@ abstract public class BeanCopier
new Signature("copy", Type.VOID_TYPE, new Type[]{ Constants.TYPE_OBJECT, Constants.TYPE_OBJECT, CONVERTER }); new Signature("copy", Type.VOID_TYPE, new Type[]{ Constants.TYPE_OBJECT, Constants.TYPE_OBJECT, CONVERTER });
private static final Signature CONVERT = private static final Signature CONVERT =
TypeUtils.parseSignature("Object convert(Object, Class, Object)"); TypeUtils.parseSignature("Object convert(Object, Class, Object)");
interface BeanCopierKey { interface BeanCopierKey {
public Object newInstance(String source, String target, boolean useConverter); public Object newInstance(String source, String target, boolean useConverter);
} }
@@ -65,14 +78,14 @@ abstract public class BeanCopier
} }
public void setSource(Class source) { public void setSource(Class source) {
if(!Modifier.isPublic(source.getModifiers())){ if(!Modifier.isPublic(source.getModifiers())){
setNamePrefix(source.getName()); setNamePrefix(source.getName());
} }
this.source = source; this.source = source;
} }
public void setTarget(Class target) { public void setTarget(Class target) {
if(!Modifier.isPublic(target.getModifiers())){ if(!Modifier.isPublic(target.getModifiers())){
setNamePrefix(target.getName()); setNamePrefix(target.getName());
} }
this.target = target; this.target = target;
@@ -85,11 +98,13 @@ abstract public class BeanCopier
this.useConverter = useConverter; this.useConverter = useConverter;
} }
protected ClassLoader getDefaultClassLoader() { @Override
protected ClassLoader getDefaultClassLoader() {
return source.getClassLoader(); return source.getClassLoader();
} }
protected ProtectionDomain getProtectionDomain() { @Override
protected ProtectionDomain getProtectionDomain() {
return ReflectUtils.getProtectionDomain(source); return ReflectUtils.getProtectionDomain(source);
} }
@@ -98,7 +113,8 @@ abstract public class BeanCopier
return (BeanCopier)super.create(key); return (BeanCopier)super.create(key);
} }
public void generateClass(ClassVisitor v) { @Override
public void generateClass(ClassVisitor v) {
Type sourceType = Type.getType(source); Type sourceType = Type.getType(source);
Type targetType = Type.getType(target); Type targetType = Type.getType(target);
ClassEmitter ce = new ClassEmitter(v); ClassEmitter ce = new ClassEmitter(v);
@@ -115,8 +131,8 @@ abstract public class BeanCopier
PropertyDescriptor[] setters = ReflectUtils.getBeanSetters(target); PropertyDescriptor[] setters = ReflectUtils.getBeanSetters(target);
Map names = new HashMap(); Map names = new HashMap();
for (int i = 0; i < getters.length; i++) { for (PropertyDescriptor getter : getters) {
names.put(getters[i].getName(), getters[i]); names.put(getter.getName(), getter);
} }
Local targetLocal = e.make_local(); Local targetLocal = e.make_local();
Local sourceLocal = e.make_local(); Local sourceLocal = e.make_local();
@@ -124,7 +140,7 @@ abstract public class BeanCopier
e.load_arg(1); e.load_arg(1);
e.checkcast(targetType); e.checkcast(targetType);
e.store_local(targetLocal); e.store_local(targetLocal);
e.load_arg(0); e.load_arg(0);
e.checkcast(sourceType); e.checkcast(sourceType);
e.store_local(sourceLocal); e.store_local(sourceLocal);
} else { } else {
@@ -133,8 +149,7 @@ abstract public class BeanCopier
e.load_arg(0); e.load_arg(0);
e.checkcast(sourceType); e.checkcast(sourceType);
} }
for (int i = 0; i < setters.length; i++) { for (PropertyDescriptor setter : setters) {
PropertyDescriptor setter = setters[i];
PropertyDescriptor getter = (PropertyDescriptor)names.get(setter.getName()); PropertyDescriptor getter = (PropertyDescriptor)names.get(setter.getName());
if (getter != null) { if (getter != null) {
MethodInfo read = ReflectUtils.getMethodInfo(getter.getReadMethod()); MethodInfo read = ReflectUtils.getMethodInfo(getter.getReadMethod());
@@ -168,11 +183,13 @@ abstract public class BeanCopier
return setter.getPropertyType().isAssignableFrom(getter.getPropertyType()); return setter.getPropertyType().isAssignableFrom(getter.getPropertyType());
} }
protected Object firstInstance(Class type) { @Override
protected Object firstInstance(Class type) {
return ReflectUtils.newInstance(type); return ReflectUtils.newInstance(type);
} }
protected Object nextInstance(Object instance) { @Override
protected Object nextInstance(Object instance) {
return instance; return instance;
} }
} }

View File

@@ -17,10 +17,18 @@ package org.springframework.cglib.beans;
import java.beans.PropertyDescriptor; import java.beans.PropertyDescriptor;
import java.security.ProtectionDomain; import java.security.ProtectionDomain;
import java.util.*; import java.util.HashMap;
import org.springframework.cglib.core.*; import java.util.Iterator;
import java.util.Map;
import org.springframework.asm.ClassVisitor; import org.springframework.asm.ClassVisitor;
import org.springframework.asm.Type; import org.springframework.asm.Type;
import org.springframework.cglib.core.AbstractClassGenerator;
import org.springframework.cglib.core.ClassEmitter;
import org.springframework.cglib.core.Constants;
import org.springframework.cglib.core.EmitUtils;
import org.springframework.cglib.core.KeyFactory;
import org.springframework.cglib.core.ReflectUtils;
/** /**
* @author Juozas Baliuka, Chris Nokleberg * @author Juozas Baliuka, Chris Nokleberg
@@ -31,7 +39,7 @@ public class BeanGenerator extends AbstractClassGenerator
private static final Source SOURCE = new Source(BeanGenerator.class.getName()); private static final Source SOURCE = new Source(BeanGenerator.class.getName());
private static final BeanGeneratorKey KEY_FACTORY = private static final BeanGeneratorKey KEY_FACTORY =
(BeanGeneratorKey)KeyFactory.create(BeanGeneratorKey.class); (BeanGeneratorKey)KeyFactory.create(BeanGeneratorKey.class);
interface BeanGeneratorKey { interface BeanGeneratorKey {
public Object newInstance(String superclass, Map props); public Object newInstance(String superclass, Map props);
} }
@@ -67,7 +75,8 @@ public class BeanGenerator extends AbstractClassGenerator
props.put(name, Type.getType(type)); props.put(name, Type.getType(type));
} }
protected ClassLoader getDefaultClassLoader() { @Override
protected ClassLoader getDefaultClassLoader() {
if (superclass != null) { if (superclass != null) {
return superclass.getClassLoader(); return superclass.getClassLoader();
} else { } else {
@@ -75,7 +84,8 @@ public class BeanGenerator extends AbstractClassGenerator
} }
} }
protected ProtectionDomain getProtectionDomain() { @Override
protected ProtectionDomain getProtectionDomain() {
return ReflectUtils.getProtectionDomain(superclass); return ReflectUtils.getProtectionDomain(superclass);
} }
@@ -98,7 +108,8 @@ public class BeanGenerator extends AbstractClassGenerator
return super.create(key); return super.create(key);
} }
public void generateClass(ClassVisitor v) throws Exception { @Override
public void generateClass(ClassVisitor v) throws Exception {
int size = props.size(); int size = props.size();
String[] names = (String[])props.keySet().toArray(new String[size]); String[] names = (String[])props.keySet().toArray(new String[size]);
Type[] types = new Type[size]; Type[] types = new Type[size];
@@ -117,7 +128,8 @@ public class BeanGenerator extends AbstractClassGenerator
ce.end_class(); ce.end_class();
} }
protected Object firstInstance(Class type) { @Override
protected Object firstInstance(Class type) {
if (classOnly) { if (classOnly) {
return type; return type;
} else { } else {
@@ -125,7 +137,8 @@ public class BeanGenerator extends AbstractClassGenerator
} }
} }
protected Object nextInstance(Object instance) { @Override
protected Object nextInstance(Object instance) {
Class protoclass = (instance instanceof Class) ? (Class)instance : instance.getClass(); Class protoclass = (instance instanceof Class) ? (Class)instance : instance.getClass();
if (classOnly) { if (classOnly) {
return protoclass; return protoclass;
@@ -146,8 +159,8 @@ public class BeanGenerator extends AbstractClassGenerator
} }
public static void addProperties(BeanGenerator gen, PropertyDescriptor[] descriptors) { public static void addProperties(BeanGenerator gen, PropertyDescriptor[] descriptors) {
for (int i = 0; i < descriptors.length; i++) { for (PropertyDescriptor descriptor : descriptors) {
gen.addProperty(descriptors[i].getName(), descriptors[i].getPropertyType()); gen.addProperty(descriptor.getName(), descriptor.getPropertyType());
} }
} }
} }

View File

@@ -54,7 +54,7 @@ abstract public class BeanMap implements Map {
* @see BeanMap.Generator#setRequire * @see BeanMap.Generator#setRequire
*/ */
public static final int REQUIRE_SETTER = 2; public static final int REQUIRE_SETTER = 2;
/** /**
* Helper method to create a new <code>BeanMap</code>. For finer * Helper method to create a new <code>BeanMap</code>. For finer
* control over the generated instance, use a new instance of * control over the generated instance, use a new instance of
@@ -77,11 +77,11 @@ abstract public class BeanMap implements Map {
interface BeanMapKey { interface BeanMapKey {
public Object newInstance(Class type, int require); public Object newInstance(Class type, int require);
} }
private Object bean; private Object bean;
private Class beanClass; private Class beanClass;
private int require; private int require;
public Generator() { public Generator() {
super(SOURCE); super(SOURCE);
} }
@@ -121,11 +121,13 @@ abstract public class BeanMap implements Map {
this.require = require; this.require = require;
} }
protected ClassLoader getDefaultClassLoader() { @Override
protected ClassLoader getDefaultClassLoader() {
return beanClass.getClassLoader(); return beanClass.getClassLoader();
} }
protected ProtectionDomain getProtectionDomain() { @Override
protected ProtectionDomain getProtectionDomain() {
return ReflectUtils.getProtectionDomain(beanClass); return ReflectUtils.getProtectionDomain(beanClass);
} }
@@ -134,21 +136,25 @@ abstract public class BeanMap implements Map {
* generated class will be reused if possible. * generated class will be reused if possible.
*/ */
public BeanMap create() { public BeanMap create() {
if (beanClass == null) if (beanClass == null) {
throw new IllegalArgumentException("Class of bean unknown"); throw new IllegalArgumentException("Class of bean unknown");
}
setNamePrefix(beanClass.getName()); setNamePrefix(beanClass.getName());
return (BeanMap)super.create(KEY_FACTORY.newInstance(beanClass, require)); return (BeanMap)super.create(KEY_FACTORY.newInstance(beanClass, require));
} }
public void generateClass(ClassVisitor v) throws Exception { @Override
public void generateClass(ClassVisitor v) throws Exception {
new BeanMapEmitter(v, getClassName(), beanClass, require); new BeanMapEmitter(v, getClassName(), beanClass, require);
} }
protected Object firstInstance(Class type) { @Override
protected Object firstInstance(Class type) {
return ((BeanMap)ReflectUtils.newInstance(type)).newInstance(bean); return ((BeanMap)ReflectUtils.newInstance(type)).newInstance(bean);
} }
protected Object nextInstance(Object instance) { @Override
protected Object nextInstance(Object instance) {
return ((BeanMap)instance).newInstance(bean); return ((BeanMap)instance).newInstance(bean);
} }
} }
@@ -177,11 +183,13 @@ abstract public class BeanMap implements Map {
setBean(bean); setBean(bean);
} }
public Object get(Object key) { @Override
public Object get(Object key) {
return get(bean, key); return get(bean, key);
} }
public Object put(Object key, Object value) { @Override
public Object put(Object key, Object value) {
return put(bean, key, value); return put(bean, key, value);
} }
@@ -223,52 +231,58 @@ abstract public class BeanMap implements Map {
return bean; return bean;
} }
public void clear() { @Override
public void clear() {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
public boolean containsKey(Object key) { @Override
public boolean containsKey(Object key) {
return keySet().contains(key); return keySet().contains(key);
} }
public boolean containsValue(Object value) { @Override
public boolean containsValue(Object value) {
for (Iterator it = keySet().iterator(); it.hasNext();) { for (Iterator it = keySet().iterator(); it.hasNext();) {
Object v = get(it.next()); Object v = get(it.next());
if (((value == null) && (v == null)) || (value != null && value.equals(v))) if (((value == null) && (v == null)) || (value != null && value.equals(v))) {
return true; return true;
}
} }
return false; return false;
} }
public int size() { @Override
public int size() {
return keySet().size(); return keySet().size();
} }
public boolean isEmpty() { @Override
public boolean isEmpty() {
return size() == 0; return size() == 0;
} }
public Object remove(Object key) { @Override
public Object remove(Object key) {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
public void putAll(Map t) { @Override
for (Iterator it = t.keySet().iterator(); it.hasNext();) { public void putAll(Map t) {
Object key = it.next(); for (Object key : t.keySet()) {
put(key, t.get(key)); put(key, t.get(key));
} }
} }
public boolean equals(Object o) { @Override
if (o == null || !(o instanceof Map)) { public boolean equals(Object o) {
if (o == null || !(o instanceof Map other)) {
return false; return false;
} }
Map other = (Map)o;
if (size() != other.size()) { if (size() != other.size()) {
return false; return false;
} }
for (Iterator it = keySet().iterator(); it.hasNext();) { for (Object key : keySet()) {
Object key = it.next();
if (!other.containsKey(key)) { if (!other.containsKey(key)) {
return false; return false;
} }
@@ -281,10 +295,10 @@ abstract public class BeanMap implements Map {
return true; return true;
} }
public int hashCode() { @Override
public int hashCode() {
int code = 0; int code = 0;
for (Iterator it = keySet().iterator(); it.hasNext();) { for (Object key : keySet()) {
Object key = it.next();
Object value = get(key); Object value = get(key);
code += ((key == null) ? 0 : key.hashCode()) ^ code += ((key == null) ? 0 : key.hashCode()) ^
((value == null) ? 0 : value.hashCode()); ((value == null) ? 0 : value.hashCode());
@@ -293,16 +307,17 @@ abstract public class BeanMap implements Map {
} }
// TODO: optimize // TODO: optimize
public Set entrySet() { @Override
public Set entrySet() {
HashMap copy = new HashMap(); HashMap copy = new HashMap();
for (Iterator it = keySet().iterator(); it.hasNext();) { for (Object key : keySet()) {
Object key = it.next();
copy.put(key, get(key)); copy.put(key, get(key));
} }
return Collections.unmodifiableMap(copy).entrySet(); return Collections.unmodifiableMap(copy).entrySet();
} }
public Collection values() { @Override
public Collection values() {
Set keys = keySet(); Set keys = keySet();
List values = new ArrayList(keys.size()); List values = new ArrayList(keys.size());
for (Iterator it = keys.iterator(); it.hasNext();) { for (Iterator it = keys.iterator(); it.hasNext();) {
@@ -314,7 +329,8 @@ abstract public class BeanMap implements Map {
/* /*
* @see java.util.AbstractMap#toString * @see java.util.AbstractMap#toString
*/ */
public String toString() @Override
public String toString()
{ {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
sb.append('{'); sb.append('{');

View File

@@ -15,12 +15,23 @@
*/ */
package org.springframework.cglib.beans; package org.springframework.cglib.beans;
import java.beans.*; import java.beans.PropertyDescriptor;
import java.util.*; import java.util.HashMap;
import org.springframework.cglib.core.*; import java.util.Iterator;
import java.util.Map;
import org.springframework.asm.ClassVisitor; import org.springframework.asm.ClassVisitor;
import org.springframework.asm.Label; import org.springframework.asm.Label;
import org.springframework.asm.Type; import org.springframework.asm.Type;
import org.springframework.cglib.core.ClassEmitter;
import org.springframework.cglib.core.CodeEmitter;
import org.springframework.cglib.core.Constants;
import org.springframework.cglib.core.EmitUtils;
import org.springframework.cglib.core.MethodInfo;
import org.springframework.cglib.core.ObjectSwitchCallback;
import org.springframework.cglib.core.ReflectUtils;
import org.springframework.cglib.core.Signature;
import org.springframework.cglib.core.TypeUtils;
@SuppressWarnings({"rawtypes", "unchecked"}) @SuppressWarnings({"rawtypes", "unchecked"})
class BeanMapEmitter extends ClassEmitter { class BeanMapEmitter extends ClassEmitter {
@@ -50,7 +61,7 @@ class BeanMapEmitter extends ClassEmitter {
EmitUtils.null_constructor(this); EmitUtils.null_constructor(this);
EmitUtils.factory_method(this, NEW_INSTANCE); EmitUtils.factory_method(this, NEW_INSTANCE);
generateConstructor(); generateConstructor();
Map getters = makePropertyMap(ReflectUtils.getBeanGetters(type)); Map getters = makePropertyMap(ReflectUtils.getBeanGetters(type));
Map setters = makePropertyMap(ReflectUtils.getBeanSetters(type)); Map setters = makePropertyMap(ReflectUtils.getBeanSetters(type));
Map allProps = new HashMap(); Map allProps = new HashMap();
@@ -79,8 +90,8 @@ class BeanMapEmitter extends ClassEmitter {
private Map makePropertyMap(PropertyDescriptor[] props) { private Map makePropertyMap(PropertyDescriptor[] props) {
Map names = new HashMap(); Map names = new HashMap();
for (int i = 0; i < props.length; i++) { for (PropertyDescriptor prop : props) {
names.put(props[i].getName(), props[i]); names.put(prop.getName(), prop);
} }
return names; return names;
} }
@@ -97,7 +108,7 @@ class BeanMapEmitter extends ClassEmitter {
e.return_value(); e.return_value();
e.end_method(); e.end_method();
} }
private void generateGet(Class type, final Map getters) { private void generateGet(Class type, final Map getters) {
final CodeEmitter e = begin_method(Constants.ACC_PUBLIC, BEAN_MAP_GET, null); final CodeEmitter e = begin_method(Constants.ACC_PUBLIC, BEAN_MAP_GET, null);
e.load_arg(0); e.load_arg(0);
@@ -105,14 +116,16 @@ class BeanMapEmitter extends ClassEmitter {
e.load_arg(1); e.load_arg(1);
e.checkcast(Constants.TYPE_STRING); e.checkcast(Constants.TYPE_STRING);
EmitUtils.string_switch(e, getNames(getters), Constants.SWITCH_STYLE_HASH, new ObjectSwitchCallback() { EmitUtils.string_switch(e, getNames(getters), Constants.SWITCH_STYLE_HASH, new ObjectSwitchCallback() {
public void processCase(Object key, Label end) { @Override
public void processCase(Object key, Label end) {
PropertyDescriptor pd = (PropertyDescriptor)getters.get(key); PropertyDescriptor pd = (PropertyDescriptor)getters.get(key);
MethodInfo method = ReflectUtils.getMethodInfo(pd.getReadMethod()); MethodInfo method = ReflectUtils.getMethodInfo(pd.getReadMethod());
e.invoke(method); e.invoke(method);
e.box(method.getSignature().getReturnType()); e.box(method.getSignature().getReturnType());
e.return_value(); e.return_value();
} }
public void processDefault() { @Override
public void processDefault() {
e.aconst_null(); e.aconst_null();
e.return_value(); e.return_value();
} }
@@ -127,7 +140,8 @@ class BeanMapEmitter extends ClassEmitter {
e.load_arg(1); e.load_arg(1);
e.checkcast(Constants.TYPE_STRING); e.checkcast(Constants.TYPE_STRING);
EmitUtils.string_switch(e, getNames(setters), Constants.SWITCH_STYLE_HASH, new ObjectSwitchCallback() { EmitUtils.string_switch(e, getNames(setters), Constants.SWITCH_STYLE_HASH, new ObjectSwitchCallback() {
public void processCase(Object key, Label end) { @Override
public void processCase(Object key, Label end) {
PropertyDescriptor pd = (PropertyDescriptor)setters.get(key); PropertyDescriptor pd = (PropertyDescriptor)setters.get(key);
if (pd.getReadMethod() == null) { if (pd.getReadMethod() == null) {
e.aconst_null(); e.aconst_null();
@@ -144,7 +158,8 @@ class BeanMapEmitter extends ClassEmitter {
e.invoke(write); e.invoke(write);
e.return_value(); e.return_value();
} }
public void processDefault() { @Override
public void processDefault() {
// fall-through // fall-through
} }
}); });
@@ -152,7 +167,7 @@ class BeanMapEmitter extends ClassEmitter {
e.return_value(); e.return_value();
e.end_method(); e.end_method();
} }
private void generateKeySet(String[] allNames) { private void generateKeySet(String[] allNames) {
// static initializer // static initializer
declare_field(Constants.ACC_STATIC | Constants.ACC_PRIVATE, "keys", FIXED_KEY_SET, null); declare_field(Constants.ACC_STATIC | Constants.ACC_PRIVATE, "keys", FIXED_KEY_SET, null);
@@ -178,12 +193,14 @@ class BeanMapEmitter extends ClassEmitter {
final CodeEmitter e = begin_method(Constants.ACC_PUBLIC, GET_PROPERTY_TYPE, null); final CodeEmitter e = begin_method(Constants.ACC_PUBLIC, GET_PROPERTY_TYPE, null);
e.load_arg(0); e.load_arg(0);
EmitUtils.string_switch(e, allNames, Constants.SWITCH_STYLE_HASH, new ObjectSwitchCallback() { EmitUtils.string_switch(e, allNames, Constants.SWITCH_STYLE_HASH, new ObjectSwitchCallback() {
public void processCase(Object key, Label end) { @Override
public void processCase(Object key, Label end) {
PropertyDescriptor pd = (PropertyDescriptor)allProps.get(key); PropertyDescriptor pd = (PropertyDescriptor)allProps.get(key);
EmitUtils.load_class(e, Type.getType(pd.getPropertyType())); EmitUtils.load_class(e, Type.getType(pd.getPropertyType()));
e.return_value(); e.return_value();
} }
public void processDefault() { @Override
public void processDefault() {
e.aconst_null(); e.aconst_null();
e.return_value(); e.return_value();
} }

View File

@@ -16,8 +16,11 @@
package org.springframework.cglib.beans; package org.springframework.cglib.beans;
import java.security.ProtectionDomain; import java.security.ProtectionDomain;
import org.springframework.cglib.core.*;
import org.springframework.asm.ClassVisitor; import org.springframework.asm.ClassVisitor;
import org.springframework.cglib.core.AbstractClassGenerator;
import org.springframework.cglib.core.KeyFactory;
import org.springframework.cglib.core.ReflectUtils;
/** /**
* @author Juozas Baliuka * @author Juozas Baliuka
@@ -27,17 +30,17 @@ abstract public class BulkBean
{ {
private static final BulkBeanKey KEY_FACTORY = private static final BulkBeanKey KEY_FACTORY =
(BulkBeanKey)KeyFactory.create(BulkBeanKey.class); (BulkBeanKey)KeyFactory.create(BulkBeanKey.class);
interface BulkBeanKey { interface BulkBeanKey {
public Object newInstance(String target, String[] getters, String[] setters, String[] types); public Object newInstance(String target, String[] getters, String[] setters, String[] types);
} }
protected Class target; protected Class target;
protected String[] getters, setters; protected String[] getters, setters;
protected Class[] types; protected Class[] types;
protected BulkBean() { } protected BulkBean() { }
abstract public void getPropertyValues(Object bean, Object[] values); abstract public void getPropertyValues(Object bean, Object[] values);
abstract public void setPropertyValues(Object bean, Object[] values); abstract public void setPropertyValues(Object bean, Object[] values);
@@ -46,15 +49,15 @@ abstract public class BulkBean
getPropertyValues(bean, values); getPropertyValues(bean, values);
return values; return values;
} }
public Class[] getPropertyTypes() { public Class[] getPropertyTypes() {
return types.clone(); return types.clone();
} }
public String[] getGetters() { public String[] getGetters() {
return getters.clone(); return getters.clone();
} }
public String[] getSetters() { public String[] getSetters() {
return setters.clone(); return setters.clone();
} }
@@ -98,11 +101,13 @@ abstract public class BulkBean
this.types = types; this.types = types;
} }
protected ClassLoader getDefaultClassLoader() { @Override
protected ClassLoader getDefaultClassLoader() {
return target.getClassLoader(); return target.getClassLoader();
} }
protected ProtectionDomain getProtectionDomain() { @Override
protected ProtectionDomain getProtectionDomain() {
return ReflectUtils.getProtectionDomain(target); return ReflectUtils.getProtectionDomain(target);
} }
@@ -114,28 +119,31 @@ abstract public class BulkBean
return (BulkBean)super.create(key); return (BulkBean)super.create(key);
} }
public void generateClass(ClassVisitor v) throws Exception { @Override
public void generateClass(ClassVisitor v) throws Exception {
new BulkBeanEmitter(v, getClassName(), target, getters, setters, types); new BulkBeanEmitter(v, getClassName(), target, getters, setters, types);
} }
protected Object firstInstance(Class type) { @Override
protected Object firstInstance(Class type) {
BulkBean instance = (BulkBean)ReflectUtils.newInstance(type); BulkBean instance = (BulkBean)ReflectUtils.newInstance(type);
instance.target = target; instance.target = target;
int length = getters.length; int length = getters.length;
instance.getters = new String[length]; instance.getters = new String[length];
System.arraycopy(getters, 0, instance.getters, 0, length); System.arraycopy(getters, 0, instance.getters, 0, length);
instance.setters = new String[length]; instance.setters = new String[length];
System.arraycopy(setters, 0, instance.setters, 0, length); System.arraycopy(setters, 0, instance.setters, 0, length);
instance.types = new Class[types.length]; instance.types = new Class[types.length];
System.arraycopy(types, 0, instance.types, 0, types.length); System.arraycopy(types, 0, instance.types, 0, types.length);
return instance; return instance;
} }
protected Object nextInstance(Object instance) { @Override
protected Object nextInstance(Object instance) {
return instance; return instance;
} }
} }

View File

@@ -17,9 +17,19 @@ package org.springframework.cglib.beans;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.lang.reflect.Modifier; import java.lang.reflect.Modifier;
import org.springframework.cglib.core.*;
import org.springframework.asm.ClassVisitor; import org.springframework.asm.ClassVisitor;
import org.springframework.asm.Type; import org.springframework.asm.Type;
import org.springframework.cglib.core.Block;
import org.springframework.cglib.core.ClassEmitter;
import org.springframework.cglib.core.CodeEmitter;
import org.springframework.cglib.core.Constants;
import org.springframework.cglib.core.EmitUtils;
import org.springframework.cglib.core.Local;
import org.springframework.cglib.core.MethodInfo;
import org.springframework.cglib.core.ReflectUtils;
import org.springframework.cglib.core.Signature;
import org.springframework.cglib.core.TypeUtils;
@SuppressWarnings({"rawtypes", "unchecked"}) @SuppressWarnings({"rawtypes", "unchecked"})
class BulkBeanEmitter extends ClassEmitter { class BulkBeanEmitter extends ClassEmitter {
@@ -33,7 +43,7 @@ class BulkBeanEmitter extends ClassEmitter {
TypeUtils.parseType("org.springframework.cglib.beans.BulkBean"); TypeUtils.parseType("org.springframework.cglib.beans.BulkBean");
private static final Type BULK_BEAN_EXCEPTION = private static final Type BULK_BEAN_EXCEPTION =
TypeUtils.parseType("org.springframework.cglib.beans.BulkBeanException"); TypeUtils.parseType("org.springframework.cglib.beans.BulkBeanException");
public BulkBeanEmitter(ClassVisitor v, public BulkBeanEmitter(ClassVisitor v,
String className, String className,
Class target, Class target,
@@ -116,7 +126,7 @@ class BulkBeanEmitter extends ClassEmitter {
} }
e.end_method(); e.end_method();
} }
private static void validate(Class target, private static void validate(Class target,
String[] getters, String[] getters,
String[] setters, String[] setters,

View File

@@ -20,7 +20,7 @@ public class BulkBeanException extends RuntimeException
{ {
private int index; private int index;
private Throwable cause; private Throwable cause;
public BulkBeanException(String message, int index) { public BulkBeanException(String message, int index) {
super(message); super(message);
this.index = index; this.index = index;
@@ -35,8 +35,9 @@ public class BulkBeanException extends RuntimeException
public int getIndex() { public int getIndex() {
return index; return index;
} }
public Throwable getCause() { @Override
public Throwable getCause() {
return cause; return cause;
} }
} }

View File

@@ -15,7 +15,12 @@
*/ */
package org.springframework.cglib.beans; package org.springframework.cglib.beans;
import java.util.*; import java.util.AbstractSet;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
@SuppressWarnings({"rawtypes", "unchecked"}) @SuppressWarnings({"rawtypes", "unchecked"})
public /* need it for class loading */ class FixedKeySet extends AbstractSet { public /* need it for class loading */ class FixedKeySet extends AbstractSet {
@@ -27,11 +32,13 @@ public /* need it for class loading */ class FixedKeySet extends AbstractSet {
set = Collections.unmodifiableSet(new HashSet(Arrays.asList(keys))); set = Collections.unmodifiableSet(new HashSet(Arrays.asList(keys)));
} }
public Iterator iterator() { @Override
public Iterator iterator() {
return set.iterator(); return set.iterator();
} }
public int size() { @Override
public int size() {
return size; return size;
} }
} }

View File

@@ -18,9 +18,18 @@ package org.springframework.cglib.beans;
import java.beans.PropertyDescriptor; import java.beans.PropertyDescriptor;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.security.ProtectionDomain; import java.security.ProtectionDomain;
import org.springframework.cglib.core.*;
import org.springframework.asm.ClassVisitor; import org.springframework.asm.ClassVisitor;
import org.springframework.asm.Type; import org.springframework.asm.Type;
import org.springframework.cglib.core.AbstractClassGenerator;
import org.springframework.cglib.core.ClassEmitter;
import org.springframework.cglib.core.CodeEmitter;
import org.springframework.cglib.core.Constants;
import org.springframework.cglib.core.EmitUtils;
import org.springframework.cglib.core.MethodInfo;
import org.springframework.cglib.core.ReflectUtils;
import org.springframework.cglib.core.Signature;
import org.springframework.cglib.core.TypeUtils;
/** /**
* @author Chris Nokleberg * @author Chris Nokleberg
*/ */
@@ -60,11 +69,13 @@ public class ImmutableBean
// SPRING PATCH END // SPRING PATCH END
} }
protected ClassLoader getDefaultClassLoader() { @Override
protected ClassLoader getDefaultClassLoader() {
return target.getClassLoader(); return target.getClassLoader();
} }
protected ProtectionDomain getProtectionDomain() { @Override
protected ProtectionDomain getProtectionDomain() {
return ReflectUtils.getProtectionDomain(target); return ReflectUtils.getProtectionDomain(target);
} }
@@ -74,7 +85,8 @@ public class ImmutableBean
return super.create(name); return super.create(name);
} }
public void generateClass(ClassVisitor v) { @Override
public void generateClass(ClassVisitor v) {
Type targetType = Type.getType(target); Type targetType = Type.getType(target);
ClassEmitter ce = new ClassEmitter(v); ClassEmitter ce = new ClassEmitter(v);
ce.begin_class(Constants.V1_8, ce.begin_class(Constants.V1_8,
@@ -100,8 +112,8 @@ public class ImmutableBean
Method[] getters = ReflectUtils.getPropertyMethods(descriptors, true, false); Method[] getters = ReflectUtils.getPropertyMethods(descriptors, true, false);
Method[] setters = ReflectUtils.getPropertyMethods(descriptors, false, true); Method[] setters = ReflectUtils.getPropertyMethods(descriptors, false, true);
for (int i = 0; i < getters.length; i++) { for (Method getter2 : getters) {
MethodInfo getter = ReflectUtils.getMethodInfo(getters[i]); MethodInfo getter = ReflectUtils.getMethodInfo(getter2);
e = EmitUtils.begin_method(ce, getter, Constants.ACC_PUBLIC); e = EmitUtils.begin_method(ce, getter, Constants.ACC_PUBLIC);
e.load_this(); e.load_this();
e.getfield(FIELD_NAME); e.getfield(FIELD_NAME);
@@ -110,8 +122,8 @@ public class ImmutableBean
e.end_method(); e.end_method();
} }
for (int i = 0; i < setters.length; i++) { for (Method setter2 : setters) {
MethodInfo setter = ReflectUtils.getMethodInfo(setters[i]); MethodInfo setter = ReflectUtils.getMethodInfo(setter2);
e = EmitUtils.begin_method(ce, setter, Constants.ACC_PUBLIC); e = EmitUtils.begin_method(ce, setter, Constants.ACC_PUBLIC);
e.throw_exception(ILLEGAL_STATE_EXCEPTION, "Bean is immutable"); e.throw_exception(ILLEGAL_STATE_EXCEPTION, "Bean is immutable");
e.end_method(); e.end_method();
@@ -120,12 +132,14 @@ public class ImmutableBean
ce.end_class(); ce.end_class();
} }
protected Object firstInstance(Class type) { @Override
protected Object firstInstance(Class type) {
return ReflectUtils.newInstance(type, OBJECT_CLASSES, new Object[]{ bean }); return ReflectUtils.newInstance(type, OBJECT_CLASSES, new Object[]{ bean });
} }
// TODO: optimize // TODO: optimize
protected Object nextInstance(Object instance) { @Override
protected Object nextInstance(Object instance) {
return firstInstance(instance.getClass()); return firstInstance(instance.getClass());
} }
} }

View File

@@ -38,7 +38,7 @@ abstract public class AbstractClassGenerator<T> implements ClassGenerator {
private static final ThreadLocal CURRENT = new ThreadLocal(); private static final ThreadLocal CURRENT = new ThreadLocal();
private static volatile Map<ClassLoader, ClassLoaderData> CACHE = new WeakHashMap<ClassLoader, ClassLoaderData>(); private static volatile Map<ClassLoader, ClassLoaderData> CACHE = new WeakHashMap<>();
private static final boolean DEFAULT_USE_CACHE = private static final boolean DEFAULT_USE_CACHE =
Boolean.parseBoolean(System.getProperty("cglib.useCache", "true")); Boolean.parseBoolean(System.getProperty("cglib.useCache", "true"));
@@ -70,7 +70,7 @@ abstract public class AbstractClassGenerator<T> implements ClassGenerator {
protected static class ClassLoaderData { protected static class ClassLoaderData {
private final Set<String> reservedClassNames = new HashSet<String>(); private final Set<String> reservedClassNames = new HashSet<>();
/** /**
* {@link AbstractClassGenerator} here holds "cache key" (e.g. {@link org.springframework.cglib.proxy.Enhancer} * {@link AbstractClassGenerator} here holds "cache key" (e.g. {@link org.springframework.cglib.proxy.Enhancer}
@@ -90,31 +90,20 @@ abstract public class AbstractClassGenerator<T> implements ClassGenerator {
*/ */
private final WeakReference<ClassLoader> classLoader; private final WeakReference<ClassLoader> classLoader;
private final Predicate uniqueNamePredicate = new Predicate() { private final Predicate uniqueNamePredicate = this.reservedClassNames::contains;
public boolean evaluate(Object name) {
return reservedClassNames.contains(name);
}
};
private static final Function<AbstractClassGenerator, Object> GET_KEY = new Function<AbstractClassGenerator, Object>() { private static final Function<AbstractClassGenerator, Object> GET_KEY = gen -> gen.key;
public Object apply(AbstractClassGenerator gen) {
return gen.key;
}
};
public ClassLoaderData(ClassLoader classLoader) { public ClassLoaderData(ClassLoader classLoader) {
if (classLoader == null) { if (classLoader == null) {
throw new IllegalArgumentException("classLoader == null is not yet supported"); throw new IllegalArgumentException("classLoader == null is not yet supported");
} }
this.classLoader = new WeakReference<ClassLoader>(classLoader); this.classLoader = new WeakReference<>(classLoader);
Function<AbstractClassGenerator, Object> load = Function<AbstractClassGenerator, Object> load = gen -> {
new Function<AbstractClassGenerator, Object>() { Class klass = gen.generate(ClassLoaderData.this);
public Object apply(AbstractClassGenerator gen) { return gen.wrapCachedClass(klass);
Class klass = gen.generate(ClassLoaderData.this); };
return gen.wrapCachedClass(klass); generatedClasses = new LoadingCache<>(GET_KEY, load);
}
};
generatedClasses = new LoadingCache<AbstractClassGenerator, Object, Object>(GET_KEY, load);
} }
public ClassLoader getClassLoader() { public ClassLoader getClassLoader() {
@@ -205,8 +194,9 @@ abstract public class AbstractClassGenerator<T> implements ClassGenerator {
* @see DefaultNamingPolicy * @see DefaultNamingPolicy
*/ */
public void setNamingPolicy(NamingPolicy namingPolicy) { public void setNamingPolicy(NamingPolicy namingPolicy) {
if (namingPolicy == null) if (namingPolicy == null) {
namingPolicy = DefaultNamingPolicy.INSTANCE; namingPolicy = DefaultNamingPolicy.INSTANCE;
}
this.namingPolicy = namingPolicy; this.namingPolicy = namingPolicy;
} }
@@ -250,8 +240,9 @@ abstract public class AbstractClassGenerator<T> implements ClassGenerator {
* By default an instance of {@link DefaultGeneratorStrategy} is used. * By default an instance of {@link DefaultGeneratorStrategy} is used.
*/ */
public void setStrategy(GeneratorStrategy strategy) { public void setStrategy(GeneratorStrategy strategy) {
if (strategy == null) if (strategy == null) {
strategy = DefaultGeneratorStrategy.INSTANCE; strategy = DefaultGeneratorStrategy.INSTANCE;
}
this.strategy = strategy; this.strategy = strategy;
} }
@@ -311,7 +302,7 @@ abstract public class AbstractClassGenerator<T> implements ClassGenerator {
cache = CACHE; cache = CACHE;
data = cache.get(loader); data = cache.get(loader);
if (data == null) { if (data == null) {
Map<ClassLoader, ClassLoaderData> newCache = new WeakHashMap<ClassLoader, ClassLoaderData>(cache); Map<ClassLoader, ClassLoaderData> newCache = new WeakHashMap<>(cache);
data = new ClassLoaderData(loader); data = new ClassLoaderData(loader);
newCache.put(loader, data); newCache.put(loader, data);
CACHE = newCache; CACHE = newCache;
@@ -320,8 +311,8 @@ abstract public class AbstractClassGenerator<T> implements ClassGenerator {
} }
this.key = key; this.key = key;
Object obj = data.get(this, getUseCache()); Object obj = data.get(this, getUseCache());
if (obj instanceof Class) { if (obj instanceof Class<?> clazz) {
return firstInstance((Class) obj); return firstInstance(clazz);
} }
return nextInstance(obj); return nextInstance(obj);
} }

View File

@@ -38,7 +38,7 @@ public class Block
} }
end = e.mark(); end = e.mark();
} }
public Label getStart() { public Label getStart() {
return start; return start;
} }

View File

@@ -15,14 +15,14 @@
*/ */
package org.springframework.cglib.core; package org.springframework.cglib.core;
import java.util.HashMap;
import java.util.Map;
import org.springframework.asm.ClassVisitor; import org.springframework.asm.ClassVisitor;
import org.springframework.asm.FieldVisitor; import org.springframework.asm.FieldVisitor;
import org.springframework.asm.MethodVisitor; import org.springframework.asm.MethodVisitor;
import org.springframework.asm.Type; import org.springframework.asm.Type;
import java.util.HashMap;
import java.util.Map;
/** /**
* @author Juozas Baliuka, Chris Nokleberg * @author Juozas Baliuka, Chris Nokleberg
*/ */
@@ -45,7 +45,8 @@ public class ClassEmitter extends ClassTransformer {
super(Constants.ASM_API); super(Constants.ASM_API);
} }
public void setTarget(ClassVisitor cv) { @Override
public void setTarget(ClassVisitor cv) {
this.cv = cv; this.cv = cv;
fieldInfo = new HashMap(); fieldInfo = new HashMap();
@@ -65,16 +66,20 @@ public class ClassEmitter extends ClassTransformer {
public void begin_class(int version, final int access, String className, final Type superType, final Type[] interfaces, String source) { public void begin_class(int version, final int access, String className, final Type superType, final Type[] interfaces, String source) {
final Type classType = Type.getType("L" + className.replace('.', '/') + ";"); final Type classType = Type.getType("L" + className.replace('.', '/') + ";");
classInfo = new ClassInfo() { classInfo = new ClassInfo() {
public Type getType() { @Override
public Type getType() {
return classType; return classType;
} }
public Type getSuperType() { @Override
public Type getSuperType() {
return (superType != null) ? superType : Constants.TYPE_OBJECT; return (superType != null) ? superType : Constants.TYPE_OBJECT;
} }
public Type[] getInterfaces() { @Override
public Type[] getInterfaces() {
return interfaces; return interfaces;
} }
public int getModifiers() { @Override
public int getModifiers() {
return access; return access;
} }
}; };
@@ -84,8 +89,9 @@ public class ClassEmitter extends ClassTransformer {
null, null,
classInfo.getSuperType().getInternalName(), classInfo.getSuperType().getInternalName(),
TypeUtils.toInternalNames(interfaces)); TypeUtils.toInternalNames(interfaces));
if (source != null) if (source != null) {
cv.visitSource(source, null); cv.visitSource(source, null);
}
init(); init();
} }
@@ -137,8 +143,9 @@ public class ClassEmitter extends ClassTransformer {
} }
public CodeEmitter begin_method(int access, Signature sig, Type[] exceptions) { public CodeEmitter begin_method(int access, Signature sig, Type[] exceptions) {
if (classInfo == null) if (classInfo == null) {
throw new IllegalStateException("classInfo is null! " + this); throw new IllegalStateException("classInfo is null! " + this);
}
MethodVisitor v = cv.visitMethod(access, MethodVisitor v = cv.visitMethod(access,
sig.getName(), sig.getName(),
sig.getDescriptor(), sig.getDescriptor(),
@@ -147,10 +154,12 @@ public class ClassEmitter extends ClassTransformer {
if (sig.equals(Constants.SIG_STATIC) && !TypeUtils.isInterface(getAccess())) { if (sig.equals(Constants.SIG_STATIC) && !TypeUtils.isInterface(getAccess())) {
rawStaticInit = v; rawStaticInit = v;
MethodVisitor wrapped = new MethodVisitor(Constants.ASM_API, v) { MethodVisitor wrapped = new MethodVisitor(Constants.ASM_API, v) {
public void visitMaxs(int maxStack, int maxLocals) { @Override
public void visitMaxs(int maxStack, int maxLocals) {
// ignore // ignore
} }
public void visitInsn(int insn) { @Override
public void visitInsn(int insn) {
if (insn != Constants.RETURN) { if (insn != Constants.RETURN) {
super.visitInsn(insn); super.visitInsn(insn);
} }
@@ -166,7 +175,8 @@ public class ClassEmitter extends ClassTransformer {
return staticInit; return staticInit;
} else if (sig.equals(staticHookSig)) { } else if (sig.equals(staticHookSig)) {
return new CodeEmitter(this, v, access, sig, exceptions) { return new CodeEmitter(this, v, access, sig, exceptions) {
public boolean isStaticHook() { @Override
public boolean isStaticHook() {
return true; return true;
} }
}; };
@@ -204,13 +214,13 @@ public class ClassEmitter extends ClassTransformer {
} }
return field; return field;
} }
static class FieldInfo { static class FieldInfo {
int access; int access;
String name; String name;
Type type; Type type;
Object value; Object value;
public FieldInfo(int access, String name, Type type, Object value) { public FieldInfo(int access, String name, Type type, Object value) {
this.access = access; this.access = access;
this.name = name; this.name = name;
@@ -218,30 +228,36 @@ public class ClassEmitter extends ClassTransformer {
this.value = value; this.value = value;
} }
public boolean equals(Object o) { @Override
if (o == null) public boolean equals(Object o) {
return false; if (o == null) {
if (!(o instanceof FieldInfo)) return false;
return false; }
FieldInfo other = (FieldInfo)o; if (!(o instanceof FieldInfo other)) {
return false;
}
if (access != other.access || if (access != other.access ||
!name.equals(other.name) || !name.equals(other.name) ||
!type.equals(other.type)) { !type.equals(other.type)) {
return false; return false;
} }
if ((value == null) ^ (other.value == null)) if ((value == null) ^ (other.value == null)) {
return false; return false;
if (value != null && !value.equals(other.value)) }
return false; if (value != null && !value.equals(other.value)) {
return false;
}
return true; return true;
} }
public int hashCode() { @Override
public int hashCode() {
return access ^ name.hashCode() ^ type.hashCode() ^ ((value == null) ? 0 : value.hashCode()); return access ^ name.hashCode() ^ type.hashCode() ^ ((value == null) ? 0 : value.hashCode());
} }
} }
public void visit(int version, @Override
public void visit(int version,
int access, int access,
String name, String name,
String signature, String signature,
@@ -254,12 +270,14 @@ public class ClassEmitter extends ClassTransformer {
TypeUtils.fromInternalNames(interfaces), TypeUtils.fromInternalNames(interfaces),
null); // TODO null); // TODO
} }
public void visitEnd() { @Override
public void visitEnd() {
end_class(); end_class();
} }
public FieldVisitor visitField(int access, @Override
public FieldVisitor visitField(int access,
String name, String name,
String desc, String desc,
String signature, String signature,
@@ -267,14 +285,15 @@ public class ClassEmitter extends ClassTransformer {
declare_field(access, name, Type.getType(desc), value); declare_field(access, name, Type.getType(desc), value);
return null; // TODO return null; // TODO
} }
public MethodVisitor visitMethod(int access, @Override
public MethodVisitor visitMethod(int access,
String name, String name,
String desc, String desc,
String signature, String signature,
String[] exceptions) { String[] exceptions) {
return begin_method(access, return begin_method(access,
new Signature(name, desc), new Signature(name, desc),
TypeUtils.fromInternalNames(exceptions)); TypeUtils.fromInternalNames(exceptions));
} }
} }

View File

@@ -28,14 +28,16 @@ abstract public class ClassInfo {
abstract public Type[] getInterfaces(); abstract public Type[] getInterfaces();
abstract public int getModifiers(); abstract public int getModifiers();
@Override @Override
public boolean equals(Object o) { public boolean equals(Object o) {
if (o == null) if (o == null) {
return false; return false;
if (!(o instanceof ClassInfo)) }
return false; if (!(o instanceof ClassInfo classInfo)) {
return getType().equals(((ClassInfo)o).getType()); return false;
} }
return getType().equals(classInfo.getType());
}
@Override @Override
public int hashCode() { public int hashCode() {

View File

@@ -15,51 +15,53 @@
*/ */
package org.springframework.cglib.core; package org.springframework.cglib.core;
import java.util.ArrayList;
import java.util.List;
import org.springframework.asm.ClassReader; import org.springframework.asm.ClassReader;
import org.springframework.asm.ClassVisitor; import org.springframework.asm.ClassVisitor;
import java.util.*;
// TODO: optimize (ClassReader buffers entire class before accept) // TODO: optimize (ClassReader buffers entire class before accept)
@SuppressWarnings({"rawtypes", "unchecked"}) @SuppressWarnings({"rawtypes", "unchecked"})
public class ClassNameReader { public class ClassNameReader {
private ClassNameReader() {
}
private static final EarlyExitException EARLY_EXIT = new EarlyExitException(); private ClassNameReader() {
}
private static final EarlyExitException EARLY_EXIT = new EarlyExitException();
@SuppressWarnings("serial") @SuppressWarnings("serial")
private static class EarlyExitException extends RuntimeException { } private static class EarlyExitException extends RuntimeException {
}
public static String getClassName(ClassReader r) {
public static String getClassName(ClassReader r) {
return getClassInfo(r)[0]; return getClassInfo(r)[0];
}
}
public static String[] getClassInfo(ClassReader r) { public static String[] getClassInfo(ClassReader r) {
final List array = new ArrayList(); final List<String> array = new ArrayList<>();
try { try {
r.accept(new ClassVisitor(Constants.ASM_API, null) { r.accept(new ClassVisitor(Constants.ASM_API, null) {
@Override
public void visit(int version, public void visit(int version,
int access, int access,
String name, String name,
String signature, String signature,
String superName, String superName,
String[] interfaces) { String[] interfaces) {
array.add( name.replace('/', '.') ); array.add(name.replace('/', '.'));
if(superName != null){ if (superName != null) {
array.add( superName.replace('/', '.') ); array.add(superName.replace('/', '.'));
} }
for(int i = 0; i < interfaces.length; i++ ){ for (String element : interfaces) {
array.add( interfaces[i].replace('/', '.') ); array.add(element.replace('/', '.'));
} }
throw EARLY_EXIT; throw EARLY_EXIT;
} }
}, ClassReader.SKIP_DEBUG | ClassReader.SKIP_FRAMES); }, ClassReader.SKIP_DEBUG | ClassReader.SKIP_FRAMES);
} catch (EarlyExitException e) { } } catch (EarlyExitException e) { }
return (String[])array.toArray( new String[]{} ); return array.toArray(new String[0]);
} }
} }

View File

@@ -17,7 +17,7 @@ package org.springframework.cglib.core;
public class ClassesKey { public class ClassesKey {
private static final Key FACTORY = (Key)KeyFactory.create(Key.class); private static final Key FACTORY = (Key)KeyFactory.create(Key.class);
interface Key { interface Key {
Object newInstance(Object[] array); Object newInstance(Object[] array);
} }

View File

@@ -613,8 +613,9 @@ public class CodeEmitter extends LocalVariablesSorter {
} }
public void process_switch(int[] keys, ProcessSwitchCallback callback, boolean useTable) { public void process_switch(int[] keys, ProcessSwitchCallback callback, boolean useTable) {
if (!isSorted(keys)) if (!isSorted(keys)) {
throw new IllegalArgumentException("keys to switch must be sorted ascending"); throw new IllegalArgumentException("keys to switch must be sorted ascending");
}
Label def = make_label(); Label def = make_label();
Label end = make_label(); Label end = make_label();
@@ -656,9 +657,7 @@ public class CodeEmitter extends LocalVariablesSorter {
callback.processDefault(); callback.processDefault();
mark(end); mark(end);
} catch (RuntimeException e) { } catch (RuntimeException | Error e) {
throw e;
} catch (Error e) {
throw e; throw e;
} catch (Exception e) { } catch (Exception e) {
throw new CodeGenerationException(e); throw new CodeGenerationException(e);
@@ -667,8 +666,9 @@ public class CodeEmitter extends LocalVariablesSorter {
private static boolean isSorted(int[] keys) { private static boolean isSorted(int[] keys) {
for (int i = 1; i < keys.length; i++) { for (int i = 1; i < keys.length; i++) {
if (keys[i] < keys[i - 1]) if (keys[i] < keys[i - 1]) {
return false; return false;
}
} }
return true; return true;
} }

View File

@@ -27,7 +27,8 @@ public class CodeGenerationException extends RuntimeException {
this.cause = cause; this.cause = cause;
} }
public Throwable getCause() { @Override
public Throwable getCause() {
return cause; return cause;
} }
} }

View File

@@ -34,8 +34,7 @@ public class CollectionUtils {
public static Map bucket(Collection c, Transformer t) { public static Map bucket(Collection c, Transformer t) {
Map buckets = new HashMap(); Map buckets = new HashMap();
for (Iterator it = c.iterator(); it.hasNext();) { for (Object value : c) {
Object value = it.next();
Object key = t.transform(value); Object key = t.transform(value);
List bucket = (List)buckets.get(key); List bucket = (List)buckets.get(key);
if (bucket == null) { if (bucket == null) {
@@ -47,8 +46,7 @@ public class CollectionUtils {
} }
public static void reverse(Map source, Map target) { public static void reverse(Map source, Map target) {
for (Iterator it = source.keySet().iterator(); it.hasNext();) { for (Object key : source.keySet()) {
Object key = it.next();
target.put(source.get(key), key); target.put(source.get(key), key);
} }
} }

View File

@@ -32,7 +32,7 @@ public interface Constants extends org.springframework.asm.Opcodes {
public static final Signature SIG_STATIC = public static final Signature SIG_STATIC =
TypeUtils.parseSignature("void <clinit>()"); TypeUtils.parseSignature("void <clinit>()");
public static final Type TYPE_OBJECT_ARRAY = TypeUtils.parseType("Object[]"); public static final Type TYPE_OBJECT_ARRAY = TypeUtils.parseType("Object[]");
public static final Type TYPE_CLASS_ARRAY = TypeUtils.parseType("Class[]"); public static final Type TYPE_CLASS_ARRAY = TypeUtils.parseType("Class[]");
public static final Type TYPE_STRING_ARRAY = TypeUtils.parseType("String[]"); public static final Type TYPE_STRING_ARRAY = TypeUtils.parseType("String[]");

View File

@@ -19,8 +19,9 @@ import org.springframework.asm.ClassWriter;
public class DefaultGeneratorStrategy implements GeneratorStrategy { public class DefaultGeneratorStrategy implements GeneratorStrategy {
public static final DefaultGeneratorStrategy INSTANCE = new DefaultGeneratorStrategy(); public static final DefaultGeneratorStrategy INSTANCE = new DefaultGeneratorStrategy();
public byte[] generate(ClassGenerator cg) throws Exception { @Override
public byte[] generate(ClassGenerator cg) throws Exception {
DebuggingClassWriter cw = getClassVisitor(); DebuggingClassWriter cw = getClassVisitor();
transform(cg).generateClass(cw); transform(cg).generateClass(cw);
return transform(cw.toByteArray()); return transform(cw.toByteArray());
@@ -36,7 +37,7 @@ public class DefaultGeneratorStrategy implements GeneratorStrategy {
throw new UnsupportedOperationException("You are calling " + throw new UnsupportedOperationException("You are calling " +
"getClassWriter, which no longer exists in this cglib version."); "getClassWriter, which no longer exists in this cglib version.");
} }
protected byte[] transform(byte[] b) throws Exception { protected byte[] transform(byte[] b) throws Exception {
return b; return b;
} }

View File

@@ -48,8 +48,9 @@ public class DefaultNamingPolicy implements NamingPolicy {
Integer.toHexString(STRESS_HASH_CODE ? 0 : key.hashCode()); Integer.toHexString(STRESS_HASH_CODE ? 0 : key.hashCode());
String attempt = base; String attempt = base;
int index = 2; int index = 2;
while (names.evaluate(attempt)) while (names.evaluate(attempt)) {
attempt = base + "_" + index++; attempt = base + "_" + index++;
}
return attempt; return attempt;
} }

View File

@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package org.springframework.cglib.core; package org.springframework.cglib.core;
import java.io.IOException; import java.io.IOException;
@@ -24,6 +25,7 @@ import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import org.springframework.asm.ClassReader; import org.springframework.asm.ClassReader;
import org.springframework.asm.ClassVisitor; import org.springframework.asm.ClassVisitor;
import org.springframework.asm.MethodVisitor; import org.springframework.asm.MethodVisitor;
@@ -45,7 +47,7 @@ public class DuplicatesPredicate implements Predicate {
/** /**
* Constructs a DuplicatesPredicate that prefers using superclass non-bridge methods despite a * Constructs a DuplicatesPredicate that prefers using superclass non-bridge methods despite a
* subclass method with the same signtaure existing (if the subclass is a bridge method). * subclass method with the same signature existing (if the subclass is a bridge method).
*/ */
public DuplicatesPredicate(List allMethods) { public DuplicatesPredicate(List allMethods) {
rejected = new HashSet(); rejected = new HashSet();
@@ -70,7 +72,7 @@ public class DuplicatesPredicate implements Predicate {
suspects.put(sig, existing); suspects.put(sig, existing);
} }
} }
if (!suspects.isEmpty()) { if (!suspects.isEmpty()) {
Set classes = new HashSet(); Set classes = new HashSet();
UnnecessaryBridgeFinder finder = new UnnecessaryBridgeFinder(rejected); UnnecessaryBridgeFinder finder = new UnnecessaryBridgeFinder(rejected);
@@ -101,10 +103,11 @@ public class DuplicatesPredicate implements Predicate {
} }
} }
@Override
public boolean evaluate(Object arg) { public boolean evaluate(Object arg) {
return !rejected.contains(arg) && unique.add(MethodWrapper.create((Method) arg)); return !rejected.contains(arg) && unique.add(MethodWrapper.create((Method) arg));
} }
private static ClassLoader getClassLoader(Class c) { private static ClassLoader getClassLoader(Class c) {
ClassLoader cl = c.getClassLoader(); ClassLoader cl = c.getClassLoader();
if (cl == null) { if (cl == null) {
@@ -131,6 +134,7 @@ public class DuplicatesPredicate implements Predicate {
methods.put(ReflectUtils.getSignature(m), m); methods.put(ReflectUtils.getSignature(m), m);
} }
@Override
public void visit( public void visit(
int version, int version,
int access, int access,
@@ -139,6 +143,7 @@ public class DuplicatesPredicate implements Predicate {
String superName, String superName,
String[] interfaces) {} String[] interfaces) {}
@Override
public MethodVisitor visitMethod( public MethodVisitor visitMethod(
int access, String name, String desc, String signature, String[] exceptions) { int access, String name, String desc, String signature, String[] exceptions) {
Signature sig = new Signature(name, desc); Signature sig = new Signature(name, desc);
@@ -146,6 +151,7 @@ public class DuplicatesPredicate implements Predicate {
if (currentMethod != null) { if (currentMethod != null) {
currentMethodSig = sig; currentMethodSig = sig;
return new MethodVisitor(Constants.ASM_API) { return new MethodVisitor(Constants.ASM_API) {
@Override
public void visitMethodInsn( public void visitMethodInsn(
int opcode, String owner, String name, String desc, boolean itf) { int opcode, String owner, String name, String desc, boolean itf) {
if (opcode == Opcodes.INVOKESPECIAL && currentMethodSig != null) { if (opcode == Opcodes.INVOKESPECIAL && currentMethodSig != null) {

View File

@@ -187,9 +187,7 @@ public class EmitUtils {
default: default:
throw new IllegalArgumentException("unknown switch style " + switchStyle); throw new IllegalArgumentException("unknown switch style " + switchStyle);
} }
} catch (RuntimeException ex) { } catch (RuntimeException | Error ex) {
throw ex;
} catch (Error ex) {
throw ex; throw ex;
} catch (Exception ex) { } catch (Exception ex) {
throw new CodeGenerationException(ex); throw new CodeGenerationException(ex);
@@ -201,12 +199,7 @@ public class EmitUtils {
final ObjectSwitchCallback callback) throws Exception { final ObjectSwitchCallback callback) throws Exception {
final Label def = e.make_label(); final Label def = e.make_label();
final Label end = e.make_label(); final Label end = e.make_label();
final Map buckets = CollectionUtils.bucket(Arrays.asList(strings), new Transformer() { final Map buckets = CollectionUtils.bucket(Arrays.asList(strings), value -> ((String)value).length());
@Override
public Object transform(Object value) {
return ((String)value).length();
}
});
e.dup(); e.dup();
e.invoke_virtual(Constants.TYPE_STRING, STRING_LENGTH); e.invoke_virtual(Constants.TYPE_STRING, STRING_LENGTH);
e.process_switch(getSwitchKeys(buckets), new ProcessSwitchCallback() { e.process_switch(getSwitchKeys(buckets), new ProcessSwitchCallback() {
@@ -233,12 +226,7 @@ public class EmitUtils {
final Label end, final Label end,
final int index) throws Exception { final int index) throws Exception {
final int len = ((String)strings.get(0)).length(); final int len = ((String)strings.get(0)).length();
final Map buckets = CollectionUtils.bucket(strings, new Transformer() { final Map buckets = CollectionUtils.bucket(strings, value -> ((String)value).charAt(index));
@Override
public Object transform(Object value) {
return ((String)value).charAt(index);
}
});
e.dup(); e.dup();
e.push(index); e.push(index);
e.invoke_virtual(Constants.TYPE_STRING, STRING_CHAR_AT); e.invoke_virtual(Constants.TYPE_STRING, STRING_CHAR_AT);
@@ -274,12 +262,7 @@ public class EmitUtils {
final String[] strings, final String[] strings,
final ObjectSwitchCallback callback, final ObjectSwitchCallback callback,
final boolean skipEquals) throws Exception { final boolean skipEquals) throws Exception {
final Map buckets = CollectionUtils.bucket(Arrays.asList(strings), new Transformer() { final Map buckets = CollectionUtils.bucket(Arrays.asList(strings), value -> value.hashCode());
@Override
public Object transform(Object value) {
return value.hashCode();
}
});
final Label def = e.make_label(); final Label def = e.make_label();
final Label end = e.make_label(); final Label end = e.make_label();
e.dup(); e.dup();
@@ -290,8 +273,9 @@ public class EmitUtils {
List bucket = (List)buckets.get(key); List bucket = (List)buckets.get(key);
Label next = null; Label next = null;
if (skipEquals && bucket.size() == 1) { if (skipEquals && bucket.size() == 1) {
if (skipEquals) if (skipEquals) {
e.pop(); e.pop();
}
callback.processCase(bucket.get(0), end); callback.processCase(bucket.get(0), end);
} else { } else {
for (Iterator it = bucket.iterator(); it.hasNext();) { for (Iterator it = bucket.iterator(); it.hasNext();) {
@@ -373,8 +357,9 @@ public class EmitUtils {
} }
private static Class remapComponentType(Class componentType) { private static Class remapComponentType(Class componentType) {
if (componentType.equals(Type.class)) if (componentType.equals(Type.class)) {
return Class.class; return Class.class;
}
return componentType; return componentType;
} }
@@ -437,12 +422,7 @@ public class EmitUtils {
Label end = e.make_label(); Label end = e.make_label();
e.dup(); e.dup();
e.ifnull(skip); e.ifnull(skip);
EmitUtils.process_array(e, type, new ProcessArrayCallback() { EmitUtils.process_array(e, type, type1 -> hash_code(e, type1, multiplier, registry));
@Override
public void processElement(Type type) {
hash_code(e, type, multiplier, registry);
}
});
e.goTo(end); e.goTo(end);
e.mark(skip); e.mark(skip);
e.pop(); e.pop();
@@ -752,26 +732,18 @@ public class EmitUtils {
boolean useName) { boolean useName) {
try { try {
final Map cache = new HashMap(); final Map cache = new HashMap();
final ParameterTyper cached = new ParameterTyper() { final ParameterTyper cached = member -> {
@Override Type[] types = (Type[]) cache.get(member);
public Type[] getParameterTypes(MethodInfo member) { if (types == null) {
Type[] types = (Type[])cache.get(member); cache.put(member, types = member.getSignature().getArgumentTypes());
if (types == null) { }
cache.put(member, types = member.getSignature().getArgumentTypes()); return types;
} };
return types;
}
};
final Label def = e.make_label(); final Label def = e.make_label();
final Label end = e.make_label(); final Label end = e.make_label();
if (useName) { if (useName) {
e.swap(); e.swap();
final Map buckets = CollectionUtils.bucket(members, new Transformer() { final Map buckets = CollectionUtils.bucket(members, value -> ((MethodInfo)value).getSignature().getName());
@Override
public Object transform(Object value) {
return ((MethodInfo)value).getSignature().getName();
}
});
String[] names = (String[])buckets.keySet().toArray(new String[buckets.size()]); String[] names = (String[])buckets.keySet().toArray(new String[buckets.size()]);
EmitUtils.string_switch(e, names, Constants.SWITCH_STYLE_HASH, new ObjectSwitchCallback() { EmitUtils.string_switch(e, names, Constants.SWITCH_STYLE_HASH, new ObjectSwitchCallback() {
@Override @Override
@@ -790,9 +762,7 @@ public class EmitUtils {
e.pop(); e.pop();
callback.processDefault(); callback.processDefault();
e.mark(end); e.mark(end);
} catch (RuntimeException ex) { } catch (RuntimeException | Error ex) {
throw ex;
} catch (Error ex) {
throw ex; throw ex;
} catch (Exception ex) { } catch (Exception ex) {
throw new CodeGenerationException(ex); throw new CodeGenerationException(ex);
@@ -805,12 +775,7 @@ public class EmitUtils {
final ParameterTyper typer, final ParameterTyper typer,
final Label def, final Label def,
final Label end) throws Exception { final Label end) throws Exception {
final Map buckets = CollectionUtils.bucket(members, new Transformer() { final Map buckets = CollectionUtils.bucket(members, value -> typer.getParameterTypes((MethodInfo)value).length);
@Override
public Object transform(Object value) {
return typer.getParameterTypes((MethodInfo)value).length;
}
});
e.dup(); e.dup();
e.arraylength(); e.arraylength();
e.process_switch(EmitUtils.getSwitchKeys(buckets), new ProcessSwitchCallback() { e.process_switch(EmitUtils.getSwitchKeys(buckets), new ProcessSwitchCallback() {
@@ -856,12 +821,8 @@ public class EmitUtils {
int index = -1; int index = -1;
for (int i = 0; i < example.length; i++) { for (int i = 0; i < example.length; i++) {
final int j = i; final int j = i;
Map test = CollectionUtils.bucket(members, new Transformer() { Map test = CollectionUtils.bucket(members,
@Override value -> TypeUtils.emulateClassGetName(typer.getParameterTypes((MethodInfo)value)[j]));
public Object transform(Object value) {
return TypeUtils.emulateClassGetName(typer.getParameterTypes((MethodInfo)value)[j]);
}
});
if (buckets == null || test.size() > buckets.size()) { if (buckets == null || test.size() > buckets.size()) {
buckets = test; buckets = test;
index = i; index = i;
@@ -951,8 +912,9 @@ public class EmitUtils {
public static void wrap_undeclared_throwable(CodeEmitter e, Block handler, Type[] exceptions, Type wrapper) { public static void wrap_undeclared_throwable(CodeEmitter e, Block handler, Type[] exceptions, Type wrapper) {
Set set = (exceptions == null) ? Collections.EMPTY_SET : new HashSet(Arrays.asList(exceptions)); Set set = (exceptions == null) ? Collections.EMPTY_SET : new HashSet(Arrays.asList(exceptions));
if (set.contains(Constants.TYPE_THROWABLE)) if (set.contains(Constants.TYPE_THROWABLE)) {
return; return;
}
boolean needThrow = exceptions != null; boolean needThrow = exceptions != null;
if (!set.contains(Constants.TYPE_RUNTIME_EXCEPTION)) { if (!set.contains(Constants.TYPE_RUNTIME_EXCEPTION)) {
@@ -964,8 +926,8 @@ public class EmitUtils {
needThrow = true; needThrow = true;
} }
if (exceptions != null) { if (exceptions != null) {
for (int i = 0; i < exceptions.length; i++) { for (Type exception : exceptions) {
e.catch_exception(handler, exceptions[i]); e.catch_exception(handler, exception);
} }
} }
if (needThrow) { if (needThrow) {

View File

@@ -40,5 +40,6 @@ public interface GeneratorStrategy {
* correctly implement <code>equals</code> and <code>hashCode</code> * correctly implement <code>equals</code> and <code>hashCode</code>
* to avoid generating too many classes. * to avoid generating too many classes.
*/ */
boolean equals(Object o); @Override
boolean equals(Object o);
} }

View File

@@ -98,20 +98,20 @@ abstract public class KeyFactory {
938313161, 1288102441, 1768288259}; 938313161, 1288102441, 1768288259};
public static final Customizer CLASS_BY_NAME = new Customizer() { public static final Customizer CLASS_BY_NAME = (e, type) -> {
public void customize(CodeEmitter e, Type type) { if (type.equals(Constants.TYPE_CLASS)) {
if (type.equals(Constants.TYPE_CLASS)) { e.invoke_virtual(Constants.TYPE_CLASS, GET_NAME);
e.invoke_virtual(Constants.TYPE_CLASS, GET_NAME);
}
} }
}; };
public static final FieldTypeCustomizer STORE_CLASS_AS_STRING = new FieldTypeCustomizer() { public static final FieldTypeCustomizer STORE_CLASS_AS_STRING = new FieldTypeCustomizer() {
@Override
public void customize(CodeEmitter e, int index, Type type) { public void customize(CodeEmitter e, int index, Type type) {
if (type.equals(Constants.TYPE_CLASS)) { if (type.equals(Constants.TYPE_CLASS)) {
e.invoke_virtual(Constants.TYPE_CLASS, GET_NAME); e.invoke_virtual(Constants.TYPE_CLASS, GET_NAME);
} }
} }
@Override
public Type getOutType(int index, Type type) { public Type getOutType(int index, Type type) {
if (type.equals(Constants.TYPE_CLASS)) { if (type.equals(Constants.TYPE_CLASS)) {
return Constants.TYPE_STRING; return Constants.TYPE_STRING;
@@ -124,14 +124,12 @@ abstract public class KeyFactory {
* {@link Type#hashCode()} is very expensive as it traverses full descriptor to calculate hash code. * {@link Type#hashCode()} is very expensive as it traverses full descriptor to calculate hash code.
* This customizer uses {@link Type#getSort()} as a hash code. * This customizer uses {@link Type#getSort()} as a hash code.
*/ */
public static final HashCodeCustomizer HASH_ASM_TYPE = new HashCodeCustomizer() { public static final HashCodeCustomizer HASH_ASM_TYPE = (e, type) -> {
public boolean customize(CodeEmitter e, Type type) { if (Constants.TYPE_TYPE.equals(type)) {
if (Constants.TYPE_TYPE.equals(type)) { e.invoke_virtual(type, GET_SORT);
e.invoke_virtual(type, GET_SORT); return true;
return true;
}
return false;
} }
return false;
}; };
/** /**
@@ -139,11 +137,7 @@ abstract public class KeyFactory {
* It is recommended to have pre-processing method that would strip Objects and represent Classes as Strings * It is recommended to have pre-processing method that would strip Objects and represent Classes as Strings
*/ */
@Deprecated @Deprecated
public static final Customizer OBJECT_BY_CLASS = new Customizer() { public static final Customizer OBJECT_BY_CLASS = (e, type) -> e.invoke_virtual(Constants.TYPE_OBJECT, GET_CLASS);
public void customize(CodeEmitter e, Type type) {
e.invoke_virtual(Constants.TYPE_OBJECT, GET_CLASS);
}
};
protected KeyFactory() { protected KeyFactory() {
} }
@@ -204,10 +198,12 @@ abstract public class KeyFactory {
super(SOURCE); super(SOURCE);
} }
@Override
protected ClassLoader getDefaultClassLoader() { protected ClassLoader getDefaultClassLoader() {
return keyInterface.getClassLoader(); return keyInterface.getClassLoader();
} }
@Override
protected ProtectionDomain getProtectionDomain() { protected ProtectionDomain getProtectionDomain() {
return ReflectUtils.getProtectionDomain(keyInterface); return ReflectUtils.getProtectionDomain(keyInterface);
} }
@@ -245,14 +241,17 @@ abstract public class KeyFactory {
this.multiplier = multiplier; this.multiplier = multiplier;
} }
@Override
protected Object firstInstance(Class type) { protected Object firstInstance(Class type) {
return ReflectUtils.newInstance(type); return ReflectUtils.newInstance(type);
} }
@Override
protected Object nextInstance(Object instance) { protected Object nextInstance(Object instance) {
return instance; return instance;
} }
@Override
public void generateClass(ClassVisitor v) { public void generateClass(ClassVisitor v) {
ClassEmitter ce = new ClassEmitter(v); ClassEmitter ce = new ClassEmitter(v);

View File

@@ -21,12 +21,12 @@ public class Local
{ {
private Type type; private Type type;
private int index; private int index;
public Local(int index, Type type) { public Local(int index, Type type) {
this.type = type; this.type = type;
this.index = index; this.index = index;
} }
public int getIndex() { public int getIndex() {
return index; return index;
} }

View File

@@ -38,7 +38,7 @@ import org.springframework.asm.Type;
* A {@link MethodVisitor} that renumbers local variables in their order of * A {@link MethodVisitor} that renumbers local variables in their order of
* appearance. This adapter allows one to easily add new local variables to a * appearance. This adapter allows one to easily add new local variables to a
* method. * method.
* *
* @author Chris Nokleberg * @author Chris Nokleberg
* @author Eric Bruneton * @author Eric Bruneton
*/ */
@@ -51,7 +51,7 @@ public class LocalVariablesSorter extends MethodVisitor {
*/ */
private static class State private static class State
{ {
int[] mapping = new int[40]; int[] mapping = new int[40];
int nextLocal; int nextLocal;
} }
@@ -67,8 +67,8 @@ public class LocalVariablesSorter extends MethodVisitor {
state = new State(); state = new State();
Type[] args = Type.getArgumentTypes(desc); Type[] args = Type.getArgumentTypes(desc);
state.nextLocal = ((Opcodes.ACC_STATIC & access) != 0) ? 0 : 1; state.nextLocal = ((Opcodes.ACC_STATIC & access) != 0) ? 0 : 1;
for (int i = 0; i < args.length; i++) { for (Type arg : args) {
state.nextLocal += args[i].getSize(); state.nextLocal += arg.getSize();
} }
firstLocal = state.nextLocal; firstLocal = state.nextLocal;
} }
@@ -79,30 +79,27 @@ public class LocalVariablesSorter extends MethodVisitor {
firstLocal = lvs.firstLocal; firstLocal = lvs.firstLocal;
} }
public void visitVarInsn(final int opcode, final int var) { @Override
int size; public void visitVarInsn(final int opcode, final int var) {
switch (opcode) { int size = switch (opcode) {
case Opcodes.LLOAD: case Opcodes.LLOAD, Opcodes.LSTORE, Opcodes.DLOAD, Opcodes.DSTORE -> 2;
case Opcodes.LSTORE: default -> 1;
case Opcodes.DLOAD: };
case Opcodes.DSTORE:
size = 2;
break;
default:
size = 1;
}
mv.visitVarInsn(opcode, remap(var, size)); mv.visitVarInsn(opcode, remap(var, size));
} }
public void visitIincInsn(final int var, final int increment) { @Override
public void visitIincInsn(final int var, final int increment) {
mv.visitIincInsn(remap(var, 1), increment); mv.visitIincInsn(remap(var, 1), increment);
} }
public void visitMaxs(final int maxStack, final int maxLocals) { @Override
public void visitMaxs(final int maxStack, final int maxLocals) {
mv.visitMaxs(maxStack, state.nextLocal); mv.visitMaxs(maxStack, state.nextLocal);
} }
public void visitLocalVariable( @Override
public void visitLocalVariable(
final String name, final String name,
final String desc, final String desc,
final String signature, final String signature,

View File

@@ -20,31 +20,34 @@ import org.springframework.asm.Type;
abstract public class MethodInfo { abstract public class MethodInfo {
protected MethodInfo() { protected MethodInfo() {
} }
abstract public ClassInfo getClassInfo(); abstract public ClassInfo getClassInfo();
abstract public int getModifiers(); abstract public int getModifiers();
abstract public Signature getSignature(); abstract public Signature getSignature();
abstract public Type[] getExceptionTypes(); abstract public Type[] getExceptionTypes();
@Override @Override
public boolean equals(Object o) { public boolean equals(Object o) {
if (o == null) if (o == null) {
return false; return false;
if (!(o instanceof MethodInfo)) }
return false; if (!(o instanceof MethodInfo other)) {
return getSignature().equals(((MethodInfo)o).getSignature()); return false;
} }
return getSignature().equals(other.getSignature());
}
@Override @Override
public int hashCode() { public int hashCode() {
return getSignature().hashCode(); return getSignature().hashCode();
} }
@Override
public String toString() {
// TODO: include modifiers, exceptions
return getSignature().toString();
}
@Override
public String toString() {
// TODO: include modifiers, exceptions
return getSignature().toString();
}
} }

View File

@@ -16,7 +16,12 @@
package org.springframework.cglib.core; package org.springframework.cglib.core;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.*; import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
@SuppressWarnings({"rawtypes", "unchecked"}) @SuppressWarnings({"rawtypes", "unchecked"})
public class MethodWrapper { public class MethodWrapper {

View File

@@ -13,9 +13,10 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package org.springframework.cglib.core; package org.springframework.cglib.core;
@FunctionalInterface
public interface Predicate { public interface Predicate {
boolean evaluate(Object arg); boolean evaluate(Object arg);
} }

View File

@@ -60,7 +60,7 @@ public class ReflectUtils {
private static final ProtectionDomain PROTECTION_DOMAIN; private static final ProtectionDomain PROTECTION_DOMAIN;
private static final List<Method> OBJECT_METHODS = new ArrayList<Method>(); private static final List<Method> OBJECT_METHODS = new ArrayList<>();
private static BiConsumer<String, byte[]> generatedClassHandler; private static BiConsumer<String, byte[]> generatedClassHandler;
@@ -125,11 +125,11 @@ public class ReflectUtils {
} }
public static Type[] getExceptionTypes(Member member) { public static Type[] getExceptionTypes(Member member) {
if (member instanceof Method) { if (member instanceof Method method) {
return TypeUtils.getTypes(((Method) member).getExceptionTypes()); return TypeUtils.getTypes(method.getExceptionTypes());
} }
else if (member instanceof Constructor) { else if (member instanceof Constructor<?> constructor) {
return TypeUtils.getTypes(((Constructor) member).getExceptionTypes()); return TypeUtils.getTypes(constructor.getExceptionTypes());
} }
else { else {
throw new IllegalArgumentException("Cannot get exception types of a field"); throw new IllegalArgumentException("Cannot get exception types of a field");
@@ -137,14 +137,13 @@ public class ReflectUtils {
} }
public static Signature getSignature(Member member) { public static Signature getSignature(Member member) {
if (member instanceof Method) { if (member instanceof Method method) {
return new Signature(member.getName(), Type.getMethodDescriptor((Method) member)); return new Signature(member.getName(), Type.getMethodDescriptor(method));
} }
else if (member instanceof Constructor) { else if (member instanceof Constructor<?> constructor) {
Type[] types = TypeUtils.getTypes(((Constructor) member).getParameterTypes()); Type[] types = TypeUtils.getTypes(constructor.getParameterTypes());
return new Signature(Constants.CONSTRUCTOR_NAME, return new Signature(Constants.CONSTRUCTOR_NAME,
Type.getMethodDescriptor(Type.VOID_TYPE, types)); Type.getMethodDescriptor(Type.VOID_TYPE, types));
} }
else { else {
throw new IllegalArgumentException("Cannot get signature of a field"); throw new IllegalArgumentException("Cannot get signature of a field");
@@ -230,9 +229,9 @@ public class ReflectUtils {
} }
catch (ClassNotFoundException ignore) { catch (ClassNotFoundException ignore) {
} }
for (int i = 0; i < packages.length; i++) { for (String pkg : packages) {
try { try {
return Class.forName(prefix + packages[i] + '.' + className + suffix, false, loader); return Class.forName(prefix + pkg + '.' + className + suffix, false, loader);
} }
catch (ClassNotFoundException ignore) { catch (ClassNotFoundException ignore) {
} }
@@ -274,10 +273,7 @@ public class ReflectUtils {
Object result = cstruct.newInstance(args); Object result = cstruct.newInstance(args);
return result; return result;
} }
catch (InstantiationException e) { catch (InstantiationException | IllegalAccessException e) {
throw new CodeGenerationException(e);
}
catch (IllegalAccessException e) {
throw new CodeGenerationException(e); throw new CodeGenerationException(e);
} }
catch (InvocationTargetException e) { catch (InvocationTargetException e) {
@@ -302,8 +298,9 @@ public class ReflectUtils {
} }
public static String[] getNames(Class[] classes) { public static String[] getNames(Class[] classes) {
if (classes == null) if (classes == null) {
return null; return null;
}
String[] names = new String[classes.length]; String[] names = new String[classes.length];
for (int i = 0; i < names.length; i++) { for (int i = 0; i < names.length; i++) {
names[i] = classes[i].getName(); names[i] = classes[i].getName();
@@ -329,8 +326,7 @@ public class ReflectUtils {
public static Method[] getPropertyMethods(PropertyDescriptor[] properties, boolean read, boolean write) { public static Method[] getPropertyMethods(PropertyDescriptor[] properties, boolean read, boolean write) {
Set methods = new HashSet(); Set methods = new HashSet();
for (int i = 0; i < properties.length; i++) { for (PropertyDescriptor pd : properties) {
PropertyDescriptor pd = properties[i];
if (read) { if (read) {
methods.add(pd.getReadMethod()); methods.add(pd.getReadMethod());
} }
@@ -362,8 +358,7 @@ public class ReflectUtils {
return all; return all;
} }
List properties = new ArrayList(all.length); List properties = new ArrayList(all.length);
for (int i = 0; i < all.length; i++) { for (PropertyDescriptor pd : all) {
PropertyDescriptor pd = all[i];
if ((read && pd.getReadMethod() != null) || if ((read && pd.getReadMethod() != null) ||
(write && pd.getWriteMethod() != null)) { (write && pd.getWriteMethod() != null)) {
properties.add(pd); properties.add(pd);
@@ -396,16 +391,17 @@ public class ReflectUtils {
if (type == Object.class) { if (type == Object.class) {
list.addAll(OBJECT_METHODS); list.addAll(OBJECT_METHODS);
} }
else else {
list.addAll(java.util.Arrays.asList(type.getDeclaredMethods())); list.addAll(java.util.Arrays.asList(type.getDeclaredMethods()));
}
Class superclass = type.getSuperclass(); Class superclass = type.getSuperclass();
if (superclass != null) { if (superclass != null) {
addAllMethods(superclass, list); addAllMethods(superclass, list);
} }
Class[] interfaces = type.getInterfaces(); Class[] interfaces = type.getInterfaces();
for (int i = 0; i < interfaces.length; i++) { for (Class element : interfaces) {
addAllMethods(interfaces[i], list); addAllMethods(element, list);
} }
return list; return list;
@@ -584,20 +580,25 @@ public class ReflectUtils {
return new MethodInfo() { return new MethodInfo() {
private ClassInfo ci; private ClassInfo ci;
@Override
public ClassInfo getClassInfo() { public ClassInfo getClassInfo() {
if (ci == null) if (ci == null) {
ci = ReflectUtils.getClassInfo(member.getDeclaringClass()); ci = ReflectUtils.getClassInfo(member.getDeclaringClass());
}
return ci; return ci;
} }
@Override
public int getModifiers() { public int getModifiers() {
return modifiers; return modifiers;
} }
@Override
public Signature getSignature() { public Signature getSignature() {
return sig; return sig;
} }
@Override
public Type[] getExceptionTypes() { public Type[] getExceptionTypes() {
return ReflectUtils.getExceptionTypes(member); return ReflectUtils.getExceptionTypes(member);
} }
@@ -612,15 +613,19 @@ public class ReflectUtils {
final Type type = Type.getType(clazz); final Type type = Type.getType(clazz);
final Type sc = (clazz.getSuperclass() == null) ? null : Type.getType(clazz.getSuperclass()); final Type sc = (clazz.getSuperclass() == null) ? null : Type.getType(clazz.getSuperclass());
return new ClassInfo() { return new ClassInfo() {
@Override
public Type getType() { public Type getType() {
return type; return type;
} }
@Override
public Type getSuperType() { public Type getSuperType() {
return sc; return sc;
} }
@Override
public Type[] getInterfaces() { public Type[] getInterfaces() {
return TypeUtils.getTypes(clazz.getInterfaces()); return TypeUtils.getTypes(clazz.getInterfaces());
} }
@Override
public int getModifiers() { public int getModifiers() {
return clazz.getModifiers(); return clazz.getModifiers();
} }
@@ -630,8 +635,7 @@ public class ReflectUtils {
// used by MethodInterceptorGenerated generated code // used by MethodInterceptorGenerated generated code
public static Method[] findMethods(String[] namesAndDescriptors, Method[] methods) { public static Method[] findMethods(String[] namesAndDescriptors, Method[] methods) {
Map map = new HashMap(); Map map = new HashMap();
for (int i = 0; i < methods.length; i++) { for (Method method : methods) {
Method method = methods[i];
map.put(method.getName() + Type.getMethodDescriptor(method), method); map.put(method.getName() + Type.getMethodDescriptor(method), method);
} }
Method[] result = new Method[namesAndDescriptors.length / 2]; Method[] result = new Method[namesAndDescriptors.length / 2];

View File

@@ -15,7 +15,7 @@
*/ */
package org.springframework.cglib.core; package org.springframework.cglib.core;
import java.lang.reflect.*; import java.lang.reflect.Member;
public class RejectModifierPredicate implements Predicate { public class RejectModifierPredicate implements Predicate {
private int rejectMask; private int rejectMask;
@@ -24,7 +24,8 @@ public class RejectModifierPredicate implements Predicate {
this.rejectMask = rejectMask; this.rejectMask = rejectMask;
} }
public boolean evaluate(Object arg) { @Override
public boolean evaluate(Object arg) {
return (((Member)arg).getModifiers() & rejectMask) == 0; return (((Member)arg).getModifiers() & rejectMask) == 0;
} }
} }

View File

@@ -54,20 +54,24 @@ public class Signature {
return Type.getArgumentTypes(desc); return Type.getArgumentTypes(desc);
} }
public String toString() { @Override
public String toString() {
return name + desc; return name + desc;
} }
public boolean equals(Object o) { @Override
if (o == null) public boolean equals(Object o) {
return false; if (o == null) {
if (!(o instanceof Signature)) return false;
return false; }
Signature other = (Signature)o; if (!(o instanceof Signature other)) {
return false;
}
return name.equals(other.name) && desc.equals(other.desc); return name.equals(other.name) && desc.equals(other.desc);
} }
public int hashCode() { @Override
public int hashCode() {
return name.hashCode() ^ desc.hashCode(); return name.hashCode() ^ desc.hashCode();
} }
} }

View File

@@ -36,6 +36,7 @@ public final class SpringNamingPolicy implements NamingPolicy {
private SpringNamingPolicy() { private SpringNamingPolicy() {
} }
@Override
public String getClassName(String prefix, String source, Object key, Predicate names) { public String getClassName(String prefix, String source, Object key, Predicate names) {
if (prefix == null) { if (prefix == null) {
prefix = "org.springframework.cglib.empty.Object"; prefix = "org.springframework.cglib.empty.Object";

View File

@@ -15,7 +15,13 @@
*/ */
package org.springframework.cglib.core; package org.springframework.cglib.core;
import java.util.*; import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.springframework.asm.Type; import org.springframework.asm.Type;
@SuppressWarnings({"rawtypes", "unchecked"}) @SuppressWarnings({"rawtypes", "unchecked"})
@@ -63,7 +69,7 @@ public class TypeUtils {
public static boolean isAbstract(int access) { public static boolean isAbstract(int access) {
return (Constants.ACC_ABSTRACT & access) != 0; return (Constants.ACC_ABSTRACT & access) != 0;
} }
public static boolean isInterface(int access) { public static boolean isInterface(int access) {
return (Constants.ACC_INTERFACE & access) != 0; return (Constants.ACC_INTERFACE & access) != 0;
} }
@@ -71,15 +77,15 @@ public class TypeUtils {
public static boolean isPrivate(int access) { public static boolean isPrivate(int access) {
return (Constants.ACC_PRIVATE & access) != 0; return (Constants.ACC_PRIVATE & access) != 0;
} }
public static boolean isSynthetic(int access) { public static boolean isSynthetic(int access) {
return (Constants.ACC_SYNTHETIC & access) != 0; return (Constants.ACC_SYNTHETIC & access) != 0;
} }
public static boolean isBridge(int access) { public static boolean isBridge(int access) {
return (Constants.ACC_BRIDGE & access) != 0; return (Constants.ACC_BRIDGE & access) != 0;
} }
// getPackage returns null on JDK 1.2 // getPackage returns null on JDK 1.2
public static String getPackageName(Type type) { public static String getPackageName(Type type) {
return getPackageName(getClassName(type)); return getPackageName(getClassName(type));
@@ -89,7 +95,7 @@ public class TypeUtils {
int idx = className.lastIndexOf('.'); int idx = className.lastIndexOf('.');
return (idx < 0) ? "" : className.substring(0, idx); return (idx < 0) ? "" : className.substring(0, idx);
} }
public static String upperFirst(String s) { public static String upperFirst(String s) {
if (s == null || s.length() == 0) { if (s == null || s.length() == 0) {
return s; return s;
@@ -148,8 +154,8 @@ public class TypeUtils {
public static int getStackSize(Type[] types) { public static int getStackSize(Type[] types) {
int size = 0; int size = 0;
for (int i = 0; i < types.length; i++) { for (Type type : types) {
size += types[i].getSize(); size += type.getSize();
} }
return size; return size;
} }
@@ -197,8 +203,8 @@ public class TypeUtils {
public static Signature parseConstructor(Type[] types) { public static Signature parseConstructor(Type[] types) {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
sb.append("("); sb.append("(");
for (int i = 0; i < types.length; i++) { for (Type type : types) {
sb.append(types[i].getDescriptor()); sb.append(type.getDescriptor());
} }
sb.append(")"); sb.append(")");
sb.append("V"); sb.append("V");

View File

@@ -15,7 +15,9 @@
*/ */
package org.springframework.cglib.core; package org.springframework.cglib.core;
import java.lang.reflect.*; import java.lang.reflect.Member;
import java.lang.reflect.Modifier;
import org.springframework.asm.Type; import org.springframework.asm.Type;
@SuppressWarnings({"rawtypes", "unchecked"}) @SuppressWarnings({"rawtypes", "unchecked"})
@@ -26,13 +28,14 @@ public class VisibilityPredicate implements Predicate {
public VisibilityPredicate(Class source, boolean protectedOk) { public VisibilityPredicate(Class source, boolean protectedOk) {
this.protectedOk = protectedOk; this.protectedOk = protectedOk;
// same package is not ok for the bootstrap loaded classes. In all other cases we are // same package is not ok for the bootstrap loaded classes. In all other cases we are
// generating classes in the same classloader // generating classes in the same classloader
this.samePackageOk = source.getClassLoader() != null; this.samePackageOk = source.getClassLoader() != null;
pkg = TypeUtils.getPackageName(Type.getType(source)); pkg = TypeUtils.getPackageName(Type.getType(source));
} }
public boolean evaluate(Object arg) { @Override
public boolean evaluate(Object arg) {
Member member = (Member)arg; Member member = (Member)arg;
int mod = member.getModifiers(); int mod = member.getModifiers();
if (Modifier.isPrivate(mod)) { if (Modifier.isPrivate(mod)) {
@@ -43,9 +46,9 @@ public class VisibilityPredicate implements Predicate {
// protected is fine if 'protectedOk' is true (for subclasses) // protected is fine if 'protectedOk' is true (for subclasses)
return true; return true;
} else { } else {
// protected/package private if the member is in the same package as the source class // protected/package private if the member is in the same package as the source class
// and we are generating into the same classloader. // and we are generating into the same classloader.
return samePackageOk return samePackageOk
&& pkg.equals(TypeUtils.getPackageName(Type.getType(member.getDeclaringClass()))); && pkg.equals(TypeUtils.getPackageName(Type.getType(member.getDeclaringClass())));
} }
} }

View File

@@ -12,7 +12,7 @@ import org.springframework.cglib.core.KeyFactoryCustomizer;
@SuppressWarnings({"rawtypes", "unchecked"}) @SuppressWarnings({"rawtypes", "unchecked"})
public class CustomizerRegistry { public class CustomizerRegistry {
private final Class[] customizerTypes; private final Class[] customizerTypes;
private Map<Class, List<KeyFactoryCustomizer>> customizers = new HashMap<Class, List<KeyFactoryCustomizer>>(); private Map<Class, List<KeyFactoryCustomizer>> customizers = new HashMap<>();
public CustomizerRegistry(Class[] customizerTypes) { public CustomizerRegistry(Class[] customizerTypes) {
this.customizerTypes = customizerTypes; this.customizerTypes = customizerTypes;
@@ -24,7 +24,7 @@ public class CustomizerRegistry {
if (type.isAssignableFrom(klass)) { if (type.isAssignableFrom(klass)) {
List<KeyFactoryCustomizer> list = customizers.get(type); List<KeyFactoryCustomizer> list = customizers.get(type);
if (list == null) { if (list == null) {
customizers.put(type, list = new ArrayList<KeyFactoryCustomizer>()); customizers.put(type, list = new ArrayList<>());
} }
list.add(customizer); list.add(customizer);
} }

View File

@@ -1,6 +1,9 @@
package org.springframework.cglib.core.internal; package org.springframework.cglib.core.internal;
import java.util.concurrent.*; import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
@SuppressWarnings({"rawtypes", "unchecked"}) @SuppressWarnings({"rawtypes", "unchecked"})
public class LoadingCache<K, KK, V> { public class LoadingCache<K, KK, V> {
@@ -8,16 +11,12 @@ public class LoadingCache<K, KK, V> {
protected final Function<K, V> loader; protected final Function<K, V> loader;
protected final Function<K, KK> keyMapper; protected final Function<K, KK> keyMapper;
public static final Function IDENTITY = new Function() { public static final Function IDENTITY = key -> key;
public Object apply(Object key) {
return key;
}
};
public LoadingCache(Function<K, KK> keyMapper, Function<K, V> loader) { public LoadingCache(Function<K, KK> keyMapper, Function<K, V> loader) {
this.keyMapper = keyMapper; this.keyMapper = keyMapper;
this.loader = loader; this.loader = loader;
this.map = new ConcurrentHashMap<KK, Object>(); this.map = new ConcurrentHashMap<>();
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@@ -50,11 +49,7 @@ public class LoadingCache<K, KK, V> {
// Another thread is already loading an instance // Another thread is already loading an instance
task = (FutureTask<V>) v; task = (FutureTask<V>) v;
} else { } else {
task = new FutureTask<V>(new Callable<V>() { task = new FutureTask<>(() -> loader.apply(key));
public V call() throws Exception {
return loader.apply(key);
}
});
Object prevTask = map.putIfAbsent(cacheKey, task); Object prevTask = map.putIfAbsent(cacheKey, task);
if (prevTask == null) { if (prevTask == null) {
// creator does the load // creator does the load

View File

@@ -22,12 +22,13 @@ import java.util.HashMap;
import java.util.Iterator; import java.util.Iterator;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import org.springframework.cglib.core.Constants;
import org.springframework.cglib.core.Signature;
import org.springframework.asm.ClassReader; import org.springframework.asm.ClassReader;
import org.springframework.asm.ClassVisitor; import org.springframework.asm.ClassVisitor;
import org.springframework.asm.MethodVisitor; import org.springframework.asm.MethodVisitor;
import org.springframework.asm.Opcodes; import org.springframework.asm.Opcodes;
import org.springframework.cglib.core.Constants;
import org.springframework.cglib.core.Signature;
/** /**
* Uses bytecode reflection to figure out the targets of all bridge methods that use invokespecial * Uses bytecode reflection to figure out the targets of all bridge methods that use invokespecial
@@ -80,7 +81,7 @@ class BridgeMethodResolver {
private static class BridgedFinder extends ClassVisitor { private static class BridgedFinder extends ClassVisitor {
private Map/*<Signature, Signature>*/ resolved; private Map/*<Signature, Signature>*/ resolved;
private Set/*<Signature>*/ eligibleMethods; private Set/*<Signature>*/ eligibleMethods;
private Signature currentMethod = null; private Signature currentMethod = null;
BridgedFinder(Set eligibleMethods, Map resolved) { BridgedFinder(Set eligibleMethods, Map resolved) {
@@ -89,17 +90,20 @@ class BridgeMethodResolver {
this.eligibleMethods = eligibleMethods; this.eligibleMethods = eligibleMethods;
} }
public void visit(int version, int access, String name, @Override
public void visit(int version, int access, String name,
String signature, String superName, String[] interfaces) { String signature, String superName, String[] interfaces) {
} }
public MethodVisitor visitMethod(int access, String name, String desc, @Override
public MethodVisitor visitMethod(int access, String name, String desc,
String signature, String[] exceptions) { String signature, String[] exceptions) {
Signature sig = new Signature(name, desc); Signature sig = new Signature(name, desc);
if (eligibleMethods.remove(sig)) { if (eligibleMethods.remove(sig)) {
currentMethod = sig; currentMethod = sig;
return new MethodVisitor(Constants.ASM_API) { return new MethodVisitor(Constants.ASM_API) {
public void visitMethodInsn( @Override
public void visitMethodInsn(
int opcode, String owner, String name, String desc, boolean itf) { int opcode, String owner, String name, String desc, boolean itf) {
if ((opcode == Opcodes.INVOKESPECIAL if ((opcode == Opcodes.INVOKESPECIAL
|| (itf && opcode == Opcodes.INVOKEINTERFACE)) || (itf && opcode == Opcodes.INVOKEINTERFACE))

View File

@@ -31,7 +31,7 @@ public interface CallbackFilter {
/** /**
* Map a method to a callback. * Map a method to a callback.
* @param method the intercepted method * @param method the intercepted method
* @return the index into the array of callbacks (as specified by {@link Enhancer#setCallbacks}) to use for the method, * @return the index into the array of callbacks (as specified by {@link Enhancer#setCallbacks}) to use for the method,
*/ */
int accept(Method method); int accept(Method method);
@@ -42,5 +42,6 @@ public interface CallbackFilter {
* <code>hashCode</code> for custom <code>CallbackFilter</code> * <code>hashCode</code> for custom <code>CallbackFilter</code>
* implementations in order to improve performance. * implementations in order to improve performance.
*/ */
boolean equals(Object o); @Override
boolean equals(Object o);
} }

View File

@@ -16,7 +16,11 @@
package org.springframework.cglib.proxy; package org.springframework.cglib.proxy;
import java.util.List; import java.util.List;
import org.springframework.cglib.core.*;
import org.springframework.cglib.core.ClassEmitter;
import org.springframework.cglib.core.CodeEmitter;
import org.springframework.cglib.core.MethodInfo;
import org.springframework.cglib.core.Signature;
@SuppressWarnings({"rawtypes", "unchecked"}) @SuppressWarnings({"rawtypes", "unchecked"})
interface CallbackGenerator interface CallbackGenerator

View File

@@ -15,9 +15,13 @@
*/ */
package org.springframework.cglib.proxy; package org.springframework.cglib.proxy;
import org.springframework.cglib.core.ReflectUtils;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.*; import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.springframework.cglib.core.ReflectUtils;
/** /**
* @version $Id: CallbackHelper.java,v 1.2 2004/06/24 21:15:20 herbyderby Exp $ * @version $Id: CallbackHelper.java,v 1.2 2004/06/24 21:15:20 herbyderby Exp $
@@ -28,22 +32,24 @@ implements CallbackFilter
{ {
private Map methodMap = new HashMap(); private Map methodMap = new HashMap();
private List callbacks = new ArrayList(); private List callbacks = new ArrayList();
public CallbackHelper(Class superclass, Class[] interfaces) public CallbackHelper(Class superclass, Class[] interfaces) {
{
List methods = new ArrayList(); List methods = new ArrayList();
Enhancer.getMethods(superclass, interfaces, methods); Enhancer.getMethods(superclass, interfaces, methods);
Map indexes = new HashMap(); Map indexes = new HashMap();
for (int i = 0, size = methods.size(); i < size; i++) { for (int i = 0, size = methods.size(); i < size; i++) {
Method method = (Method)methods.get(i); Method method = (Method)methods.get(i);
Object callback = getCallback(method); Object callback = getCallback(method);
if (callback == null) if (callback == null) {
throw new IllegalStateException("getCallback cannot return null"); throw new IllegalStateException("getCallback cannot return null");
}
boolean isCallback = callback instanceof Callback; boolean isCallback = callback instanceof Callback;
if (!(isCallback || (callback instanceof Class))) if (!(isCallback || (callback instanceof Class))) {
throw new IllegalStateException("getCallback must return a Callback or a Class"); throw new IllegalStateException("getCallback must return a Callback or a Class");
if (i > 0 && ((callbacks.get(i - 1) instanceof Callback) ^ isCallback)) }
if (i > 0 && ((callbacks.get(i - 1) instanceof Callback) ^ isCallback)) {
throw new IllegalStateException("getCallback must return a Callback or a Class consistently for every Method"); throw new IllegalStateException("getCallback must return a Callback or a Class consistently for every Method");
}
Integer index = (Integer)indexes.get(callback); Integer index = (Integer)indexes.get(callback);
if (index == null) { if (index == null) {
index = callbacks.size(); index = callbacks.size();
@@ -56,44 +62,49 @@ implements CallbackFilter
abstract protected Object getCallback(Method method); abstract protected Object getCallback(Method method);
public Callback[] getCallbacks() public Callback[] getCallbacks() {
{ if (callbacks.size() == 0) {
if (callbacks.size() == 0)
return new Callback[0]; return new Callback[0];
}
if (callbacks.get(0) instanceof Callback) { if (callbacks.get(0) instanceof Callback) {
return (Callback[])callbacks.toArray(new Callback[callbacks.size()]); return (Callback[])callbacks.toArray(new Callback[callbacks.size()]);
} else { }
else {
throw new IllegalStateException("getCallback returned classes, not callbacks; call getCallbackTypes instead"); throw new IllegalStateException("getCallback returned classes, not callbacks; call getCallbackTypes instead");
} }
} }
public Class[] getCallbackTypes() public Class[] getCallbackTypes() {
{ if (callbacks.size() == 0) {
if (callbacks.size() == 0)
return new Class[0]; return new Class[0];
}
if (callbacks.get(0) instanceof Callback) { if (callbacks.get(0) instanceof Callback) {
return ReflectUtils.getClasses(getCallbacks()); return ReflectUtils.getClasses(getCallbacks());
} else { }
else {
return (Class[])callbacks.toArray(new Class[callbacks.size()]); return (Class[])callbacks.toArray(new Class[callbacks.size()]);
} }
} }
public int accept(Method method) @Override
{ public int accept(Method method) {
return ((Integer)methodMap.get(method)).intValue(); return ((Integer)methodMap.get(method)).intValue();
} }
public int hashCode() @Override
{ public int hashCode() {
return methodMap.hashCode(); return methodMap.hashCode();
} }
public boolean equals(Object o) @Override
{ public boolean equals(Object o) {
if (o == null) if (o == null) {
return false; return false;
if (!(o instanceof CallbackHelper)) }
if (!(o instanceof CallbackHelper other)) {
return false; return false;
return methodMap.equals(((CallbackHelper)o).methodMap); }
return this.methodMap.equals(other.methodMap);
} }
} }

View File

@@ -57,7 +57,7 @@ class CallbackInfo
private Class cls; private Class cls;
private CallbackGenerator generator; private CallbackGenerator generator;
private Type type; private Type type;
private static final CallbackInfo[] CALLBACKS = { private static final CallbackInfo[] CALLBACKS = {
new CallbackInfo(NoOp.class, NoOpGenerator.INSTANCE), new CallbackInfo(NoOp.class, NoOpGenerator.INSTANCE),
new CallbackInfo(MethodInterceptor.class, MethodInterceptorGenerator.INSTANCE), new CallbackInfo(MethodInterceptor.class, MethodInterceptorGenerator.INSTANCE),
@@ -84,8 +84,7 @@ class CallbackInfo
private static Type determineType(Class callbackType, boolean checkAll) { private static Type determineType(Class callbackType, boolean checkAll) {
Class cur = null; Class cur = null;
Type type = null; Type type = null;
for (int i = 0; i < CALLBACKS.length; i++) { for (CallbackInfo info : CALLBACKS) {
CallbackInfo info = CALLBACKS[i];
if (info.cls.isAssignableFrom(callbackType)) { if (info.cls.isAssignableFrom(callbackType)) {
if (cur != null) { if (cur != null) {
throw new IllegalStateException("Callback implements both " + cur + " and " + info.cls); throw new IllegalStateException("Callback implements both " + cur + " and " + info.cls);
@@ -104,8 +103,7 @@ class CallbackInfo
} }
private static CallbackGenerator getGenerator(Type callbackType) { private static CallbackGenerator getGenerator(Type callbackType) {
for (int i = 0; i < CALLBACKS.length; i++) { for (CallbackInfo info : CALLBACKS) {
CallbackInfo info = CALLBACKS[i];
if (info.type.equals(callbackType)) { if (info.type.equals(callbackType)) {
return info.generator; return info.generator;
} }
@@ -113,5 +111,5 @@ class CallbackInfo
throw new IllegalStateException("Unknown callback type " + callbackType); throw new IllegalStateException("Unknown callback type " + callbackType);
} }
} }

View File

@@ -15,9 +15,15 @@
*/ */
package org.springframework.cglib.proxy; package org.springframework.cglib.proxy;
import java.util.*; import java.util.Iterator;
import org.springframework.cglib.core.*; import java.util.List;
import org.springframework.asm.Type; import org.springframework.asm.Type;
import org.springframework.cglib.core.ClassEmitter;
import org.springframework.cglib.core.CodeEmitter;
import org.springframework.cglib.core.MethodInfo;
import org.springframework.cglib.core.Signature;
import org.springframework.cglib.core.TypeUtils;
@SuppressWarnings({"rawtypes", "unchecked"}) @SuppressWarnings({"rawtypes", "unchecked"})
class DispatcherGenerator implements CallbackGenerator { class DispatcherGenerator implements CallbackGenerator {
@@ -41,7 +47,8 @@ class DispatcherGenerator implements CallbackGenerator {
this.proxyRef = proxyRef; this.proxyRef = proxyRef;
} }
public void generate(ClassEmitter ce, Context context, List methods) { @Override
public void generate(ClassEmitter ce, Context context, List methods) {
for (Iterator it = methods.iterator(); it.hasNext();) { for (Iterator it = methods.iterator(); it.hasNext();) {
MethodInfo method = (MethodInfo)it.next(); MethodInfo method = (MethodInfo)it.next();
if (!TypeUtils.isProtected(method.getModifiers())) { if (!TypeUtils.isProtected(method.getModifiers())) {
@@ -62,5 +69,6 @@ class DispatcherGenerator implements CallbackGenerator {
} }
} }
public void generateStatic(CodeEmitter e, Context context, List methods) { } @Override
public void generateStatic(CodeEmitter e, Context context, List methods) { }
} }

View File

@@ -51,7 +51,6 @@ import org.springframework.cglib.core.ProcessSwitchCallback;
import org.springframework.cglib.core.ReflectUtils; import org.springframework.cglib.core.ReflectUtils;
import org.springframework.cglib.core.RejectModifierPredicate; import org.springframework.cglib.core.RejectModifierPredicate;
import org.springframework.cglib.core.Signature; import org.springframework.cglib.core.Signature;
import org.springframework.cglib.core.Transformer;
import org.springframework.cglib.core.TypeUtils; import org.springframework.cglib.core.TypeUtils;
import org.springframework.cglib.core.VisibilityPredicate; import org.springframework.cglib.core.VisibilityPredicate;
import org.springframework.cglib.core.WeakCacheKey; import org.springframework.cglib.core.WeakCacheKey;
@@ -91,11 +90,7 @@ import org.springframework.cglib.core.WeakCacheKey;
@SuppressWarnings({"rawtypes", "unchecked"}) @SuppressWarnings({"rawtypes", "unchecked"})
public class Enhancer extends AbstractClassGenerator { public class Enhancer extends AbstractClassGenerator {
private static final CallbackFilter ALL_ZERO = new CallbackFilter() { private static final CallbackFilter ALL_ZERO = method -> 0;
public int accept(Method method) {
return 0;
}
};
private static final Source SOURCE = new Source(Enhancer.class.getName()); private static final Source SOURCE = new Source(Enhancer.class.getName());
@@ -463,12 +458,12 @@ public class Enhancer extends AbstractClassGenerator {
callbackTypes = CallbackInfo.determineTypes(callbacks); callbackTypes = CallbackInfo.determineTypes(callbacks);
} }
if (interfaces != null) { if (interfaces != null) {
for (int i = 0; i < interfaces.length; i++) { for (Class element : interfaces) {
if (interfaces[i] == null) { if (element == null) {
throw new IllegalStateException("Interfaces cannot be null"); throw new IllegalStateException("Interfaces cannot be null");
} }
if (!interfaces[i].isInterface()) { if (!element.isInterface()) {
throw new IllegalStateException(interfaces[i] + " is not an interface"); throw new IllegalStateException(element + " is not an interface");
} }
} }
} }
@@ -557,7 +552,7 @@ public class Enhancer extends AbstractClassGenerator {
// SPRING PATCH BEGIN // SPRING PATCH BEGIN
Object key = new EnhancerKey((superclass != null ? superclass.getName() : null), Object key = new EnhancerKey((superclass != null ? superclass.getName() : null),
(interfaces != null ? Arrays.asList(ReflectUtils.getNames(interfaces)) : null), (interfaces != null ? Arrays.asList(ReflectUtils.getNames(interfaces)) : null),
(filter == ALL_ZERO ? null : new WeakCacheKey<CallbackFilter>(filter)), (filter == ALL_ZERO ? null : new WeakCacheKey<>(filter)),
Arrays.asList(callbackTypes), Arrays.asList(callbackTypes),
useFactory, useFactory,
interceptDuringConstruction, interceptDuringConstruction,
@@ -580,6 +575,7 @@ public class Enhancer extends AbstractClassGenerator {
return super.generate(data); return super.generate(data);
} }
@Override
protected ClassLoader getDefaultClassLoader() { protected ClassLoader getDefaultClassLoader() {
if (superclass != null) { if (superclass != null) {
return superclass.getClassLoader(); return superclass.getClassLoader();
@@ -592,6 +588,7 @@ public class Enhancer extends AbstractClassGenerator {
} }
} }
@Override
protected ProtectionDomain getProtectionDomain() { protected ProtectionDomain getProtectionDomain() {
if (superclass != null) { if (superclass != null) {
return ReflectUtils.getProtectionDomain(superclass); return ReflectUtils.getProtectionDomain(superclass);
@@ -630,9 +627,9 @@ public class Enhancer extends AbstractClassGenerator {
ReflectUtils.addAllMethods(superclass, methods); ReflectUtils.addAllMethods(superclass, methods);
List target = (interfaceMethods != null) ? interfaceMethods : methods; List target = (interfaceMethods != null) ? interfaceMethods : methods;
if (interfaces != null) { if (interfaces != null) {
for (int i = 0; i < interfaces.length; i++) { for (Class element : interfaces) {
if (interfaces[i] != Factory.class) { if (element != Factory.class) {
ReflectUtils.addAllMethods(interfaces[i], target); ReflectUtils.addAllMethods(element, target);
} }
} }
} }
@@ -648,11 +645,13 @@ public class Enhancer extends AbstractClassGenerator {
CollectionUtils.filter(methods, new RejectModifierPredicate(Constants.ACC_FINAL)); CollectionUtils.filter(methods, new RejectModifierPredicate(Constants.ACC_FINAL));
} }
@Override
public void generateClass(ClassVisitor v) throws Exception { public void generateClass(ClassVisitor v) throws Exception {
Class sc = (superclass == null) ? Object.class : superclass; Class sc = (superclass == null) ? Object.class : superclass;
if (TypeUtils.isFinal(sc.getModifiers())) if (TypeUtils.isFinal(sc.getModifiers())) {
throw new IllegalArgumentException("Cannot subclass final class " + sc.getName()); throw new IllegalArgumentException("Cannot subclass final class " + sc.getName());
}
List constructors = new ArrayList(Arrays.asList(sc.getDeclaredConstructors())); List constructors = new ArrayList(Arrays.asList(sc.getDeclaredConstructors()));
filterConstructors(sc, constructors); filterConstructors(sc, constructors);
@@ -664,19 +663,17 @@ public class Enhancer extends AbstractClassGenerator {
final Set forcePublic = new HashSet(); final Set forcePublic = new HashSet();
getMethods(sc, interfaces, actualMethods, interfaceMethods, forcePublic); getMethods(sc, interfaces, actualMethods, interfaceMethods, forcePublic);
List methods = CollectionUtils.transform(actualMethods, new Transformer() { List methods = CollectionUtils.transform(actualMethods, value -> {
public Object transform(Object value) { Method method = (Method) value;
Method method = (Method) value; int modifiers = Constants.ACC_FINAL
int modifiers = Constants.ACC_FINAL | (method.getModifiers()
| (method.getModifiers() & ~Constants.ACC_ABSTRACT
& ~Constants.ACC_ABSTRACT & ~Constants.ACC_NATIVE
& ~Constants.ACC_NATIVE & ~Constants.ACC_SYNCHRONIZED);
& ~Constants.ACC_SYNCHRONIZED); if (forcePublic.contains(MethodWrapper.create(method))) {
if (forcePublic.contains(MethodWrapper.create(method))) { modifiers = (modifiers & ~Constants.ACC_PROTECTED) | Constants.ACC_PUBLIC;
modifiers = (modifiers & ~Constants.ACC_PROTECTED) | Constants.ACC_PUBLIC;
}
return ReflectUtils.getMethodInfo(method, modifiers);
} }
return ReflectUtils.getMethodInfo(method, modifiers);
}); });
ClassEmitter e = new ClassEmitter(v); ClassEmitter e = new ClassEmitter(v);
@@ -754,8 +751,9 @@ public class Enhancer extends AbstractClassGenerator {
*/ */
protected void filterConstructors(Class sc, List constructors) { protected void filterConstructors(Class sc, List constructors) {
CollectionUtils.filter(constructors, new VisibilityPredicate(sc, true)); CollectionUtils.filter(constructors, new VisibilityPredicate(sc, true));
if (constructors.size() == 0) if (constructors.size() == 0) {
throw new IllegalArgumentException("No visible constructors in " + sc); throw new IllegalArgumentException("No visible constructors in " + sc);
}
} }
/** /**
@@ -767,6 +765,7 @@ public class Enhancer extends AbstractClassGenerator {
* @return newly created proxy instance * @return newly created proxy instance
* @throws Exception if something goes wrong * @throws Exception if something goes wrong
*/ */
@Override
protected Object firstInstance(Class type) throws Exception { protected Object firstInstance(Class type) throws Exception {
if (classOnly) { if (classOnly) {
return type; return type;
@@ -776,6 +775,7 @@ public class Enhancer extends AbstractClassGenerator {
} }
} }
@Override
protected Object nextInstance(Object instance) { protected Object nextInstance(Object instance) {
EnhancerFactoryData data = (EnhancerFactoryData) instance; EnhancerFactoryData data = (EnhancerFactoryData) instance;
@@ -809,13 +809,10 @@ public class Enhancer extends AbstractClassGenerator {
callbackFilterField.setAccessible(true); callbackFilterField.setAccessible(true);
callbackFilterField.set(null, this.filter); callbackFilterField.set(null, this.filter);
} }
catch (NoSuchFieldException e) { catch (NoSuchFieldException | IllegalAccessException e) {
throw new CodeGenerationException(e); throw new CodeGenerationException(e);
} }
catch (IllegalAccessException e) { return new WeakReference<>(factoryData);
throw new CodeGenerationException(e);
}
return new WeakReference<EnhancerFactoryData>(factoryData);
} }
@Override @Override
@@ -895,10 +892,7 @@ public class Enhancer extends AbstractClassGenerator {
catch (NoSuchMethodException e) { catch (NoSuchMethodException e) {
throw new IllegalArgumentException(type + " is not an enhanced class"); throw new IllegalArgumentException(type + " is not an enhanced class");
} }
catch (IllegalAccessException e) { catch (IllegalAccessException | InvocationTargetException e) {
throw new CodeGenerationException(e);
}
catch (InvocationTargetException e) {
throw new CodeGenerationException(e); throw new CodeGenerationException(e);
} }
} }
@@ -1027,8 +1021,9 @@ public class Enhancer extends AbstractClassGenerator {
e.return_value(); e.return_value();
e.end_method(); e.end_method();
} }
if (!classOnly && !seenNull && arguments == null) if (!classOnly && !seenNull && arguments == null) {
throw new IllegalArgumentException("Superclass has no null constructors but no arguments were given"); throw new IllegalArgumentException("Superclass has no null constructors but no arguments were given");
}
} }
private int[] getCallbackKeys() { private int[] getCallbackKeys() {
@@ -1046,11 +1041,13 @@ public class Enhancer extends AbstractClassGenerator {
e.load_this(); e.load_this();
e.load_arg(0); e.load_arg(0);
e.process_switch(keys, new ProcessSwitchCallback() { e.process_switch(keys, new ProcessSwitchCallback() {
@Override
public void processCase(int key, Label end) { public void processCase(int key, Label end) {
e.getfield(getCallbackField(key)); e.getfield(getCallbackField(key));
e.goTo(end); e.goTo(end);
} }
@Override
public void processDefault() { public void processDefault() {
e.pop(); // stack height e.pop(); // stack height
e.aconst_null(); e.aconst_null();
@@ -1064,6 +1061,7 @@ public class Enhancer extends AbstractClassGenerator {
final CodeEmitter e = ce.begin_method(Constants.ACC_PUBLIC, SET_CALLBACK, null); final CodeEmitter e = ce.begin_method(Constants.ACC_PUBLIC, SET_CALLBACK, null);
e.load_arg(0); e.load_arg(0);
e.process_switch(keys, new ProcessSwitchCallback() { e.process_switch(keys, new ProcessSwitchCallback() {
@Override
public void processCase(int key, Label end) { public void processCase(int key, Label end) {
e.load_this(); e.load_this();
e.load_arg(1); e.load_arg(1);
@@ -1072,6 +1070,7 @@ public class Enhancer extends AbstractClassGenerator {
e.goTo(end); e.goTo(end);
} }
@Override
public void processDefault() { public void processDefault() {
// TODO: error? // TODO: error?
} }
@@ -1171,6 +1170,7 @@ public class Enhancer extends AbstractClassGenerator {
e.dup(); e.dup();
e.load_arg(0); e.load_arg(0);
EmitUtils.constructor_switch(e, constructors, new ObjectSwitchCallback() { EmitUtils.constructor_switch(e, constructors, new ObjectSwitchCallback() {
@Override
public void processCase(Object key, Label end) { public void processCase(Object key, Label end) {
MethodInfo constructor = (MethodInfo) key; MethodInfo constructor = (MethodInfo) key;
Type types[] = constructor.getSignature().getArgumentTypes(); Type types[] = constructor.getSignature().getArgumentTypes();
@@ -1184,6 +1184,7 @@ public class Enhancer extends AbstractClassGenerator {
e.goTo(end); e.goTo(end);
} }
@Override
public void processDefault() { public void processDefault() {
e.throw_exception(ILLEGAL_ARGUMENT_EXCEPTION, "Constructor not found"); e.throw_exception(ILLEGAL_ARGUMENT_EXCEPTION, "Constructor not found");
} }
@@ -1243,26 +1244,32 @@ public class Enhancer extends AbstractClassGenerator {
se.putfield(THREAD_CALLBACKS_FIELD); se.putfield(THREAD_CALLBACKS_FIELD);
CallbackGenerator.Context context = new CallbackGenerator.Context() { CallbackGenerator.Context context = new CallbackGenerator.Context() {
@Override
public ClassLoader getClassLoader() { public ClassLoader getClassLoader() {
return Enhancer.this.getClassLoader(); return Enhancer.this.getClassLoader();
} }
@Override
public int getOriginalModifiers(MethodInfo method) { public int getOriginalModifiers(MethodInfo method) {
return ((Integer) originalModifiers.get(method)).intValue(); return ((Integer) originalModifiers.get(method)).intValue();
} }
@Override
public int getIndex(MethodInfo method) { public int getIndex(MethodInfo method) {
return ((Integer) indexes.get(method)).intValue(); return ((Integer) indexes.get(method)).intValue();
} }
@Override
public void emitCallback(CodeEmitter e, int index) { public void emitCallback(CodeEmitter e, int index) {
emitCurrentCallback(e, index); emitCurrentCallback(e, index);
} }
@Override
public Signature getImplSignature(MethodInfo method) { public Signature getImplSignature(MethodInfo method) {
return rename(method.getSignature(), ((Integer) positions.get(method)).intValue()); return rename(method.getSignature(), ((Integer) positions.get(method)).intValue());
} }
@Override
public void emitLoadArgsAndInvoke(CodeEmitter e, MethodInfo method) { public void emitLoadArgsAndInvoke(CodeEmitter e, MethodInfo method) {
// If this is a bridge and we know the target was called from invokespecial, // If this is a bridge and we know the target was called from invokespecial,
// then we need to invoke_virtual w/ the bridge target instead of doing // then we need to invoke_virtual w/ the bridge target instead of doing
@@ -1302,6 +1309,7 @@ public class Enhancer extends AbstractClassGenerator {
} }
} }
@Override
public CodeEmitter beginMethod(ClassEmitter ce, MethodInfo method) { public CodeEmitter beginMethod(ClassEmitter ce, MethodInfo method) {
CodeEmitter e = EmitUtils.begin_method(ce, method); CodeEmitter e = EmitUtils.begin_method(ce, method);
if (!interceptDuringConstruction && if (!interceptDuringConstruction &&

View File

@@ -32,14 +32,14 @@ public interface Factory {
* If multiple callbacks are required an exception will be thrown. * If multiple callbacks are required an exception will be thrown.
* @param callback the new interceptor to use * @param callback the new interceptor to use
* @return new instance of the same type * @return new instance of the same type
*/ */
Object newInstance(Callback callback); Object newInstance(Callback callback);
/** /**
* Creates new instance of the same type, using the no-arg constructor. * Creates new instance of the same type, using the no-arg constructor.
* @param callbacks the new callbacks(s) to use * @param callbacks the new callbacks(s) to use
* @return new instance of the same type * @return new instance of the same type
*/ */
Object newInstance(Callback[] callbacks); Object newInstance(Callback[] callbacks);
/** /**
@@ -75,6 +75,6 @@ public interface Factory {
/** /**
* Get the current set of callbacks for ths object. * Get the current set of callbacks for ths object.
* @return a new array instance * @return a new array instance
*/ */
Callback[] getCallbacks(); Callback[] getCallbacks();
} }

View File

@@ -15,9 +15,15 @@
*/ */
package org.springframework.cglib.proxy; package org.springframework.cglib.proxy;
import java.util.*; import java.util.Iterator;
import org.springframework.cglib.core.*; import java.util.List;
import org.springframework.asm.Type; import org.springframework.asm.Type;
import org.springframework.cglib.core.ClassEmitter;
import org.springframework.cglib.core.CodeEmitter;
import org.springframework.cglib.core.MethodInfo;
import org.springframework.cglib.core.Signature;
import org.springframework.cglib.core.TypeUtils;
@SuppressWarnings({"rawtypes", "unchecked"}) @SuppressWarnings({"rawtypes", "unchecked"})
class FixedValueGenerator implements CallbackGenerator { class FixedValueGenerator implements CallbackGenerator {
@@ -27,7 +33,8 @@ class FixedValueGenerator implements CallbackGenerator {
private static final Signature LOAD_OBJECT = private static final Signature LOAD_OBJECT =
TypeUtils.parseSignature("Object loadObject()"); TypeUtils.parseSignature("Object loadObject()");
public void generate(ClassEmitter ce, Context context, List methods) { @Override
public void generate(ClassEmitter ce, Context context, List methods) {
for (Iterator it = methods.iterator(); it.hasNext();) { for (Iterator it = methods.iterator(); it.hasNext();) {
MethodInfo method = (MethodInfo)it.next(); MethodInfo method = (MethodInfo)it.next();
CodeEmitter e = context.beginMethod(ce, method); CodeEmitter e = context.beginMethod(ce, method);
@@ -39,5 +46,6 @@ class FixedValueGenerator implements CallbackGenerator {
} }
} }
public void generateStatic(CodeEmitter e, Context context, List methods) { } @Override
public void generateStatic(CodeEmitter e, Context context, List methods) { }
} }

View File

@@ -15,11 +15,18 @@
*/ */
package org.springframework.cglib.proxy; package org.springframework.cglib.proxy;
import java.lang.reflect.*; import java.lang.reflect.Method;
import java.util.*; import java.util.HashMap;
import org.springframework.cglib.core.*; import java.util.Iterator;
import java.util.Map;
import org.springframework.asm.ClassVisitor; import org.springframework.asm.ClassVisitor;
import org.springframework.asm.Type; import org.springframework.asm.Type;
import org.springframework.cglib.core.AbstractClassGenerator;
import org.springframework.cglib.core.ClassEmitter;
import org.springframework.cglib.core.Constants;
import org.springframework.cglib.core.ReflectUtils;
import org.springframework.cglib.core.Signature;
/** /**
* Generates new interfaces at runtime. * Generates new interfaces at runtime.
@@ -71,8 +78,7 @@ public class InterfaceMaker extends AbstractClassGenerator
*/ */
public void add(Class clazz) { public void add(Class clazz) {
Method[] methods = clazz.getMethods(); Method[] methods = clazz.getMethods();
for (int i = 0; i < methods.length; i++) { for (Method m : methods) {
Method m = methods[i];
if (!m.getDeclaringClass().getName().equals("java.lang.Object")) { if (!m.getDeclaringClass().getName().equals("java.lang.Object")) {
add(m); add(m);
} }
@@ -87,19 +93,23 @@ public class InterfaceMaker extends AbstractClassGenerator
return (Class)super.create(this); return (Class)super.create(this);
} }
protected ClassLoader getDefaultClassLoader() { @Override
protected ClassLoader getDefaultClassLoader() {
return null; return null;
} }
protected Object firstInstance(Class type) { @Override
protected Object firstInstance(Class type) {
return type; return type;
} }
protected Object nextInstance(Object instance) { @Override
protected Object nextInstance(Object instance) {
throw new IllegalStateException("InterfaceMaker does not cache"); throw new IllegalStateException("InterfaceMaker does not cache");
} }
public void generateClass(ClassVisitor v) throws Exception { @Override
public void generateClass(ClassVisitor v) throws Exception {
ClassEmitter ce = new ClassEmitter(v); ClassEmitter ce = new ClassEmitter(v);
ce.begin_class(Constants.V1_8, ce.begin_class(Constants.V1_8,
Constants.ACC_PUBLIC | Constants.ACC_INTERFACE | Constants.ACC_ABSTRACT, Constants.ACC_PUBLIC | Constants.ACC_INTERFACE | Constants.ACC_ABSTRACT,

View File

@@ -15,9 +15,18 @@
*/ */
package org.springframework.cglib.proxy; package org.springframework.cglib.proxy;
import org.springframework.cglib.core.*; import java.util.Iterator;
import java.util.*; import java.util.List;
import org.springframework.asm.Type; import org.springframework.asm.Type;
import org.springframework.cglib.core.Block;
import org.springframework.cglib.core.ClassEmitter;
import org.springframework.cglib.core.CodeEmitter;
import org.springframework.cglib.core.Constants;
import org.springframework.cglib.core.EmitUtils;
import org.springframework.cglib.core.MethodInfo;
import org.springframework.cglib.core.Signature;
import org.springframework.cglib.core.TypeUtils;
@SuppressWarnings({"rawtypes", "unchecked"}) @SuppressWarnings({"rawtypes", "unchecked"})
class InvocationHandlerGenerator class InvocationHandlerGenerator
@@ -34,7 +43,8 @@ implements CallbackGenerator
private static final Signature INVOKE = private static final Signature INVOKE =
TypeUtils.parseSignature("Object invoke(Object, java.lang.reflect.Method, Object[])"); TypeUtils.parseSignature("Object invoke(Object, java.lang.reflect.Method, Object[])");
public void generate(ClassEmitter ce, Context context, List methods) { @Override
public void generate(ClassEmitter ce, Context context, List methods) {
for (Iterator it = methods.iterator(); it.hasNext();) { for (Iterator it = methods.iterator(); it.hasNext();) {
MethodInfo method = (MethodInfo)it.next(); MethodInfo method = (MethodInfo)it.next();
Signature impl = context.getImplSignature(method); Signature impl = context.getImplSignature(method);
@@ -55,7 +65,8 @@ implements CallbackGenerator
} }
} }
public void generateStatic(CodeEmitter e, Context context, List methods) { @Override
public void generateStatic(CodeEmitter e, Context context, List methods) {
for (Iterator it = methods.iterator(); it.hasNext();) { for (Iterator it = methods.iterator(); it.hasNext();) {
MethodInfo method = (MethodInfo)it.next(); MethodInfo method = (MethodInfo)it.next();
EmitUtils.load_method(e, method); EmitUtils.load_method(e, method);

View File

@@ -15,21 +15,31 @@
*/ */
package org.springframework.cglib.proxy; package org.springframework.cglib.proxy;
import java.util.*; import java.util.HashSet;
import org.springframework.cglib.core.*; import java.util.Iterator;
import java.util.List;
import java.util.Set;
import org.springframework.asm.Label; import org.springframework.asm.Label;
import org.springframework.asm.Type; import org.springframework.asm.Type;
import org.springframework.cglib.core.ClassEmitter;
import org.springframework.cglib.core.CodeEmitter;
import org.springframework.cglib.core.Constants;
import org.springframework.cglib.core.MethodInfo;
import org.springframework.cglib.core.Signature;
import org.springframework.cglib.core.TypeUtils;
@SuppressWarnings({"rawtypes", "unchecked"}) @SuppressWarnings({"rawtypes", "unchecked"})
class LazyLoaderGenerator implements CallbackGenerator { class LazyLoaderGenerator implements CallbackGenerator {
public static final LazyLoaderGenerator INSTANCE = new LazyLoaderGenerator(); public static final LazyLoaderGenerator INSTANCE = new LazyLoaderGenerator();
private static final Signature LOAD_OBJECT = private static final Signature LOAD_OBJECT =
TypeUtils.parseSignature("Object loadObject()"); TypeUtils.parseSignature("Object loadObject()");
private static final Type LAZY_LOADER = private static final Type LAZY_LOADER =
TypeUtils.parseType("org.springframework.cglib.proxy.LazyLoader"); TypeUtils.parseType("org.springframework.cglib.proxy.LazyLoader");
public void generate(ClassEmitter ce, Context context, List methods) { @Override
public void generate(ClassEmitter ce, Context context, List methods) {
Set indexes = new HashSet(); Set indexes = new HashSet();
for (Iterator it = methods.iterator(); it.hasNext();) { for (Iterator it = methods.iterator(); it.hasNext();) {
MethodInfo method = (MethodInfo)it.next(); MethodInfo method = (MethodInfo)it.next();
@@ -75,7 +85,7 @@ class LazyLoaderGenerator implements CallbackGenerator {
e.mark(end); e.mark(end);
e.return_value(); e.return_value();
e.end_method(); e.end_method();
} }
} }
@@ -85,5 +95,6 @@ class LazyLoaderGenerator implements CallbackGenerator {
Constants.TYPES_EMPTY); Constants.TYPES_EMPTY);
} }
public void generateStatic(CodeEmitter e, Context context, List methods) { } @Override
public void generateStatic(CodeEmitter e, Context context, List methods) { }
} }

View File

@@ -35,7 +35,7 @@ extends Callback
* @throws Throwable any exception may be thrown; if so, super method will not be invoked * @throws Throwable any exception may be thrown; if so, super method will not be invoked
* @return any value compatible with the signature of the proxied method. Method returning void will ignore this value. * @return any value compatible with the signature of the proxied method. Method returning void will ignore this value.
* @see MethodProxy * @see MethodProxy
*/ */
public Object intercept(Object obj, java.lang.reflect.Method method, Object[] args, public Object intercept(Object obj, java.lang.reflect.Method method, Object[] args,
MethodProxy proxy) throws Throwable; MethodProxy proxy) throws Throwable;

View File

@@ -79,12 +79,7 @@ implements CallbackGenerator
new Signature(FIND_PROXY_NAME, METHOD_PROXY, new Type[]{ Constants.TYPE_SIGNATURE }); new Signature(FIND_PROXY_NAME, METHOD_PROXY, new Type[]{ Constants.TYPE_SIGNATURE });
private static final Signature TO_STRING = private static final Signature TO_STRING =
TypeUtils.parseSignature("String toString()"); TypeUtils.parseSignature("String toString()");
private static final Transformer METHOD_TO_CLASS = new Transformer(){ private static final Transformer METHOD_TO_CLASS = value -> ((MethodInfo)value).getClassInfo();
@Override
public Object transform(Object value) {
return ((MethodInfo)value).getClassInfo();
}
};
private String getMethodField(Signature impl) { private String getMethodField(Signature impl) {
return impl.getName() + "$Method"; return impl.getName() + "$Method";

View File

@@ -234,8 +234,9 @@ public class MethodProxy {
throw ex.getTargetException(); throw ex.getTargetException();
} }
catch (IllegalArgumentException ex) { catch (IllegalArgumentException ex) {
if (fastClassInfo.i1 < 0) if (fastClassInfo.i1 < 0) {
throw new IllegalArgumentException("Protected method: " + sig1); throw new IllegalArgumentException("Protected method: " + sig1);
}
throw ex; throw ex;
} }
} }

View File

@@ -16,8 +16,9 @@
package org.springframework.cglib.proxy; package org.springframework.cglib.proxy;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import org.springframework.cglib.core.ReflectUtils;
import org.springframework.asm.ClassVisitor; import org.springframework.asm.ClassVisitor;
import org.springframework.cglib.core.ReflectUtils;
/** /**
* @author Chris Nokleberg * @author Chris Nokleberg
@@ -29,11 +30,13 @@ class MixinBeanEmitter extends MixinEmitter {
super(v, className, classes, null); super(v, className, classes, null);
} }
protected Class[] getInterfaces(Class[] classes) { @Override
protected Class[] getInterfaces(Class[] classes) {
return null; return null;
} }
protected Method[] getMethods(Class type) { @Override
protected Method[] getMethods(Class type) {
return ReflectUtils.getPropertyMethods(ReflectUtils.getBeanProperties(type), true, true); return ReflectUtils.getPropertyMethods(ReflectUtils.getBeanProperties(type), true, true);
} }
} }

View File

@@ -16,10 +16,20 @@
package org.springframework.cglib.proxy; package org.springframework.cglib.proxy;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.*; import java.util.HashSet;
import org.springframework.cglib.core.*; import java.util.Set;
import org.springframework.asm.ClassVisitor; import org.springframework.asm.ClassVisitor;
import org.springframework.asm.Type; import org.springframework.asm.Type;
import org.springframework.cglib.core.ClassEmitter;
import org.springframework.cglib.core.CodeEmitter;
import org.springframework.cglib.core.Constants;
import org.springframework.cglib.core.EmitUtils;
import org.springframework.cglib.core.MethodInfo;
import org.springframework.cglib.core.MethodWrapper;
import org.springframework.cglib.core.ReflectUtils;
import org.springframework.cglib.core.Signature;
import org.springframework.cglib.core.TypeUtils;
/** /**
* @author Chris Nokleberg * @author Chris Nokleberg
@@ -61,20 +71,20 @@ class MixinEmitter extends ClassEmitter {
Set unique = new HashSet(); Set unique = new HashSet();
for (int i = 0; i < classes.length; i++) { for (int i = 0; i < classes.length; i++) {
Method[] methods = getMethods(classes[i]); Method[] methods = getMethods(classes[i]);
for (int j = 0; j < methods.length; j++) { for (Method method : methods) {
if (unique.add(MethodWrapper.create(methods[j]))) { if (unique.add(MethodWrapper.create(method))) {
MethodInfo method = ReflectUtils.getMethodInfo(methods[j]); MethodInfo methodInfo = ReflectUtils.getMethodInfo(method);
int modifiers = Constants.ACC_PUBLIC; int modifiers = Constants.ACC_PUBLIC;
if ((method.getModifiers() & Constants.ACC_VARARGS) == Constants.ACC_VARARGS) { if ((methodInfo.getModifiers() & Constants.ACC_VARARGS) == Constants.ACC_VARARGS) {
modifiers |= Constants.ACC_VARARGS; modifiers |= Constants.ACC_VARARGS;
} }
e = EmitUtils.begin_method(this, method, modifiers); e = EmitUtils.begin_method(this, methodInfo, modifiers);
e.load_this(); e.load_this();
e.getfield(FIELD_NAME); e.getfield(FIELD_NAME);
e.aaload((route != null) ? route[i] : i); e.aaload((route != null) ? route[i] : i);
e.checkcast(method.getClassInfo().getType()); e.checkcast(methodInfo.getClassInfo().getType());
e.load_args(); e.load_args();
e.invoke(method); e.invoke(methodInfo);
e.return_value(); e.return_value();
e.end_method(); e.end_method();
} }

View File

@@ -13,15 +13,19 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package org.springframework.cglib.proxy; package org.springframework.cglib.proxy;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.lang.reflect.Modifier; import java.lang.reflect.Modifier;
import java.util.*; import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.springframework.asm.ClassVisitor;
import org.springframework.cglib.core.CollectionUtils; import org.springframework.cglib.core.CollectionUtils;
import org.springframework.cglib.core.ReflectUtils; import org.springframework.cglib.core.ReflectUtils;
import org.springframework.cglib.core.RejectModifierPredicate; import org.springframework.cglib.core.RejectModifierPredicate;
import org.springframework.asm.ClassVisitor;
/** /**
* @author Chris Nokleberg * @author Chris Nokleberg
@@ -34,15 +38,17 @@ class MixinEverythingEmitter extends MixinEmitter {
super(v, className, classes, null); super(v, className, classes, null);
} }
@Override
protected Class[] getInterfaces(Class[] classes) { protected Class[] getInterfaces(Class[] classes) {
List list = new ArrayList(); List list = new ArrayList();
for (int i = 0; i < classes.length; i++) { for (Class clazz : classes) {
ReflectUtils.addAllInterfaces(classes[i], list); ReflectUtils.addAllInterfaces(clazz, list);
} }
return (Class[])list.toArray(new Class[list.size()]); return (Class[])list.toArray(new Class[list.size()]);
} }
protected Method[] getMethods(Class type) { @Override
protected Method[] getMethods(Class type) {
List methods = new ArrayList(Arrays.asList(type.getMethods())); List methods = new ArrayList(Arrays.asList(type.getMethods()));
CollectionUtils.filter(methods, new RejectModifierPredicate(Modifier.FINAL | Modifier.STATIC)); CollectionUtils.filter(methods, new RejectModifierPredicate(Modifier.FINAL | Modifier.STATIC));
return (Method[])methods.toArray(new Method[methods.size()]); return (Method[])methods.toArray(new Method[methods.size()]);

View File

@@ -17,7 +17,12 @@ package org.springframework.cglib.proxy;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import org.springframework.cglib.core.*;
import org.springframework.cglib.core.ClassEmitter;
import org.springframework.cglib.core.CodeEmitter;
import org.springframework.cglib.core.EmitUtils;
import org.springframework.cglib.core.MethodInfo;
import org.springframework.cglib.core.TypeUtils;
@SuppressWarnings({"rawtypes", "unchecked"}) @SuppressWarnings({"rawtypes", "unchecked"})
class NoOpGenerator class NoOpGenerator
@@ -25,7 +30,8 @@ implements CallbackGenerator
{ {
public static final NoOpGenerator INSTANCE = new NoOpGenerator(); public static final NoOpGenerator INSTANCE = new NoOpGenerator();
public void generate(ClassEmitter ce, Context context, List methods) { @Override
public void generate(ClassEmitter ce, Context context, List methods) {
for (Iterator it = methods.iterator(); it.hasNext();) { for (Iterator it = methods.iterator(); it.hasNext();) {
MethodInfo method = (MethodInfo)it.next(); MethodInfo method = (MethodInfo)it.next();
if (TypeUtils.isBridge(method.getModifiers()) || ( if (TypeUtils.isBridge(method.getModifiers()) || (
@@ -39,6 +45,7 @@ implements CallbackGenerator
} }
} }
} }
public void generateStatic(CodeEmitter e, Context context, List methods) { } @Override
public void generateStatic(CodeEmitter e, Context context, List methods) { }
} }

View File

@@ -17,7 +17,6 @@
package org.springframework.cglib.proxy; package org.springframework.cglib.proxy;
import java.io.Serializable; import java.io.Serializable;
import java.lang.reflect.Method;
import org.springframework.cglib.core.CodeGenerationException; import org.springframework.cglib.core.CodeGenerationException;
@@ -40,20 +39,17 @@ import org.springframework.cglib.core.CodeGenerationException;
public class Proxy implements Serializable { public class Proxy implements Serializable {
protected InvocationHandler h; protected InvocationHandler h;
private static final CallbackFilter BAD_OBJECT_METHOD_FILTER = new CallbackFilter() { private static final CallbackFilter BAD_OBJECT_METHOD_FILTER = method -> {
@Override if (method.getDeclaringClass().getName().equals("java.lang.Object")) {
public int accept(Method method) { String name = method.getName();
if (method.getDeclaringClass().getName().equals("java.lang.Object")) { if (!(name.equals("hashCode") ||
String name = method.getName(); name.equals("equals") ||
if (!(name.equals("hashCode") || name.equals("toString"))) {
name.equals("equals") || return 1;
name.equals("toString"))) { }
return 1; }
} return 0;
} };
return 0;
}
};
protected Proxy(InvocationHandler h) { protected Proxy(InvocationHandler h) {
Enhancer.registerCallbacks(getClass(), new Callback[]{ h, null }); Enhancer.registerCallbacks(getClass(), new Callback[]{ h, null });

View File

@@ -30,7 +30,7 @@ public class UndeclaredThrowableException extends CodeGenerationException {
public UndeclaredThrowableException(Throwable t) { public UndeclaredThrowableException(Throwable t) {
super(t); super(t);
} }
public Throwable getUndeclaredThrowable() { public Throwable getUndeclaredThrowable() {
return getCause(); return getCause();
} }

View File

@@ -15,11 +15,20 @@
*/ */
package org.springframework.cglib.reflect; package org.springframework.cglib.reflect;
import java.lang.reflect.*; import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.security.ProtectionDomain; import java.security.ProtectionDomain;
import org.springframework.cglib.core.*;
import org.springframework.asm.ClassVisitor; import org.springframework.asm.ClassVisitor;
import org.springframework.asm.Type; import org.springframework.asm.Type;
import org.springframework.cglib.core.AbstractClassGenerator;
import org.springframework.cglib.core.ClassEmitter;
import org.springframework.cglib.core.CodeEmitter;
import org.springframework.cglib.core.Constants;
import org.springframework.cglib.core.EmitUtils;
import org.springframework.cglib.core.KeyFactory;
import org.springframework.cglib.core.ReflectUtils;
import org.springframework.cglib.core.TypeUtils;
/** /**
* @author Chris Nokleberg * @author Chris Nokleberg
@@ -29,7 +38,7 @@ import org.springframework.asm.Type;
abstract public class ConstructorDelegate { abstract public class ConstructorDelegate {
private static final ConstructorKey KEY_FACTORY = private static final ConstructorKey KEY_FACTORY =
(ConstructorKey)KeyFactory.create(ConstructorKey.class, KeyFactory.CLASS_BY_NAME); (ConstructorKey)KeyFactory.create(ConstructorKey.class, KeyFactory.CLASS_BY_NAME);
interface ConstructorKey { interface ConstructorKey {
public Object newInstance(String declaring, String iface); public Object newInstance(String declaring, String iface);
} }
@@ -70,15 +79,18 @@ abstract public class ConstructorDelegate {
return (ConstructorDelegate)super.create(key); return (ConstructorDelegate)super.create(key);
} }
protected ClassLoader getDefaultClassLoader() { @Override
protected ClassLoader getDefaultClassLoader() {
return targetClass.getClassLoader(); return targetClass.getClassLoader();
} }
protected ProtectionDomain getProtectionDomain() { @Override
protected ProtectionDomain getProtectionDomain() {
return ReflectUtils.getProtectionDomain(targetClass); return ReflectUtils.getProtectionDomain(targetClass);
} }
public void generateClass(ClassVisitor v) { @Override
public void generateClass(ClassVisitor v) {
setNamePrefix(targetClass.getName()); setNamePrefix(targetClass.getName());
final Method newInstance = ReflectUtils.findNewInstance(iface); final Method newInstance = ReflectUtils.findNewInstance(iface);
@@ -113,11 +125,13 @@ abstract public class ConstructorDelegate {
ce.end_class(); ce.end_class();
} }
protected Object firstInstance(Class type) { @Override
protected Object firstInstance(Class type) {
return ReflectUtils.newInstance(type); return ReflectUtils.newInstance(type);
} }
protected Object nextInstance(Object instance) { @Override
protected Object nextInstance(Object instance) {
return instance; return instance;
} }
} }

View File

@@ -15,13 +15,17 @@
*/ */
package org.springframework.cglib.reflect; package org.springframework.cglib.reflect;
import org.springframework.cglib.core.*;
import java.lang.reflect.Constructor; import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.security.ProtectionDomain; import java.security.ProtectionDomain;
import org.springframework.asm.ClassVisitor; import org.springframework.asm.ClassVisitor;
import org.springframework.asm.Type; import org.springframework.asm.Type;
import org.springframework.cglib.core.AbstractClassGenerator;
import org.springframework.cglib.core.Constants;
import org.springframework.cglib.core.ReflectUtils;
import org.springframework.cglib.core.Signature;
@SuppressWarnings({"rawtypes", "unchecked"}) @SuppressWarnings({"rawtypes", "unchecked"})
abstract public class FastClass abstract public class FastClass
@@ -37,9 +41,9 @@ abstract public class FastClass
} }
public static FastClass create(Class type) { public static FastClass create(Class type) {
return create(type.getClassLoader(),type); return create(type.getClassLoader(),type);
} }
public static FastClass create(ClassLoader loader, Class type) { public static FastClass create(ClassLoader loader, Class type) {
Generator gen = new Generator(); Generator gen = new Generator();
@@ -52,7 +56,7 @@ abstract public class FastClass
{ {
private static final Source SOURCE = new Source(FastClass.class.getName()); private static final Source SOURCE = new Source(FastClass.class.getName());
private Class type; private Class type;
public Generator() { public Generator() {
super(SOURCE); super(SOURCE);
} }
@@ -60,35 +64,40 @@ abstract public class FastClass
public void setType(Class type) { public void setType(Class type) {
this.type = type; this.type = type;
} }
public FastClass create() { public FastClass create() {
setNamePrefix(type.getName()); setNamePrefix(type.getName());
return (FastClass)super.create(type.getName()); return (FastClass)super.create(type.getName());
} }
protected ClassLoader getDefaultClassLoader() { @Override
protected ClassLoader getDefaultClassLoader() {
return type.getClassLoader(); return type.getClassLoader();
} }
protected ProtectionDomain getProtectionDomain() { @Override
protected ProtectionDomain getProtectionDomain() {
return ReflectUtils.getProtectionDomain(type); return ReflectUtils.getProtectionDomain(type);
} }
public void generateClass(ClassVisitor v) throws Exception { @Override
public void generateClass(ClassVisitor v) throws Exception {
new FastClassEmitter(v, getClassName(), type); new FastClassEmitter(v, getClassName(), type);
} }
protected Object firstInstance(Class type) { @Override
protected Object firstInstance(Class type) {
return ReflectUtils.newInstance(type, return ReflectUtils.newInstance(type,
new Class[]{ Class.class }, new Class[]{ Class.class },
new Object[]{ this.type }); new Object[]{ this.type });
} }
protected Object nextInstance(Object instance) { @Override
protected Object nextInstance(Object instance) {
return instance; return instance;
} }
} }
public Object invoke(String name, Class[] parameterTypes, Object obj, Object[] args) throws InvocationTargetException { public Object invoke(String name, Class[] parameterTypes, Object obj, Object[] args) throws InvocationTargetException {
return invoke(getIndex(name, parameterTypes), obj, args); return invoke(getIndex(name, parameterTypes), obj, args);
} }
@@ -100,7 +109,7 @@ abstract public class FastClass
public Object newInstance(Class[] parameterTypes, Object[] args) throws InvocationTargetException { public Object newInstance(Class[] parameterTypes, Object[] args) throws InvocationTargetException {
return newInstance(getIndex(parameterTypes), args); return newInstance(getIndex(parameterTypes), args);
} }
public FastMethod getMethod(Method method) { public FastMethod getMethod(Method method) {
return new FastMethod(this, method); return new FastMethod(this, method);
} }
@@ -133,15 +142,18 @@ abstract public class FastClass
return type; return type;
} }
public String toString() { @Override
public String toString() {
return type.toString(); return type.toString();
} }
public int hashCode() { @Override
public int hashCode() {
return type.hashCode(); return type.hashCode();
} }
public boolean equals(Object o) { @Override
public boolean equals(Object o) {
if (o == null || !(o instanceof FastClass)) { if (o == null || !(o instanceof FastClass)) {
return false; return false;
} }
@@ -199,8 +211,8 @@ abstract public class FastClass
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
sb.append(name); sb.append(name);
sb.append('('); sb.append('(');
for (int i = 0; i < parameterTypes.length; i++) { for (Class parameterType : parameterTypes) {
sb.append(Type.getDescriptor(parameterTypes[i])); sb.append(Type.getDescriptor(parameterType));
} }
sb.append(')'); sb.append(')');
return sb.toString(); return sb.toString();

View File

@@ -13,14 +13,35 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package org.springframework.cglib.reflect; package org.springframework.cglib.reflect;
import java.lang.reflect.*; import java.lang.reflect.Method;
import java.util.*; import java.util.ArrayList;
import org.springframework.cglib.core.*; import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.springframework.asm.ClassVisitor; import org.springframework.asm.ClassVisitor;
import org.springframework.asm.Label; import org.springframework.asm.Label;
import org.springframework.asm.Type; import org.springframework.asm.Type;
import org.springframework.cglib.core.Block;
import org.springframework.cglib.core.ClassEmitter;
import org.springframework.cglib.core.CodeEmitter;
import org.springframework.cglib.core.CollectionUtils;
import org.springframework.cglib.core.Constants;
import org.springframework.cglib.core.DuplicatesPredicate;
import org.springframework.cglib.core.EmitUtils;
import org.springframework.cglib.core.MethodInfo;
import org.springframework.cglib.core.MethodInfoTransformer;
import org.springframework.cglib.core.ObjectSwitchCallback;
import org.springframework.cglib.core.ProcessSwitchCallback;
import org.springframework.cglib.core.ReflectUtils;
import org.springframework.cglib.core.Signature;
import org.springframework.cglib.core.TypeUtils;
import org.springframework.cglib.core.VisibilityPredicate;
@SuppressWarnings({"rawtypes", "unchecked", "deprecation"}) @SuppressWarnings({"rawtypes", "unchecked", "deprecation"})
class FastClassEmitter extends ClassEmitter { class FastClassEmitter extends ClassEmitter {
@@ -49,7 +70,7 @@ class FastClassEmitter extends ClassEmitter {
private static final Type INVOCATION_TARGET_EXCEPTION = private static final Type INVOCATION_TARGET_EXCEPTION =
TypeUtils.parseType("java.lang.reflect.InvocationTargetException"); TypeUtils.parseType("java.lang.reflect.InvocationTargetException");
private static final Type[] INVOCATION_TARGET_EXCEPTION_ARRAY = { INVOCATION_TARGET_EXCEPTION }; private static final Type[] INVOCATION_TARGET_EXCEPTION_ARRAY = { INVOCATION_TARGET_EXCEPTION };
public FastClassEmitter(ClassVisitor v, String className, Class type) { public FastClassEmitter(ClassVisitor v, String className, Class type) {
super(v); super(v);
@@ -70,13 +91,13 @@ class FastClassEmitter extends ClassEmitter {
CollectionUtils.filter(methods, new DuplicatesPredicate()); CollectionUtils.filter(methods, new DuplicatesPredicate());
List constructors = new ArrayList(Arrays.asList(type.getDeclaredConstructors())); List constructors = new ArrayList(Arrays.asList(type.getDeclaredConstructors()));
CollectionUtils.filter(constructors, vp); CollectionUtils.filter(constructors, vp);
// getIndex(String) // getIndex(String)
emitIndexBySignature(methods); emitIndexBySignature(methods);
// getIndex(String, Class[]) // getIndex(String, Class[])
emitIndexByClassArray(methods); emitIndexByClassArray(methods);
// getIndex(Class[]) // getIndex(Class[])
e = begin_method(Constants.ACC_PUBLIC, CONSTRUCTOR_GET_INDEX, null); e = begin_method(Constants.ACC_PUBLIC, CONSTRUCTOR_GET_INDEX, null);
e.load_args(); e.load_args();
@@ -112,11 +133,7 @@ class FastClassEmitter extends ClassEmitter {
// TODO: support constructor indices ("<init>") // TODO: support constructor indices ("<init>")
private void emitIndexBySignature(List methods) { private void emitIndexBySignature(List methods) {
CodeEmitter e = begin_method(Constants.ACC_PUBLIC, SIGNATURE_GET_INDEX, null); CodeEmitter e = begin_method(Constants.ACC_PUBLIC, SIGNATURE_GET_INDEX, null);
List signatures = CollectionUtils.transform(methods, new Transformer() { List signatures = CollectionUtils.transform(methods, obj -> ReflectUtils.getSignature((Method)obj).toString());
public Object transform(Object obj) {
return ReflectUtils.getSignature((Method)obj).toString();
}
});
e.load_arg(0); e.load_arg(0);
e.invoke_virtual(Constants.TYPE_OBJECT, TO_STRING); e.invoke_virtual(Constants.TYPE_OBJECT, TO_STRING);
signatureSwitchHelper(e, signatures); signatureSwitchHelper(e, signatures);
@@ -128,12 +145,10 @@ class FastClassEmitter extends ClassEmitter {
CodeEmitter e = begin_method(Constants.ACC_PUBLIC, METHOD_GET_INDEX, null); CodeEmitter e = begin_method(Constants.ACC_PUBLIC, METHOD_GET_INDEX, null);
if (methods.size() > TOO_MANY_METHODS) { if (methods.size() > TOO_MANY_METHODS) {
// hack for big classes // hack for big classes
List signatures = CollectionUtils.transform(methods, new Transformer() { List signatures = CollectionUtils.transform(methods, obj -> {
public Object transform(Object obj) { String s = ReflectUtils.getSignature((Method)obj).toString();
String s = ReflectUtils.getSignature((Method)obj).toString(); return s.substring(0, s.lastIndexOf(')') + 1);
return s.substring(0, s.lastIndexOf(')') + 1); });
}
});
e.load_args(); e.load_args();
e.invoke_static(FAST_CLASS, GET_SIGNATURE_WITHOUT_RETURN_TYPE); e.invoke_static(FAST_CLASS, GET_SIGNATURE_WITHOUT_RETURN_TYPE);
signatureSwitchHelper(e, signatures); signatureSwitchHelper(e, signatures);
@@ -147,12 +162,14 @@ class FastClassEmitter extends ClassEmitter {
private void signatureSwitchHelper(final CodeEmitter e, final List signatures) { private void signatureSwitchHelper(final CodeEmitter e, final List signatures) {
ObjectSwitchCallback callback = new ObjectSwitchCallback() { ObjectSwitchCallback callback = new ObjectSwitchCallback() {
public void processCase(Object key, Label end) { @Override
public void processCase(Object key, Label end) {
// TODO: remove linear indexOf // TODO: remove linear indexOf
e.push(signatures.indexOf(key)); e.push(signatures.indexOf(key));
e.return_value(); e.return_value();
} }
public void processDefault() { @Override
public void processDefault() {
e.push(-1); e.push(-1);
e.return_value(); e.return_value();
} }
@@ -164,11 +181,12 @@ class FastClassEmitter extends ClassEmitter {
} }
private static void invokeSwitchHelper(final CodeEmitter e, List members, final int arg, final Type base) { private static void invokeSwitchHelper(final CodeEmitter e, List members, final int arg, final Type base) {
final List info = CollectionUtils.transform(members, MethodInfoTransformer.getInstance()); final List info = CollectionUtils.transform(members, MethodInfoTransformer.getInstance());
final Label illegalArg = e.make_label(); final Label illegalArg = e.make_label();
Block block = e.begin_block(); Block block = e.begin_block();
e.process_switch(getIntRange(info.size()), new ProcessSwitchCallback() { e.process_switch(getIntRange(info.size()), new ProcessSwitchCallback() {
public void processCase(int key, Label end) { @Override
public void processCase(int key, Label end) {
MethodInfo method = (MethodInfo)info.get(key); MethodInfo method = (MethodInfo)info.get(key);
Type[] types = method.getSignature().getArgumentTypes(); Type[] types = method.getSignature().getArgumentTypes();
for (int i = 0; i < types.length; i++) { for (int i = 0; i < types.length; i++) {
@@ -184,7 +202,8 @@ class FastClassEmitter extends ClassEmitter {
} }
e.return_value(); e.return_value();
} }
public void processDefault() { @Override
public void processDefault() {
e.goTo(illegalArg); e.goTo(illegalArg);
} }
}); });
@@ -205,18 +224,20 @@ class FastClassEmitter extends ClassEmitter {
indexes.put(it.next(), index++); indexes.put(it.next(), index++);
} }
} }
public void processCase(Object key, Label end) { @Override
public void processCase(Object key, Label end) {
e.push(((Integer)indexes.get(key))); e.push(((Integer)indexes.get(key)));
e.return_value(); e.return_value();
} }
public void processDefault() { @Override
public void processDefault() {
e.push(-1); e.push(-1);
e.return_value(); e.return_value();
} }
} }
private static int[] getIntRange(int length) { private static int[] getIntRange(int length) {
int[] range = new int[length]; int[] range = new int[length];
for (int i = 0; i < length; i++) { for (int i = 0; i < length; i++) {

View File

@@ -25,11 +25,13 @@ public class FastConstructor extends FastMember
super(fc, constructor, fc.getIndex(constructor.getParameterTypes())); super(fc, constructor, fc.getIndex(constructor.getParameterTypes()));
} }
public Class[] getParameterTypes() { @Override
public Class[] getParameterTypes() {
return ((Constructor)member).getParameterTypes(); return ((Constructor)member).getParameterTypes();
} }
public Class[] getExceptionTypes() { @Override
public Class[] getExceptionTypes() {
return ((Constructor)member).getExceptionTypes(); return ((Constructor)member).getExceptionTypes();
} }

View File

@@ -49,18 +49,22 @@ abstract public class FastMember
return member.getModifiers(); return member.getModifiers();
} }
@Override
public String toString() { public String toString() {
return member.toString(); return member.toString();
} }
@Override
public int hashCode() { public int hashCode() {
return member.hashCode(); return member.hashCode();
} }
@Override
public boolean equals(Object o) { public boolean equals(Object o) {
if (o == null || !(o instanceof FastMember)) { if (o == null || !(o instanceof FastMember other)) {
return false; return false;
} }
return member.equals(((FastMember)o).member); return member.equals(other.member);
} }
} }

View File

@@ -18,9 +18,8 @@ package org.springframework.cglib.reflect;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import org.springframework.cglib.core.Signature;
import org.springframework.asm.Type; import org.springframework.asm.Type;
import org.springframework.cglib.core.Signature;
@SuppressWarnings({"rawtypes", "unchecked"}) @SuppressWarnings({"rawtypes", "unchecked"})
public class FastMethod extends FastMember public class FastMethod extends FastMember
@@ -46,11 +45,13 @@ public class FastMethod extends FastMember
return ((Method)member).getReturnType(); return ((Method)member).getReturnType();
} }
public Class[] getParameterTypes() { @Override
public Class[] getParameterTypes() {
return ((Method)member).getParameterTypes(); return ((Method)member).getParameterTypes();
} }
public Class[] getExceptionTypes() { @Override
public Class[] getExceptionTypes() {
return ((Method)member).getExceptionTypes(); return ((Method)member).getExceptionTypes();
} }

View File

@@ -30,7 +30,6 @@ import org.springframework.cglib.core.Constants;
import org.springframework.cglib.core.EmitUtils; import org.springframework.cglib.core.EmitUtils;
import org.springframework.cglib.core.Local; import org.springframework.cglib.core.Local;
import org.springframework.cglib.core.MethodInfo; import org.springframework.cglib.core.MethodInfo;
import org.springframework.cglib.core.ProcessArrayCallback;
import org.springframework.cglib.core.ReflectUtils; import org.springframework.cglib.core.ReflectUtils;
import org.springframework.cglib.core.Signature; import org.springframework.cglib.core.Signature;
import org.springframework.cglib.core.TypeUtils; import org.springframework.cglib.core.TypeUtils;
@@ -166,17 +165,14 @@ abstract public class MulticastDelegate implements Cloneable {
e.load_this(); e.load_this();
e.super_getfield("targets", Constants.TYPE_OBJECT_ARRAY); e.super_getfield("targets", Constants.TYPE_OBJECT_ARRAY);
final Local result2 = result; final Local result2 = result;
EmitUtils.process_array(e, Constants.TYPE_OBJECT_ARRAY, new ProcessArrayCallback() { EmitUtils.process_array(e, Constants.TYPE_OBJECT_ARRAY, type -> {
@Override e.checkcast(Type.getType(iface));
public void processElement(Type type) { e.load_args();
e.checkcast(Type.getType(iface)); e.invoke(method);
e.load_args(); if (returns) {
e.invoke(method); e.store_local(result2);
if (returns) { }
e.store_local(result2); });
}
}
});
if (returns) { if (returns) {
e.load_local(result); e.load_local(result);
} }

View File

@@ -26,7 +26,8 @@ abstract public class AbstractClassFilterTransformer extends AbstractClassTransf
private ClassTransformer pass; private ClassTransformer pass;
private ClassVisitor target; private ClassVisitor target;
public void setTarget(ClassVisitor target) { @Override
public void setTarget(ClassVisitor target) {
super.setTarget(target); super.setTarget(target);
pass.setTarget(target); pass.setTarget(target);
} }
@@ -37,7 +38,8 @@ abstract public class AbstractClassFilterTransformer extends AbstractClassTransf
abstract protected boolean accept(int version, int access, String name, String signature, String superName, String[] interfaces); abstract protected boolean accept(int version, int access, String name, String signature, String superName, String[] interfaces);
public void visit(int version, @Override
public void visit(int version,
int access, int access,
String name, String name,
String signature, String signature,
@@ -46,36 +48,43 @@ abstract public class AbstractClassFilterTransformer extends AbstractClassTransf
target = accept(version, access, name, signature, superName, interfaces) ? pass : cv; target = accept(version, access, name, signature, superName, interfaces) ? pass : cv;
target.visit(version, access, name, signature, superName, interfaces); target.visit(version, access, name, signature, superName, interfaces);
} }
public void visitSource(String source, String debug) { @Override
public void visitSource(String source, String debug) {
target.visitSource(source, debug); target.visitSource(source, debug);
} }
public void visitOuterClass(String owner, String name, String desc) { @Override
public void visitOuterClass(String owner, String name, String desc) {
target.visitOuterClass(owner, name, desc); target.visitOuterClass(owner, name, desc);
} }
public AnnotationVisitor visitAnnotation(String desc, boolean visible) { @Override
public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
return target.visitAnnotation(desc, visible); return target.visitAnnotation(desc, visible);
} }
public void visitAttribute(Attribute attr) { @Override
public void visitAttribute(Attribute attr) {
target.visitAttribute(attr); target.visitAttribute(attr);
} }
public void visitInnerClass(String name, String outerName, String innerName, int access) { @Override
public void visitInnerClass(String name, String outerName, String innerName, int access) {
target.visitInnerClass(name, outerName, innerName, access); target.visitInnerClass(name, outerName, innerName, access);
} }
public FieldVisitor visitField(int access, @Override
public FieldVisitor visitField(int access,
String name, String name,
String desc, String desc,
String signature, String signature,
Object value) { Object value) {
return target.visitField(access, name, desc, signature, value); return target.visitField(access, name, desc, signature, value);
} }
public MethodVisitor visitMethod(int access, @Override
public MethodVisitor visitMethod(int access,
String name, String name,
String desc, String desc,
String signature, String signature,
@@ -83,7 +92,8 @@ abstract public class AbstractClassFilterTransformer extends AbstractClassTransf
return target.visitMethod(access, name, desc, signature, exceptions); return target.visitMethod(access, name, desc, signature, exceptions);
} }
public void visitEnd() { @Override
public void visitEnd() {
target.visitEnd(); target.visitEnd();
target = null; // just to be safe target = null; // just to be safe
} }

View File

@@ -15,80 +15,79 @@
*/ */
package org.springframework.cglib.transform; package org.springframework.cglib.transform;
import org.springframework.cglib.core.CodeGenerationException; import java.io.IOException;
import org.springframework.cglib.core.ClassGenerator;
import org.springframework.cglib.core.DebuggingClassWriter; import org.springframework.asm.Attribute;
import org.springframework.asm.ClassReader; import org.springframework.asm.ClassReader;
import org.springframework.asm.ClassWriter; import org.springframework.asm.ClassWriter;
import org.springframework.asm.Attribute; import org.springframework.cglib.core.ClassGenerator;
import org.springframework.cglib.core.CodeGenerationException;
import java.io.IOException; import org.springframework.cglib.core.DebuggingClassWriter;
@SuppressWarnings({"rawtypes", "unchecked"}) @SuppressWarnings({"rawtypes", "unchecked"})
abstract public class AbstractClassLoader extends ClassLoader { abstract public class AbstractClassLoader extends ClassLoader {
private ClassFilter filter; private ClassFilter filter;
private ClassLoader classPath; private ClassLoader classPath;
private static java.security.ProtectionDomain DOMAIN ; private static java.security.ProtectionDomain DOMAIN ;
static{ static{
DOMAIN = AbstractClassLoader.class.getProtectionDomain(); DOMAIN = AbstractClassLoader.class.getProtectionDomain();
} }
protected AbstractClassLoader(ClassLoader parent, ClassLoader classPath, ClassFilter filter) { protected AbstractClassLoader(ClassLoader parent, ClassLoader classPath, ClassFilter filter) {
super(parent); super(parent);
this.filter = filter; this.filter = filter;
this.classPath = classPath; this.classPath = classPath;
} }
public Class loadClass(String name) throws ClassNotFoundException { @Override
public Class loadClass(String name) throws ClassNotFoundException {
Class loaded = findLoadedClass(name); Class loaded = findLoadedClass(name);
if( loaded != null ){ if( loaded != null ){
if( loaded.getClassLoader() == this ){ if( loaded.getClassLoader() == this ){
return loaded; return loaded;
}//else reload with this class loader }//else reload with this class loader
} }
if (!filter.accept(name)) { if (!filter.accept(name)) {
return super.loadClass(name); return super.loadClass(name);
} }
ClassReader r; ClassReader r;
try { try {
java.io.InputStream is = classPath.getResourceAsStream( java.io.InputStream is = classPath.getResourceAsStream(
name.replace('.','/') + ".class" name.replace('.','/') + ".class"
); );
if (is == null) { if (is == null) {
throw new ClassNotFoundException(name); throw new ClassNotFoundException(name);
} }
try { try {
r = new ClassReader(is); r = new ClassReader(is);
} finally { } finally {
is.close(); is.close();
} }
} catch (IOException e) { } catch (IOException e) {
throw new ClassNotFoundException(name + ":" + e.getMessage()); throw new ClassNotFoundException(name + ":" + e.getMessage());
} }
try { try {
DebuggingClassWriter w = DebuggingClassWriter w =
new DebuggingClassWriter(ClassWriter.COMPUTE_FRAMES); new DebuggingClassWriter(ClassWriter.COMPUTE_FRAMES);
getGenerator(r).generateClass(w); getGenerator(r).generateClass(w);
byte[] b = w.toByteArray(); byte[] b = w.toByteArray();
Class c = super.defineClass(name, b, 0, b.length, DOMAIN); Class c = super.defineClass(name, b, 0, b.length, DOMAIN);
postProcess(c); postProcess(c);
return c; return c;
} catch (RuntimeException e) { } catch (RuntimeException | Error e) {
throw e;
} catch (Error e) {
throw e; throw e;
} catch (Exception e) { } catch (Exception e) {
throw new CodeGenerationException(e); throw new CodeGenerationException(e);
@@ -102,7 +101,7 @@ abstract public class AbstractClassLoader extends ClassLoader {
protected int getFlags() { protected int getFlags() {
return 0; return 0;
} }
protected Attribute[] attributes() { protected Attribute[] attributes() {
return null; return null;
} }

View File

@@ -15,16 +15,17 @@
*/ */
package org.springframework.cglib.transform; package org.springframework.cglib.transform;
import org.springframework.asm.ClassVisitor;
import org.springframework.cglib.core.ClassTransformer; import org.springframework.cglib.core.ClassTransformer;
import org.springframework.cglib.core.Constants; import org.springframework.cglib.core.Constants;
import org.springframework.asm.ClassVisitor;
abstract public class AbstractClassTransformer extends ClassTransformer { abstract public class AbstractClassTransformer extends ClassTransformer {
protected AbstractClassTransformer() { protected AbstractClassTransformer() {
super(Constants.ASM_API); super(Constants.ASM_API);
} }
public void setTarget(ClassVisitor target) { @Override
public void setTarget(ClassVisitor target) {
cv = target; cv = target;
} }
} }

View File

@@ -15,17 +15,19 @@
*/ */
package org.springframework.cglib.transform; package org.springframework.cglib.transform;
import org.springframework.cglib.core.Constants;
import org.springframework.asm.AnnotationVisitor; import org.springframework.asm.AnnotationVisitor;
import org.springframework.cglib.core.Constants;
public class AnnotationVisitorTee extends AnnotationVisitor { public class AnnotationVisitorTee extends AnnotationVisitor {
private AnnotationVisitor av1, av2; private AnnotationVisitor av1, av2;
public static AnnotationVisitor getInstance(AnnotationVisitor av1, AnnotationVisitor av2) { public static AnnotationVisitor getInstance(AnnotationVisitor av1, AnnotationVisitor av2) {
if (av1 == null) if (av1 == null) {
return av2; return av2;
if (av2 == null) }
return av1; if (av2 == null) {
return av1;
}
return new AnnotationVisitorTee(av1, av2); return new AnnotationVisitorTee(av1, av2);
} }
@@ -35,26 +37,31 @@ public class AnnotationVisitorTee extends AnnotationVisitor {
this.av2 = av2; this.av2 = av2;
} }
public void visit(String name, Object value) { @Override
public void visit(String name, Object value) {
av2.visit(name, value); av2.visit(name, value);
av2.visit(name, value); av2.visit(name, value);
} }
public void visitEnum(String name, String desc, String value) { @Override
public void visitEnum(String name, String desc, String value) {
av1.visitEnum(name, desc, value); av1.visitEnum(name, desc, value);
av2.visitEnum(name, desc, value); av2.visitEnum(name, desc, value);
} }
public AnnotationVisitor visitAnnotation(String name, String desc) { @Override
public AnnotationVisitor visitAnnotation(String name, String desc) {
return getInstance(av1.visitAnnotation(name, desc), return getInstance(av1.visitAnnotation(name, desc),
av2.visitAnnotation(name, desc)); av2.visitAnnotation(name, desc));
} }
public AnnotationVisitor visitArray(String name) { @Override
public AnnotationVisitor visitArray(String name) {
return getInstance(av1.visitArray(name), av2.visitArray(name)); return getInstance(av1.visitArray(name), av2.visitArray(name));
} }
public void visitEnd() { @Override
public void visitEnd() {
av1.visitEnd(); av1.visitEnd();
av2.visitEnd(); av2.visitEnd();
} }

View File

@@ -21,7 +21,7 @@ package org.springframework.cglib.transform;
* @author baliuka * @author baliuka
*/ */
public interface ClassFilter { public interface ClassFilter {
boolean accept(String className); boolean accept(String className);
} }

View File

@@ -15,16 +15,16 @@
*/ */
package org.springframework.cglib.transform; package org.springframework.cglib.transform;
import org.springframework.cglib.core.ClassGenerator;
import org.springframework.asm.Attribute; import org.springframework.asm.Attribute;
import org.springframework.asm.ClassReader; import org.springframework.asm.ClassReader;
import org.springframework.asm.ClassVisitor; import org.springframework.asm.ClassVisitor;
import org.springframework.cglib.core.ClassGenerator;
public class ClassReaderGenerator implements ClassGenerator { public class ClassReaderGenerator implements ClassGenerator {
private final ClassReader r; private final ClassReader r;
private final Attribute[] attrs; private final Attribute[] attrs;
private final int flags; private final int flags;
public ClassReaderGenerator(ClassReader r, int flags) { public ClassReaderGenerator(ClassReader r, int flags) {
this(r, null, flags); this(r, null, flags);
} }
@@ -34,8 +34,9 @@ public class ClassReaderGenerator implements ClassGenerator {
this.attrs = (attrs != null) ? attrs : new Attribute[0]; this.attrs = (attrs != null) ? attrs : new Attribute[0];
this.flags = flags; this.flags = flags;
} }
public void generateClass(ClassVisitor v) { @Override
public void generateClass(ClassVisitor v) {
r.accept(v, attrs, flags); r.accept(v, attrs, flags);
} }
} }

View File

@@ -21,12 +21,13 @@ import org.springframework.cglib.core.ClassTransformer;
public class ClassTransformerChain extends AbstractClassTransformer { public class ClassTransformerChain extends AbstractClassTransformer {
private ClassTransformer[] chain; private ClassTransformer[] chain;
public ClassTransformerChain(ClassTransformer[] chain) { public ClassTransformerChain(ClassTransformer[] chain) {
this.chain = chain.clone(); this.chain = chain.clone();
} }
public void setTarget(ClassVisitor v) { @Override
public void setTarget(ClassVisitor v) {
super.setTarget(chain[0]); super.setTarget(chain[0]);
ClassVisitor next = v; ClassVisitor next = v;
for (int i = chain.length - 1; i >= 0; i--) { for (int i = chain.length - 1; i >= 0; i--) {
@@ -35,7 +36,8 @@ public class ClassTransformerChain extends AbstractClassTransformer {
} }
} }
public MethodVisitor visitMethod(int access, @Override
public MethodVisitor visitMethod(int access,
String name, String name,
String desc, String desc,
String signature, String signature,
@@ -43,7 +45,8 @@ public class ClassTransformerChain extends AbstractClassTransformer {
return cv.visitMethod(access, name, desc, signature, exceptions); return cv.visitMethod(access, name, desc, signature, exceptions);
} }
public String toString() { @Override
public String toString() {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
sb.append("ClassTransformerChain{"); sb.append("ClassTransformerChain{");
for (int i = 0; i < chain.length; i++) { for (int i = 0; i < chain.length; i++) {

View File

@@ -15,19 +15,20 @@
*/ */
package org.springframework.cglib.transform; package org.springframework.cglib.transform;
import org.springframework.asm.ClassVisitor;
import org.springframework.cglib.core.ClassTransformer; import org.springframework.cglib.core.ClassTransformer;
import org.springframework.cglib.core.Constants; import org.springframework.cglib.core.Constants;
import org.springframework.asm.ClassVisitor;
public class ClassTransformerTee extends ClassTransformer { public class ClassTransformerTee extends ClassTransformer {
private ClassVisitor branch; private ClassVisitor branch;
public ClassTransformerTee(ClassVisitor branch) { public ClassTransformerTee(ClassVisitor branch) {
super(Constants.ASM_API); super(Constants.ASM_API);
this.branch = branch; this.branch = branch;
} }
public void setTarget(ClassVisitor target) { @Override
public void setTarget(ClassVisitor target) {
cv = new ClassVisitorTee(branch, target); cv = new ClassVisitorTee(branch, target);
} }
} }

View File

@@ -25,14 +25,15 @@ import org.springframework.cglib.core.Constants;
public class ClassVisitorTee extends ClassVisitor { public class ClassVisitorTee extends ClassVisitor {
private ClassVisitor cv1, cv2; private ClassVisitor cv1, cv2;
public ClassVisitorTee(ClassVisitor cv1, ClassVisitor cv2) { public ClassVisitorTee(ClassVisitor cv1, ClassVisitor cv2) {
super(Constants.ASM_API); super(Constants.ASM_API);
this.cv1 = cv1; this.cv1 = cv1;
this.cv2 = cv2; this.cv2 = cv2;
} }
public void visit(int version, @Override
public void visit(int version,
int access, int access,
String name, String name,
String signature, String signature,
@@ -42,67 +43,80 @@ public class ClassVisitorTee extends ClassVisitor {
cv2.visit(version, access, name, signature, superName, interfaces); cv2.visit(version, access, name, signature, superName, interfaces);
} }
public void visitEnd() { @Override
public void visitEnd() {
cv1.visitEnd(); cv1.visitEnd();
cv2.visitEnd(); cv2.visitEnd();
cv1 = cv2 = null; cv1 = cv2 = null;
} }
public void visitInnerClass(String name, String outerName, String innerName, int access) { @Override
public void visitInnerClass(String name, String outerName, String innerName, int access) {
cv1.visitInnerClass(name, outerName, innerName, access); cv1.visitInnerClass(name, outerName, innerName, access);
cv2.visitInnerClass(name, outerName, innerName, access); cv2.visitInnerClass(name, outerName, innerName, access);
} }
public FieldVisitor visitField(int access, @Override
public FieldVisitor visitField(int access,
String name, String name,
String desc, String desc,
String signature, String signature,
Object value) { Object value) {
FieldVisitor fv1 = cv1.visitField(access, name, desc, signature, value); FieldVisitor fv1 = cv1.visitField(access, name, desc, signature, value);
FieldVisitor fv2 = cv2.visitField(access, name, desc, signature, value); FieldVisitor fv2 = cv2.visitField(access, name, desc, signature, value);
if (fv1 == null) if (fv1 == null) {
return fv2; return fv2;
if (fv2 == null) }
return fv1; if (fv2 == null) {
return fv1;
}
return new FieldVisitorTee(fv1, fv2); return new FieldVisitorTee(fv1, fv2);
} }
public MethodVisitor visitMethod(int access, @Override
public MethodVisitor visitMethod(int access,
String name, String name,
String desc, String desc,
String signature, String signature,
String[] exceptions) { String[] exceptions) {
MethodVisitor mv1 = cv1.visitMethod(access, name, desc, signature, exceptions); MethodVisitor mv1 = cv1.visitMethod(access, name, desc, signature, exceptions);
MethodVisitor mv2 = cv2.visitMethod(access, name, desc, signature, exceptions); MethodVisitor mv2 = cv2.visitMethod(access, name, desc, signature, exceptions);
if (mv1 == null) if (mv1 == null) {
return mv2; return mv2;
if (mv2 == null) }
return mv1; if (mv2 == null) {
return mv1;
}
return new MethodVisitorTee(mv1, mv2); return new MethodVisitorTee(mv1, mv2);
} }
public void visitSource(String source, String debug) { @Override
public void visitSource(String source, String debug) {
cv1.visitSource(source, debug); cv1.visitSource(source, debug);
cv2.visitSource(source, debug); cv2.visitSource(source, debug);
} }
public void visitOuterClass(String owner, String name, String desc) { @Override
public void visitOuterClass(String owner, String name, String desc) {
cv1.visitOuterClass(owner, name, desc); cv1.visitOuterClass(owner, name, desc);
cv2.visitOuterClass(owner, name, desc); cv2.visitOuterClass(owner, name, desc);
} }
public AnnotationVisitor visitAnnotation(String desc, boolean visible) { @Override
public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
return AnnotationVisitorTee.getInstance(cv1.visitAnnotation(desc, visible), return AnnotationVisitorTee.getInstance(cv1.visitAnnotation(desc, visible),
cv2.visitAnnotation(desc, visible)); cv2.visitAnnotation(desc, visible));
} }
public void visitAttribute(Attribute attrs) { @Override
public void visitAttribute(Attribute attrs) {
cv1.visitAttribute(attrs); cv1.visitAttribute(attrs);
cv2.visitAttribute(attrs); cv2.visitAttribute(attrs);
} }
public AnnotationVisitor visitTypeAnnotation(int typeRef, TypePath typePath, String desc, boolean visible) { @Override
public AnnotationVisitor visitTypeAnnotation(int typeRef, TypePath typePath, String desc, boolean visible) {
return AnnotationVisitorTee.getInstance(cv1.visitTypeAnnotation(typeRef, typePath, desc, visible), return AnnotationVisitorTee.getInstance(cv1.visitTypeAnnotation(typeRef, typePath, desc, visible),
cv2.visitTypeAnnotation(typeRef, typePath, desc, visible)); cv2.visitTypeAnnotation(typeRef, typePath, desc, visible));
} }

View File

@@ -15,37 +15,41 @@
*/ */
package org.springframework.cglib.transform; package org.springframework.cglib.transform;
import org.springframework.cglib.core.Constants;
import org.springframework.asm.AnnotationVisitor; import org.springframework.asm.AnnotationVisitor;
import org.springframework.asm.Attribute; import org.springframework.asm.Attribute;
import org.springframework.asm.FieldVisitor; import org.springframework.asm.FieldVisitor;
import org.springframework.asm.TypePath; import org.springframework.asm.TypePath;
import org.springframework.cglib.core.Constants;
public class FieldVisitorTee extends FieldVisitor { public class FieldVisitorTee extends FieldVisitor {
private FieldVisitor fv1, fv2; private FieldVisitor fv1, fv2;
public FieldVisitorTee(FieldVisitor fv1, FieldVisitor fv2) { public FieldVisitorTee(FieldVisitor fv1, FieldVisitor fv2) {
super(Constants.ASM_API); super(Constants.ASM_API);
this.fv1 = fv1; this.fv1 = fv1;
this.fv2 = fv2; this.fv2 = fv2;
} }
public AnnotationVisitor visitAnnotation(String desc, boolean visible) { @Override
public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
return AnnotationVisitorTee.getInstance(fv1.visitAnnotation(desc, visible), return AnnotationVisitorTee.getInstance(fv1.visitAnnotation(desc, visible),
fv2.visitAnnotation(desc, visible)); fv2.visitAnnotation(desc, visible));
} }
public void visitAttribute(Attribute attr) { @Override
public void visitAttribute(Attribute attr) {
fv1.visitAttribute(attr); fv1.visitAttribute(attr);
fv2.visitAttribute(attr); fv2.visitAttribute(attr);
} }
public void visitEnd() { @Override
public void visitEnd() {
fv1.visitEnd(); fv1.visitEnd();
fv2.visitEnd(); fv2.visitEnd();
} }
public AnnotationVisitor visitTypeAnnotation(int typeRef, TypePath typePath, String desc, boolean visible) { @Override
public AnnotationVisitor visitTypeAnnotation(int typeRef, TypePath typePath, String desc, boolean visible) {
return AnnotationVisitorTee.getInstance(fv1.visitTypeAnnotation(typeRef, typePath, desc, visible), return AnnotationVisitorTee.getInstance(fv1.visitTypeAnnotation(typeRef, typePath, desc, visible),
fv2.visitTypeAnnotation(typeRef, typePath, desc, visible)); fv2.visitTypeAnnotation(typeRef, typePath, desc, visible));
} }

View File

@@ -23,22 +23,24 @@ public class MethodFilterTransformer extends AbstractClassTransformer {
private MethodFilter filter; private MethodFilter filter;
private ClassTransformer pass; private ClassTransformer pass;
private ClassVisitor direct; private ClassVisitor direct;
public MethodFilterTransformer(MethodFilter filter, ClassTransformer pass) { public MethodFilterTransformer(MethodFilter filter, ClassTransformer pass) {
this.filter = filter; this.filter = filter;
this.pass = pass; this.pass = pass;
super.setTarget(pass); super.setTarget(pass);
} }
public MethodVisitor visitMethod(int access, @Override
public MethodVisitor visitMethod(int access,
String name, String name,
String desc, String desc,
String signature, String signature,
String[] exceptions) { String[] exceptions) {
return (filter.accept(access, name, desc, signature, exceptions) ? pass : direct).visitMethod(access, name, desc, signature, exceptions); return (filter.accept(access, name, desc, signature, exceptions) ? pass : direct).visitMethod(access, name, desc, signature, exceptions);
} }
public void setTarget(ClassVisitor target) { @Override
public void setTarget(ClassVisitor target) {
pass.setTarget(target); pass.setTarget(target);
direct = target; direct = target;
} }

View File

@@ -27,166 +27,197 @@ import org.springframework.cglib.core.Constants;
public class MethodVisitorTee extends MethodVisitor { public class MethodVisitorTee extends MethodVisitor {
private final MethodVisitor mv1; private final MethodVisitor mv1;
private final MethodVisitor mv2; private final MethodVisitor mv2;
public MethodVisitorTee(MethodVisitor mv1, MethodVisitor mv2) { public MethodVisitorTee(MethodVisitor mv1, MethodVisitor mv2) {
super(Constants.ASM_API); super(Constants.ASM_API);
this.mv1 = mv1; this.mv1 = mv1;
this.mv2 = mv2; this.mv2 = mv2;
} }
public void visitFrame(int type, int nLocal, Object[] local, int nStack, Object[] stack) { @Override
public void visitFrame(int type, int nLocal, Object[] local, int nStack, Object[] stack) {
mv1.visitFrame(type, nLocal, local, nStack, stack); mv1.visitFrame(type, nLocal, local, nStack, stack);
mv2.visitFrame(type, nLocal, local, nStack, stack); mv2.visitFrame(type, nLocal, local, nStack, stack);
} }
public AnnotationVisitor visitAnnotationDefault() { @Override
public AnnotationVisitor visitAnnotationDefault() {
return AnnotationVisitorTee.getInstance(mv1.visitAnnotationDefault(), return AnnotationVisitorTee.getInstance(mv1.visitAnnotationDefault(),
mv2.visitAnnotationDefault()); mv2.visitAnnotationDefault());
} }
public AnnotationVisitor visitAnnotation(String desc, boolean visible) { @Override
public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
return AnnotationVisitorTee.getInstance(mv1.visitAnnotation(desc, visible), return AnnotationVisitorTee.getInstance(mv1.visitAnnotation(desc, visible),
mv2.visitAnnotation(desc, visible)); mv2.visitAnnotation(desc, visible));
} }
public AnnotationVisitor visitParameterAnnotation(int parameter, @Override
public AnnotationVisitor visitParameterAnnotation(int parameter,
String desc, String desc,
boolean visible) { boolean visible) {
return AnnotationVisitorTee.getInstance(mv1.visitParameterAnnotation(parameter, desc, visible), return AnnotationVisitorTee.getInstance(mv1.visitParameterAnnotation(parameter, desc, visible),
mv2.visitParameterAnnotation(parameter, desc, visible)); mv2.visitParameterAnnotation(parameter, desc, visible));
} }
public void visitAttribute(Attribute attr) { @Override
public void visitAttribute(Attribute attr) {
mv1.visitAttribute(attr); mv1.visitAttribute(attr);
mv2.visitAttribute(attr); mv2.visitAttribute(attr);
} }
public void visitCode() { @Override
public void visitCode() {
mv1.visitCode(); mv1.visitCode();
mv2.visitCode(); mv2.visitCode();
} }
public void visitInsn(int opcode) { @Override
public void visitInsn(int opcode) {
mv1.visitInsn(opcode); mv1.visitInsn(opcode);
mv2.visitInsn(opcode); mv2.visitInsn(opcode);
} }
public void visitIntInsn(int opcode, int operand) { @Override
public void visitIntInsn(int opcode, int operand) {
mv1.visitIntInsn(opcode, operand); mv1.visitIntInsn(opcode, operand);
mv2.visitIntInsn(opcode, operand); mv2.visitIntInsn(opcode, operand);
} }
public void visitVarInsn(int opcode, int var) { @Override
public void visitVarInsn(int opcode, int var) {
mv1.visitVarInsn(opcode, var); mv1.visitVarInsn(opcode, var);
mv2.visitVarInsn(opcode, var); mv2.visitVarInsn(opcode, var);
} }
public void visitTypeInsn(int opcode, String desc) { @Override
public void visitTypeInsn(int opcode, String desc) {
mv1.visitTypeInsn(opcode, desc); mv1.visitTypeInsn(opcode, desc);
mv2.visitTypeInsn(opcode, desc); mv2.visitTypeInsn(opcode, desc);
} }
public void visitFieldInsn(int opcode, String owner, String name, String desc) { @Override
public void visitFieldInsn(int opcode, String owner, String name, String desc) {
mv1.visitFieldInsn(opcode, owner, name, desc); mv1.visitFieldInsn(opcode, owner, name, desc);
mv2.visitFieldInsn(opcode, owner, name, desc); mv2.visitFieldInsn(opcode, owner, name, desc);
} }
public void visitMethodInsn(int opcode, String owner, String name, String desc) { @Override
public void visitMethodInsn(int opcode, String owner, String name, String desc) {
mv1.visitMethodInsn(opcode, owner, name, desc); mv1.visitMethodInsn(opcode, owner, name, desc);
mv2.visitMethodInsn(opcode, owner, name, desc); mv2.visitMethodInsn(opcode, owner, name, desc);
} }
public void visitMethodInsn(int opcode, String owner, String name, String desc, boolean itf) { @Override
public void visitMethodInsn(int opcode, String owner, String name, String desc, boolean itf) {
mv1.visitMethodInsn(opcode, owner, name, desc, itf); mv1.visitMethodInsn(opcode, owner, name, desc, itf);
mv2.visitMethodInsn(opcode, owner, name, desc, itf); mv2.visitMethodInsn(opcode, owner, name, desc, itf);
} }
public void visitJumpInsn(int opcode, Label label) { @Override
public void visitJumpInsn(int opcode, Label label) {
mv1.visitJumpInsn(opcode, label); mv1.visitJumpInsn(opcode, label);
mv2.visitJumpInsn(opcode, label); mv2.visitJumpInsn(opcode, label);
} }
public void visitLabel(Label label) { @Override
public void visitLabel(Label label) {
mv1.visitLabel(label); mv1.visitLabel(label);
mv2.visitLabel(label); mv2.visitLabel(label);
} }
public void visitLdcInsn(Object cst) { @Override
public void visitLdcInsn(Object cst) {
mv1.visitLdcInsn(cst); mv1.visitLdcInsn(cst);
mv2.visitLdcInsn(cst); mv2.visitLdcInsn(cst);
} }
public void visitIincInsn(int var, int increment) { @Override
public void visitIincInsn(int var, int increment) {
mv1.visitIincInsn(var, increment); mv1.visitIincInsn(var, increment);
mv2.visitIincInsn(var, increment); mv2.visitIincInsn(var, increment);
} }
public void visitTableSwitchInsn(int min, int max, Label dflt, Label... labels) { @Override
public void visitTableSwitchInsn(int min, int max, Label dflt, Label... labels) {
mv1.visitTableSwitchInsn(min, max, dflt, labels); mv1.visitTableSwitchInsn(min, max, dflt, labels);
mv2.visitTableSwitchInsn(min, max, dflt, labels); mv2.visitTableSwitchInsn(min, max, dflt, labels);
} }
public void visitLookupSwitchInsn(Label dflt, int[] keys, Label[] labels) { @Override
public void visitLookupSwitchInsn(Label dflt, int[] keys, Label[] labels) {
mv1.visitLookupSwitchInsn(dflt, keys, labels); mv1.visitLookupSwitchInsn(dflt, keys, labels);
mv2.visitLookupSwitchInsn(dflt, keys, labels); mv2.visitLookupSwitchInsn(dflt, keys, labels);
} }
public void visitMultiANewArrayInsn(String desc, int dims) { @Override
public void visitMultiANewArrayInsn(String desc, int dims) {
mv1.visitMultiANewArrayInsn(desc, dims); mv1.visitMultiANewArrayInsn(desc, dims);
mv2.visitMultiANewArrayInsn(desc, dims); mv2.visitMultiANewArrayInsn(desc, dims);
} }
public void visitTryCatchBlock(Label start, Label end, Label handler, String type) { @Override
public void visitTryCatchBlock(Label start, Label end, Label handler, String type) {
mv1.visitTryCatchBlock(start, end, handler, type); mv1.visitTryCatchBlock(start, end, handler, type);
mv2.visitTryCatchBlock(start, end, handler, type); mv2.visitTryCatchBlock(start, end, handler, type);
} }
public void visitLocalVariable(String name, String desc, String signature, Label start, Label end, int index) { @Override
public void visitLocalVariable(String name, String desc, String signature, Label start, Label end, int index) {
mv1.visitLocalVariable(name, desc, signature, start, end, index); mv1.visitLocalVariable(name, desc, signature, start, end, index);
mv2.visitLocalVariable(name, desc, signature, start, end, index); mv2.visitLocalVariable(name, desc, signature, start, end, index);
} }
public void visitLineNumber(int line, Label start) { @Override
public void visitLineNumber(int line, Label start) {
mv1.visitLineNumber(line, start); mv1.visitLineNumber(line, start);
mv2.visitLineNumber(line, start); mv2.visitLineNumber(line, start);
} }
public void visitMaxs(int maxStack, int maxLocals) { @Override
public void visitMaxs(int maxStack, int maxLocals) {
mv1.visitMaxs(maxStack, maxLocals); mv1.visitMaxs(maxStack, maxLocals);
mv2.visitMaxs(maxStack, maxLocals); mv2.visitMaxs(maxStack, maxLocals);
} }
public void visitEnd() { @Override
public void visitEnd() {
mv1.visitEnd(); mv1.visitEnd();
mv2.visitEnd(); mv2.visitEnd();
} }
public void visitParameter(String name, int access) { @Override
public void visitParameter(String name, int access) {
mv1.visitParameter(name, access); mv1.visitParameter(name, access);
mv2.visitParameter(name, access); mv2.visitParameter(name, access);
} }
public AnnotationVisitor visitTypeAnnotation(int typeRef, TypePath typePath, String desc, boolean visible) { @Override
public AnnotationVisitor visitTypeAnnotation(int typeRef, TypePath typePath, String desc, boolean visible) {
return AnnotationVisitorTee.getInstance(mv1.visitTypeAnnotation(typeRef, typePath, desc, visible), return AnnotationVisitorTee.getInstance(mv1.visitTypeAnnotation(typeRef, typePath, desc, visible),
mv2.visitTypeAnnotation(typeRef, typePath, desc, visible)); mv2.visitTypeAnnotation(typeRef, typePath, desc, visible));
} }
public void visitInvokeDynamicInsn(String name, String desc, Handle bsm, Object... bsmArgs) { @Override
public void visitInvokeDynamicInsn(String name, String desc, Handle bsm, Object... bsmArgs) {
mv1.visitInvokeDynamicInsn(name, desc, bsm, bsmArgs); mv1.visitInvokeDynamicInsn(name, desc, bsm, bsmArgs);
mv2.visitInvokeDynamicInsn(name, desc, bsm, bsmArgs); mv2.visitInvokeDynamicInsn(name, desc, bsm, bsmArgs);
} }
public AnnotationVisitor visitInsnAnnotation(int typeRef, TypePath typePath, String desc, boolean visible) { @Override
public AnnotationVisitor visitInsnAnnotation(int typeRef, TypePath typePath, String desc, boolean visible) {
return AnnotationVisitorTee.getInstance(mv1.visitInsnAnnotation(typeRef, typePath, desc, visible), return AnnotationVisitorTee.getInstance(mv1.visitInsnAnnotation(typeRef, typePath, desc, visible),
mv2.visitInsnAnnotation(typeRef, typePath, desc, visible)); mv2.visitInsnAnnotation(typeRef, typePath, desc, visible));
} }
public AnnotationVisitor visitTryCatchAnnotation(int typeRef, TypePath typePath, String desc, boolean visible) { @Override
public AnnotationVisitor visitTryCatchAnnotation(int typeRef, TypePath typePath, String desc, boolean visible) {
return AnnotationVisitorTee.getInstance(mv1.visitTryCatchAnnotation(typeRef, typePath, desc, visible), return AnnotationVisitorTee.getInstance(mv1.visitTryCatchAnnotation(typeRef, typePath, desc, visible),
mv2.visitTryCatchAnnotation(typeRef, typePath, desc, visible)); mv2.visitTryCatchAnnotation(typeRef, typePath, desc, visible));
} }
public AnnotationVisitor visitLocalVariableAnnotation(int typeRef, TypePath typePath, Label[] start, Label[] end, int[] index, String desc, boolean visible) { @Override
public AnnotationVisitor visitLocalVariableAnnotation(int typeRef, TypePath typePath, Label[] start, Label[] end, int[] index, String desc, boolean visible) {
return AnnotationVisitorTee.getInstance(mv1.visitLocalVariableAnnotation(typeRef, typePath, start, end, index, desc, visible), return AnnotationVisitorTee.getInstance(mv1.visitLocalVariableAnnotation(typeRef, typePath, start, end, index, desc, visible),
mv2.visitLocalVariableAnnotation(typeRef, typePath, start, end, index, desc, visible)); mv2.visitLocalVariableAnnotation(typeRef, typePath, start, end, index, desc, visible));
} }

View File

@@ -19,24 +19,42 @@ package org.springframework.cglib.transform.impl;
* @author Chris Nokleberg * @author Chris Nokleberg
*/ */
public class AbstractInterceptFieldCallback implements InterceptFieldCallback { public class AbstractInterceptFieldCallback implements InterceptFieldCallback {
public int writeInt(Object obj, String name, int oldValue, int newValue) { return newValue; }
public char writeChar(Object obj, String name, char oldValue, char newValue) { return newValue; }
public byte writeByte(Object obj, String name, byte oldValue, byte newValue) { return newValue; }
public boolean writeBoolean(Object obj, String name, boolean oldValue, boolean newValue) { return newValue; }
public short writeShort(Object obj, String name, short oldValue, short newValue) { return newValue; }
public float writeFloat(Object obj, String name, float oldValue, float newValue) { return newValue; }
public double writeDouble(Object obj, String name, double oldValue, double newValue) { return newValue; }
public long writeLong(Object obj, String name, long oldValue, long newValue) { return newValue; }
public Object writeObject(Object obj, String name, Object oldValue, Object newValue) { return newValue; }
public int readInt(Object obj, String name, int oldValue) { return oldValue; } @Override
public char readChar(Object obj, String name, char oldValue) { return oldValue; } public int writeInt(Object obj, String name, int oldValue, int newValue) { return newValue; }
public byte readByte(Object obj, String name, byte oldValue) { return oldValue; } @Override
public boolean readBoolean(Object obj, String name, boolean oldValue) { return oldValue; } public char writeChar(Object obj, String name, char oldValue, char newValue) { return newValue; }
public short readShort(Object obj, String name, short oldValue) { return oldValue; } @Override
public float readFloat(Object obj, String name, float oldValue) { return oldValue; } public byte writeByte(Object obj, String name, byte oldValue, byte newValue) { return newValue; }
public double readDouble(Object obj, String name, double oldValue) { return oldValue; } @Override
public long readLong(Object obj, String name, long oldValue) { return oldValue; } public boolean writeBoolean(Object obj, String name, boolean oldValue, boolean newValue) { return newValue; }
public Object readObject(Object obj, String name, Object oldValue) { return oldValue; } @Override
public short writeShort(Object obj, String name, short oldValue, short newValue) { return newValue; }
@Override
public float writeFloat(Object obj, String name, float oldValue, float newValue) { return newValue; }
@Override
public double writeDouble(Object obj, String name, double oldValue, double newValue) { return newValue; }
@Override
public long writeLong(Object obj, String name, long oldValue, long newValue) { return newValue; }
@Override
public Object writeObject(Object obj, String name, Object oldValue, Object newValue) { return newValue; }
@Override
public int readInt(Object obj, String name, int oldValue) { return oldValue; }
@Override
public char readChar(Object obj, String name, char oldValue) { return oldValue; }
@Override
public byte readByte(Object obj, String name, byte oldValue) { return oldValue; }
@Override
public boolean readBoolean(Object obj, String name, boolean oldValue) { return oldValue; }
@Override
public short readShort(Object obj, String name, short oldValue) { return oldValue; }
@Override
public float readFloat(Object obj, String name, float oldValue) { return oldValue; }
@Override
public double readDouble(Object obj, String name, double oldValue) { return oldValue; }
@Override
public long readLong(Object obj, String name, long oldValue) { return oldValue; }
@Override
public Object readObject(Object obj, String name, Object oldValue) { return oldValue; }
} }

View File

@@ -65,11 +65,11 @@ public class AddDelegateTransformer extends ClassEmitterTransformer {
DELEGATE, DELEGATE,
delegateType, delegateType,
null); null);
for (int i = 0; i < delegateIf.length; i++) { for (Class element : delegateIf) {
Method[] methods = delegateIf[i].getMethods(); Method[] methods = element.getMethods();
for (int j = 0; j < methods.length; j++) { for (Method method : methods) {
if (Modifier.isAbstract(methods[j].getModifiers())) { if (Modifier.isAbstract(method.getModifiers())) {
addDelegate(methods[j]); addDelegate(method);
} }
} }
} }

View File

@@ -15,10 +15,12 @@
*/ */
package org.springframework.cglib.transform.impl; package org.springframework.cglib.transform.impl;
import org.springframework.cglib.transform.*; import java.util.Map;
import java.util.*;
import org.springframework.cglib.core.*;
import org.springframework.asm.Type; import org.springframework.asm.Type;
import org.springframework.cglib.core.EmitUtils;
import org.springframework.cglib.core.TypeUtils;
import org.springframework.cglib.transform.ClassEmitterTransformer;
@SuppressWarnings({"rawtypes", "unchecked"}) @SuppressWarnings({"rawtypes", "unchecked"})
public class AddPropertyTransformer extends ClassEmitterTransformer { public class AddPropertyTransformer extends ClassEmitterTransformer {
@@ -39,7 +41,8 @@ public class AddPropertyTransformer extends ClassEmitterTransformer {
this.types = types; this.types = types;
} }
public void end_class() { @Override
public void end_class() {
if (!TypeUtils.isAbstract(getAccess())) { if (!TypeUtils.isAbstract(getAccess())) {
EmitUtils.add_properties(this, names, types); EmitUtils.add_properties(this, names, types);
} }

View File

@@ -16,9 +16,15 @@
package org.springframework.cglib.transform.impl; package org.springframework.cglib.transform.impl;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import org.springframework.cglib.core.*;
import org.springframework.cglib.transform.*;
import org.springframework.asm.Type; import org.springframework.asm.Type;
import org.springframework.cglib.core.CodeEmitter;
import org.springframework.cglib.core.Constants;
import org.springframework.cglib.core.EmitUtils;
import org.springframework.cglib.core.MethodInfo;
import org.springframework.cglib.core.ReflectUtils;
import org.springframework.cglib.core.TypeUtils;
import org.springframework.cglib.transform.ClassEmitterTransformer;
/** /**
* @author Juozas Baliuka, Chris Nokleberg * @author Juozas Baliuka, Chris Nokleberg
@@ -39,7 +45,8 @@ public class AddStaticInitTransformer extends ClassEmitterTransformer {
} }
} }
protected void init() { @Override
protected void init() {
if (!TypeUtils.isInterface(getAccess())) { if (!TypeUtils.isInterface(getAccess())) {
CodeEmitter e = getStaticHook(); CodeEmitter e = getStaticHook();
EmitUtils.load_class_this(e); EmitUtils.load_class_this(e);

View File

@@ -17,17 +17,17 @@ package org.springframework.cglib.transform.impl;
@SuppressWarnings({"rawtypes", "unchecked"}) @SuppressWarnings({"rawtypes", "unchecked"})
public interface FieldProvider { public interface FieldProvider {
String[] getFieldNames(); String[] getFieldNames();
Class[] getFieldTypes(); Class[] getFieldTypes();
void setField(int index, Object value); void setField(int index, Object value);
Object getField(int index); Object getField(int index);
void setField(String name, Object value); void setField(String name, Object value);
Object getField(String name); Object getField(String name);
} }

View File

@@ -19,7 +19,7 @@ package org.springframework.cglib.transform.impl;
* @author Juozas Baliuka * @author Juozas Baliuka
*/ */
public interface InterceptFieldCallback { public interface InterceptFieldCallback {
int writeInt(Object obj, String name, int oldValue, int newValue); int writeInt(Object obj, String name, int oldValue, int newValue);
char writeChar(Object obj, String name, char oldValue, char newValue); char writeChar(Object obj, String name, char oldValue, char newValue);
byte writeByte(Object obj, String name, byte oldValue, byte newValue); byte writeByte(Object obj, String name, byte oldValue, byte newValue);

View File

@@ -15,10 +15,14 @@
*/ */
package org.springframework.cglib.transform.impl; package org.springframework.cglib.transform.impl;
import org.springframework.cglib.transform.*;
import org.springframework.cglib.core.*;
import org.springframework.asm.Label; import org.springframework.asm.Label;
import org.springframework.asm.Type; import org.springframework.asm.Type;
import org.springframework.cglib.core.CodeEmitter;
import org.springframework.cglib.core.Constants;
import org.springframework.cglib.core.Local;
import org.springframework.cglib.core.Signature;
import org.springframework.cglib.core.TypeUtils;
import org.springframework.cglib.transform.ClassEmitterTransformer;
/** /**
* @author Juozas Baliuka, Chris Nokleberg * @author Juozas Baliuka, Chris Nokleberg
@@ -35,15 +39,16 @@ public class InterceptFieldTransformer extends ClassEmitterTransformer {
new Signature("getInterceptFieldCallback", CALLBACK, new Type[0]); new Signature("getInterceptFieldCallback", CALLBACK, new Type[0]);
private InterceptFieldFilter filter; private InterceptFieldFilter filter;
public InterceptFieldTransformer(InterceptFieldFilter filter) { public InterceptFieldTransformer(InterceptFieldFilter filter) {
this.filter = filter; this.filter = filter;
} }
public void begin_class(int version, int access, String className, Type superType, Type[] interfaces, String sourceFile) { @Override
public void begin_class(int version, int access, String className, Type superType, Type[] interfaces, String sourceFile) {
if (!TypeUtils.isInterface(access)) { if (!TypeUtils.isInterface(access)) {
super.begin_class(version, access, className, superType, TypeUtils.add(interfaces, ENABLED), sourceFile); super.begin_class(version, access, className, superType, TypeUtils.add(interfaces, ENABLED), sourceFile);
super.declare_field(Constants.ACC_PRIVATE | Constants.ACC_TRANSIENT, super.declare_field(Constants.ACC_PRIVATE | Constants.ACC_TRANSIENT,
CALLBACK_FIELD, CALLBACK_FIELD,
CALLBACK, CALLBACK,
@@ -55,7 +60,7 @@ public class InterceptFieldTransformer extends ClassEmitterTransformer {
e.getfield(CALLBACK_FIELD); e.getfield(CALLBACK_FIELD);
e.return_value(); e.return_value();
e.end_method(); e.end_method();
e = super.begin_method(Constants.ACC_PUBLIC, ENABLED_SET, null); e = super.begin_method(Constants.ACC_PUBLIC, ENABLED_SET, null);
e.load_this(); e.load_this();
e.load_arg(0); e.load_arg(0);
@@ -67,7 +72,8 @@ public class InterceptFieldTransformer extends ClassEmitterTransformer {
} }
} }
public void declare_field(int access, String name, Type type, Object value) { @Override
public void declare_field(int access, String name, Type type, Object value) {
super.declare_field(access, name, type, value); super.declare_field(access, name, type, value);
if (!TypeUtils.isStatic(access)) { if (!TypeUtils.isStatic(access)) {
if (filter.acceptRead(getClassType(), name)) { if (filter.acceptRead(getClassType(), name)) {
@@ -137,10 +143,12 @@ public class InterceptFieldTransformer extends ClassEmitterTransformer {
e.return_value(); e.return_value();
e.end_method(); e.end_method();
} }
public CodeEmitter begin_method(int access, Signature sig, Type[] exceptions) { @Override
public CodeEmitter begin_method(int access, Signature sig, Type[] exceptions) {
return new CodeEmitter(super.begin_method(access, sig, exceptions)) { return new CodeEmitter(super.begin_method(access, sig, exceptions)) {
public void visitFieldInsn(int opcode, String owner, String name, String desc) { @Override
public void visitFieldInsn(int opcode, String owner, String name, String desc) {
Type towner = TypeUtils.fromInternalName(owner); Type towner = TypeUtils.fromInternalName(owner);
switch (opcode) { switch (opcode) {
case Constants.GETFIELD: case Constants.GETFIELD:

View File

@@ -16,10 +16,10 @@
package org.springframework.cglib.transform.impl; package org.springframework.cglib.transform.impl;
import org.springframework.cglib.core.ClassGenerator; import org.springframework.cglib.core.ClassGenerator;
import org.springframework.cglib.core.ClassTransformer;
import org.springframework.cglib.core.DefaultGeneratorStrategy; import org.springframework.cglib.core.DefaultGeneratorStrategy;
import org.springframework.cglib.core.GeneratorStrategy; import org.springframework.cglib.core.GeneratorStrategy;
import org.springframework.cglib.core.TypeUtils; import org.springframework.cglib.core.TypeUtils;
import org.springframework.cglib.core.ClassTransformer;
import org.springframework.cglib.transform.MethodFilter; import org.springframework.cglib.transform.MethodFilter;
import org.springframework.cglib.transform.MethodFilterTransformer; import org.springframework.cglib.transform.MethodFilterTransformer;
import org.springframework.cglib.transform.TransformingClassGenerator; import org.springframework.cglib.transform.TransformingClassGenerator;
@@ -45,14 +45,11 @@ public class UndeclaredThrowableStrategy extends DefaultGeneratorStrategy {
public UndeclaredThrowableStrategy(Class wrapper) { public UndeclaredThrowableStrategy(Class wrapper) {
this.wrapper = wrapper; this.wrapper = wrapper;
} }
private static final MethodFilter TRANSFORM_FILTER = new MethodFilter() {
public boolean accept(int access, String name, String desc, String signature, String[] exceptions) {
return !TypeUtils.isPrivate(access) && name.indexOf('$') < 0;
}
};
protected ClassGenerator transform(ClassGenerator cg) throws Exception { private static final MethodFilter TRANSFORM_FILTER = (access, name, desc, signature, exceptions) -> !TypeUtils.isPrivate(access) && name.indexOf('$') < 0;
@Override
protected ClassGenerator transform(ClassGenerator cg) throws Exception {
ClassTransformer tr = new UndeclaredThrowableTransformer(wrapper); ClassTransformer tr = new UndeclaredThrowableTransformer(wrapper);
tr = new MethodFilterTransformer(TRANSFORM_FILTER, tr); tr = new MethodFilterTransformer(TRANSFORM_FILTER, tr);
return new TransformingClassGenerator(cg, tr); return new TransformingClassGenerator(cg, tr);

View File

@@ -36,15 +36,16 @@ public class UndeclaredThrowableTransformer extends ClassEmitterTransformer {
this.wrapper = Type.getType(wrapper); this.wrapper = Type.getType(wrapper);
boolean found = false; boolean found = false;
Constructor[] cstructs = wrapper.getConstructors(); Constructor[] cstructs = wrapper.getConstructors();
for (int i = 0; i < cstructs.length; i++) { for (Constructor cstruct : cstructs) {
Class[] types = cstructs[i].getParameterTypes(); Class[] types = cstruct.getParameterTypes();
if (types.length == 1 && types[0].equals(Throwable.class)) { if (types.length == 1 && types[0].equals(Throwable.class)) {
found = true; found = true;
break; break;
} }
} }
if (!found) if (!found) {
throw new IllegalArgumentException(wrapper + " does not have a single-arg constructor that takes a Throwable"); throw new IllegalArgumentException(wrapper + " does not have a single-arg constructor that takes a Throwable");
}
} }
@Override @Override

View File

@@ -290,9 +290,9 @@ abstract public class ParallelSorter extends SorterTemplate {
if (arrays.length == 0) { if (arrays.length == 0) {
throw new IllegalArgumentException("No arrays specified to sort"); throw new IllegalArgumentException("No arrays specified to sort");
} }
for (int i = 0; i < arrays.length; i++) { for (Object array : arrays) {
if (!arrays[i].getClass().isArray()) { if (!array.getClass().isArray()) {
throw new IllegalArgumentException(arrays[i].getClass() + " is not an array"); throw new IllegalArgumentException(array.getClass() + " is not an array");
} }
} }
new ParallelSorterEmitter(v, getClassName(), arrays); new ParallelSorterEmitter(v, getClassName(), arrays);

View File

@@ -50,10 +50,10 @@ abstract class SorterTemplate {
int v = j; int v = j;
for (;;) { for (;;) {
while (compare(++i, v) < 0) { while (compare(++i, v) < 0) {
/* nothing */; /* nothing */
} }
while (compare(--j, v) > 0) { while (compare(--j, v) > 0) {
/* nothing */; /* nothing */
} }
if (j < i) { if (j < i) {
break; break;