Polish CGLIB fork
- primarily automated "clean up" using Eclipse IDE
This commit is contained in:
@@ -16,12 +16,25 @@
|
||||
package org.springframework.cglib.beans;
|
||||
|
||||
import java.beans.PropertyDescriptor;
|
||||
import java.lang.reflect.*;
|
||||
import java.lang.reflect.Modifier;
|
||||
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.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
|
||||
@@ -39,7 +52,7 @@ abstract public class BeanCopier
|
||||
new Signature("copy", Type.VOID_TYPE, new Type[]{ Constants.TYPE_OBJECT, Constants.TYPE_OBJECT, CONVERTER });
|
||||
private static final Signature CONVERT =
|
||||
TypeUtils.parseSignature("Object convert(Object, Class, Object)");
|
||||
|
||||
|
||||
interface BeanCopierKey {
|
||||
public Object newInstance(String source, String target, boolean useConverter);
|
||||
}
|
||||
@@ -65,14 +78,14 @@ abstract public class BeanCopier
|
||||
}
|
||||
|
||||
public void setSource(Class source) {
|
||||
if(!Modifier.isPublic(source.getModifiers())){
|
||||
if(!Modifier.isPublic(source.getModifiers())){
|
||||
setNamePrefix(source.getName());
|
||||
}
|
||||
this.source = source;
|
||||
}
|
||||
|
||||
|
||||
public void setTarget(Class target) {
|
||||
if(!Modifier.isPublic(target.getModifiers())){
|
||||
if(!Modifier.isPublic(target.getModifiers())){
|
||||
setNamePrefix(target.getName());
|
||||
}
|
||||
this.target = target;
|
||||
@@ -85,11 +98,13 @@ abstract public class BeanCopier
|
||||
this.useConverter = useConverter;
|
||||
}
|
||||
|
||||
protected ClassLoader getDefaultClassLoader() {
|
||||
@Override
|
||||
protected ClassLoader getDefaultClassLoader() {
|
||||
return source.getClassLoader();
|
||||
}
|
||||
|
||||
protected ProtectionDomain getProtectionDomain() {
|
||||
@Override
|
||||
protected ProtectionDomain getProtectionDomain() {
|
||||
return ReflectUtils.getProtectionDomain(source);
|
||||
}
|
||||
|
||||
@@ -98,7 +113,8 @@ abstract public class BeanCopier
|
||||
return (BeanCopier)super.create(key);
|
||||
}
|
||||
|
||||
public void generateClass(ClassVisitor v) {
|
||||
@Override
|
||||
public void generateClass(ClassVisitor v) {
|
||||
Type sourceType = Type.getType(source);
|
||||
Type targetType = Type.getType(target);
|
||||
ClassEmitter ce = new ClassEmitter(v);
|
||||
@@ -115,8 +131,8 @@ abstract public class BeanCopier
|
||||
PropertyDescriptor[] setters = ReflectUtils.getBeanSetters(target);
|
||||
|
||||
Map names = new HashMap();
|
||||
for (int i = 0; i < getters.length; i++) {
|
||||
names.put(getters[i].getName(), getters[i]);
|
||||
for (PropertyDescriptor getter : getters) {
|
||||
names.put(getter.getName(), getter);
|
||||
}
|
||||
Local targetLocal = e.make_local();
|
||||
Local sourceLocal = e.make_local();
|
||||
@@ -124,7 +140,7 @@ abstract public class BeanCopier
|
||||
e.load_arg(1);
|
||||
e.checkcast(targetType);
|
||||
e.store_local(targetLocal);
|
||||
e.load_arg(0);
|
||||
e.load_arg(0);
|
||||
e.checkcast(sourceType);
|
||||
e.store_local(sourceLocal);
|
||||
} else {
|
||||
@@ -133,8 +149,7 @@ abstract public class BeanCopier
|
||||
e.load_arg(0);
|
||||
e.checkcast(sourceType);
|
||||
}
|
||||
for (int i = 0; i < setters.length; i++) {
|
||||
PropertyDescriptor setter = setters[i];
|
||||
for (PropertyDescriptor setter : setters) {
|
||||
PropertyDescriptor getter = (PropertyDescriptor)names.get(setter.getName());
|
||||
if (getter != null) {
|
||||
MethodInfo read = ReflectUtils.getMethodInfo(getter.getReadMethod());
|
||||
@@ -168,11 +183,13 @@ abstract public class BeanCopier
|
||||
return setter.getPropertyType().isAssignableFrom(getter.getPropertyType());
|
||||
}
|
||||
|
||||
protected Object firstInstance(Class type) {
|
||||
@Override
|
||||
protected Object firstInstance(Class type) {
|
||||
return ReflectUtils.newInstance(type);
|
||||
}
|
||||
|
||||
protected Object nextInstance(Object instance) {
|
||||
@Override
|
||||
protected Object nextInstance(Object instance) {
|
||||
return instance;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,10 +17,18 @@ package org.springframework.cglib.beans;
|
||||
|
||||
import java.beans.PropertyDescriptor;
|
||||
import java.security.ProtectionDomain;
|
||||
import java.util.*;
|
||||
import org.springframework.cglib.core.*;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.asm.ClassVisitor;
|
||||
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
|
||||
@@ -31,7 +39,7 @@ public class BeanGenerator extends AbstractClassGenerator
|
||||
private static final Source SOURCE = new Source(BeanGenerator.class.getName());
|
||||
private static final BeanGeneratorKey KEY_FACTORY =
|
||||
(BeanGeneratorKey)KeyFactory.create(BeanGeneratorKey.class);
|
||||
|
||||
|
||||
interface BeanGeneratorKey {
|
||||
public Object newInstance(String superclass, Map props);
|
||||
}
|
||||
@@ -67,7 +75,8 @@ public class BeanGenerator extends AbstractClassGenerator
|
||||
props.put(name, Type.getType(type));
|
||||
}
|
||||
|
||||
protected ClassLoader getDefaultClassLoader() {
|
||||
@Override
|
||||
protected ClassLoader getDefaultClassLoader() {
|
||||
if (superclass != null) {
|
||||
return superclass.getClassLoader();
|
||||
} else {
|
||||
@@ -75,7 +84,8 @@ public class BeanGenerator extends AbstractClassGenerator
|
||||
}
|
||||
}
|
||||
|
||||
protected ProtectionDomain getProtectionDomain() {
|
||||
@Override
|
||||
protected ProtectionDomain getProtectionDomain() {
|
||||
return ReflectUtils.getProtectionDomain(superclass);
|
||||
}
|
||||
|
||||
@@ -98,7 +108,8 @@ public class BeanGenerator extends AbstractClassGenerator
|
||||
return super.create(key);
|
||||
}
|
||||
|
||||
public void generateClass(ClassVisitor v) throws Exception {
|
||||
@Override
|
||||
public void generateClass(ClassVisitor v) throws Exception {
|
||||
int size = props.size();
|
||||
String[] names = (String[])props.keySet().toArray(new String[size]);
|
||||
Type[] types = new Type[size];
|
||||
@@ -117,7 +128,8 @@ public class BeanGenerator extends AbstractClassGenerator
|
||||
ce.end_class();
|
||||
}
|
||||
|
||||
protected Object firstInstance(Class type) {
|
||||
@Override
|
||||
protected Object firstInstance(Class type) {
|
||||
if (classOnly) {
|
||||
return type;
|
||||
} 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();
|
||||
if (classOnly) {
|
||||
return protoclass;
|
||||
@@ -146,8 +159,8 @@ public class BeanGenerator extends AbstractClassGenerator
|
||||
}
|
||||
|
||||
public static void addProperties(BeanGenerator gen, PropertyDescriptor[] descriptors) {
|
||||
for (int i = 0; i < descriptors.length; i++) {
|
||||
gen.addProperty(descriptors[i].getName(), descriptors[i].getPropertyType());
|
||||
for (PropertyDescriptor descriptor : descriptors) {
|
||||
gen.addProperty(descriptor.getName(), descriptor.getPropertyType());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -54,7 +54,7 @@ abstract public class BeanMap implements Map {
|
||||
* @see BeanMap.Generator#setRequire
|
||||
*/
|
||||
public static final int REQUIRE_SETTER = 2;
|
||||
|
||||
|
||||
/**
|
||||
* Helper method to create a new <code>BeanMap</code>. For finer
|
||||
* control over the generated instance, use a new instance of
|
||||
@@ -77,11 +77,11 @@ abstract public class BeanMap implements Map {
|
||||
interface BeanMapKey {
|
||||
public Object newInstance(Class type, int require);
|
||||
}
|
||||
|
||||
|
||||
private Object bean;
|
||||
private Class beanClass;
|
||||
private int require;
|
||||
|
||||
|
||||
public Generator() {
|
||||
super(SOURCE);
|
||||
}
|
||||
@@ -121,11 +121,13 @@ abstract public class BeanMap implements Map {
|
||||
this.require = require;
|
||||
}
|
||||
|
||||
protected ClassLoader getDefaultClassLoader() {
|
||||
@Override
|
||||
protected ClassLoader getDefaultClassLoader() {
|
||||
return beanClass.getClassLoader();
|
||||
}
|
||||
|
||||
protected ProtectionDomain getProtectionDomain() {
|
||||
@Override
|
||||
protected ProtectionDomain getProtectionDomain() {
|
||||
return ReflectUtils.getProtectionDomain(beanClass);
|
||||
}
|
||||
|
||||
@@ -134,21 +136,25 @@ abstract public class BeanMap implements Map {
|
||||
* generated class will be reused if possible.
|
||||
*/
|
||||
public BeanMap create() {
|
||||
if (beanClass == null)
|
||||
throw new IllegalArgumentException("Class of bean unknown");
|
||||
if (beanClass == null) {
|
||||
throw new IllegalArgumentException("Class of bean unknown");
|
||||
}
|
||||
setNamePrefix(beanClass.getName());
|
||||
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);
|
||||
}
|
||||
|
||||
protected Object firstInstance(Class type) {
|
||||
@Override
|
||||
protected Object firstInstance(Class type) {
|
||||
return ((BeanMap)ReflectUtils.newInstance(type)).newInstance(bean);
|
||||
}
|
||||
|
||||
protected Object nextInstance(Object instance) {
|
||||
@Override
|
||||
protected Object nextInstance(Object instance) {
|
||||
return ((BeanMap)instance).newInstance(bean);
|
||||
}
|
||||
}
|
||||
@@ -177,11 +183,13 @@ abstract public class BeanMap implements Map {
|
||||
setBean(bean);
|
||||
}
|
||||
|
||||
public Object get(Object key) {
|
||||
@Override
|
||||
public Object get(Object 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);
|
||||
}
|
||||
|
||||
@@ -223,52 +231,58 @@ abstract public class BeanMap implements Map {
|
||||
return bean;
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
@Override
|
||||
public void clear() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public boolean containsKey(Object key) {
|
||||
@Override
|
||||
public boolean containsKey(Object key) {
|
||||
return keySet().contains(key);
|
||||
}
|
||||
|
||||
public boolean containsValue(Object value) {
|
||||
@Override
|
||||
public boolean containsValue(Object value) {
|
||||
for (Iterator it = keySet().iterator(); it.hasNext();) {
|
||||
Object v = get(it.next());
|
||||
if (((value == null) && (v == null)) || (value != null && value.equals(v)))
|
||||
return true;
|
||||
if (((value == null) && (v == null)) || (value != null && value.equals(v))) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public int size() {
|
||||
@Override
|
||||
public int size() {
|
||||
return keySet().size();
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return size() == 0;
|
||||
}
|
||||
|
||||
public Object remove(Object key) {
|
||||
@Override
|
||||
public Object remove(Object key) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public void putAll(Map t) {
|
||||
for (Iterator it = t.keySet().iterator(); it.hasNext();) {
|
||||
Object key = it.next();
|
||||
@Override
|
||||
public void putAll(Map t) {
|
||||
for (Object key : t.keySet()) {
|
||||
put(key, t.get(key));
|
||||
}
|
||||
}
|
||||
|
||||
public boolean equals(Object o) {
|
||||
if (o == null || !(o instanceof Map)) {
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (o == null || !(o instanceof Map other)) {
|
||||
return false;
|
||||
}
|
||||
Map other = (Map)o;
|
||||
if (size() != other.size()) {
|
||||
return false;
|
||||
}
|
||||
for (Iterator it = keySet().iterator(); it.hasNext();) {
|
||||
Object key = it.next();
|
||||
for (Object key : keySet()) {
|
||||
if (!other.containsKey(key)) {
|
||||
return false;
|
||||
}
|
||||
@@ -281,10 +295,10 @@ abstract public class BeanMap implements Map {
|
||||
return true;
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int code = 0;
|
||||
for (Iterator it = keySet().iterator(); it.hasNext();) {
|
||||
Object key = it.next();
|
||||
for (Object key : keySet()) {
|
||||
Object value = get(key);
|
||||
code += ((key == null) ? 0 : key.hashCode()) ^
|
||||
((value == null) ? 0 : value.hashCode());
|
||||
@@ -293,16 +307,17 @@ abstract public class BeanMap implements Map {
|
||||
}
|
||||
|
||||
// TODO: optimize
|
||||
public Set entrySet() {
|
||||
@Override
|
||||
public Set entrySet() {
|
||||
HashMap copy = new HashMap();
|
||||
for (Iterator it = keySet().iterator(); it.hasNext();) {
|
||||
Object key = it.next();
|
||||
for (Object key : keySet()) {
|
||||
copy.put(key, get(key));
|
||||
}
|
||||
return Collections.unmodifiableMap(copy).entrySet();
|
||||
}
|
||||
|
||||
public Collection values() {
|
||||
@Override
|
||||
public Collection values() {
|
||||
Set keys = keySet();
|
||||
List values = new ArrayList(keys.size());
|
||||
for (Iterator it = keys.iterator(); it.hasNext();) {
|
||||
@@ -314,7 +329,8 @@ abstract public class BeanMap implements Map {
|
||||
/*
|
||||
* @see java.util.AbstractMap#toString
|
||||
*/
|
||||
public String toString()
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append('{');
|
||||
|
||||
@@ -15,12 +15,23 @@
|
||||
*/
|
||||
package org.springframework.cglib.beans;
|
||||
|
||||
import java.beans.*;
|
||||
import java.util.*;
|
||||
import org.springframework.cglib.core.*;
|
||||
import java.beans.PropertyDescriptor;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.asm.ClassVisitor;
|
||||
import org.springframework.asm.Label;
|
||||
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"})
|
||||
class BeanMapEmitter extends ClassEmitter {
|
||||
@@ -50,7 +61,7 @@ class BeanMapEmitter extends ClassEmitter {
|
||||
EmitUtils.null_constructor(this);
|
||||
EmitUtils.factory_method(this, NEW_INSTANCE);
|
||||
generateConstructor();
|
||||
|
||||
|
||||
Map getters = makePropertyMap(ReflectUtils.getBeanGetters(type));
|
||||
Map setters = makePropertyMap(ReflectUtils.getBeanSetters(type));
|
||||
Map allProps = new HashMap();
|
||||
@@ -79,8 +90,8 @@ class BeanMapEmitter extends ClassEmitter {
|
||||
|
||||
private Map makePropertyMap(PropertyDescriptor[] props) {
|
||||
Map names = new HashMap();
|
||||
for (int i = 0; i < props.length; i++) {
|
||||
names.put(props[i].getName(), props[i]);
|
||||
for (PropertyDescriptor prop : props) {
|
||||
names.put(prop.getName(), prop);
|
||||
}
|
||||
return names;
|
||||
}
|
||||
@@ -97,7 +108,7 @@ class BeanMapEmitter extends ClassEmitter {
|
||||
e.return_value();
|
||||
e.end_method();
|
||||
}
|
||||
|
||||
|
||||
private void generateGet(Class type, final Map getters) {
|
||||
final CodeEmitter e = begin_method(Constants.ACC_PUBLIC, BEAN_MAP_GET, null);
|
||||
e.load_arg(0);
|
||||
@@ -105,14 +116,16 @@ class BeanMapEmitter extends ClassEmitter {
|
||||
e.load_arg(1);
|
||||
e.checkcast(Constants.TYPE_STRING);
|
||||
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);
|
||||
MethodInfo method = ReflectUtils.getMethodInfo(pd.getReadMethod());
|
||||
e.invoke(method);
|
||||
e.box(method.getSignature().getReturnType());
|
||||
e.return_value();
|
||||
}
|
||||
public void processDefault() {
|
||||
@Override
|
||||
public void processDefault() {
|
||||
e.aconst_null();
|
||||
e.return_value();
|
||||
}
|
||||
@@ -127,7 +140,8 @@ class BeanMapEmitter extends ClassEmitter {
|
||||
e.load_arg(1);
|
||||
e.checkcast(Constants.TYPE_STRING);
|
||||
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);
|
||||
if (pd.getReadMethod() == null) {
|
||||
e.aconst_null();
|
||||
@@ -144,7 +158,8 @@ class BeanMapEmitter extends ClassEmitter {
|
||||
e.invoke(write);
|
||||
e.return_value();
|
||||
}
|
||||
public void processDefault() {
|
||||
@Override
|
||||
public void processDefault() {
|
||||
// fall-through
|
||||
}
|
||||
});
|
||||
@@ -152,7 +167,7 @@ class BeanMapEmitter extends ClassEmitter {
|
||||
e.return_value();
|
||||
e.end_method();
|
||||
}
|
||||
|
||||
|
||||
private void generateKeySet(String[] allNames) {
|
||||
// static initializer
|
||||
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);
|
||||
e.load_arg(0);
|
||||
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);
|
||||
EmitUtils.load_class(e, Type.getType(pd.getPropertyType()));
|
||||
e.return_value();
|
||||
}
|
||||
public void processDefault() {
|
||||
@Override
|
||||
public void processDefault() {
|
||||
e.aconst_null();
|
||||
e.return_value();
|
||||
}
|
||||
|
||||
@@ -16,8 +16,11 @@
|
||||
package org.springframework.cglib.beans;
|
||||
|
||||
import java.security.ProtectionDomain;
|
||||
import org.springframework.cglib.core.*;
|
||||
|
||||
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
|
||||
@@ -27,17 +30,17 @@ abstract public class BulkBean
|
||||
{
|
||||
private static final BulkBeanKey KEY_FACTORY =
|
||||
(BulkBeanKey)KeyFactory.create(BulkBeanKey.class);
|
||||
|
||||
|
||||
interface BulkBeanKey {
|
||||
public Object newInstance(String target, String[] getters, String[] setters, String[] types);
|
||||
}
|
||||
|
||||
|
||||
protected Class target;
|
||||
protected String[] getters, setters;
|
||||
protected Class[] types;
|
||||
|
||||
|
||||
protected BulkBean() { }
|
||||
|
||||
|
||||
abstract public void getPropertyValues(Object bean, Object[] values);
|
||||
abstract public void setPropertyValues(Object bean, Object[] values);
|
||||
|
||||
@@ -46,15 +49,15 @@ abstract public class BulkBean
|
||||
getPropertyValues(bean, values);
|
||||
return values;
|
||||
}
|
||||
|
||||
|
||||
public Class[] getPropertyTypes() {
|
||||
return types.clone();
|
||||
}
|
||||
|
||||
|
||||
public String[] getGetters() {
|
||||
return getters.clone();
|
||||
}
|
||||
|
||||
|
||||
public String[] getSetters() {
|
||||
return setters.clone();
|
||||
}
|
||||
@@ -98,11 +101,13 @@ abstract public class BulkBean
|
||||
this.types = types;
|
||||
}
|
||||
|
||||
protected ClassLoader getDefaultClassLoader() {
|
||||
@Override
|
||||
protected ClassLoader getDefaultClassLoader() {
|
||||
return target.getClassLoader();
|
||||
}
|
||||
|
||||
protected ProtectionDomain getProtectionDomain() {
|
||||
@Override
|
||||
protected ProtectionDomain getProtectionDomain() {
|
||||
return ReflectUtils.getProtectionDomain(target);
|
||||
}
|
||||
|
||||
@@ -114,28 +119,31 @@ abstract public class BulkBean
|
||||
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);
|
||||
}
|
||||
|
||||
protected Object firstInstance(Class type) {
|
||||
@Override
|
||||
protected Object firstInstance(Class type) {
|
||||
BulkBean instance = (BulkBean)ReflectUtils.newInstance(type);
|
||||
instance.target = target;
|
||||
|
||||
|
||||
int length = getters.length;
|
||||
instance.getters = new String[length];
|
||||
System.arraycopy(getters, 0, instance.getters, 0, length);
|
||||
|
||||
|
||||
instance.setters = new String[length];
|
||||
System.arraycopy(setters, 0, instance.setters, 0, length);
|
||||
|
||||
|
||||
instance.types = new Class[types.length];
|
||||
System.arraycopy(types, 0, instance.types, 0, types.length);
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
protected Object nextInstance(Object instance) {
|
||||
@Override
|
||||
protected Object nextInstance(Object instance) {
|
||||
return instance;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,9 +17,19 @@ package org.springframework.cglib.beans;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
import org.springframework.cglib.core.*;
|
||||
|
||||
import org.springframework.asm.ClassVisitor;
|
||||
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"})
|
||||
class BulkBeanEmitter extends ClassEmitter {
|
||||
@@ -33,7 +43,7 @@ class BulkBeanEmitter extends ClassEmitter {
|
||||
TypeUtils.parseType("org.springframework.cglib.beans.BulkBean");
|
||||
private static final Type BULK_BEAN_EXCEPTION =
|
||||
TypeUtils.parseType("org.springframework.cglib.beans.BulkBeanException");
|
||||
|
||||
|
||||
public BulkBeanEmitter(ClassVisitor v,
|
||||
String className,
|
||||
Class target,
|
||||
@@ -116,7 +126,7 @@ class BulkBeanEmitter extends ClassEmitter {
|
||||
}
|
||||
e.end_method();
|
||||
}
|
||||
|
||||
|
||||
private static void validate(Class target,
|
||||
String[] getters,
|
||||
String[] setters,
|
||||
|
||||
@@ -20,7 +20,7 @@ public class BulkBeanException extends RuntimeException
|
||||
{
|
||||
private int index;
|
||||
private Throwable cause;
|
||||
|
||||
|
||||
public BulkBeanException(String message, int index) {
|
||||
super(message);
|
||||
this.index = index;
|
||||
@@ -35,8 +35,9 @@ public class BulkBeanException extends RuntimeException
|
||||
public int getIndex() {
|
||||
return index;
|
||||
}
|
||||
|
||||
public Throwable getCause() {
|
||||
|
||||
@Override
|
||||
public Throwable getCause() {
|
||||
return cause;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,7 +15,12 @@
|
||||
*/
|
||||
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"})
|
||||
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)));
|
||||
}
|
||||
|
||||
public Iterator iterator() {
|
||||
@Override
|
||||
public Iterator iterator() {
|
||||
return set.iterator();
|
||||
}
|
||||
|
||||
public int size() {
|
||||
@Override
|
||||
public int size() {
|
||||
return size;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,9 +18,18 @@ package org.springframework.cglib.beans;
|
||||
import java.beans.PropertyDescriptor;
|
||||
import java.lang.reflect.Method;
|
||||
import java.security.ProtectionDomain;
|
||||
import org.springframework.cglib.core.*;
|
||||
|
||||
import org.springframework.asm.ClassVisitor;
|
||||
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
|
||||
*/
|
||||
@@ -60,11 +69,13 @@ public class ImmutableBean
|
||||
// SPRING PATCH END
|
||||
}
|
||||
|
||||
protected ClassLoader getDefaultClassLoader() {
|
||||
@Override
|
||||
protected ClassLoader getDefaultClassLoader() {
|
||||
return target.getClassLoader();
|
||||
}
|
||||
|
||||
protected ProtectionDomain getProtectionDomain() {
|
||||
@Override
|
||||
protected ProtectionDomain getProtectionDomain() {
|
||||
return ReflectUtils.getProtectionDomain(target);
|
||||
}
|
||||
|
||||
@@ -74,7 +85,8 @@ public class ImmutableBean
|
||||
return super.create(name);
|
||||
}
|
||||
|
||||
public void generateClass(ClassVisitor v) {
|
||||
@Override
|
||||
public void generateClass(ClassVisitor v) {
|
||||
Type targetType = Type.getType(target);
|
||||
ClassEmitter ce = new ClassEmitter(v);
|
||||
ce.begin_class(Constants.V1_8,
|
||||
@@ -100,8 +112,8 @@ public class ImmutableBean
|
||||
Method[] getters = ReflectUtils.getPropertyMethods(descriptors, true, false);
|
||||
Method[] setters = ReflectUtils.getPropertyMethods(descriptors, false, true);
|
||||
|
||||
for (int i = 0; i < getters.length; i++) {
|
||||
MethodInfo getter = ReflectUtils.getMethodInfo(getters[i]);
|
||||
for (Method getter2 : getters) {
|
||||
MethodInfo getter = ReflectUtils.getMethodInfo(getter2);
|
||||
e = EmitUtils.begin_method(ce, getter, Constants.ACC_PUBLIC);
|
||||
e.load_this();
|
||||
e.getfield(FIELD_NAME);
|
||||
@@ -110,8 +122,8 @@ public class ImmutableBean
|
||||
e.end_method();
|
||||
}
|
||||
|
||||
for (int i = 0; i < setters.length; i++) {
|
||||
MethodInfo setter = ReflectUtils.getMethodInfo(setters[i]);
|
||||
for (Method setter2 : setters) {
|
||||
MethodInfo setter = ReflectUtils.getMethodInfo(setter2);
|
||||
e = EmitUtils.begin_method(ce, setter, Constants.ACC_PUBLIC);
|
||||
e.throw_exception(ILLEGAL_STATE_EXCEPTION, "Bean is immutable");
|
||||
e.end_method();
|
||||
@@ -120,12 +132,14 @@ public class ImmutableBean
|
||||
ce.end_class();
|
||||
}
|
||||
|
||||
protected Object firstInstance(Class type) {
|
||||
@Override
|
||||
protected Object firstInstance(Class type) {
|
||||
return ReflectUtils.newInstance(type, OBJECT_CLASSES, new Object[]{ bean });
|
||||
}
|
||||
|
||||
// TODO: optimize
|
||||
protected Object nextInstance(Object instance) {
|
||||
@Override
|
||||
protected Object nextInstance(Object instance) {
|
||||
return firstInstance(instance.getClass());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@ abstract public class AbstractClassGenerator<T> implements ClassGenerator {
|
||||
|
||||
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 =
|
||||
Boolean.parseBoolean(System.getProperty("cglib.useCache", "true"));
|
||||
@@ -70,7 +70,7 @@ abstract public class AbstractClassGenerator<T> implements ClassGenerator {
|
||||
|
||||
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}
|
||||
@@ -90,31 +90,20 @@ abstract public class AbstractClassGenerator<T> implements ClassGenerator {
|
||||
*/
|
||||
private final WeakReference<ClassLoader> classLoader;
|
||||
|
||||
private final Predicate uniqueNamePredicate = new Predicate() {
|
||||
public boolean evaluate(Object name) {
|
||||
return reservedClassNames.contains(name);
|
||||
}
|
||||
};
|
||||
private final Predicate uniqueNamePredicate = this.reservedClassNames::contains;
|
||||
|
||||
private static final Function<AbstractClassGenerator, Object> GET_KEY = new Function<AbstractClassGenerator, Object>() {
|
||||
public Object apply(AbstractClassGenerator gen) {
|
||||
return gen.key;
|
||||
}
|
||||
};
|
||||
private static final Function<AbstractClassGenerator, Object> GET_KEY = gen -> gen.key;
|
||||
|
||||
public ClassLoaderData(ClassLoader classLoader) {
|
||||
if (classLoader == null) {
|
||||
throw new IllegalArgumentException("classLoader == null is not yet supported");
|
||||
}
|
||||
this.classLoader = new WeakReference<ClassLoader>(classLoader);
|
||||
Function<AbstractClassGenerator, Object> load =
|
||||
new Function<AbstractClassGenerator, Object>() {
|
||||
public Object apply(AbstractClassGenerator gen) {
|
||||
Class klass = gen.generate(ClassLoaderData.this);
|
||||
return gen.wrapCachedClass(klass);
|
||||
}
|
||||
};
|
||||
generatedClasses = new LoadingCache<AbstractClassGenerator, Object, Object>(GET_KEY, load);
|
||||
this.classLoader = new WeakReference<>(classLoader);
|
||||
Function<AbstractClassGenerator, Object> load = gen -> {
|
||||
Class klass = gen.generate(ClassLoaderData.this);
|
||||
return gen.wrapCachedClass(klass);
|
||||
};
|
||||
generatedClasses = new LoadingCache<>(GET_KEY, load);
|
||||
}
|
||||
|
||||
public ClassLoader getClassLoader() {
|
||||
@@ -205,8 +194,9 @@ abstract public class AbstractClassGenerator<T> implements ClassGenerator {
|
||||
* @see DefaultNamingPolicy
|
||||
*/
|
||||
public void setNamingPolicy(NamingPolicy namingPolicy) {
|
||||
if (namingPolicy == null)
|
||||
if (namingPolicy == null) {
|
||||
namingPolicy = DefaultNamingPolicy.INSTANCE;
|
||||
}
|
||||
this.namingPolicy = namingPolicy;
|
||||
}
|
||||
|
||||
@@ -250,8 +240,9 @@ abstract public class AbstractClassGenerator<T> implements ClassGenerator {
|
||||
* By default an instance of {@link DefaultGeneratorStrategy} is used.
|
||||
*/
|
||||
public void setStrategy(GeneratorStrategy strategy) {
|
||||
if (strategy == null)
|
||||
if (strategy == null) {
|
||||
strategy = DefaultGeneratorStrategy.INSTANCE;
|
||||
}
|
||||
this.strategy = strategy;
|
||||
}
|
||||
|
||||
@@ -311,7 +302,7 @@ abstract public class AbstractClassGenerator<T> implements ClassGenerator {
|
||||
cache = CACHE;
|
||||
data = cache.get(loader);
|
||||
if (data == null) {
|
||||
Map<ClassLoader, ClassLoaderData> newCache = new WeakHashMap<ClassLoader, ClassLoaderData>(cache);
|
||||
Map<ClassLoader, ClassLoaderData> newCache = new WeakHashMap<>(cache);
|
||||
data = new ClassLoaderData(loader);
|
||||
newCache.put(loader, data);
|
||||
CACHE = newCache;
|
||||
@@ -320,8 +311,8 @@ abstract public class AbstractClassGenerator<T> implements ClassGenerator {
|
||||
}
|
||||
this.key = key;
|
||||
Object obj = data.get(this, getUseCache());
|
||||
if (obj instanceof Class) {
|
||||
return firstInstance((Class) obj);
|
||||
if (obj instanceof Class<?> clazz) {
|
||||
return firstInstance(clazz);
|
||||
}
|
||||
return nextInstance(obj);
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@ public class Block
|
||||
}
|
||||
end = e.mark();
|
||||
}
|
||||
|
||||
|
||||
public Label getStart() {
|
||||
return start;
|
||||
}
|
||||
|
||||
@@ -15,14 +15,14 @@
|
||||
*/
|
||||
package org.springframework.cglib.core;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.asm.ClassVisitor;
|
||||
import org.springframework.asm.FieldVisitor;
|
||||
import org.springframework.asm.MethodVisitor;
|
||||
import org.springframework.asm.Type;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author Juozas Baliuka, Chris Nokleberg
|
||||
*/
|
||||
@@ -45,7 +45,8 @@ public class ClassEmitter extends ClassTransformer {
|
||||
super(Constants.ASM_API);
|
||||
}
|
||||
|
||||
public void setTarget(ClassVisitor cv) {
|
||||
@Override
|
||||
public void setTarget(ClassVisitor cv) {
|
||||
this.cv = cv;
|
||||
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) {
|
||||
final Type classType = Type.getType("L" + className.replace('.', '/') + ";");
|
||||
classInfo = new ClassInfo() {
|
||||
public Type getType() {
|
||||
@Override
|
||||
public Type getType() {
|
||||
return classType;
|
||||
}
|
||||
public Type getSuperType() {
|
||||
@Override
|
||||
public Type getSuperType() {
|
||||
return (superType != null) ? superType : Constants.TYPE_OBJECT;
|
||||
}
|
||||
public Type[] getInterfaces() {
|
||||
@Override
|
||||
public Type[] getInterfaces() {
|
||||
return interfaces;
|
||||
}
|
||||
public int getModifiers() {
|
||||
@Override
|
||||
public int getModifiers() {
|
||||
return access;
|
||||
}
|
||||
};
|
||||
@@ -84,8 +89,9 @@ public class ClassEmitter extends ClassTransformer {
|
||||
null,
|
||||
classInfo.getSuperType().getInternalName(),
|
||||
TypeUtils.toInternalNames(interfaces));
|
||||
if (source != null)
|
||||
cv.visitSource(source, null);
|
||||
if (source != null) {
|
||||
cv.visitSource(source, null);
|
||||
}
|
||||
init();
|
||||
}
|
||||
|
||||
@@ -137,8 +143,9 @@ public class ClassEmitter extends ClassTransformer {
|
||||
}
|
||||
|
||||
public CodeEmitter begin_method(int access, Signature sig, Type[] exceptions) {
|
||||
if (classInfo == null)
|
||||
throw new IllegalStateException("classInfo is null! " + this);
|
||||
if (classInfo == null) {
|
||||
throw new IllegalStateException("classInfo is null! " + this);
|
||||
}
|
||||
MethodVisitor v = cv.visitMethod(access,
|
||||
sig.getName(),
|
||||
sig.getDescriptor(),
|
||||
@@ -147,10 +154,12 @@ public class ClassEmitter extends ClassTransformer {
|
||||
if (sig.equals(Constants.SIG_STATIC) && !TypeUtils.isInterface(getAccess())) {
|
||||
rawStaticInit = 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
|
||||
}
|
||||
public void visitInsn(int insn) {
|
||||
@Override
|
||||
public void visitInsn(int insn) {
|
||||
if (insn != Constants.RETURN) {
|
||||
super.visitInsn(insn);
|
||||
}
|
||||
@@ -166,7 +175,8 @@ public class ClassEmitter extends ClassTransformer {
|
||||
return staticInit;
|
||||
} else if (sig.equals(staticHookSig)) {
|
||||
return new CodeEmitter(this, v, access, sig, exceptions) {
|
||||
public boolean isStaticHook() {
|
||||
@Override
|
||||
public boolean isStaticHook() {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
@@ -204,13 +214,13 @@ public class ClassEmitter extends ClassTransformer {
|
||||
}
|
||||
return field;
|
||||
}
|
||||
|
||||
|
||||
static class FieldInfo {
|
||||
int access;
|
||||
String name;
|
||||
Type type;
|
||||
Object value;
|
||||
|
||||
|
||||
public FieldInfo(int access, String name, Type type, Object value) {
|
||||
this.access = access;
|
||||
this.name = name;
|
||||
@@ -218,30 +228,36 @@ public class ClassEmitter extends ClassTransformer {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public boolean equals(Object o) {
|
||||
if (o == null)
|
||||
return false;
|
||||
if (!(o instanceof FieldInfo))
|
||||
return false;
|
||||
FieldInfo other = (FieldInfo)o;
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (o == null) {
|
||||
return false;
|
||||
}
|
||||
if (!(o instanceof FieldInfo other)) {
|
||||
return false;
|
||||
}
|
||||
if (access != other.access ||
|
||||
!name.equals(other.name) ||
|
||||
!type.equals(other.type)) {
|
||||
return false;
|
||||
}
|
||||
if ((value == null) ^ (other.value == null))
|
||||
return false;
|
||||
if (value != null && !value.equals(other.value))
|
||||
return false;
|
||||
if ((value == null) ^ (other.value == null)) {
|
||||
return false;
|
||||
}
|
||||
if (value != null && !value.equals(other.value)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
@Override
|
||||
public int 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,
|
||||
String name,
|
||||
String signature,
|
||||
@@ -254,12 +270,14 @@ public class ClassEmitter extends ClassTransformer {
|
||||
TypeUtils.fromInternalNames(interfaces),
|
||||
null); // TODO
|
||||
}
|
||||
|
||||
public void visitEnd() {
|
||||
|
||||
@Override
|
||||
public void visitEnd() {
|
||||
end_class();
|
||||
}
|
||||
|
||||
public FieldVisitor visitField(int access,
|
||||
|
||||
@Override
|
||||
public FieldVisitor visitField(int access,
|
||||
String name,
|
||||
String desc,
|
||||
String signature,
|
||||
@@ -267,14 +285,15 @@ public class ClassEmitter extends ClassTransformer {
|
||||
declare_field(access, name, Type.getType(desc), value);
|
||||
return null; // TODO
|
||||
}
|
||||
|
||||
public MethodVisitor visitMethod(int access,
|
||||
|
||||
@Override
|
||||
public MethodVisitor visitMethod(int access,
|
||||
String name,
|
||||
String desc,
|
||||
String signature,
|
||||
String[] exceptions) {
|
||||
return begin_method(access,
|
||||
new Signature(name, desc),
|
||||
TypeUtils.fromInternalNames(exceptions));
|
||||
TypeUtils.fromInternalNames(exceptions));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,14 +28,16 @@ abstract public class ClassInfo {
|
||||
abstract public Type[] getInterfaces();
|
||||
abstract public int getModifiers();
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (o == null)
|
||||
return false;
|
||||
if (!(o instanceof ClassInfo))
|
||||
return false;
|
||||
return getType().equals(((ClassInfo)o).getType());
|
||||
}
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (o == null) {
|
||||
return false;
|
||||
}
|
||||
if (!(o instanceof ClassInfo classInfo)) {
|
||||
return false;
|
||||
}
|
||||
return getType().equals(classInfo.getType());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
|
||||
@@ -15,51 +15,53 @@
|
||||
*/
|
||||
package org.springframework.cglib.core;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.asm.ClassReader;
|
||||
import org.springframework.asm.ClassVisitor;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
// TODO: optimize (ClassReader buffers entire class before accept)
|
||||
@SuppressWarnings({"rawtypes", "unchecked"})
|
||||
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")
|
||||
private static class EarlyExitException extends RuntimeException { }
|
||||
|
||||
public static String getClassName(ClassReader r) {
|
||||
|
||||
return getClassInfo(r)[0];
|
||||
|
||||
}
|
||||
|
||||
private static class EarlyExitException extends RuntimeException {
|
||||
}
|
||||
|
||||
public static String getClassName(ClassReader r) {
|
||||
return getClassInfo(r)[0];
|
||||
}
|
||||
|
||||
public static String[] getClassInfo(ClassReader r) {
|
||||
final List array = new ArrayList();
|
||||
final List<String> array = new ArrayList<>();
|
||||
try {
|
||||
r.accept(new ClassVisitor(Constants.ASM_API, null) {
|
||||
@Override
|
||||
public void visit(int version,
|
||||
int access,
|
||||
String name,
|
||||
String signature,
|
||||
String superName,
|
||||
String[] interfaces) {
|
||||
array.add( name.replace('/', '.') );
|
||||
if(superName != null){
|
||||
array.add( superName.replace('/', '.') );
|
||||
array.add(name.replace('/', '.'));
|
||||
if (superName != null) {
|
||||
array.add(superName.replace('/', '.'));
|
||||
}
|
||||
for(int i = 0; i < interfaces.length; i++ ){
|
||||
array.add( interfaces[i].replace('/', '.') );
|
||||
for (String element : interfaces) {
|
||||
array.add(element.replace('/', '.'));
|
||||
}
|
||||
|
||||
|
||||
throw EARLY_EXIT;
|
||||
}
|
||||
}, ClassReader.SKIP_DEBUG | ClassReader.SKIP_FRAMES);
|
||||
} catch (EarlyExitException e) { }
|
||||
|
||||
return (String[])array.toArray( new String[]{} );
|
||||
|
||||
return array.toArray(new String[0]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ package org.springframework.cglib.core;
|
||||
|
||||
public class ClassesKey {
|
||||
private static final Key FACTORY = (Key)KeyFactory.create(Key.class);
|
||||
|
||||
|
||||
interface Key {
|
||||
Object newInstance(Object[] array);
|
||||
}
|
||||
|
||||
@@ -613,8 +613,9 @@ public class CodeEmitter extends LocalVariablesSorter {
|
||||
}
|
||||
|
||||
public void process_switch(int[] keys, ProcessSwitchCallback callback, boolean useTable) {
|
||||
if (!isSorted(keys))
|
||||
throw new IllegalArgumentException("keys to switch must be sorted ascending");
|
||||
if (!isSorted(keys)) {
|
||||
throw new IllegalArgumentException("keys to switch must be sorted ascending");
|
||||
}
|
||||
Label def = make_label();
|
||||
Label end = make_label();
|
||||
|
||||
@@ -656,9 +657,7 @@ public class CodeEmitter extends LocalVariablesSorter {
|
||||
callback.processDefault();
|
||||
mark(end);
|
||||
|
||||
} catch (RuntimeException e) {
|
||||
throw e;
|
||||
} catch (Error e) {
|
||||
} catch (RuntimeException | Error e) {
|
||||
throw e;
|
||||
} catch (Exception e) {
|
||||
throw new CodeGenerationException(e);
|
||||
@@ -667,8 +666,9 @@ public class CodeEmitter extends LocalVariablesSorter {
|
||||
|
||||
private static boolean isSorted(int[] keys) {
|
||||
for (int i = 1; i < keys.length; i++) {
|
||||
if (keys[i] < keys[i - 1])
|
||||
return false;
|
||||
if (keys[i] < keys[i - 1]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -27,7 +27,8 @@ public class CodeGenerationException extends RuntimeException {
|
||||
this.cause = cause;
|
||||
}
|
||||
|
||||
public Throwable getCause() {
|
||||
@Override
|
||||
public Throwable getCause() {
|
||||
return cause;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,8 +34,7 @@ public class CollectionUtils {
|
||||
|
||||
public static Map bucket(Collection c, Transformer t) {
|
||||
Map buckets = new HashMap();
|
||||
for (Iterator it = c.iterator(); it.hasNext();) {
|
||||
Object value = it.next();
|
||||
for (Object value : c) {
|
||||
Object key = t.transform(value);
|
||||
List bucket = (List)buckets.get(key);
|
||||
if (bucket == null) {
|
||||
@@ -47,8 +46,7 @@ public class CollectionUtils {
|
||||
}
|
||||
|
||||
public static void reverse(Map source, Map target) {
|
||||
for (Iterator it = source.keySet().iterator(); it.hasNext();) {
|
||||
Object key = it.next();
|
||||
for (Object key : source.keySet()) {
|
||||
target.put(source.get(key), key);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@ public interface Constants extends org.springframework.asm.Opcodes {
|
||||
|
||||
public static final Signature SIG_STATIC =
|
||||
TypeUtils.parseSignature("void <clinit>()");
|
||||
|
||||
|
||||
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_STRING_ARRAY = TypeUtils.parseType("String[]");
|
||||
|
||||
@@ -19,8 +19,9 @@ import org.springframework.asm.ClassWriter;
|
||||
|
||||
public class DefaultGeneratorStrategy implements GeneratorStrategy {
|
||||
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();
|
||||
transform(cg).generateClass(cw);
|
||||
return transform(cw.toByteArray());
|
||||
@@ -36,7 +37,7 @@ public class DefaultGeneratorStrategy implements GeneratorStrategy {
|
||||
throw new UnsupportedOperationException("You are calling " +
|
||||
"getClassWriter, which no longer exists in this cglib version.");
|
||||
}
|
||||
|
||||
|
||||
protected byte[] transform(byte[] b) throws Exception {
|
||||
return b;
|
||||
}
|
||||
|
||||
@@ -48,8 +48,9 @@ public class DefaultNamingPolicy implements NamingPolicy {
|
||||
Integer.toHexString(STRESS_HASH_CODE ? 0 : key.hashCode());
|
||||
String attempt = base;
|
||||
int index = 2;
|
||||
while (names.evaluate(attempt))
|
||||
attempt = base + "_" + index++;
|
||||
while (names.evaluate(attempt)) {
|
||||
attempt = base + "_" + index++;
|
||||
}
|
||||
return attempt;
|
||||
}
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cglib.core;
|
||||
|
||||
import java.io.IOException;
|
||||
@@ -24,6 +25,7 @@ import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.springframework.asm.ClassReader;
|
||||
import org.springframework.asm.ClassVisitor;
|
||||
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
|
||||
* 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) {
|
||||
rejected = new HashSet();
|
||||
@@ -70,7 +72,7 @@ public class DuplicatesPredicate implements Predicate {
|
||||
suspects.put(sig, existing);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (!suspects.isEmpty()) {
|
||||
Set classes = new HashSet();
|
||||
UnnecessaryBridgeFinder finder = new UnnecessaryBridgeFinder(rejected);
|
||||
@@ -101,10 +103,11 @@ public class DuplicatesPredicate implements Predicate {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean evaluate(Object arg) {
|
||||
return !rejected.contains(arg) && unique.add(MethodWrapper.create((Method) arg));
|
||||
}
|
||||
|
||||
|
||||
private static ClassLoader getClassLoader(Class c) {
|
||||
ClassLoader cl = c.getClassLoader();
|
||||
if (cl == null) {
|
||||
@@ -131,6 +134,7 @@ public class DuplicatesPredicate implements Predicate {
|
||||
methods.put(ReflectUtils.getSignature(m), m);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(
|
||||
int version,
|
||||
int access,
|
||||
@@ -139,6 +143,7 @@ public class DuplicatesPredicate implements Predicate {
|
||||
String superName,
|
||||
String[] interfaces) {}
|
||||
|
||||
@Override
|
||||
public MethodVisitor visitMethod(
|
||||
int access, String name, String desc, String signature, String[] exceptions) {
|
||||
Signature sig = new Signature(name, desc);
|
||||
@@ -146,6 +151,7 @@ public class DuplicatesPredicate implements Predicate {
|
||||
if (currentMethod != null) {
|
||||
currentMethodSig = sig;
|
||||
return new MethodVisitor(Constants.ASM_API) {
|
||||
@Override
|
||||
public void visitMethodInsn(
|
||||
int opcode, String owner, String name, String desc, boolean itf) {
|
||||
if (opcode == Opcodes.INVOKESPECIAL && currentMethodSig != null) {
|
||||
|
||||
@@ -187,9 +187,7 @@ public class EmitUtils {
|
||||
default:
|
||||
throw new IllegalArgumentException("unknown switch style " + switchStyle);
|
||||
}
|
||||
} catch (RuntimeException ex) {
|
||||
throw ex;
|
||||
} catch (Error ex) {
|
||||
} catch (RuntimeException | Error ex) {
|
||||
throw ex;
|
||||
} catch (Exception ex) {
|
||||
throw new CodeGenerationException(ex);
|
||||
@@ -201,12 +199,7 @@ public class EmitUtils {
|
||||
final ObjectSwitchCallback callback) throws Exception {
|
||||
final Label def = e.make_label();
|
||||
final Label end = e.make_label();
|
||||
final Map buckets = CollectionUtils.bucket(Arrays.asList(strings), new Transformer() {
|
||||
@Override
|
||||
public Object transform(Object value) {
|
||||
return ((String)value).length();
|
||||
}
|
||||
});
|
||||
final Map buckets = CollectionUtils.bucket(Arrays.asList(strings), value -> ((String)value).length());
|
||||
e.dup();
|
||||
e.invoke_virtual(Constants.TYPE_STRING, STRING_LENGTH);
|
||||
e.process_switch(getSwitchKeys(buckets), new ProcessSwitchCallback() {
|
||||
@@ -233,12 +226,7 @@ public class EmitUtils {
|
||||
final Label end,
|
||||
final int index) throws Exception {
|
||||
final int len = ((String)strings.get(0)).length();
|
||||
final Map buckets = CollectionUtils.bucket(strings, new Transformer() {
|
||||
@Override
|
||||
public Object transform(Object value) {
|
||||
return ((String)value).charAt(index);
|
||||
}
|
||||
});
|
||||
final Map buckets = CollectionUtils.bucket(strings, value -> ((String)value).charAt(index));
|
||||
e.dup();
|
||||
e.push(index);
|
||||
e.invoke_virtual(Constants.TYPE_STRING, STRING_CHAR_AT);
|
||||
@@ -274,12 +262,7 @@ public class EmitUtils {
|
||||
final String[] strings,
|
||||
final ObjectSwitchCallback callback,
|
||||
final boolean skipEquals) throws Exception {
|
||||
final Map buckets = CollectionUtils.bucket(Arrays.asList(strings), new Transformer() {
|
||||
@Override
|
||||
public Object transform(Object value) {
|
||||
return value.hashCode();
|
||||
}
|
||||
});
|
||||
final Map buckets = CollectionUtils.bucket(Arrays.asList(strings), value -> value.hashCode());
|
||||
final Label def = e.make_label();
|
||||
final Label end = e.make_label();
|
||||
e.dup();
|
||||
@@ -290,8 +273,9 @@ public class EmitUtils {
|
||||
List bucket = (List)buckets.get(key);
|
||||
Label next = null;
|
||||
if (skipEquals && bucket.size() == 1) {
|
||||
if (skipEquals)
|
||||
e.pop();
|
||||
if (skipEquals) {
|
||||
e.pop();
|
||||
}
|
||||
callback.processCase(bucket.get(0), end);
|
||||
} else {
|
||||
for (Iterator it = bucket.iterator(); it.hasNext();) {
|
||||
@@ -373,8 +357,9 @@ public class EmitUtils {
|
||||
}
|
||||
|
||||
private static Class remapComponentType(Class componentType) {
|
||||
if (componentType.equals(Type.class))
|
||||
return Class.class;
|
||||
if (componentType.equals(Type.class)) {
|
||||
return Class.class;
|
||||
}
|
||||
return componentType;
|
||||
}
|
||||
|
||||
@@ -437,12 +422,7 @@ public class EmitUtils {
|
||||
Label end = e.make_label();
|
||||
e.dup();
|
||||
e.ifnull(skip);
|
||||
EmitUtils.process_array(e, type, new ProcessArrayCallback() {
|
||||
@Override
|
||||
public void processElement(Type type) {
|
||||
hash_code(e, type, multiplier, registry);
|
||||
}
|
||||
});
|
||||
EmitUtils.process_array(e, type, type1 -> hash_code(e, type1, multiplier, registry));
|
||||
e.goTo(end);
|
||||
e.mark(skip);
|
||||
e.pop();
|
||||
@@ -752,26 +732,18 @@ public class EmitUtils {
|
||||
boolean useName) {
|
||||
try {
|
||||
final Map cache = new HashMap();
|
||||
final ParameterTyper cached = new ParameterTyper() {
|
||||
@Override
|
||||
public Type[] getParameterTypes(MethodInfo member) {
|
||||
Type[] types = (Type[])cache.get(member);
|
||||
if (types == null) {
|
||||
cache.put(member, types = member.getSignature().getArgumentTypes());
|
||||
}
|
||||
return types;
|
||||
}
|
||||
};
|
||||
final ParameterTyper cached = member -> {
|
||||
Type[] types = (Type[]) cache.get(member);
|
||||
if (types == null) {
|
||||
cache.put(member, types = member.getSignature().getArgumentTypes());
|
||||
}
|
||||
return types;
|
||||
};
|
||||
final Label def = e.make_label();
|
||||
final Label end = e.make_label();
|
||||
if (useName) {
|
||||
e.swap();
|
||||
final Map buckets = CollectionUtils.bucket(members, new Transformer() {
|
||||
@Override
|
||||
public Object transform(Object value) {
|
||||
return ((MethodInfo)value).getSignature().getName();
|
||||
}
|
||||
});
|
||||
final Map buckets = CollectionUtils.bucket(members, value -> ((MethodInfo)value).getSignature().getName());
|
||||
String[] names = (String[])buckets.keySet().toArray(new String[buckets.size()]);
|
||||
EmitUtils.string_switch(e, names, Constants.SWITCH_STYLE_HASH, new ObjectSwitchCallback() {
|
||||
@Override
|
||||
@@ -790,9 +762,7 @@ public class EmitUtils {
|
||||
e.pop();
|
||||
callback.processDefault();
|
||||
e.mark(end);
|
||||
} catch (RuntimeException ex) {
|
||||
throw ex;
|
||||
} catch (Error ex) {
|
||||
} catch (RuntimeException | Error ex) {
|
||||
throw ex;
|
||||
} catch (Exception ex) {
|
||||
throw new CodeGenerationException(ex);
|
||||
@@ -805,12 +775,7 @@ public class EmitUtils {
|
||||
final ParameterTyper typer,
|
||||
final Label def,
|
||||
final Label end) throws Exception {
|
||||
final Map buckets = CollectionUtils.bucket(members, new Transformer() {
|
||||
@Override
|
||||
public Object transform(Object value) {
|
||||
return typer.getParameterTypes((MethodInfo)value).length;
|
||||
}
|
||||
});
|
||||
final Map buckets = CollectionUtils.bucket(members, value -> typer.getParameterTypes((MethodInfo)value).length);
|
||||
e.dup();
|
||||
e.arraylength();
|
||||
e.process_switch(EmitUtils.getSwitchKeys(buckets), new ProcessSwitchCallback() {
|
||||
@@ -856,12 +821,8 @@ public class EmitUtils {
|
||||
int index = -1;
|
||||
for (int i = 0; i < example.length; i++) {
|
||||
final int j = i;
|
||||
Map test = CollectionUtils.bucket(members, new Transformer() {
|
||||
@Override
|
||||
public Object transform(Object value) {
|
||||
return TypeUtils.emulateClassGetName(typer.getParameterTypes((MethodInfo)value)[j]);
|
||||
}
|
||||
});
|
||||
Map test = CollectionUtils.bucket(members,
|
||||
value -> TypeUtils.emulateClassGetName(typer.getParameterTypes((MethodInfo)value)[j]));
|
||||
if (buckets == null || test.size() > buckets.size()) {
|
||||
buckets = test;
|
||||
index = i;
|
||||
@@ -951,8 +912,9 @@ public class EmitUtils {
|
||||
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));
|
||||
|
||||
if (set.contains(Constants.TYPE_THROWABLE))
|
||||
return;
|
||||
if (set.contains(Constants.TYPE_THROWABLE)) {
|
||||
return;
|
||||
}
|
||||
|
||||
boolean needThrow = exceptions != null;
|
||||
if (!set.contains(Constants.TYPE_RUNTIME_EXCEPTION)) {
|
||||
@@ -964,8 +926,8 @@ public class EmitUtils {
|
||||
needThrow = true;
|
||||
}
|
||||
if (exceptions != null) {
|
||||
for (int i = 0; i < exceptions.length; i++) {
|
||||
e.catch_exception(handler, exceptions[i]);
|
||||
for (Type exception : exceptions) {
|
||||
e.catch_exception(handler, exception);
|
||||
}
|
||||
}
|
||||
if (needThrow) {
|
||||
|
||||
@@ -40,5 +40,6 @@ public interface GeneratorStrategy {
|
||||
* correctly implement <code>equals</code> and <code>hashCode</code>
|
||||
* to avoid generating too many classes.
|
||||
*/
|
||||
boolean equals(Object o);
|
||||
@Override
|
||||
boolean equals(Object o);
|
||||
}
|
||||
|
||||
@@ -98,20 +98,20 @@ abstract public class KeyFactory {
|
||||
938313161, 1288102441, 1768288259};
|
||||
|
||||
|
||||
public static final Customizer CLASS_BY_NAME = new Customizer() {
|
||||
public void customize(CodeEmitter e, Type type) {
|
||||
if (type.equals(Constants.TYPE_CLASS)) {
|
||||
e.invoke_virtual(Constants.TYPE_CLASS, GET_NAME);
|
||||
}
|
||||
public static final Customizer CLASS_BY_NAME = (e, type) -> {
|
||||
if (type.equals(Constants.TYPE_CLASS)) {
|
||||
e.invoke_virtual(Constants.TYPE_CLASS, GET_NAME);
|
||||
}
|
||||
};
|
||||
|
||||
public static final FieldTypeCustomizer STORE_CLASS_AS_STRING = new FieldTypeCustomizer() {
|
||||
@Override
|
||||
public void customize(CodeEmitter e, int index, Type type) {
|
||||
if (type.equals(Constants.TYPE_CLASS)) {
|
||||
e.invoke_virtual(Constants.TYPE_CLASS, GET_NAME);
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public Type getOutType(int index, Type type) {
|
||||
if (type.equals(Constants.TYPE_CLASS)) {
|
||||
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.
|
||||
* This customizer uses {@link Type#getSort()} as a hash code.
|
||||
*/
|
||||
public static final HashCodeCustomizer HASH_ASM_TYPE = new HashCodeCustomizer() {
|
||||
public boolean customize(CodeEmitter e, Type type) {
|
||||
if (Constants.TYPE_TYPE.equals(type)) {
|
||||
e.invoke_virtual(type, GET_SORT);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
public static final HashCodeCustomizer HASH_ASM_TYPE = (e, type) -> {
|
||||
if (Constants.TYPE_TYPE.equals(type)) {
|
||||
e.invoke_virtual(type, GET_SORT);
|
||||
return true;
|
||||
}
|
||||
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
|
||||
*/
|
||||
@Deprecated
|
||||
public static final Customizer OBJECT_BY_CLASS = new Customizer() {
|
||||
public void customize(CodeEmitter e, Type type) {
|
||||
e.invoke_virtual(Constants.TYPE_OBJECT, GET_CLASS);
|
||||
}
|
||||
};
|
||||
public static final Customizer OBJECT_BY_CLASS = (e, type) -> e.invoke_virtual(Constants.TYPE_OBJECT, GET_CLASS);
|
||||
|
||||
protected KeyFactory() {
|
||||
}
|
||||
@@ -204,10 +198,12 @@ abstract public class KeyFactory {
|
||||
super(SOURCE);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ClassLoader getDefaultClassLoader() {
|
||||
return keyInterface.getClassLoader();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ProtectionDomain getProtectionDomain() {
|
||||
return ReflectUtils.getProtectionDomain(keyInterface);
|
||||
}
|
||||
@@ -245,14 +241,17 @@ abstract public class KeyFactory {
|
||||
this.multiplier = multiplier;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Object firstInstance(Class type) {
|
||||
return ReflectUtils.newInstance(type);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Object nextInstance(Object instance) {
|
||||
return instance;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void generateClass(ClassVisitor v) {
|
||||
ClassEmitter ce = new ClassEmitter(v);
|
||||
|
||||
|
||||
@@ -21,12 +21,12 @@ public class Local
|
||||
{
|
||||
private Type type;
|
||||
private int index;
|
||||
|
||||
|
||||
public Local(int index, Type type) {
|
||||
this.type = type;
|
||||
this.index = index;
|
||||
}
|
||||
|
||||
|
||||
public int getIndex() {
|
||||
return index;
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@ import org.springframework.asm.Type;
|
||||
* A {@link MethodVisitor} that renumbers local variables in their order of
|
||||
* appearance. This adapter allows one to easily add new local variables to a
|
||||
* method.
|
||||
*
|
||||
*
|
||||
* @author Chris Nokleberg
|
||||
* @author Eric Bruneton
|
||||
*/
|
||||
@@ -51,7 +51,7 @@ public class LocalVariablesSorter extends MethodVisitor {
|
||||
*/
|
||||
private static class State
|
||||
{
|
||||
int[] mapping = new int[40];
|
||||
int[] mapping = new int[40];
|
||||
int nextLocal;
|
||||
}
|
||||
|
||||
@@ -67,8 +67,8 @@ public class LocalVariablesSorter extends MethodVisitor {
|
||||
state = new State();
|
||||
Type[] args = Type.getArgumentTypes(desc);
|
||||
state.nextLocal = ((Opcodes.ACC_STATIC & access) != 0) ? 0 : 1;
|
||||
for (int i = 0; i < args.length; i++) {
|
||||
state.nextLocal += args[i].getSize();
|
||||
for (Type arg : args) {
|
||||
state.nextLocal += arg.getSize();
|
||||
}
|
||||
firstLocal = state.nextLocal;
|
||||
}
|
||||
@@ -79,30 +79,27 @@ public class LocalVariablesSorter extends MethodVisitor {
|
||||
firstLocal = lvs.firstLocal;
|
||||
}
|
||||
|
||||
public void visitVarInsn(final int opcode, final int var) {
|
||||
int size;
|
||||
switch (opcode) {
|
||||
case Opcodes.LLOAD:
|
||||
case Opcodes.LSTORE:
|
||||
case Opcodes.DLOAD:
|
||||
case Opcodes.DSTORE:
|
||||
size = 2;
|
||||
break;
|
||||
default:
|
||||
size = 1;
|
||||
}
|
||||
@Override
|
||||
public void visitVarInsn(final int opcode, final int var) {
|
||||
int size = switch (opcode) {
|
||||
case Opcodes.LLOAD, Opcodes.LSTORE, Opcodes.DLOAD, Opcodes.DSTORE -> 2;
|
||||
default -> 1;
|
||||
};
|
||||
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);
|
||||
}
|
||||
|
||||
public void visitMaxs(final int maxStack, final int maxLocals) {
|
||||
@Override
|
||||
public void visitMaxs(final int maxStack, final int maxLocals) {
|
||||
mv.visitMaxs(maxStack, state.nextLocal);
|
||||
}
|
||||
|
||||
public void visitLocalVariable(
|
||||
@Override
|
||||
public void visitLocalVariable(
|
||||
final String name,
|
||||
final String desc,
|
||||
final String signature,
|
||||
|
||||
@@ -20,31 +20,34 @@ import org.springframework.asm.Type;
|
||||
|
||||
abstract public class MethodInfo {
|
||||
|
||||
protected MethodInfo() {
|
||||
}
|
||||
protected MethodInfo() {
|
||||
}
|
||||
|
||||
abstract public ClassInfo getClassInfo();
|
||||
abstract public int getModifiers();
|
||||
abstract public Signature getSignature();
|
||||
abstract public Type[] getExceptionTypes();
|
||||
abstract public ClassInfo getClassInfo();
|
||||
abstract public int getModifiers();
|
||||
abstract public Signature getSignature();
|
||||
abstract public Type[] getExceptionTypes();
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (o == null)
|
||||
return false;
|
||||
if (!(o instanceof MethodInfo))
|
||||
return false;
|
||||
return getSignature().equals(((MethodInfo)o).getSignature());
|
||||
}
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (o == null) {
|
||||
return false;
|
||||
}
|
||||
if (!(o instanceof MethodInfo other)) {
|
||||
return false;
|
||||
}
|
||||
return getSignature().equals(other.getSignature());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return getSignature().hashCode();
|
||||
}
|
||||
@Override
|
||||
public int 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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,7 +16,12 @@
|
||||
package org.springframework.cglib.core;
|
||||
|
||||
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"})
|
||||
public class MethodWrapper {
|
||||
|
||||
@@ -13,9 +13,10 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cglib.core;
|
||||
|
||||
@FunctionalInterface
|
||||
public interface Predicate {
|
||||
boolean evaluate(Object arg);
|
||||
boolean evaluate(Object arg);
|
||||
}
|
||||
|
||||
|
||||
@@ -60,7 +60,7 @@ public class ReflectUtils {
|
||||
|
||||
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;
|
||||
|
||||
@@ -125,11 +125,11 @@ public class ReflectUtils {
|
||||
}
|
||||
|
||||
public static Type[] getExceptionTypes(Member member) {
|
||||
if (member instanceof Method) {
|
||||
return TypeUtils.getTypes(((Method) member).getExceptionTypes());
|
||||
if (member instanceof Method method) {
|
||||
return TypeUtils.getTypes(method.getExceptionTypes());
|
||||
}
|
||||
else if (member instanceof Constructor) {
|
||||
return TypeUtils.getTypes(((Constructor) member).getExceptionTypes());
|
||||
else if (member instanceof Constructor<?> constructor) {
|
||||
return TypeUtils.getTypes(constructor.getExceptionTypes());
|
||||
}
|
||||
else {
|
||||
throw new IllegalArgumentException("Cannot get exception types of a field");
|
||||
@@ -137,14 +137,13 @@ public class ReflectUtils {
|
||||
}
|
||||
|
||||
public static Signature getSignature(Member member) {
|
||||
if (member instanceof Method) {
|
||||
return new Signature(member.getName(), Type.getMethodDescriptor((Method) member));
|
||||
if (member instanceof Method method) {
|
||||
return new Signature(member.getName(), Type.getMethodDescriptor(method));
|
||||
}
|
||||
else if (member instanceof Constructor) {
|
||||
Type[] types = TypeUtils.getTypes(((Constructor) member).getParameterTypes());
|
||||
else if (member instanceof Constructor<?> constructor) {
|
||||
Type[] types = TypeUtils.getTypes(constructor.getParameterTypes());
|
||||
return new Signature(Constants.CONSTRUCTOR_NAME,
|
||||
Type.getMethodDescriptor(Type.VOID_TYPE, types));
|
||||
|
||||
}
|
||||
else {
|
||||
throw new IllegalArgumentException("Cannot get signature of a field");
|
||||
@@ -230,9 +229,9 @@ public class ReflectUtils {
|
||||
}
|
||||
catch (ClassNotFoundException ignore) {
|
||||
}
|
||||
for (int i = 0; i < packages.length; i++) {
|
||||
for (String pkg : packages) {
|
||||
try {
|
||||
return Class.forName(prefix + packages[i] + '.' + className + suffix, false, loader);
|
||||
return Class.forName(prefix + pkg + '.' + className + suffix, false, loader);
|
||||
}
|
||||
catch (ClassNotFoundException ignore) {
|
||||
}
|
||||
@@ -274,10 +273,7 @@ public class ReflectUtils {
|
||||
Object result = cstruct.newInstance(args);
|
||||
return result;
|
||||
}
|
||||
catch (InstantiationException e) {
|
||||
throw new CodeGenerationException(e);
|
||||
}
|
||||
catch (IllegalAccessException e) {
|
||||
catch (InstantiationException | IllegalAccessException e) {
|
||||
throw new CodeGenerationException(e);
|
||||
}
|
||||
catch (InvocationTargetException e) {
|
||||
@@ -302,8 +298,9 @@ public class ReflectUtils {
|
||||
}
|
||||
|
||||
public static String[] getNames(Class[] classes) {
|
||||
if (classes == null)
|
||||
if (classes == null) {
|
||||
return null;
|
||||
}
|
||||
String[] names = new String[classes.length];
|
||||
for (int i = 0; i < names.length; i++) {
|
||||
names[i] = classes[i].getName();
|
||||
@@ -329,8 +326,7 @@ public class ReflectUtils {
|
||||
|
||||
public static Method[] getPropertyMethods(PropertyDescriptor[] properties, boolean read, boolean write) {
|
||||
Set methods = new HashSet();
|
||||
for (int i = 0; i < properties.length; i++) {
|
||||
PropertyDescriptor pd = properties[i];
|
||||
for (PropertyDescriptor pd : properties) {
|
||||
if (read) {
|
||||
methods.add(pd.getReadMethod());
|
||||
}
|
||||
@@ -362,8 +358,7 @@ public class ReflectUtils {
|
||||
return all;
|
||||
}
|
||||
List properties = new ArrayList(all.length);
|
||||
for (int i = 0; i < all.length; i++) {
|
||||
PropertyDescriptor pd = all[i];
|
||||
for (PropertyDescriptor pd : all) {
|
||||
if ((read && pd.getReadMethod() != null) ||
|
||||
(write && pd.getWriteMethod() != null)) {
|
||||
properties.add(pd);
|
||||
@@ -396,16 +391,17 @@ public class ReflectUtils {
|
||||
if (type == Object.class) {
|
||||
list.addAll(OBJECT_METHODS);
|
||||
}
|
||||
else
|
||||
else {
|
||||
list.addAll(java.util.Arrays.asList(type.getDeclaredMethods()));
|
||||
}
|
||||
|
||||
Class superclass = type.getSuperclass();
|
||||
if (superclass != null) {
|
||||
addAllMethods(superclass, list);
|
||||
}
|
||||
Class[] interfaces = type.getInterfaces();
|
||||
for (int i = 0; i < interfaces.length; i++) {
|
||||
addAllMethods(interfaces[i], list);
|
||||
for (Class element : interfaces) {
|
||||
addAllMethods(element, list);
|
||||
}
|
||||
|
||||
return list;
|
||||
@@ -584,20 +580,25 @@ public class ReflectUtils {
|
||||
return new MethodInfo() {
|
||||
private ClassInfo ci;
|
||||
|
||||
@Override
|
||||
public ClassInfo getClassInfo() {
|
||||
if (ci == null)
|
||||
if (ci == null) {
|
||||
ci = ReflectUtils.getClassInfo(member.getDeclaringClass());
|
||||
}
|
||||
return ci;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getModifiers() {
|
||||
return modifiers;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Signature getSignature() {
|
||||
return sig;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Type[] getExceptionTypes() {
|
||||
return ReflectUtils.getExceptionTypes(member);
|
||||
}
|
||||
@@ -612,15 +613,19 @@ public class ReflectUtils {
|
||||
final Type type = Type.getType(clazz);
|
||||
final Type sc = (clazz.getSuperclass() == null) ? null : Type.getType(clazz.getSuperclass());
|
||||
return new ClassInfo() {
|
||||
@Override
|
||||
public Type getType() {
|
||||
return type;
|
||||
}
|
||||
@Override
|
||||
public Type getSuperType() {
|
||||
return sc;
|
||||
}
|
||||
@Override
|
||||
public Type[] getInterfaces() {
|
||||
return TypeUtils.getTypes(clazz.getInterfaces());
|
||||
}
|
||||
@Override
|
||||
public int getModifiers() {
|
||||
return clazz.getModifiers();
|
||||
}
|
||||
@@ -630,8 +635,7 @@ public class ReflectUtils {
|
||||
// used by MethodInterceptorGenerated generated code
|
||||
public static Method[] findMethods(String[] namesAndDescriptors, Method[] methods) {
|
||||
Map map = new HashMap();
|
||||
for (int i = 0; i < methods.length; i++) {
|
||||
Method method = methods[i];
|
||||
for (Method method : methods) {
|
||||
map.put(method.getName() + Type.getMethodDescriptor(method), method);
|
||||
}
|
||||
Method[] result = new Method[namesAndDescriptors.length / 2];
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
*/
|
||||
package org.springframework.cglib.core;
|
||||
|
||||
import java.lang.reflect.*;
|
||||
import java.lang.reflect.Member;
|
||||
|
||||
public class RejectModifierPredicate implements Predicate {
|
||||
private int rejectMask;
|
||||
@@ -24,7 +24,8 @@ public class RejectModifierPredicate implements Predicate {
|
||||
this.rejectMask = rejectMask;
|
||||
}
|
||||
|
||||
public boolean evaluate(Object arg) {
|
||||
@Override
|
||||
public boolean evaluate(Object arg) {
|
||||
return (((Member)arg).getModifiers() & rejectMask) == 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -54,20 +54,24 @@ public class Signature {
|
||||
return Type.getArgumentTypes(desc);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
@Override
|
||||
public String toString() {
|
||||
return name + desc;
|
||||
}
|
||||
|
||||
public boolean equals(Object o) {
|
||||
if (o == null)
|
||||
return false;
|
||||
if (!(o instanceof Signature))
|
||||
return false;
|
||||
Signature other = (Signature)o;
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (o == null) {
|
||||
return false;
|
||||
}
|
||||
if (!(o instanceof Signature other)) {
|
||||
return false;
|
||||
}
|
||||
return name.equals(other.name) && desc.equals(other.desc);
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return name.hashCode() ^ desc.hashCode();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,6 +36,7 @@ public final class SpringNamingPolicy implements NamingPolicy {
|
||||
private SpringNamingPolicy() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getClassName(String prefix, String source, Object key, Predicate names) {
|
||||
if (prefix == null) {
|
||||
prefix = "org.springframework.cglib.empty.Object";
|
||||
|
||||
@@ -15,7 +15,13 @@
|
||||
*/
|
||||
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;
|
||||
|
||||
@SuppressWarnings({"rawtypes", "unchecked"})
|
||||
@@ -63,7 +69,7 @@ public class TypeUtils {
|
||||
public static boolean isAbstract(int access) {
|
||||
return (Constants.ACC_ABSTRACT & access) != 0;
|
||||
}
|
||||
|
||||
|
||||
public static boolean isInterface(int access) {
|
||||
return (Constants.ACC_INTERFACE & access) != 0;
|
||||
}
|
||||
@@ -71,15 +77,15 @@ public class TypeUtils {
|
||||
public static boolean isPrivate(int access) {
|
||||
return (Constants.ACC_PRIVATE & access) != 0;
|
||||
}
|
||||
|
||||
|
||||
public static boolean isSynthetic(int access) {
|
||||
return (Constants.ACC_SYNTHETIC & access) != 0;
|
||||
}
|
||||
|
||||
|
||||
public static boolean isBridge(int access) {
|
||||
return (Constants.ACC_BRIDGE & access) != 0;
|
||||
}
|
||||
|
||||
|
||||
// getPackage returns null on JDK 1.2
|
||||
public static String getPackageName(Type type) {
|
||||
return getPackageName(getClassName(type));
|
||||
@@ -89,7 +95,7 @@ public class TypeUtils {
|
||||
int idx = className.lastIndexOf('.');
|
||||
return (idx < 0) ? "" : className.substring(0, idx);
|
||||
}
|
||||
|
||||
|
||||
public static String upperFirst(String s) {
|
||||
if (s == null || s.length() == 0) {
|
||||
return s;
|
||||
@@ -148,8 +154,8 @@ public class TypeUtils {
|
||||
|
||||
public static int getStackSize(Type[] types) {
|
||||
int size = 0;
|
||||
for (int i = 0; i < types.length; i++) {
|
||||
size += types[i].getSize();
|
||||
for (Type type : types) {
|
||||
size += type.getSize();
|
||||
}
|
||||
return size;
|
||||
}
|
||||
@@ -197,8 +203,8 @@ public class TypeUtils {
|
||||
public static Signature parseConstructor(Type[] types) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("(");
|
||||
for (int i = 0; i < types.length; i++) {
|
||||
sb.append(types[i].getDescriptor());
|
||||
for (Type type : types) {
|
||||
sb.append(type.getDescriptor());
|
||||
}
|
||||
sb.append(")");
|
||||
sb.append("V");
|
||||
|
||||
@@ -15,7 +15,9 @@
|
||||
*/
|
||||
package org.springframework.cglib.core;
|
||||
|
||||
import java.lang.reflect.*;
|
||||
import java.lang.reflect.Member;
|
||||
import java.lang.reflect.Modifier;
|
||||
|
||||
import org.springframework.asm.Type;
|
||||
|
||||
@SuppressWarnings({"rawtypes", "unchecked"})
|
||||
@@ -26,13 +28,14 @@ public class VisibilityPredicate implements Predicate {
|
||||
|
||||
public VisibilityPredicate(Class source, boolean 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
|
||||
this.samePackageOk = source.getClassLoader() != null;
|
||||
pkg = TypeUtils.getPackageName(Type.getType(source));
|
||||
}
|
||||
|
||||
public boolean evaluate(Object arg) {
|
||||
@Override
|
||||
public boolean evaluate(Object arg) {
|
||||
Member member = (Member)arg;
|
||||
int mod = member.getModifiers();
|
||||
if (Modifier.isPrivate(mod)) {
|
||||
@@ -43,9 +46,9 @@ public class VisibilityPredicate implements Predicate {
|
||||
// protected is fine if 'protectedOk' is true (for subclasses)
|
||||
return true;
|
||||
} 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.
|
||||
return samePackageOk
|
||||
return samePackageOk
|
||||
&& pkg.equals(TypeUtils.getPackageName(Type.getType(member.getDeclaringClass())));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ import org.springframework.cglib.core.KeyFactoryCustomizer;
|
||||
@SuppressWarnings({"rawtypes", "unchecked"})
|
||||
public class CustomizerRegistry {
|
||||
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) {
|
||||
this.customizerTypes = customizerTypes;
|
||||
@@ -24,7 +24,7 @@ public class CustomizerRegistry {
|
||||
if (type.isAssignableFrom(klass)) {
|
||||
List<KeyFactoryCustomizer> list = customizers.get(type);
|
||||
if (list == null) {
|
||||
customizers.put(type, list = new ArrayList<KeyFactoryCustomizer>());
|
||||
customizers.put(type, list = new ArrayList<>());
|
||||
}
|
||||
list.add(customizer);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
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"})
|
||||
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, KK> keyMapper;
|
||||
|
||||
public static final Function IDENTITY = new Function() {
|
||||
public Object apply(Object key) {
|
||||
return key;
|
||||
}
|
||||
};
|
||||
public static final Function IDENTITY = key -> key;
|
||||
|
||||
public LoadingCache(Function<K, KK> keyMapper, Function<K, V> loader) {
|
||||
this.keyMapper = keyMapper;
|
||||
this.loader = loader;
|
||||
this.map = new ConcurrentHashMap<KK, Object>();
|
||||
this.map = new ConcurrentHashMap<>();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@@ -50,11 +49,7 @@ public class LoadingCache<K, KK, V> {
|
||||
// Another thread is already loading an instance
|
||||
task = (FutureTask<V>) v;
|
||||
} else {
|
||||
task = new FutureTask<V>(new Callable<V>() {
|
||||
public V call() throws Exception {
|
||||
return loader.apply(key);
|
||||
}
|
||||
});
|
||||
task = new FutureTask<>(() -> loader.apply(key));
|
||||
Object prevTask = map.putIfAbsent(cacheKey, task);
|
||||
if (prevTask == null) {
|
||||
// creator does the load
|
||||
|
||||
@@ -22,12 +22,13 @@ import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
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.ClassVisitor;
|
||||
import org.springframework.asm.MethodVisitor;
|
||||
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
|
||||
@@ -80,7 +81,7 @@ class BridgeMethodResolver {
|
||||
private static class BridgedFinder extends ClassVisitor {
|
||||
private Map/*<Signature, Signature>*/ resolved;
|
||||
private Set/*<Signature>*/ eligibleMethods;
|
||||
|
||||
|
||||
private Signature currentMethod = null;
|
||||
|
||||
BridgedFinder(Set eligibleMethods, Map resolved) {
|
||||
@@ -89,17 +90,20 @@ class BridgeMethodResolver {
|
||||
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) {
|
||||
}
|
||||
|
||||
public MethodVisitor visitMethod(int access, String name, String desc,
|
||||
@Override
|
||||
public MethodVisitor visitMethod(int access, String name, String desc,
|
||||
String signature, String[] exceptions) {
|
||||
Signature sig = new Signature(name, desc);
|
||||
if (eligibleMethods.remove(sig)) {
|
||||
currentMethod = sig;
|
||||
return new MethodVisitor(Constants.ASM_API) {
|
||||
public void visitMethodInsn(
|
||||
@Override
|
||||
public void visitMethodInsn(
|
||||
int opcode, String owner, String name, String desc, boolean itf) {
|
||||
if ((opcode == Opcodes.INVOKESPECIAL
|
||||
|| (itf && opcode == Opcodes.INVOKEINTERFACE))
|
||||
|
||||
@@ -31,7 +31,7 @@ public interface CallbackFilter {
|
||||
/**
|
||||
* Map a method to a callback.
|
||||
* @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);
|
||||
|
||||
@@ -42,5 +42,6 @@ public interface CallbackFilter {
|
||||
* <code>hashCode</code> for custom <code>CallbackFilter</code>
|
||||
* implementations in order to improve performance.
|
||||
*/
|
||||
boolean equals(Object o);
|
||||
@Override
|
||||
boolean equals(Object o);
|
||||
}
|
||||
|
||||
@@ -16,7 +16,11 @@
|
||||
package org.springframework.cglib.proxy;
|
||||
|
||||
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"})
|
||||
interface CallbackGenerator
|
||||
|
||||
@@ -15,9 +15,13 @@
|
||||
*/
|
||||
package org.springframework.cglib.proxy;
|
||||
|
||||
import org.springframework.cglib.core.ReflectUtils;
|
||||
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 $
|
||||
@@ -28,22 +32,24 @@ implements CallbackFilter
|
||||
{
|
||||
private Map methodMap = new HashMap();
|
||||
private List callbacks = new ArrayList();
|
||||
|
||||
public CallbackHelper(Class superclass, Class[] interfaces)
|
||||
{
|
||||
|
||||
public CallbackHelper(Class superclass, Class[] interfaces) {
|
||||
List methods = new ArrayList();
|
||||
Enhancer.getMethods(superclass, interfaces, methods);
|
||||
Map indexes = new HashMap();
|
||||
for (int i = 0, size = methods.size(); i < size; i++) {
|
||||
Method method = (Method)methods.get(i);
|
||||
Object callback = getCallback(method);
|
||||
if (callback == null)
|
||||
if (callback == null) {
|
||||
throw new IllegalStateException("getCallback cannot return null");
|
||||
}
|
||||
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");
|
||||
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");
|
||||
}
|
||||
Integer index = (Integer)indexes.get(callback);
|
||||
if (index == null) {
|
||||
index = callbacks.size();
|
||||
@@ -56,44 +62,49 @@ implements CallbackFilter
|
||||
|
||||
abstract protected Object getCallback(Method method);
|
||||
|
||||
public Callback[] getCallbacks()
|
||||
{
|
||||
if (callbacks.size() == 0)
|
||||
public Callback[] getCallbacks() {
|
||||
if (callbacks.size() == 0) {
|
||||
return new Callback[0];
|
||||
}
|
||||
if (callbacks.get(0) instanceof Callback) {
|
||||
return (Callback[])callbacks.toArray(new Callback[callbacks.size()]);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
throw new IllegalStateException("getCallback returned classes, not callbacks; call getCallbackTypes instead");
|
||||
}
|
||||
}
|
||||
|
||||
public Class[] getCallbackTypes()
|
||||
{
|
||||
if (callbacks.size() == 0)
|
||||
public Class[] getCallbackTypes() {
|
||||
if (callbacks.size() == 0) {
|
||||
return new Class[0];
|
||||
}
|
||||
if (callbacks.get(0) instanceof Callback) {
|
||||
return ReflectUtils.getClasses(getCallbacks());
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
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();
|
||||
}
|
||||
|
||||
public int hashCode()
|
||||
{
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return methodMap.hashCode();
|
||||
}
|
||||
|
||||
public boolean equals(Object o)
|
||||
{
|
||||
if (o == null)
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (o == null) {
|
||||
return false;
|
||||
if (!(o instanceof CallbackHelper))
|
||||
}
|
||||
if (!(o instanceof CallbackHelper other)) {
|
||||
return false;
|
||||
return methodMap.equals(((CallbackHelper)o).methodMap);
|
||||
}
|
||||
return this.methodMap.equals(other.methodMap);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -57,7 +57,7 @@ class CallbackInfo
|
||||
private Class cls;
|
||||
private CallbackGenerator generator;
|
||||
private Type type;
|
||||
|
||||
|
||||
private static final CallbackInfo[] CALLBACKS = {
|
||||
new CallbackInfo(NoOp.class, NoOpGenerator.INSTANCE),
|
||||
new CallbackInfo(MethodInterceptor.class, MethodInterceptorGenerator.INSTANCE),
|
||||
@@ -84,8 +84,7 @@ class CallbackInfo
|
||||
private static Type determineType(Class callbackType, boolean checkAll) {
|
||||
Class cur = null;
|
||||
Type type = null;
|
||||
for (int i = 0; i < CALLBACKS.length; i++) {
|
||||
CallbackInfo info = CALLBACKS[i];
|
||||
for (CallbackInfo info : CALLBACKS) {
|
||||
if (info.cls.isAssignableFrom(callbackType)) {
|
||||
if (cur != null) {
|
||||
throw new IllegalStateException("Callback implements both " + cur + " and " + info.cls);
|
||||
@@ -104,8 +103,7 @@ class CallbackInfo
|
||||
}
|
||||
|
||||
private static CallbackGenerator getGenerator(Type callbackType) {
|
||||
for (int i = 0; i < CALLBACKS.length; i++) {
|
||||
CallbackInfo info = CALLBACKS[i];
|
||||
for (CallbackInfo info : CALLBACKS) {
|
||||
if (info.type.equals(callbackType)) {
|
||||
return info.generator;
|
||||
}
|
||||
@@ -113,5 +111,5 @@ class CallbackInfo
|
||||
throw new IllegalStateException("Unknown callback type " + callbackType);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -15,9 +15,15 @@
|
||||
*/
|
||||
package org.springframework.cglib.proxy;
|
||||
|
||||
import java.util.*;
|
||||
import org.springframework.cglib.core.*;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
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"})
|
||||
class DispatcherGenerator implements CallbackGenerator {
|
||||
@@ -41,7 +47,8 @@ class DispatcherGenerator implements CallbackGenerator {
|
||||
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();) {
|
||||
MethodInfo method = (MethodInfo)it.next();
|
||||
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) { }
|
||||
}
|
||||
|
||||
@@ -51,7 +51,6 @@ import org.springframework.cglib.core.ProcessSwitchCallback;
|
||||
import org.springframework.cglib.core.ReflectUtils;
|
||||
import org.springframework.cglib.core.RejectModifierPredicate;
|
||||
import org.springframework.cglib.core.Signature;
|
||||
import org.springframework.cglib.core.Transformer;
|
||||
import org.springframework.cglib.core.TypeUtils;
|
||||
import org.springframework.cglib.core.VisibilityPredicate;
|
||||
import org.springframework.cglib.core.WeakCacheKey;
|
||||
@@ -91,11 +90,7 @@ import org.springframework.cglib.core.WeakCacheKey;
|
||||
@SuppressWarnings({"rawtypes", "unchecked"})
|
||||
public class Enhancer extends AbstractClassGenerator {
|
||||
|
||||
private static final CallbackFilter ALL_ZERO = new CallbackFilter() {
|
||||
public int accept(Method method) {
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
private static final CallbackFilter ALL_ZERO = method -> 0;
|
||||
|
||||
private static final Source SOURCE = new Source(Enhancer.class.getName());
|
||||
|
||||
@@ -463,12 +458,12 @@ public class Enhancer extends AbstractClassGenerator {
|
||||
callbackTypes = CallbackInfo.determineTypes(callbacks);
|
||||
}
|
||||
if (interfaces != null) {
|
||||
for (int i = 0; i < interfaces.length; i++) {
|
||||
if (interfaces[i] == null) {
|
||||
for (Class element : interfaces) {
|
||||
if (element == null) {
|
||||
throw new IllegalStateException("Interfaces cannot be null");
|
||||
}
|
||||
if (!interfaces[i].isInterface()) {
|
||||
throw new IllegalStateException(interfaces[i] + " is not an interface");
|
||||
if (!element.isInterface()) {
|
||||
throw new IllegalStateException(element + " is not an interface");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -557,7 +552,7 @@ public class Enhancer extends AbstractClassGenerator {
|
||||
// SPRING PATCH BEGIN
|
||||
Object key = new EnhancerKey((superclass != null ? superclass.getName() : 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),
|
||||
useFactory,
|
||||
interceptDuringConstruction,
|
||||
@@ -580,6 +575,7 @@ public class Enhancer extends AbstractClassGenerator {
|
||||
return super.generate(data);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ClassLoader getDefaultClassLoader() {
|
||||
if (superclass != null) {
|
||||
return superclass.getClassLoader();
|
||||
@@ -592,6 +588,7 @@ public class Enhancer extends AbstractClassGenerator {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ProtectionDomain getProtectionDomain() {
|
||||
if (superclass != null) {
|
||||
return ReflectUtils.getProtectionDomain(superclass);
|
||||
@@ -630,9 +627,9 @@ public class Enhancer extends AbstractClassGenerator {
|
||||
ReflectUtils.addAllMethods(superclass, methods);
|
||||
List target = (interfaceMethods != null) ? interfaceMethods : methods;
|
||||
if (interfaces != null) {
|
||||
for (int i = 0; i < interfaces.length; i++) {
|
||||
if (interfaces[i] != Factory.class) {
|
||||
ReflectUtils.addAllMethods(interfaces[i], target);
|
||||
for (Class element : interfaces) {
|
||||
if (element != Factory.class) {
|
||||
ReflectUtils.addAllMethods(element, target);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -648,11 +645,13 @@ public class Enhancer extends AbstractClassGenerator {
|
||||
CollectionUtils.filter(methods, new RejectModifierPredicate(Constants.ACC_FINAL));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void generateClass(ClassVisitor v) throws Exception {
|
||||
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());
|
||||
}
|
||||
List constructors = new ArrayList(Arrays.asList(sc.getDeclaredConstructors()));
|
||||
filterConstructors(sc, constructors);
|
||||
|
||||
@@ -664,19 +663,17 @@ public class Enhancer extends AbstractClassGenerator {
|
||||
final Set forcePublic = new HashSet();
|
||||
getMethods(sc, interfaces, actualMethods, interfaceMethods, forcePublic);
|
||||
|
||||
List methods = CollectionUtils.transform(actualMethods, new Transformer() {
|
||||
public Object transform(Object value) {
|
||||
Method method = (Method) value;
|
||||
int modifiers = Constants.ACC_FINAL
|
||||
| (method.getModifiers()
|
||||
& ~Constants.ACC_ABSTRACT
|
||||
& ~Constants.ACC_NATIVE
|
||||
& ~Constants.ACC_SYNCHRONIZED);
|
||||
if (forcePublic.contains(MethodWrapper.create(method))) {
|
||||
modifiers = (modifiers & ~Constants.ACC_PROTECTED) | Constants.ACC_PUBLIC;
|
||||
}
|
||||
return ReflectUtils.getMethodInfo(method, modifiers);
|
||||
List methods = CollectionUtils.transform(actualMethods, value -> {
|
||||
Method method = (Method) value;
|
||||
int modifiers = Constants.ACC_FINAL
|
||||
| (method.getModifiers()
|
||||
& ~Constants.ACC_ABSTRACT
|
||||
& ~Constants.ACC_NATIVE
|
||||
& ~Constants.ACC_SYNCHRONIZED);
|
||||
if (forcePublic.contains(MethodWrapper.create(method))) {
|
||||
modifiers = (modifiers & ~Constants.ACC_PROTECTED) | Constants.ACC_PUBLIC;
|
||||
}
|
||||
return ReflectUtils.getMethodInfo(method, modifiers);
|
||||
});
|
||||
|
||||
ClassEmitter e = new ClassEmitter(v);
|
||||
@@ -754,8 +751,9 @@ public class Enhancer extends AbstractClassGenerator {
|
||||
*/
|
||||
protected void filterConstructors(Class sc, List constructors) {
|
||||
CollectionUtils.filter(constructors, new VisibilityPredicate(sc, true));
|
||||
if (constructors.size() == 0)
|
||||
if (constructors.size() == 0) {
|
||||
throw new IllegalArgumentException("No visible constructors in " + sc);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -767,6 +765,7 @@ public class Enhancer extends AbstractClassGenerator {
|
||||
* @return newly created proxy instance
|
||||
* @throws Exception if something goes wrong
|
||||
*/
|
||||
@Override
|
||||
protected Object firstInstance(Class type) throws Exception {
|
||||
if (classOnly) {
|
||||
return type;
|
||||
@@ -776,6 +775,7 @@ public class Enhancer extends AbstractClassGenerator {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Object nextInstance(Object instance) {
|
||||
EnhancerFactoryData data = (EnhancerFactoryData) instance;
|
||||
|
||||
@@ -809,13 +809,10 @@ public class Enhancer extends AbstractClassGenerator {
|
||||
callbackFilterField.setAccessible(true);
|
||||
callbackFilterField.set(null, this.filter);
|
||||
}
|
||||
catch (NoSuchFieldException e) {
|
||||
catch (NoSuchFieldException | IllegalAccessException e) {
|
||||
throw new CodeGenerationException(e);
|
||||
}
|
||||
catch (IllegalAccessException e) {
|
||||
throw new CodeGenerationException(e);
|
||||
}
|
||||
return new WeakReference<EnhancerFactoryData>(factoryData);
|
||||
return new WeakReference<>(factoryData);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -895,10 +892,7 @@ public class Enhancer extends AbstractClassGenerator {
|
||||
catch (NoSuchMethodException e) {
|
||||
throw new IllegalArgumentException(type + " is not an enhanced class");
|
||||
}
|
||||
catch (IllegalAccessException e) {
|
||||
throw new CodeGenerationException(e);
|
||||
}
|
||||
catch (InvocationTargetException e) {
|
||||
catch (IllegalAccessException | InvocationTargetException e) {
|
||||
throw new CodeGenerationException(e);
|
||||
}
|
||||
}
|
||||
@@ -1027,8 +1021,9 @@ public class Enhancer extends AbstractClassGenerator {
|
||||
e.return_value();
|
||||
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");
|
||||
}
|
||||
}
|
||||
|
||||
private int[] getCallbackKeys() {
|
||||
@@ -1046,11 +1041,13 @@ public class Enhancer extends AbstractClassGenerator {
|
||||
e.load_this();
|
||||
e.load_arg(0);
|
||||
e.process_switch(keys, new ProcessSwitchCallback() {
|
||||
@Override
|
||||
public void processCase(int key, Label end) {
|
||||
e.getfield(getCallbackField(key));
|
||||
e.goTo(end);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processDefault() {
|
||||
e.pop(); // stack height
|
||||
e.aconst_null();
|
||||
@@ -1064,6 +1061,7 @@ public class Enhancer extends AbstractClassGenerator {
|
||||
final CodeEmitter e = ce.begin_method(Constants.ACC_PUBLIC, SET_CALLBACK, null);
|
||||
e.load_arg(0);
|
||||
e.process_switch(keys, new ProcessSwitchCallback() {
|
||||
@Override
|
||||
public void processCase(int key, Label end) {
|
||||
e.load_this();
|
||||
e.load_arg(1);
|
||||
@@ -1072,6 +1070,7 @@ public class Enhancer extends AbstractClassGenerator {
|
||||
e.goTo(end);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processDefault() {
|
||||
// TODO: error?
|
||||
}
|
||||
@@ -1171,6 +1170,7 @@ public class Enhancer extends AbstractClassGenerator {
|
||||
e.dup();
|
||||
e.load_arg(0);
|
||||
EmitUtils.constructor_switch(e, constructors, new ObjectSwitchCallback() {
|
||||
@Override
|
||||
public void processCase(Object key, Label end) {
|
||||
MethodInfo constructor = (MethodInfo) key;
|
||||
Type types[] = constructor.getSignature().getArgumentTypes();
|
||||
@@ -1184,6 +1184,7 @@ public class Enhancer extends AbstractClassGenerator {
|
||||
e.goTo(end);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processDefault() {
|
||||
e.throw_exception(ILLEGAL_ARGUMENT_EXCEPTION, "Constructor not found");
|
||||
}
|
||||
@@ -1243,26 +1244,32 @@ public class Enhancer extends AbstractClassGenerator {
|
||||
se.putfield(THREAD_CALLBACKS_FIELD);
|
||||
|
||||
CallbackGenerator.Context context = new CallbackGenerator.Context() {
|
||||
@Override
|
||||
public ClassLoader getClassLoader() {
|
||||
return Enhancer.this.getClassLoader();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOriginalModifiers(MethodInfo method) {
|
||||
return ((Integer) originalModifiers.get(method)).intValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getIndex(MethodInfo method) {
|
||||
return ((Integer) indexes.get(method)).intValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void emitCallback(CodeEmitter e, int index) {
|
||||
emitCurrentCallback(e, index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Signature getImplSignature(MethodInfo method) {
|
||||
return rename(method.getSignature(), ((Integer) positions.get(method)).intValue());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void emitLoadArgsAndInvoke(CodeEmitter e, MethodInfo method) {
|
||||
// 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
|
||||
@@ -1302,6 +1309,7 @@ public class Enhancer extends AbstractClassGenerator {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public CodeEmitter beginMethod(ClassEmitter ce, MethodInfo method) {
|
||||
CodeEmitter e = EmitUtils.begin_method(ce, method);
|
||||
if (!interceptDuringConstruction &&
|
||||
|
||||
@@ -32,14 +32,14 @@ public interface Factory {
|
||||
* If multiple callbacks are required an exception will be thrown.
|
||||
* @param callback the new interceptor to use
|
||||
* @return new instance of the same type
|
||||
*/
|
||||
*/
|
||||
Object newInstance(Callback callback);
|
||||
|
||||
|
||||
/**
|
||||
* Creates new instance of the same type, using the no-arg constructor.
|
||||
* @param callbacks the new callbacks(s) to use
|
||||
* @return new instance of the same type
|
||||
*/
|
||||
*/
|
||||
Object newInstance(Callback[] callbacks);
|
||||
|
||||
/**
|
||||
@@ -75,6 +75,6 @@ public interface Factory {
|
||||
/**
|
||||
* Get the current set of callbacks for ths object.
|
||||
* @return a new array instance
|
||||
*/
|
||||
*/
|
||||
Callback[] getCallbacks();
|
||||
}
|
||||
|
||||
@@ -15,9 +15,15 @@
|
||||
*/
|
||||
package org.springframework.cglib.proxy;
|
||||
|
||||
import java.util.*;
|
||||
import org.springframework.cglib.core.*;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
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"})
|
||||
class FixedValueGenerator implements CallbackGenerator {
|
||||
@@ -27,7 +33,8 @@ class FixedValueGenerator implements CallbackGenerator {
|
||||
private static final Signature LOAD_OBJECT =
|
||||
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();) {
|
||||
MethodInfo method = (MethodInfo)it.next();
|
||||
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) { }
|
||||
}
|
||||
|
||||
@@ -15,11 +15,18 @@
|
||||
*/
|
||||
package org.springframework.cglib.proxy;
|
||||
|
||||
import java.lang.reflect.*;
|
||||
import java.util.*;
|
||||
import org.springframework.cglib.core.*;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.asm.ClassVisitor;
|
||||
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.
|
||||
@@ -71,8 +78,7 @@ public class InterfaceMaker extends AbstractClassGenerator
|
||||
*/
|
||||
public void add(Class clazz) {
|
||||
Method[] methods = clazz.getMethods();
|
||||
for (int i = 0; i < methods.length; i++) {
|
||||
Method m = methods[i];
|
||||
for (Method m : methods) {
|
||||
if (!m.getDeclaringClass().getName().equals("java.lang.Object")) {
|
||||
add(m);
|
||||
}
|
||||
@@ -87,19 +93,23 @@ public class InterfaceMaker extends AbstractClassGenerator
|
||||
return (Class)super.create(this);
|
||||
}
|
||||
|
||||
protected ClassLoader getDefaultClassLoader() {
|
||||
@Override
|
||||
protected ClassLoader getDefaultClassLoader() {
|
||||
return null;
|
||||
}
|
||||
|
||||
protected Object firstInstance(Class type) {
|
||||
|
||||
@Override
|
||||
protected Object firstInstance(Class type) {
|
||||
return type;
|
||||
}
|
||||
|
||||
protected Object nextInstance(Object instance) {
|
||||
@Override
|
||||
protected Object nextInstance(Object instance) {
|
||||
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);
|
||||
ce.begin_class(Constants.V1_8,
|
||||
Constants.ACC_PUBLIC | Constants.ACC_INTERFACE | Constants.ACC_ABSTRACT,
|
||||
|
||||
@@ -15,9 +15,18 @@
|
||||
*/
|
||||
package org.springframework.cglib.proxy;
|
||||
|
||||
import org.springframework.cglib.core.*;
|
||||
import java.util.*;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
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"})
|
||||
class InvocationHandlerGenerator
|
||||
@@ -34,7 +43,8 @@ implements CallbackGenerator
|
||||
private static final Signature INVOKE =
|
||||
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();) {
|
||||
MethodInfo method = (MethodInfo)it.next();
|
||||
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();) {
|
||||
MethodInfo method = (MethodInfo)it.next();
|
||||
EmitUtils.load_method(e, method);
|
||||
|
||||
@@ -15,21 +15,31 @@
|
||||
*/
|
||||
package org.springframework.cglib.proxy;
|
||||
|
||||
import java.util.*;
|
||||
import org.springframework.cglib.core.*;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.springframework.asm.Label;
|
||||
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"})
|
||||
class LazyLoaderGenerator implements CallbackGenerator {
|
||||
public static final LazyLoaderGenerator INSTANCE = new LazyLoaderGenerator();
|
||||
|
||||
private static final Signature LOAD_OBJECT =
|
||||
private static final Signature LOAD_OBJECT =
|
||||
TypeUtils.parseSignature("Object loadObject()");
|
||||
private static final Type LAZY_LOADER =
|
||||
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();
|
||||
for (Iterator it = methods.iterator(); it.hasNext();) {
|
||||
MethodInfo method = (MethodInfo)it.next();
|
||||
@@ -75,7 +85,7 @@ class LazyLoaderGenerator implements CallbackGenerator {
|
||||
e.mark(end);
|
||||
e.return_value();
|
||||
e.end_method();
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -85,5 +95,6 @@ class LazyLoaderGenerator implements CallbackGenerator {
|
||||
Constants.TYPES_EMPTY);
|
||||
}
|
||||
|
||||
public void generateStatic(CodeEmitter e, Context context, List methods) { }
|
||||
@Override
|
||||
public void generateStatic(CodeEmitter e, Context context, List methods) { }
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ extends Callback
|
||||
* @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.
|
||||
* @see MethodProxy
|
||||
*/
|
||||
*/
|
||||
public Object intercept(Object obj, java.lang.reflect.Method method, Object[] args,
|
||||
MethodProxy proxy) throws Throwable;
|
||||
|
||||
|
||||
@@ -79,12 +79,7 @@ implements CallbackGenerator
|
||||
new Signature(FIND_PROXY_NAME, METHOD_PROXY, new Type[]{ Constants.TYPE_SIGNATURE });
|
||||
private static final Signature TO_STRING =
|
||||
TypeUtils.parseSignature("String toString()");
|
||||
private static final Transformer METHOD_TO_CLASS = new Transformer(){
|
||||
@Override
|
||||
public Object transform(Object value) {
|
||||
return ((MethodInfo)value).getClassInfo();
|
||||
}
|
||||
};
|
||||
private static final Transformer METHOD_TO_CLASS = value -> ((MethodInfo)value).getClassInfo();
|
||||
|
||||
private String getMethodField(Signature impl) {
|
||||
return impl.getName() + "$Method";
|
||||
|
||||
@@ -234,8 +234,9 @@ public class MethodProxy {
|
||||
throw ex.getTargetException();
|
||||
}
|
||||
catch (IllegalArgumentException ex) {
|
||||
if (fastClassInfo.i1 < 0)
|
||||
if (fastClassInfo.i1 < 0) {
|
||||
throw new IllegalArgumentException("Protected method: " + sig1);
|
||||
}
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,8 +16,9 @@
|
||||
package org.springframework.cglib.proxy;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import org.springframework.cglib.core.ReflectUtils;
|
||||
|
||||
import org.springframework.asm.ClassVisitor;
|
||||
import org.springframework.cglib.core.ReflectUtils;
|
||||
|
||||
/**
|
||||
* @author Chris Nokleberg
|
||||
@@ -29,11 +30,13 @@ class MixinBeanEmitter extends MixinEmitter {
|
||||
super(v, className, classes, null);
|
||||
}
|
||||
|
||||
protected Class[] getInterfaces(Class[] classes) {
|
||||
@Override
|
||||
protected Class[] getInterfaces(Class[] classes) {
|
||||
return null;
|
||||
}
|
||||
|
||||
protected Method[] getMethods(Class type) {
|
||||
@Override
|
||||
protected Method[] getMethods(Class type) {
|
||||
return ReflectUtils.getPropertyMethods(ReflectUtils.getBeanProperties(type), true, true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,10 +16,20 @@
|
||||
package org.springframework.cglib.proxy;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.*;
|
||||
import org.springframework.cglib.core.*;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import org.springframework.asm.ClassVisitor;
|
||||
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
|
||||
@@ -61,20 +71,20 @@ class MixinEmitter extends ClassEmitter {
|
||||
Set unique = new HashSet();
|
||||
for (int i = 0; i < classes.length; i++) {
|
||||
Method[] methods = getMethods(classes[i]);
|
||||
for (int j = 0; j < methods.length; j++) {
|
||||
if (unique.add(MethodWrapper.create(methods[j]))) {
|
||||
MethodInfo method = ReflectUtils.getMethodInfo(methods[j]);
|
||||
for (Method method : methods) {
|
||||
if (unique.add(MethodWrapper.create(method))) {
|
||||
MethodInfo methodInfo = ReflectUtils.getMethodInfo(method);
|
||||
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;
|
||||
}
|
||||
e = EmitUtils.begin_method(this, method, modifiers);
|
||||
e = EmitUtils.begin_method(this, methodInfo, modifiers);
|
||||
e.load_this();
|
||||
e.getfield(FIELD_NAME);
|
||||
e.aaload((route != null) ? route[i] : i);
|
||||
e.checkcast(method.getClassInfo().getType());
|
||||
e.checkcast(methodInfo.getClassInfo().getType());
|
||||
e.load_args();
|
||||
e.invoke(method);
|
||||
e.invoke(methodInfo);
|
||||
e.return_value();
|
||||
e.end_method();
|
||||
}
|
||||
|
||||
@@ -13,15 +13,19 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cglib.proxy;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
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.ReflectUtils;
|
||||
import org.springframework.cglib.core.RejectModifierPredicate;
|
||||
import org.springframework.asm.ClassVisitor;
|
||||
|
||||
/**
|
||||
* @author Chris Nokleberg
|
||||
@@ -34,15 +38,17 @@ class MixinEverythingEmitter extends MixinEmitter {
|
||||
super(v, className, classes, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Class[] getInterfaces(Class[] classes) {
|
||||
List list = new ArrayList();
|
||||
for (int i = 0; i < classes.length; i++) {
|
||||
ReflectUtils.addAllInterfaces(classes[i], list);
|
||||
for (Class clazz : classes) {
|
||||
ReflectUtils.addAllInterfaces(clazz, list);
|
||||
}
|
||||
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()));
|
||||
CollectionUtils.filter(methods, new RejectModifierPredicate(Modifier.FINAL | Modifier.STATIC));
|
||||
return (Method[])methods.toArray(new Method[methods.size()]);
|
||||
|
||||
@@ -17,7 +17,12 @@ package org.springframework.cglib.proxy;
|
||||
|
||||
import java.util.Iterator;
|
||||
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"})
|
||||
class NoOpGenerator
|
||||
@@ -25,7 +30,8 @@ implements CallbackGenerator
|
||||
{
|
||||
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();) {
|
||||
MethodInfo method = (MethodInfo)it.next();
|
||||
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) { }
|
||||
}
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
package org.springframework.cglib.proxy;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import org.springframework.cglib.core.CodeGenerationException;
|
||||
|
||||
@@ -40,20 +39,17 @@ import org.springframework.cglib.core.CodeGenerationException;
|
||||
public class Proxy implements Serializable {
|
||||
protected InvocationHandler h;
|
||||
|
||||
private static final CallbackFilter BAD_OBJECT_METHOD_FILTER = new CallbackFilter() {
|
||||
@Override
|
||||
public int accept(Method method) {
|
||||
if (method.getDeclaringClass().getName().equals("java.lang.Object")) {
|
||||
String name = method.getName();
|
||||
if (!(name.equals("hashCode") ||
|
||||
name.equals("equals") ||
|
||||
name.equals("toString"))) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
private static final CallbackFilter BAD_OBJECT_METHOD_FILTER = method -> {
|
||||
if (method.getDeclaringClass().getName().equals("java.lang.Object")) {
|
||||
String name = method.getName();
|
||||
if (!(name.equals("hashCode") ||
|
||||
name.equals("equals") ||
|
||||
name.equals("toString"))) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
};
|
||||
|
||||
protected Proxy(InvocationHandler h) {
|
||||
Enhancer.registerCallbacks(getClass(), new Callback[]{ h, null });
|
||||
|
||||
@@ -30,7 +30,7 @@ public class UndeclaredThrowableException extends CodeGenerationException {
|
||||
public UndeclaredThrowableException(Throwable t) {
|
||||
super(t);
|
||||
}
|
||||
|
||||
|
||||
public Throwable getUndeclaredThrowable() {
|
||||
return getCause();
|
||||
}
|
||||
|
||||
@@ -15,11 +15,20 @@
|
||||
*/
|
||||
package org.springframework.cglib.reflect;
|
||||
|
||||
import java.lang.reflect.*;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Method;
|
||||
import java.security.ProtectionDomain;
|
||||
import org.springframework.cglib.core.*;
|
||||
|
||||
import org.springframework.asm.ClassVisitor;
|
||||
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
|
||||
@@ -29,7 +38,7 @@ import org.springframework.asm.Type;
|
||||
abstract public class ConstructorDelegate {
|
||||
private static final ConstructorKey KEY_FACTORY =
|
||||
(ConstructorKey)KeyFactory.create(ConstructorKey.class, KeyFactory.CLASS_BY_NAME);
|
||||
|
||||
|
||||
interface ConstructorKey {
|
||||
public Object newInstance(String declaring, String iface);
|
||||
}
|
||||
@@ -70,15 +79,18 @@ abstract public class ConstructorDelegate {
|
||||
return (ConstructorDelegate)super.create(key);
|
||||
}
|
||||
|
||||
protected ClassLoader getDefaultClassLoader() {
|
||||
@Override
|
||||
protected ClassLoader getDefaultClassLoader() {
|
||||
return targetClass.getClassLoader();
|
||||
}
|
||||
|
||||
protected ProtectionDomain getProtectionDomain() {
|
||||
@Override
|
||||
protected ProtectionDomain getProtectionDomain() {
|
||||
return ReflectUtils.getProtectionDomain(targetClass);
|
||||
}
|
||||
|
||||
public void generateClass(ClassVisitor v) {
|
||||
@Override
|
||||
public void generateClass(ClassVisitor v) {
|
||||
setNamePrefix(targetClass.getName());
|
||||
|
||||
final Method newInstance = ReflectUtils.findNewInstance(iface);
|
||||
@@ -113,11 +125,13 @@ abstract public class ConstructorDelegate {
|
||||
ce.end_class();
|
||||
}
|
||||
|
||||
protected Object firstInstance(Class type) {
|
||||
@Override
|
||||
protected Object firstInstance(Class type) {
|
||||
return ReflectUtils.newInstance(type);
|
||||
}
|
||||
|
||||
protected Object nextInstance(Object instance) {
|
||||
@Override
|
||||
protected Object nextInstance(Object instance) {
|
||||
return instance;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,13 +15,17 @@
|
||||
*/
|
||||
package org.springframework.cglib.reflect;
|
||||
|
||||
import org.springframework.cglib.core.*;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.security.ProtectionDomain;
|
||||
|
||||
import org.springframework.asm.ClassVisitor;
|
||||
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"})
|
||||
abstract public class FastClass
|
||||
@@ -37,9 +41,9 @@ abstract public class FastClass
|
||||
}
|
||||
|
||||
public static FastClass create(Class type) {
|
||||
|
||||
|
||||
return create(type.getClassLoader(),type);
|
||||
|
||||
|
||||
}
|
||||
public static FastClass create(ClassLoader loader, Class type) {
|
||||
Generator gen = new Generator();
|
||||
@@ -52,7 +56,7 @@ abstract public class FastClass
|
||||
{
|
||||
private static final Source SOURCE = new Source(FastClass.class.getName());
|
||||
private Class type;
|
||||
|
||||
|
||||
public Generator() {
|
||||
super(SOURCE);
|
||||
}
|
||||
@@ -60,35 +64,40 @@ abstract public class FastClass
|
||||
public void setType(Class type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
|
||||
public FastClass create() {
|
||||
setNamePrefix(type.getName());
|
||||
return (FastClass)super.create(type.getName());
|
||||
}
|
||||
|
||||
protected ClassLoader getDefaultClassLoader() {
|
||||
@Override
|
||||
protected ClassLoader getDefaultClassLoader() {
|
||||
return type.getClassLoader();
|
||||
}
|
||||
|
||||
protected ProtectionDomain getProtectionDomain() {
|
||||
@Override
|
||||
protected ProtectionDomain getProtectionDomain() {
|
||||
return ReflectUtils.getProtectionDomain(type);
|
||||
}
|
||||
|
||||
public void generateClass(ClassVisitor v) throws Exception {
|
||||
@Override
|
||||
public void generateClass(ClassVisitor v) throws Exception {
|
||||
new FastClassEmitter(v, getClassName(), type);
|
||||
}
|
||||
|
||||
protected Object firstInstance(Class type) {
|
||||
@Override
|
||||
protected Object firstInstance(Class type) {
|
||||
return ReflectUtils.newInstance(type,
|
||||
new Class[]{ Class.class },
|
||||
new Object[]{ this.type });
|
||||
}
|
||||
|
||||
protected Object nextInstance(Object instance) {
|
||||
@Override
|
||||
protected Object nextInstance(Object instance) {
|
||||
return instance;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public Object invoke(String name, Class[] parameterTypes, Object obj, Object[] args) throws InvocationTargetException {
|
||||
return invoke(getIndex(name, parameterTypes), obj, args);
|
||||
}
|
||||
@@ -100,7 +109,7 @@ abstract public class FastClass
|
||||
public Object newInstance(Class[] parameterTypes, Object[] args) throws InvocationTargetException {
|
||||
return newInstance(getIndex(parameterTypes), args);
|
||||
}
|
||||
|
||||
|
||||
public FastMethod getMethod(Method method) {
|
||||
return new FastMethod(this, method);
|
||||
}
|
||||
@@ -133,15 +142,18 @@ abstract public class FastClass
|
||||
return type;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
@Override
|
||||
public String toString() {
|
||||
return type.toString();
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return type.hashCode();
|
||||
}
|
||||
|
||||
public boolean equals(Object o) {
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (o == null || !(o instanceof FastClass)) {
|
||||
return false;
|
||||
}
|
||||
@@ -199,8 +211,8 @@ abstract public class FastClass
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(name);
|
||||
sb.append('(');
|
||||
for (int i = 0; i < parameterTypes.length; i++) {
|
||||
sb.append(Type.getDescriptor(parameterTypes[i]));
|
||||
for (Class parameterType : parameterTypes) {
|
||||
sb.append(Type.getDescriptor(parameterType));
|
||||
}
|
||||
sb.append(')');
|
||||
return sb.toString();
|
||||
|
||||
@@ -13,14 +13,35 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cglib.reflect;
|
||||
|
||||
import java.lang.reflect.*;
|
||||
import java.util.*;
|
||||
import org.springframework.cglib.core.*;
|
||||
import java.lang.reflect.Method;
|
||||
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.ClassVisitor;
|
||||
import org.springframework.asm.Label;
|
||||
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"})
|
||||
class FastClassEmitter extends ClassEmitter {
|
||||
@@ -49,7 +70,7 @@ class FastClassEmitter extends ClassEmitter {
|
||||
private static final Type INVOCATION_TARGET_EXCEPTION =
|
||||
TypeUtils.parseType("java.lang.reflect.InvocationTargetException");
|
||||
private static final Type[] INVOCATION_TARGET_EXCEPTION_ARRAY = { INVOCATION_TARGET_EXCEPTION };
|
||||
|
||||
|
||||
public FastClassEmitter(ClassVisitor v, String className, Class type) {
|
||||
super(v);
|
||||
|
||||
@@ -70,13 +91,13 @@ class FastClassEmitter extends ClassEmitter {
|
||||
CollectionUtils.filter(methods, new DuplicatesPredicate());
|
||||
List constructors = new ArrayList(Arrays.asList(type.getDeclaredConstructors()));
|
||||
CollectionUtils.filter(constructors, vp);
|
||||
|
||||
|
||||
// getIndex(String)
|
||||
emitIndexBySignature(methods);
|
||||
|
||||
// getIndex(String, Class[])
|
||||
emitIndexByClassArray(methods);
|
||||
|
||||
|
||||
// getIndex(Class[])
|
||||
e = begin_method(Constants.ACC_PUBLIC, CONSTRUCTOR_GET_INDEX, null);
|
||||
e.load_args();
|
||||
@@ -112,11 +133,7 @@ class FastClassEmitter extends ClassEmitter {
|
||||
// TODO: support constructor indices ("<init>")
|
||||
private void emitIndexBySignature(List methods) {
|
||||
CodeEmitter e = begin_method(Constants.ACC_PUBLIC, SIGNATURE_GET_INDEX, null);
|
||||
List signatures = CollectionUtils.transform(methods, new Transformer() {
|
||||
public Object transform(Object obj) {
|
||||
return ReflectUtils.getSignature((Method)obj).toString();
|
||||
}
|
||||
});
|
||||
List signatures = CollectionUtils.transform(methods, obj -> ReflectUtils.getSignature((Method)obj).toString());
|
||||
e.load_arg(0);
|
||||
e.invoke_virtual(Constants.TYPE_OBJECT, TO_STRING);
|
||||
signatureSwitchHelper(e, signatures);
|
||||
@@ -128,12 +145,10 @@ class FastClassEmitter extends ClassEmitter {
|
||||
CodeEmitter e = begin_method(Constants.ACC_PUBLIC, METHOD_GET_INDEX, null);
|
||||
if (methods.size() > TOO_MANY_METHODS) {
|
||||
// hack for big classes
|
||||
List signatures = CollectionUtils.transform(methods, new Transformer() {
|
||||
public Object transform(Object obj) {
|
||||
String s = ReflectUtils.getSignature((Method)obj).toString();
|
||||
return s.substring(0, s.lastIndexOf(')') + 1);
|
||||
}
|
||||
});
|
||||
List signatures = CollectionUtils.transform(methods, obj -> {
|
||||
String s = ReflectUtils.getSignature((Method)obj).toString();
|
||||
return s.substring(0, s.lastIndexOf(')') + 1);
|
||||
});
|
||||
e.load_args();
|
||||
e.invoke_static(FAST_CLASS, GET_SIGNATURE_WITHOUT_RETURN_TYPE);
|
||||
signatureSwitchHelper(e, signatures);
|
||||
@@ -147,12 +162,14 @@ class FastClassEmitter extends ClassEmitter {
|
||||
|
||||
private void signatureSwitchHelper(final CodeEmitter e, final List signatures) {
|
||||
ObjectSwitchCallback callback = new ObjectSwitchCallback() {
|
||||
public void processCase(Object key, Label end) {
|
||||
@Override
|
||||
public void processCase(Object key, Label end) {
|
||||
// TODO: remove linear indexOf
|
||||
e.push(signatures.indexOf(key));
|
||||
e.return_value();
|
||||
}
|
||||
public void processDefault() {
|
||||
@Override
|
||||
public void processDefault() {
|
||||
e.push(-1);
|
||||
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) {
|
||||
final List info = CollectionUtils.transform(members, MethodInfoTransformer.getInstance());
|
||||
final List info = CollectionUtils.transform(members, MethodInfoTransformer.getInstance());
|
||||
final Label illegalArg = e.make_label();
|
||||
Block block = e.begin_block();
|
||||
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);
|
||||
Type[] types = method.getSignature().getArgumentTypes();
|
||||
for (int i = 0; i < types.length; i++) {
|
||||
@@ -184,7 +202,8 @@ class FastClassEmitter extends ClassEmitter {
|
||||
}
|
||||
e.return_value();
|
||||
}
|
||||
public void processDefault() {
|
||||
@Override
|
||||
public void processDefault() {
|
||||
e.goTo(illegalArg);
|
||||
}
|
||||
});
|
||||
@@ -205,18 +224,20 @@ class FastClassEmitter extends ClassEmitter {
|
||||
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.return_value();
|
||||
}
|
||||
|
||||
public void processDefault() {
|
||||
|
||||
@Override
|
||||
public void processDefault() {
|
||||
e.push(-1);
|
||||
e.return_value();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static int[] getIntRange(int length) {
|
||||
int[] range = new int[length];
|
||||
for (int i = 0; i < length; i++) {
|
||||
|
||||
@@ -25,11 +25,13 @@ public class FastConstructor extends FastMember
|
||||
super(fc, constructor, fc.getIndex(constructor.getParameterTypes()));
|
||||
}
|
||||
|
||||
public Class[] getParameterTypes() {
|
||||
@Override
|
||||
public Class[] getParameterTypes() {
|
||||
return ((Constructor)member).getParameterTypes();
|
||||
}
|
||||
|
||||
public Class[] getExceptionTypes() {
|
||||
@Override
|
||||
public Class[] getExceptionTypes() {
|
||||
return ((Constructor)member).getExceptionTypes();
|
||||
}
|
||||
|
||||
|
||||
@@ -49,18 +49,22 @@ abstract public class FastMember
|
||||
return member.getModifiers();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return member.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return member.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (o == null || !(o instanceof FastMember)) {
|
||||
if (o == null || !(o instanceof FastMember other)) {
|
||||
return false;
|
||||
}
|
||||
return member.equals(((FastMember)o).member);
|
||||
return member.equals(other.member);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -18,9 +18,8 @@ package org.springframework.cglib.reflect;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import org.springframework.cglib.core.Signature;
|
||||
|
||||
import org.springframework.asm.Type;
|
||||
import org.springframework.cglib.core.Signature;
|
||||
|
||||
@SuppressWarnings({"rawtypes", "unchecked"})
|
||||
public class FastMethod extends FastMember
|
||||
@@ -46,11 +45,13 @@ public class FastMethod extends FastMember
|
||||
return ((Method)member).getReturnType();
|
||||
}
|
||||
|
||||
public Class[] getParameterTypes() {
|
||||
@Override
|
||||
public Class[] getParameterTypes() {
|
||||
return ((Method)member).getParameterTypes();
|
||||
}
|
||||
|
||||
public Class[] getExceptionTypes() {
|
||||
@Override
|
||||
public Class[] getExceptionTypes() {
|
||||
return ((Method)member).getExceptionTypes();
|
||||
}
|
||||
|
||||
|
||||
@@ -30,7 +30,6 @@ 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.ProcessArrayCallback;
|
||||
import org.springframework.cglib.core.ReflectUtils;
|
||||
import org.springframework.cglib.core.Signature;
|
||||
import org.springframework.cglib.core.TypeUtils;
|
||||
@@ -166,17 +165,14 @@ abstract public class MulticastDelegate implements Cloneable {
|
||||
e.load_this();
|
||||
e.super_getfield("targets", Constants.TYPE_OBJECT_ARRAY);
|
||||
final Local result2 = result;
|
||||
EmitUtils.process_array(e, Constants.TYPE_OBJECT_ARRAY, new ProcessArrayCallback() {
|
||||
@Override
|
||||
public void processElement(Type type) {
|
||||
e.checkcast(Type.getType(iface));
|
||||
e.load_args();
|
||||
e.invoke(method);
|
||||
if (returns) {
|
||||
e.store_local(result2);
|
||||
}
|
||||
}
|
||||
});
|
||||
EmitUtils.process_array(e, Constants.TYPE_OBJECT_ARRAY, type -> {
|
||||
e.checkcast(Type.getType(iface));
|
||||
e.load_args();
|
||||
e.invoke(method);
|
||||
if (returns) {
|
||||
e.store_local(result2);
|
||||
}
|
||||
});
|
||||
if (returns) {
|
||||
e.load_local(result);
|
||||
}
|
||||
|
||||
@@ -26,7 +26,8 @@ abstract public class AbstractClassFilterTransformer extends AbstractClassTransf
|
||||
private ClassTransformer pass;
|
||||
private ClassVisitor target;
|
||||
|
||||
public void setTarget(ClassVisitor target) {
|
||||
@Override
|
||||
public void setTarget(ClassVisitor target) {
|
||||
super.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);
|
||||
|
||||
public void visit(int version,
|
||||
@Override
|
||||
public void visit(int version,
|
||||
int access,
|
||||
String name,
|
||||
String signature,
|
||||
@@ -46,36 +48,43 @@ abstract public class AbstractClassFilterTransformer extends AbstractClassTransf
|
||||
target = accept(version, access, name, signature, superName, interfaces) ? pass : cv;
|
||||
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);
|
||||
}
|
||||
|
||||
public void visitOuterClass(String owner, String name, String desc) {
|
||||
|
||||
@Override
|
||||
public void visitOuterClass(String owner, String name, String 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);
|
||||
}
|
||||
|
||||
public void visitAttribute(Attribute attr) {
|
||||
|
||||
@Override
|
||||
public void visitAttribute(Attribute 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);
|
||||
}
|
||||
|
||||
public FieldVisitor visitField(int access,
|
||||
@Override
|
||||
public FieldVisitor visitField(int access,
|
||||
String name,
|
||||
String desc,
|
||||
String signature,
|
||||
Object value) {
|
||||
return target.visitField(access, name, desc, signature, value);
|
||||
}
|
||||
|
||||
public MethodVisitor visitMethod(int access,
|
||||
|
||||
@Override
|
||||
public MethodVisitor visitMethod(int access,
|
||||
String name,
|
||||
String desc,
|
||||
String signature,
|
||||
@@ -83,7 +92,8 @@ abstract public class AbstractClassFilterTransformer extends AbstractClassTransf
|
||||
return target.visitMethod(access, name, desc, signature, exceptions);
|
||||
}
|
||||
|
||||
public void visitEnd() {
|
||||
@Override
|
||||
public void visitEnd() {
|
||||
target.visitEnd();
|
||||
target = null; // just to be safe
|
||||
}
|
||||
|
||||
@@ -15,80 +15,79 @@
|
||||
*/
|
||||
package org.springframework.cglib.transform;
|
||||
|
||||
import org.springframework.cglib.core.CodeGenerationException;
|
||||
import org.springframework.cglib.core.ClassGenerator;
|
||||
import org.springframework.cglib.core.DebuggingClassWriter;
|
||||
import java.io.IOException;
|
||||
|
||||
import org.springframework.asm.Attribute;
|
||||
import org.springframework.asm.ClassReader;
|
||||
import org.springframework.asm.ClassWriter;
|
||||
import org.springframework.asm.Attribute;
|
||||
|
||||
import java.io.IOException;
|
||||
import org.springframework.cglib.core.ClassGenerator;
|
||||
import org.springframework.cglib.core.CodeGenerationException;
|
||||
import org.springframework.cglib.core.DebuggingClassWriter;
|
||||
|
||||
@SuppressWarnings({"rawtypes", "unchecked"})
|
||||
abstract public class AbstractClassLoader extends ClassLoader {
|
||||
private ClassFilter filter;
|
||||
private ClassLoader classPath;
|
||||
private static java.security.ProtectionDomain DOMAIN ;
|
||||
|
||||
|
||||
static{
|
||||
DOMAIN = AbstractClassLoader.class.getProtectionDomain();
|
||||
}
|
||||
|
||||
|
||||
protected AbstractClassLoader(ClassLoader parent, ClassLoader classPath, ClassFilter filter) {
|
||||
super(parent);
|
||||
this.filter = filter;
|
||||
this.classPath = classPath;
|
||||
}
|
||||
|
||||
public Class loadClass(String name) throws ClassNotFoundException {
|
||||
|
||||
@Override
|
||||
public Class loadClass(String name) throws ClassNotFoundException {
|
||||
|
||||
Class loaded = findLoadedClass(name);
|
||||
|
||||
|
||||
if( loaded != null ){
|
||||
if( loaded.getClassLoader() == this ){
|
||||
return loaded;
|
||||
}//else reload with this class loader
|
||||
}
|
||||
|
||||
|
||||
if (!filter.accept(name)) {
|
||||
return super.loadClass(name);
|
||||
}
|
||||
ClassReader r;
|
||||
try {
|
||||
|
||||
java.io.InputStream is = classPath.getResourceAsStream(
|
||||
|
||||
java.io.InputStream is = classPath.getResourceAsStream(
|
||||
name.replace('.','/') + ".class"
|
||||
);
|
||||
|
||||
);
|
||||
|
||||
if (is == null) {
|
||||
|
||||
|
||||
throw new ClassNotFoundException(name);
|
||||
|
||||
|
||||
}
|
||||
try {
|
||||
|
||||
try {
|
||||
|
||||
r = new ClassReader(is);
|
||||
|
||||
|
||||
} finally {
|
||||
|
||||
|
||||
is.close();
|
||||
|
||||
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new ClassNotFoundException(name + ":" + e.getMessage());
|
||||
}
|
||||
|
||||
try {
|
||||
DebuggingClassWriter w =
|
||||
DebuggingClassWriter w =
|
||||
new DebuggingClassWriter(ClassWriter.COMPUTE_FRAMES);
|
||||
getGenerator(r).generateClass(w);
|
||||
byte[] b = w.toByteArray();
|
||||
Class c = super.defineClass(name, b, 0, b.length, DOMAIN);
|
||||
postProcess(c);
|
||||
return c;
|
||||
} catch (RuntimeException e) {
|
||||
throw e;
|
||||
} catch (Error e) {
|
||||
} catch (RuntimeException | Error e) {
|
||||
throw e;
|
||||
} catch (Exception e) {
|
||||
throw new CodeGenerationException(e);
|
||||
@@ -102,7 +101,7 @@ abstract public class AbstractClassLoader extends ClassLoader {
|
||||
protected int getFlags() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
protected Attribute[] attributes() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -15,16 +15,17 @@
|
||||
*/
|
||||
package org.springframework.cglib.transform;
|
||||
|
||||
import org.springframework.asm.ClassVisitor;
|
||||
import org.springframework.cglib.core.ClassTransformer;
|
||||
import org.springframework.cglib.core.Constants;
|
||||
import org.springframework.asm.ClassVisitor;
|
||||
|
||||
abstract public class AbstractClassTransformer extends ClassTransformer {
|
||||
protected AbstractClassTransformer() {
|
||||
super(Constants.ASM_API);
|
||||
}
|
||||
|
||||
public void setTarget(ClassVisitor target) {
|
||||
@Override
|
||||
public void setTarget(ClassVisitor target) {
|
||||
cv = target;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,17 +15,19 @@
|
||||
*/
|
||||
package org.springframework.cglib.transform;
|
||||
|
||||
import org.springframework.cglib.core.Constants;
|
||||
import org.springframework.asm.AnnotationVisitor;
|
||||
import org.springframework.cglib.core.Constants;
|
||||
|
||||
public class AnnotationVisitorTee extends AnnotationVisitor {
|
||||
private AnnotationVisitor av1, av2;
|
||||
|
||||
public static AnnotationVisitor getInstance(AnnotationVisitor av1, AnnotationVisitor av2) {
|
||||
if (av1 == null)
|
||||
return av2;
|
||||
if (av2 == null)
|
||||
return av1;
|
||||
if (av1 == null) {
|
||||
return av2;
|
||||
}
|
||||
if (av2 == null) {
|
||||
return av1;
|
||||
}
|
||||
return new AnnotationVisitorTee(av1, av2);
|
||||
}
|
||||
|
||||
@@ -35,26 +37,31 @@ public class AnnotationVisitorTee extends AnnotationVisitor {
|
||||
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);
|
||||
}
|
||||
|
||||
public void visitEnum(String name, String desc, String value) {
|
||||
|
||||
@Override
|
||||
public void visitEnum(String name, String desc, String value) {
|
||||
av1.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),
|
||||
av2.visitAnnotation(name, desc));
|
||||
}
|
||||
|
||||
public AnnotationVisitor visitArray(String name) {
|
||||
|
||||
@Override
|
||||
public AnnotationVisitor visitArray(String name) {
|
||||
return getInstance(av1.visitArray(name), av2.visitArray(name));
|
||||
}
|
||||
|
||||
public void visitEnd() {
|
||||
|
||||
@Override
|
||||
public void visitEnd() {
|
||||
av1.visitEnd();
|
||||
av2.visitEnd();
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ package org.springframework.cglib.transform;
|
||||
* @author baliuka
|
||||
*/
|
||||
public interface ClassFilter {
|
||||
|
||||
|
||||
boolean accept(String className);
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -15,16 +15,16 @@
|
||||
*/
|
||||
package org.springframework.cglib.transform;
|
||||
|
||||
import org.springframework.cglib.core.ClassGenerator;
|
||||
import org.springframework.asm.Attribute;
|
||||
import org.springframework.asm.ClassReader;
|
||||
import org.springframework.asm.ClassVisitor;
|
||||
import org.springframework.cglib.core.ClassGenerator;
|
||||
|
||||
public class ClassReaderGenerator implements ClassGenerator {
|
||||
private final ClassReader r;
|
||||
private final Attribute[] attrs;
|
||||
private final int flags;
|
||||
|
||||
|
||||
public ClassReaderGenerator(ClassReader r, int flags) {
|
||||
this(r, null, flags);
|
||||
}
|
||||
@@ -34,8 +34,9 @@ public class ClassReaderGenerator implements ClassGenerator {
|
||||
this.attrs = (attrs != null) ? attrs : new Attribute[0];
|
||||
this.flags = flags;
|
||||
}
|
||||
|
||||
public void generateClass(ClassVisitor v) {
|
||||
|
||||
@Override
|
||||
public void generateClass(ClassVisitor v) {
|
||||
r.accept(v, attrs, flags);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,12 +21,13 @@ import org.springframework.cglib.core.ClassTransformer;
|
||||
|
||||
public class ClassTransformerChain extends AbstractClassTransformer {
|
||||
private ClassTransformer[] chain;
|
||||
|
||||
|
||||
public ClassTransformerChain(ClassTransformer[] chain) {
|
||||
this.chain = chain.clone();
|
||||
}
|
||||
|
||||
public void setTarget(ClassVisitor v) {
|
||||
@Override
|
||||
public void setTarget(ClassVisitor v) {
|
||||
super.setTarget(chain[0]);
|
||||
ClassVisitor next = v;
|
||||
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 desc,
|
||||
String signature,
|
||||
@@ -43,7 +45,8 @@ public class ClassTransformerChain extends AbstractClassTransformer {
|
||||
return cv.visitMethod(access, name, desc, signature, exceptions);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("ClassTransformerChain{");
|
||||
for (int i = 0; i < chain.length; i++) {
|
||||
|
||||
@@ -15,19 +15,20 @@
|
||||
*/
|
||||
package org.springframework.cglib.transform;
|
||||
|
||||
import org.springframework.asm.ClassVisitor;
|
||||
import org.springframework.cglib.core.ClassTransformer;
|
||||
import org.springframework.cglib.core.Constants;
|
||||
import org.springframework.asm.ClassVisitor;
|
||||
|
||||
public class ClassTransformerTee extends ClassTransformer {
|
||||
private ClassVisitor branch;
|
||||
|
||||
|
||||
public ClassTransformerTee(ClassVisitor branch) {
|
||||
super(Constants.ASM_API);
|
||||
this.branch = branch;
|
||||
}
|
||||
|
||||
public void setTarget(ClassVisitor target) {
|
||||
|
||||
@Override
|
||||
public void setTarget(ClassVisitor target) {
|
||||
cv = new ClassVisitorTee(branch, target);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,14 +25,15 @@ import org.springframework.cglib.core.Constants;
|
||||
|
||||
public class ClassVisitorTee extends ClassVisitor {
|
||||
private ClassVisitor cv1, cv2;
|
||||
|
||||
|
||||
public ClassVisitorTee(ClassVisitor cv1, ClassVisitor cv2) {
|
||||
super(Constants.ASM_API);
|
||||
this.cv1 = cv1;
|
||||
this.cv2 = cv2;
|
||||
}
|
||||
|
||||
public void visit(int version,
|
||||
@Override
|
||||
public void visit(int version,
|
||||
int access,
|
||||
String name,
|
||||
String signature,
|
||||
@@ -42,67 +43,80 @@ public class ClassVisitorTee extends ClassVisitor {
|
||||
cv2.visit(version, access, name, signature, superName, interfaces);
|
||||
}
|
||||
|
||||
public void visitEnd() {
|
||||
@Override
|
||||
public void visitEnd() {
|
||||
cv1.visitEnd();
|
||||
cv2.visitEnd();
|
||||
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);
|
||||
cv2.visitInnerClass(name, outerName, innerName, access);
|
||||
}
|
||||
|
||||
public FieldVisitor visitField(int access,
|
||||
@Override
|
||||
public FieldVisitor visitField(int access,
|
||||
String name,
|
||||
String desc,
|
||||
String signature,
|
||||
Object value) {
|
||||
FieldVisitor fv1 = cv1.visitField(access, name, desc, signature, value);
|
||||
FieldVisitor fv2 = cv2.visitField(access, name, desc, signature, value);
|
||||
if (fv1 == null)
|
||||
return fv2;
|
||||
if (fv2 == null)
|
||||
return fv1;
|
||||
if (fv1 == null) {
|
||||
return fv2;
|
||||
}
|
||||
if (fv2 == null) {
|
||||
return fv1;
|
||||
}
|
||||
return new FieldVisitorTee(fv1, fv2);
|
||||
}
|
||||
|
||||
|
||||
public MethodVisitor visitMethod(int access,
|
||||
@Override
|
||||
public MethodVisitor visitMethod(int access,
|
||||
String name,
|
||||
String desc,
|
||||
String signature,
|
||||
String[] exceptions) {
|
||||
MethodVisitor mv1 = cv1.visitMethod(access, name, desc, signature, exceptions);
|
||||
MethodVisitor mv2 = cv2.visitMethod(access, name, desc, signature, exceptions);
|
||||
if (mv1 == null)
|
||||
return mv2;
|
||||
if (mv2 == null)
|
||||
return mv1;
|
||||
if (mv1 == null) {
|
||||
return mv2;
|
||||
}
|
||||
if (mv2 == null) {
|
||||
return mv1;
|
||||
}
|
||||
return new MethodVisitorTee(mv1, mv2);
|
||||
}
|
||||
|
||||
public void visitSource(String source, String debug) {
|
||||
@Override
|
||||
public void visitSource(String source, String debug) {
|
||||
cv1.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);
|
||||
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),
|
||||
cv2.visitAnnotation(desc, visible));
|
||||
}
|
||||
|
||||
public void visitAttribute(Attribute attrs) {
|
||||
|
||||
@Override
|
||||
public void visitAttribute(Attribute attrs) {
|
||||
cv1.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),
|
||||
cv2.visitTypeAnnotation(typeRef, typePath, desc, visible));
|
||||
}
|
||||
|
||||
@@ -15,37 +15,41 @@
|
||||
*/
|
||||
package org.springframework.cglib.transform;
|
||||
|
||||
import org.springframework.cglib.core.Constants;
|
||||
import org.springframework.asm.AnnotationVisitor;
|
||||
import org.springframework.asm.Attribute;
|
||||
import org.springframework.asm.FieldVisitor;
|
||||
import org.springframework.asm.TypePath;
|
||||
import org.springframework.cglib.core.Constants;
|
||||
|
||||
public class FieldVisitorTee extends FieldVisitor {
|
||||
private FieldVisitor fv1, fv2;
|
||||
|
||||
|
||||
public FieldVisitorTee(FieldVisitor fv1, FieldVisitor fv2) {
|
||||
super(Constants.ASM_API);
|
||||
this.fv1 = fv1;
|
||||
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),
|
||||
fv2.visitAnnotation(desc, visible));
|
||||
}
|
||||
|
||||
public void visitAttribute(Attribute attr) {
|
||||
|
||||
@Override
|
||||
public void visitAttribute(Attribute attr) {
|
||||
fv1.visitAttribute(attr);
|
||||
fv2.visitAttribute(attr);
|
||||
}
|
||||
|
||||
public void visitEnd() {
|
||||
@Override
|
||||
public void visitEnd() {
|
||||
fv1.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),
|
||||
fv2.visitTypeAnnotation(typeRef, typePath, desc, visible));
|
||||
}
|
||||
|
||||
@@ -23,22 +23,24 @@ public class MethodFilterTransformer extends AbstractClassTransformer {
|
||||
private MethodFilter filter;
|
||||
private ClassTransformer pass;
|
||||
private ClassVisitor direct;
|
||||
|
||||
|
||||
public MethodFilterTransformer(MethodFilter filter, ClassTransformer pass) {
|
||||
this.filter = filter;
|
||||
this.pass = pass;
|
||||
super.setTarget(pass);
|
||||
}
|
||||
|
||||
public MethodVisitor visitMethod(int access,
|
||||
@Override
|
||||
public MethodVisitor visitMethod(int access,
|
||||
String name,
|
||||
String desc,
|
||||
String signature,
|
||||
String[] 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);
|
||||
direct = target;
|
||||
}
|
||||
|
||||
@@ -27,166 +27,197 @@ import org.springframework.cglib.core.Constants;
|
||||
public class MethodVisitorTee extends MethodVisitor {
|
||||
private final MethodVisitor mv1;
|
||||
private final MethodVisitor mv2;
|
||||
|
||||
|
||||
public MethodVisitorTee(MethodVisitor mv1, MethodVisitor mv2) {
|
||||
super(Constants.ASM_API);
|
||||
this.mv1 = mv1;
|
||||
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);
|
||||
mv2.visitFrame(type, nLocal, local, nStack, stack);
|
||||
}
|
||||
|
||||
public AnnotationVisitor visitAnnotationDefault() {
|
||||
@Override
|
||||
public AnnotationVisitor visitAnnotationDefault() {
|
||||
return AnnotationVisitorTee.getInstance(mv1.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),
|
||||
mv2.visitAnnotation(desc, visible));
|
||||
}
|
||||
|
||||
public AnnotationVisitor visitParameterAnnotation(int parameter,
|
||||
|
||||
@Override
|
||||
public AnnotationVisitor visitParameterAnnotation(int parameter,
|
||||
String desc,
|
||||
boolean visible) {
|
||||
return AnnotationVisitorTee.getInstance(mv1.visitParameterAnnotation(parameter, desc, visible),
|
||||
mv2.visitParameterAnnotation(parameter, desc, visible));
|
||||
}
|
||||
|
||||
public void visitAttribute(Attribute attr) {
|
||||
@Override
|
||||
public void visitAttribute(Attribute attr) {
|
||||
mv1.visitAttribute(attr);
|
||||
mv2.visitAttribute(attr);
|
||||
}
|
||||
|
||||
public void visitCode() {
|
||||
|
||||
@Override
|
||||
public void visitCode() {
|
||||
mv1.visitCode();
|
||||
mv2.visitCode();
|
||||
}
|
||||
|
||||
public void visitInsn(int opcode) {
|
||||
|
||||
@Override
|
||||
public void visitInsn(int opcode) {
|
||||
mv1.visitInsn(opcode);
|
||||
mv2.visitInsn(opcode);
|
||||
}
|
||||
|
||||
public void visitIntInsn(int opcode, int operand) {
|
||||
|
||||
@Override
|
||||
public void visitIntInsn(int opcode, int operand) {
|
||||
mv1.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);
|
||||
mv2.visitVarInsn(opcode, var);
|
||||
}
|
||||
|
||||
public void visitTypeInsn(int opcode, String desc) {
|
||||
|
||||
@Override
|
||||
public void visitTypeInsn(int opcode, String desc) {
|
||||
mv1.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);
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
mv2.visitJumpInsn(opcode, label);
|
||||
}
|
||||
|
||||
public void visitLabel(Label label) {
|
||||
|
||||
@Override
|
||||
public void visitLabel(Label label) {
|
||||
mv1.visitLabel(label);
|
||||
mv2.visitLabel(label);
|
||||
}
|
||||
|
||||
public void visitLdcInsn(Object cst) {
|
||||
|
||||
@Override
|
||||
public void visitLdcInsn(Object cst) {
|
||||
mv1.visitLdcInsn(cst);
|
||||
mv2.visitLdcInsn(cst);
|
||||
}
|
||||
|
||||
public void visitIincInsn(int var, int increment) {
|
||||
|
||||
@Override
|
||||
public void visitIincInsn(int var, int increment) {
|
||||
mv1.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);
|
||||
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);
|
||||
mv2.visitLookupSwitchInsn(dflt, keys, labels);
|
||||
}
|
||||
|
||||
public void visitMultiANewArrayInsn(String desc, int dims) {
|
||||
|
||||
@Override
|
||||
public void visitMultiANewArrayInsn(String desc, int dims) {
|
||||
mv1.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);
|
||||
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);
|
||||
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);
|
||||
mv2.visitLineNumber(line, start);
|
||||
}
|
||||
|
||||
public void visitMaxs(int maxStack, int maxLocals) {
|
||||
|
||||
@Override
|
||||
public void visitMaxs(int maxStack, int maxLocals) {
|
||||
mv1.visitMaxs(maxStack, maxLocals);
|
||||
mv2.visitMaxs(maxStack, maxLocals);
|
||||
}
|
||||
|
||||
public void visitEnd() {
|
||||
|
||||
@Override
|
||||
public void visitEnd() {
|
||||
mv1.visitEnd();
|
||||
mv2.visitEnd();
|
||||
}
|
||||
|
||||
public void visitParameter(String name, int access) {
|
||||
@Override
|
||||
public void visitParameter(String name, int access) {
|
||||
mv1.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),
|
||||
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);
|
||||
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),
|
||||
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),
|
||||
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),
|
||||
mv2.visitLocalVariableAnnotation(typeRef, typePath, start, end, index, desc, visible));
|
||||
}
|
||||
|
||||
@@ -19,24 +19,42 @@ package org.springframework.cglib.transform.impl;
|
||||
* @author Chris Nokleberg
|
||||
*/
|
||||
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; }
|
||||
public char readChar(Object obj, String name, char oldValue) { return oldValue; }
|
||||
public byte readByte(Object obj, String name, byte oldValue) { return oldValue; }
|
||||
public boolean readBoolean(Object obj, String name, boolean oldValue) { return oldValue; }
|
||||
public short readShort(Object obj, String name, short oldValue) { return oldValue; }
|
||||
public float readFloat(Object obj, String name, float oldValue) { return oldValue; }
|
||||
public double readDouble(Object obj, String name, double oldValue) { return oldValue; }
|
||||
public long readLong(Object obj, String name, long oldValue) { return oldValue; }
|
||||
public Object readObject(Object obj, String name, Object oldValue) { return oldValue; }
|
||||
@Override
|
||||
public int writeInt(Object obj, String name, int oldValue, int newValue) { return newValue; }
|
||||
@Override
|
||||
public char writeChar(Object obj, String name, char oldValue, char newValue) { return newValue; }
|
||||
@Override
|
||||
public byte writeByte(Object obj, String name, byte oldValue, byte newValue) { return newValue; }
|
||||
@Override
|
||||
public boolean writeBoolean(Object obj, String name, boolean oldValue, boolean newValue) { return newValue; }
|
||||
@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; }
|
||||
}
|
||||
|
||||
@@ -65,11 +65,11 @@ public class AddDelegateTransformer extends ClassEmitterTransformer {
|
||||
DELEGATE,
|
||||
delegateType,
|
||||
null);
|
||||
for (int i = 0; i < delegateIf.length; i++) {
|
||||
Method[] methods = delegateIf[i].getMethods();
|
||||
for (int j = 0; j < methods.length; j++) {
|
||||
if (Modifier.isAbstract(methods[j].getModifiers())) {
|
||||
addDelegate(methods[j]);
|
||||
for (Class element : delegateIf) {
|
||||
Method[] methods = element.getMethods();
|
||||
for (Method method : methods) {
|
||||
if (Modifier.isAbstract(method.getModifiers())) {
|
||||
addDelegate(method);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,10 +15,12 @@
|
||||
*/
|
||||
package org.springframework.cglib.transform.impl;
|
||||
|
||||
import org.springframework.cglib.transform.*;
|
||||
import java.util.*;
|
||||
import org.springframework.cglib.core.*;
|
||||
import java.util.Map;
|
||||
|
||||
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"})
|
||||
public class AddPropertyTransformer extends ClassEmitterTransformer {
|
||||
@@ -39,7 +41,8 @@ public class AddPropertyTransformer extends ClassEmitterTransformer {
|
||||
this.types = types;
|
||||
}
|
||||
|
||||
public void end_class() {
|
||||
@Override
|
||||
public void end_class() {
|
||||
if (!TypeUtils.isAbstract(getAccess())) {
|
||||
EmitUtils.add_properties(this, names, types);
|
||||
}
|
||||
|
||||
@@ -16,9 +16,15 @@
|
||||
package org.springframework.cglib.transform.impl;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import org.springframework.cglib.core.*;
|
||||
import org.springframework.cglib.transform.*;
|
||||
|
||||
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
|
||||
@@ -39,7 +45,8 @@ public class AddStaticInitTransformer extends ClassEmitterTransformer {
|
||||
}
|
||||
}
|
||||
|
||||
protected void init() {
|
||||
@Override
|
||||
protected void init() {
|
||||
if (!TypeUtils.isInterface(getAccess())) {
|
||||
CodeEmitter e = getStaticHook();
|
||||
EmitUtils.load_class_this(e);
|
||||
|
||||
@@ -17,17 +17,17 @@ package org.springframework.cglib.transform.impl;
|
||||
|
||||
@SuppressWarnings({"rawtypes", "unchecked"})
|
||||
public interface FieldProvider {
|
||||
|
||||
|
||||
String[] getFieldNames();
|
||||
|
||||
|
||||
Class[] getFieldTypes();
|
||||
|
||||
|
||||
void setField(int index, Object value);
|
||||
|
||||
|
||||
Object getField(int index);
|
||||
|
||||
void setField(String name, Object value);
|
||||
|
||||
|
||||
Object getField(String name);
|
||||
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ package org.springframework.cglib.transform.impl;
|
||||
* @author Juozas Baliuka
|
||||
*/
|
||||
public interface InterceptFieldCallback {
|
||||
|
||||
|
||||
int writeInt(Object obj, String name, int oldValue, int newValue);
|
||||
char writeChar(Object obj, String name, char oldValue, char newValue);
|
||||
byte writeByte(Object obj, String name, byte oldValue, byte newValue);
|
||||
|
||||
@@ -15,10 +15,14 @@
|
||||
*/
|
||||
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.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
|
||||
@@ -35,15 +39,16 @@ public class InterceptFieldTransformer extends ClassEmitterTransformer {
|
||||
new Signature("getInterceptFieldCallback", CALLBACK, new Type[0]);
|
||||
|
||||
private InterceptFieldFilter filter;
|
||||
|
||||
|
||||
public InterceptFieldTransformer(InterceptFieldFilter 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)) {
|
||||
super.begin_class(version, access, className, superType, TypeUtils.add(interfaces, ENABLED), sourceFile);
|
||||
|
||||
|
||||
super.declare_field(Constants.ACC_PRIVATE | Constants.ACC_TRANSIENT,
|
||||
CALLBACK_FIELD,
|
||||
CALLBACK,
|
||||
@@ -55,7 +60,7 @@ public class InterceptFieldTransformer extends ClassEmitterTransformer {
|
||||
e.getfield(CALLBACK_FIELD);
|
||||
e.return_value();
|
||||
e.end_method();
|
||||
|
||||
|
||||
e = super.begin_method(Constants.ACC_PUBLIC, ENABLED_SET, null);
|
||||
e.load_this();
|
||||
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);
|
||||
if (!TypeUtils.isStatic(access)) {
|
||||
if (filter.acceptRead(getClassType(), name)) {
|
||||
@@ -137,10 +143,12 @@ public class InterceptFieldTransformer extends ClassEmitterTransformer {
|
||||
e.return_value();
|
||||
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)) {
|
||||
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);
|
||||
switch (opcode) {
|
||||
case Constants.GETFIELD:
|
||||
|
||||
@@ -16,10 +16,10 @@
|
||||
package org.springframework.cglib.transform.impl;
|
||||
|
||||
import org.springframework.cglib.core.ClassGenerator;
|
||||
import org.springframework.cglib.core.ClassTransformer;
|
||||
import org.springframework.cglib.core.DefaultGeneratorStrategy;
|
||||
import org.springframework.cglib.core.GeneratorStrategy;
|
||||
import org.springframework.cglib.core.TypeUtils;
|
||||
import org.springframework.cglib.core.ClassTransformer;
|
||||
import org.springframework.cglib.transform.MethodFilter;
|
||||
import org.springframework.cglib.transform.MethodFilterTransformer;
|
||||
import org.springframework.cglib.transform.TransformingClassGenerator;
|
||||
@@ -45,14 +45,11 @@ public class UndeclaredThrowableStrategy extends DefaultGeneratorStrategy {
|
||||
public UndeclaredThrowableStrategy(Class 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);
|
||||
tr = new MethodFilterTransformer(TRANSFORM_FILTER, tr);
|
||||
return new TransformingClassGenerator(cg, tr);
|
||||
|
||||
@@ -36,15 +36,16 @@ public class UndeclaredThrowableTransformer extends ClassEmitterTransformer {
|
||||
this.wrapper = Type.getType(wrapper);
|
||||
boolean found = false;
|
||||
Constructor[] cstructs = wrapper.getConstructors();
|
||||
for (int i = 0; i < cstructs.length; i++) {
|
||||
Class[] types = cstructs[i].getParameterTypes();
|
||||
for (Constructor cstruct : cstructs) {
|
||||
Class[] types = cstruct.getParameterTypes();
|
||||
if (types.length == 1 && types[0].equals(Throwable.class)) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found)
|
||||
throw new IllegalArgumentException(wrapper + " does not have a single-arg constructor that takes a Throwable");
|
||||
if (!found) {
|
||||
throw new IllegalArgumentException(wrapper + " does not have a single-arg constructor that takes a Throwable");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -290,9 +290,9 @@ abstract public class ParallelSorter extends SorterTemplate {
|
||||
if (arrays.length == 0) {
|
||||
throw new IllegalArgumentException("No arrays specified to sort");
|
||||
}
|
||||
for (int i = 0; i < arrays.length; i++) {
|
||||
if (!arrays[i].getClass().isArray()) {
|
||||
throw new IllegalArgumentException(arrays[i].getClass() + " is not an array");
|
||||
for (Object array : arrays) {
|
||||
if (!array.getClass().isArray()) {
|
||||
throw new IllegalArgumentException(array.getClass() + " is not an array");
|
||||
}
|
||||
}
|
||||
new ParallelSorterEmitter(v, getClassName(), arrays);
|
||||
|
||||
@@ -50,10 +50,10 @@ abstract class SorterTemplate {
|
||||
int v = j;
|
||||
for (;;) {
|
||||
while (compare(++i, v) < 0) {
|
||||
/* nothing */;
|
||||
/* nothing */
|
||||
}
|
||||
while (compare(--j, v) > 0) {
|
||||
/* nothing */;
|
||||
/* nothing */
|
||||
}
|
||||
if (j < i) {
|
||||
break;
|
||||
|
||||
Reference in New Issue
Block a user